Canvas renders drawing but it extends outside the canvas

504 Views Asked by At

I'm new to using Canvas in javascript. I have Web Speech API detecting words said by the user. The canvas then renders this as points of text outline using opentype.js library. However when the user says a longer line, I would like the text to draw the word further down the Y axis. Attaching an image of the problem.enter image description here This is what I've got so far -

JS

var fontFileName = 'fonts/SourceCodePro-Regular.otf';
var font = null; // font object filled once font loads
var fontSize = 60;
var textToRender = "SHWING!"; // holds string value
var drawPoints = false; // bool to draw letterform points
var drawMetrics = false; // bool for drawing grid
var kerning = true; // apply letter spacing
var ligatures = true; // a ligature occurs where two or more graphemes or letters are joined as a single glyph eg fi
var hinting = false; // Hinting, or screen optimising, is the process by which TrueType or PostScript fonts are adjusted for maximum readability on computer monitors.
var snapPath = null; // path of letterforms
var snapStrength = 10; // letter strength
var snapDistance = 10; // 
var snapX = 0; // x axis for each letter
var snapY = 0; // y axis for each letter
var fontSizeSlider = document.getElementById("font-size-range");

let recognition = new SpeechRecognition();
recognition.continuous = true;
recognition.lang = 'en-US';
recognition.interimResults = false;
recognition.maxAlternatives = 1
const recordbtn = document.getElementById('record');

recordbtn.addEventListener('click', () => {
   // start speech rec
   recognition.start();
   initialiseMic()
})

recognition.onresult = function (event) {
   let current = event.resultIndex
   textToRender = event.results[current][0].transcript

   renderText()
}

function renderText() {
   if (!font) return;

   var options = {
      kerning: kerning,
      hinting: hinting,
      features: {
         liga: ligatures,
         rlig: ligatures
      }
   };
   //  path of points 
   snapPath = font.getPath(textToRender, 0, 200, fontSize, options);
   // snap points into grid
   doSnap(snapPath);
   var snapCtx = document.getElementById('snap').getContext('2d');
   // clear canvas before drawing
   snapCtx.clearRect(0, 0, 940, 300);
   snapPath.draw(snapCtx);

   if (drawPoints) { // create points of text form
      font.drawPoints(snapCtx, textToRender, 0, 200, fontSize, options);
   }
   if (drawMetrics) { // create a visual grid for each letter
      font.drawMetrics(snapCtx, textToRender, 0, 200, fontSize, options);
   }
}


// Round a value to the nearest "step".
function snap(v, distance, strength) {
   return (v * (1.0 - strength)) + (strength * Math.round(v / distance) * distance);
}

function doSnap(path) {

   var strength = snapStrength / 100.0;

   for (let i = 0; i < path.commands.length; i++) {
      var cmd = path.commands[i];
      if (cmd.type !== 'Z') {
         // 'z' indicates a closed path
         cmd.x = snap(cmd.x + snapX, snapDistance, strength) - snapX;
         cmd.y = snap(cmd.y + snapY, snapDistance, strength) - snapY;
      }
      if (cmd.type === 'Q' || cmd.type === 'C') {
         // 'C' is curveTo and 'Q' is quadratic Béziers
         cmd.x1 = snap(cmd.x1 + snapX, snapDistance, strength) - snapX;
         cmd.y1 = snap(cmd.y1 + snapY, snapDistance, strength) - snapY;
      }
      if (cmd.type === 'C') {
         // 'C' is curveTo
         cmd.x2 = snap(cmd.x2 + snapX, snapDistance, strength) - snapX;
         cmd.y2 = snap(cmd.y2 + snapY, snapDistance, strength) - snapY;
      }
   }
}

HTML

<!DOCTYPE html>
<html>

<head>
   <title>Prototype 3</title>
   <meta name="description" content="A prototype to change the letterforms of text with speech analysis">
   <meta charset="utf-8">
   <script src="https://cdn.socket.io/socket.io-3.0.1.min.js"></script>
   <script type="text/javascript" src="libraries/opentype.js"></script>
   <link rel="stylesheet" href="style.css">
</head>

<body>
   <!-- title -->
   <div class="container">
      <span class="info" id="font-name"></span>

      <button id ="record">Record</button>
      
      <!-- font size -->
      <label>Font Size<input type="range" min="6" max="500" step="2" value="150" id="font-size-range"
            autocomplete="off"><span id="fontSize">150</span></label>

   </div>

   <div class="container2">
      <canvas id="snap" width="940" height="600" class="text"></canvas>
   </div>
   <script src="sketch.js" type="text/javascript"></script>
</body>

</html>
0

There are 0 best solutions below