title: Drawing text on canvas by the letter to control the alpha of individual letters while being aligned to centre
body: <p>I am trying to draw some letters to a canvas in a very specific way - able to target individual letters and apply an alpha. 
  These words need to be centered on the baseline and aligned center in the canvas and filled with strokeText rather than fill style. </p>
  
  <p>The text also needs to be line broken resulting in eg;</p>
  
  <p><a href="https://i.stack.imgur.com/YXN7y.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YXN7y.png" alt="enter image description here"></a></p>
  
  <p>Now, I have tried several ways of getting this out - it works fine (without the fade) when writing out the words (as full words) - however when I attempt to write them out as individual letters I cannot center them correctly. My code is below omitting the alpha on the specific letters, which once I can center things correctly shouldn't be an issue!</p>
  
  <p>I realize the issue is I am trying to draw each letter separately centered at 0 on the canvas and adding letter spacing for each letter, but given the different size of the middle line I cannot figure a way to have them centered!</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var can = document.querySelector('canvas'),
      ctx = can.getContext('2d');
      
   function drawStroked(text, fontSize, color, offsetX, offsetY) {
          let line = text.split('\n');
          this.ctx.font = fontSize + 'px ' + 'TimesNewRoman';
          this.ctx.strokeStyle = color;
          this.ctx.lineWidth = 2;
          this.ctx.textBaseline = 'middle';
          this.ctx.textAlign = 'center';
          let positionX = this.ctx.canvas.width/3;
          let positionY = this.ctx.canvas.height/4;
  
          if(offsetX !== 0) {
              positionX += offsetX;
          }
  
          if(offsetY !== 0) {
              positionY += offsetY;
          }
          for (var i = 0; i &lt; line.length; i++) {
              for (var j = 0; j &lt; line[i].length; j++) {
                  let letterSpacing = 0;
                  let lineHeight = positionY;
  
                  if(line[i][j] === line[i].length) {
                      lineHeight = lineHeight * i;
                  }
              this.ctx.strokeText(line[i][j], positionX + (letterSpacing + (j*130)), positionY + (i*fontSize));
              }
          }
      }
      
  drawStroked('THIS\nIS THE\nTEXT', 100, '#000', 0, 0);</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;canvas width="1000" height="1000"&gt;&lt;/canvas&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <hr>
  
  <h2>Resulting output &amp; Finished code thanks to Blindman67!</h2>
  
  <p><a href="https://i.stack.imgur.com/ixz4d.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ixz4d.jpg" alt="enter image description here"></a></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>const Hero = class {
      constructor(pos, canvas) {
          this.position = document.getElementById(pos);
          this.canvas = document.getElementById(canvas);
          this.height = document.getElementsByClassName('home')[0].clientHeight;
          this.width = this.position.offsetWidth;
          this.ctx = this.canvas.getContext('2d');
          this.title = 'THIS\nIS THE\nTEXT';
          this.canvas.width = this.width;
          this.canvas.height = this.height;
  
          this._init_ui();
      }
  
      // Draw text to text canvas
      _init_ui() {
          // BLUE
          this.drawStroked(300, '#1816ff', -3, 2, 0.95, [1, 5, 9, 12]);
          // GREEN
          this.drawStroked(300, '#1bff32', 0, 0, 0.95, [1, 5, 9, 12]);
          // RED
          this.drawStroked(300, '#ff162f', 3, -2, 0.95, [1, 5, 9, 12]);
      }
  
      drawStroked(fontSize, color, offsetX, offsetY, textVertSpacing, fade) {
          // Random Char's to scramble through --- to do
          // let chars = '!&lt;&gt;-_\\/[]{}—=+*^?#________';
          // The words
          let line = this.title.split('\n');
          // Set the font + size
          this.ctx.font = fontSize + 'px ' + 'Kommissar';
          // Set the colour - NEED TO ADD ALPHA LOGIC
          this.ctx.strokeStyle = color;
          // Set the stroke width
          this.ctx.lineWidth = 1;
          // Set the baseline
          this.ctx.textBaseline = 'middle';
          // Set the align
          this.ctx.textAlign = 'center';
  
          let positionX = this.width/2;
          let positionY = this.height/4;
          positionX += offsetX;
          positionY += offsetY;
  
          let charIndex = 0;
  
          for (var i = 0; i &lt; line.length; i++) {
              // get the width of the whole line
              let width = this.ctx.measureText(line[i]).width;
              console.log(width);
              // use the width to find start
              var textPosX = positionX - width / 2;
  
              for (let j = 0; j &lt; line[i].length; j++) {
                  // get char
                  let char = line[i][j];
                  // get its width
                  let cWidth = this.ctx.measureText(char).width;
                  // check if char needs to fade
                  if (fade.indexOf(charIndex) &gt; -1) {
                      this.ctx.globalAlpha = 0.2;
                  } else {
                      this.ctx.globalAlpha = 1;
                  }
                  // draw the char offset by half its width (center)
                  this.ctx.strokeText(char, textPosX + cWidth / 2, positionY);
                  // move too the next pos
                  textPosX += cWidth;
                  // count the char
                  charIndex += 1;
              }
              // move down one line
              positionY += fontSize * textVertSpacing;
          }
      }
  };
  
  export default Hero;</code></pre>
  </div>
  </div>
  </p>