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. 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>