简体   繁体   English

JS Canvas:为什么文字渲染不流畅?

[英]JS Canvas: Why is the text rendering not smooth?

why is the text not rendered smoothly in the following JavaScript canvas example?为什么在下面的 JavaScript 画布示例中文本渲染不流畅?

let canvas = document.getElementById('canvas');
let context = this.canvas.getContext('2d');
let tick = 0;

let loop = function() {
  context.clearRect(0, 0, canvas.width, canvas.height);
    
  let scale = 1 + tick * 0.005;
  context.save();
  context.scale(scale,scale)
    
  context.font = 'bold 50px Sans-serif';
  context.textBaseline = 'top';
  context.fillStyle = 'black';
  context.fillText('Hello, world!', 0, 0);
  
  
  context.restore();
  tick++;  
  window.requestAnimationFrame(loop);
}

window.requestAnimationFrame(loop);

Demo : https://jsfiddle.net/kemrf9p7/演示https : //jsfiddle.net/kemrf9p7/

The y position is always exactly the same, despite not being changed by the code.尽管代码没有更改,y 位置始终完全相同。 It seems to be y +/- 1.它似乎是 y +/- 1。

I have tested different ways to sclae text without this strange behavior but couldn't find a solution.我已经测试了不同的方法来消除这种奇怪的行为,但找不到解决方案。 For example I did not use scale() but changed the size of the text directly.例如我没有使用scale()而是直接改变了文本的大小。 I also tried different values for textBaseline .我还为textBaseline尝试了不同的值。

Here is a try to fix the problem.这是解决问题的尝试。 First of all you may draw a canvas on other canvas, so I tried to create a 5000*5000px canvas, draw the text on it with 500px font-size.首先你可能会在其他画布上画画布,所以我尝试创建一个 5000*5000px 的画布,用 500px 的字体大小在其上绘制文本。 But it wasn't perfect when getting bigger at the start, so I made several canvases and put them on visible canvas by steps.但是刚开始变大时并不完美,所以我做了几幅画布,然后一步一步地把它们放在可见的画布上。

It is just for some idea how it can be solved, not elegant method.这只是为了一些想法如何解决它,而不是优雅的方法。 Better solution for this example will be SVG!这个例子更好的解决方案是 SVG!

 let canvas = document.getElementById('canvas'); let context = this.canvas.getContext('2d'); let tick = 0; let scale_steps = [2,4,7,10]; let canvases = []; for(let i=0; i < scale_steps.length; i++){ canvases[i] = document.createElement('canvas'); canvases[i].width = canvases[i].height = 500 * scale_steps[i]; let ctx = canvases[i].getContext('2d'); ctx.font = `bold ${scale_steps[i] * 50}px Sans-serif`; ctx.textBaseline = 'top'; ctx.fillStyle = 'black'; ctx.fillText('Hello, world!', 0, 0); } let loop = function() { context.clearRect(0, 0, canvas.width, canvas.height); let scale = 1 + tick * 0.005; let index = scale < 4 ? Math.floor(scale-1) : 3; context.save(); context.scale(scale,scale); context.drawImage(canvases[index],0,0,scale_steps[index] *500,scale_steps[index]*500,0,0,500,500); context.restore(); tick++; window.requestAnimationFrame(loop); } window.requestAnimationFrame(loop);
 <canvas id="canvas" width="500" height="500"></canvas>

