canvas 绘制各种动画效果时,我们经常会使用画布旋转,使绘制上去的元素有旋转的效果。

  最近在项目中碰到了很严重的性能问题,经常排查发现是因为绘制批量文字时使用了画布旋转,且每行文字的旋转角度是不一样的,每次绘制前都会去动态的改变画布上下文context的旋转角度值,导致CPU占用太多。

  而且发现如果绘制的不是文字元素,而是其他路径类如:rect arc等路径时,cpu并不会飙升。

  text旋转后绘制性能低于canvas其他路径类,下面给大家看下测试的结果:

  有如下代码:分别绘制100个文字,并设置了旋转角度,设置50ms绘制一遍

  1. 1 <html>
  2. 2
  3. 3 <head></head>
  4. 4
  5. 5 <body>
  6. 6 <div>
  7. 7 <canvas id="canvas" width="1920" height="1080"></canvas>
  8. 8
  9. 9 </div>
  10. 10 <script>
  11. 11 let canvas = document.getElementById("canvas");
  12. 12 let ctx = canvas.getContext('2d');
  13. 13 //测试绘制旋转文字的性能
  14. 14 setInterval(drawText, 50);
  15. 15 //测试绘制旋转矩形的性能
  16. 16 // setInterval(drawRect, 50);
  17. 17
  18. 18 function drawRect() {
  19. 19 ctx.clearRect(0, 0, 1920, 1080);
  20. 20 for (let i = 0; i <= 500; i += 5) {
  21. 21 ctx.save();
  22. 22 ctx.beginPath();
  23. 23 rotateContext(ctx, 500, 500, i * Math.random());
  24. 24 ctx.fillStyle = "red";
  25. 25 ctx.rect(250, i + 250, 20, 10);
  26. 26 ctx.fill();
  27. 27 ctx.restore();
  28. 28 }
  29. 29 }
  30. 30 function drawText() {
  31. 31 ctx.clearRect(0, 0, 1920, 1080);
  32. 32 for (let i = 0; i <= 500; i += 5) {
  33. 33 ctx.save();
  34. 34 ctx.beginPath();
  35. 35 rotateContext(ctx, 500, 500, i * Math.random());
  36. 36 ctx.fillStyle = "red";
  37. 37 ctx.fillText("反倒是的", 250, i + 250);
  38. 38 ctx.restore();
  39. 39 }
  40. 40 }
  41. 41 //确保是以(x,y)为中心进行旋转,而不是简单的以画布原点旋转
  42. 42 function rotateContext(ctx, x, y, degree) {
  43. 43 ctx.translate(x, y);
  44. 44 ctx.rotate(degree * Math.PI / 180);
  45. 45 ctx.translate(-x, -y);
  46. 46 }
  47. 47
  48. 48 </script>
  49. 49 </body>
  50. 50
  51. 51 </html>

 

  绘制效果如下:

  可以观察浏览器里面的性能指标,已经接近100%

 

  而如果我们绘制的是100个矩形,同样设置旋转角度

  把上面代码段中的drawRect循环绘制的代码行t放开,注释掉drawText循环绘制。再看绘制效果,和drawText的效果是一样的。

   而此时的在浏览器里观察cpu占用的就非常低

  至于为什么有这个问题,还需要深入学习canvas绘制文字的方式,希望有研究的同学能够分享给大家!

 

版权声明:本文为fangsmile原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/fangsmile/p/9947823.html