JSFiddle - React, Tailwind, and code Playground
Font Kerning & Letter Spacing: HTML Text vs SVG on Canvas
by skibulk
HTML
<div class="layer">
<p style="font-family: Arial">Lorem ipsum dolor sit amet</p>
<p style="font-family: Verdana">Lorem ipsum dolor sit amet</p>
<p style="font-family: 'Times New Roman'">Lorem ipsum dolor sit amet</p>
<p style="font-family: Georgia">Lorem ipsum dolor sit amet</p>
</div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="layer">
<style>
text {
font-size: 24px;
text-rendering: geometricPrecision;
}
</style>
<text x="0" y="24" font-family="Arial">
Lorem ipsum dolor sit amet
</text>
<text x="0" y="48" font-family="Verdana">
Lorem ipsum dolor sit amet
</text>
<text x="0" y="72" font-family="Times New Roman">
Lorem ipsum dolor sit amet
</text>
<text x="0" y="96" font-family="Georgia">
Lorem ipsum dolor sit amet
</text>
</svg>
<img class="layer">
<canvas class="layer" width="400" height="120"></canvas>
CSS
* {
margin: 0;
padding: 0;
}
body{
position: relative;
}
.layer {
position: absolute;
top: 0;
left: 0;
width: 400px;
height: 120px;
}
p {
font-size: 24px;
line-height: 24px;
text-rendering: geometricPrecision;
font-kerning: normal;
}
JavaScript
// SEE THIS: https://github.com/nodebox/opentype.js/issues/220
var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');
// get svg data
var xml = new XMLSerializer().serializeToString(svg);
// make it base64
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64,';
// prepend a "header"
var image64 = b64Start + svg64;
// set it as the source of the img element
img.src = image64;
// draw the image onto the canvas
canvas.getContext('2d').drawImage(img, 0, 0, 400, 120);