Also you can add the text as a SVG-path:您也可以将文本添加为​​ SVG 路径:

 let canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); let w,h; w = h = canvas.width = canvas.height = 500; draw.t = 0; function draw(){ ctx.clearRect(0, 0, w, h); let scale = 1 + draw.t * 0.005; ctx.save(); ctx.scale(scale, scale); ctx.fill(new Path2D("M0 0.72l10.42 0 0 15.41 15.36 0 0 -15.41 10.42 0 0 40.41 -10.42 0 0 -17.13 -15.36 0 0 17.13 -10.42 0 0 -40.41zm76.21 25.17l0 2.77 -22.67 0c0.23,2.27 1.05,3.97 2.46,5.11 1.41,1.13 3.38,1.7 5.91,1.7 2.04,0 4.13,-0.3 6.26,-0.9 2.14,-0.61 4.34,-1.53 6.6,-2.75l0 7.48c-2.29,0.86 -4.58,1.5 -6.88,1.95 -2.29,0.43 -4.58,0.65 -6.87,0.65 -5.49,0 -9.75,-1.39 -12.78,-4.17 -3.04,-2.79 -4.57,-6.7 -4.57,-11.73 0,-4.95 1.5,-8.84 4.48,-11.66 2.99,-2.84 7.1,-4.25 12.34,-4.25 4.75,0 8.57,1.43 11.43,4.3 2.86,2.87 4.29,6.7 4.29,11.5zm-9.98 -3.22c0,-1.85 -0.53,-3.33 -1.61,-4.46 -1.08,-1.13 -2.47,-1.69 -4.21,-1.69 -1.87,0 -3.4,0.52 -4.57,1.59 -1.17,1.05 -1.9,2.57 -2.19,4.56l12.58 0zm17.31 -23.67l9.7 0 0 42.13 -9.7 0 0 -42.13zm19 0l9.7 0 0 42.13 -9.7 0 0 -42.13zm33.43 18.02c-2.15,0 -3.79,0.76 -4.92,2.31 -1.13,1.54 -1.69,3.76 -1.69,6.67 0,2.9 0.56,5.12 1.69,6.67 1.13,1.54 2.77,2.31 4.92,2.31 2.11,0 3.73,-0.77 4.85,-2.31 1.11,-1.55 1.68,-3.77 1.68,-6.67 0,-2.91 -0.57,-5.13 -1.68,-6.67 -1.12,-1.55 -2.74,-2.31 -4.85,-2.31zm0 -6.93c5.22,0 9.29,1.4 12.22,4.22 2.93,2.81 4.4,6.71 4.4,11.69 0,4.98 -1.47,8.87 -4.4,11.68 -2.93,2.82 -7,4.22 -12.22,4.22 -5.23,0 -9.33,-1.4 -12.27,-4.22 -2.95,-2.81 -4.43,-6.7 -4.43,-11.68 0,-4.98 1.48,-8.88 4.43,-11.69 2.94,-2.82 7.04,-4.22 12.27,-4.22zm24.65 20.56l9.76 0 0 8.25 -6.71 10.1 -5.76 0 2.71 -10.1 0 -8.25zm36.64 -19.84l9.43 0 5.08 20.9 5.12 -20.9 8.09 0 5.09 20.68 5.11 -20.68 9.42 0 -7.98 30.32 -10.59 0 -5.11 -20.84 -5.09 20.84 -10.58 0 -7.99 -30.32zm68.35 6.21c-2.14,0 -3.79,0.76 -4.91,2.31 -1.13,1.54 -1.69,3.76 -1.69,6.67 0,2.9 0.56,5.12 1.69,6.67 1.12,1.54 2.77,2.31 4.91,2.31 2.12,0 3.73,-0.77 4.85,-2.31 1.12,-1.55 1.68,-3.77 1.68,-6.67 0,-2.91 -0.56,-5.13 -1.68,-6.67 -1.12,-1.55 -2.73,-2.31 -4.85,-2.31zm0 -6.93c5.22,0 9.3,1.4 12.23,4.22 2.92,2.81 4.39,6.71 4.39,11.69 0,4.98 -1.47,8.87 -4.39,11.68 -2.93,2.82 -7.01,4.22 -12.23,4.22 -5.23,0 -9.32,-1.4 -12.27,-4.22 -2.94,-2.81 -4.42,-6.7 -4.42,-11.68 0,-4.98 1.48,-8.88 4.42,-11.69 2.95,-2.82 7.04,-4.22 12.27,-4.22zm46.17 8.98c-0.85,-0.4 -1.69,-0.7 -2.53,-0.88 -0.83,-0.19 -1.68,-0.29 -2.53,-0.29 -2.48,0 -4.39,0.8 -5.73,2.39 -1.34,1.6 -2.02,3.89 -2.02,6.87l0 13.97 -9.7 0 0 -30.32 9.7 0 0 4.99c1.25,-1.99 2.67,-3.44 4.28,-4.35 1.62,-0.91 3.55,-1.36 5.8,-1.36 0.33,0 0.68,0.01 1.06,0.03 0.37,0.03 0.92,0.1 1.64,0.18l0.03 8.77zm4.83 -20.07l9.7 0 0 42.13 -9.7 0 0 -42.13zm39.62 16.24l0 -16.24 9.76 0 0 42.13 -9.76 0 0 -4.38c-1.33,1.78 -2.8,3.09 -4.4,3.92 -1.61,0.82 -3.47,1.23 -5.58,1.23 -3.74,0 -6.8,-1.48 -9.2,-4.45 -2.4,-2.96 -3.6,-6.78 -3.6,-11.45 0,-4.68 1.2,-8.49 3.6,-11.46 2.4,-2.97 5.46,-4.45 9.2,-4.45 2.09,0 3.94,0.41 5.56,1.25 1.62,0.83 3.09,2.14 4.42,3.9zm-6.38 19.63c2.07,0 3.66,-0.76 4.75,-2.28 1.09,-1.51 1.63,-3.71 1.63,-6.59 0,-2.89 -0.54,-5.08 -1.63,-6.6 -1.09,-1.52 -2.68,-2.27 -4.75,-2.27 -2.06,0 -3.64,0.75 -4.73,2.27 -1.09,1.52 -1.63,3.71 -1.63,6.6 0,2.88 0.54,5.08 1.63,6.59 1.09,1.52 2.67,2.28 4.73,2.28zm28.55 -34.15l9.76 0 0 15.51 -1.39 11.32 -6.99 0 -1.38 -11.32 0 -15.51zm0 30.76l9.76 0 0 9.65 -9.76 0 0 -9.65z")); ctx.restore(); draw.t++; window.requestAnimationFrame(draw); } window.requestAnimationFrame(draw);
 <canvas id="canvas"></canvas>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM