专栏首页前端博客:https://alili.tech常见的canvas优化——模糊问题、旋转效果

抱歉,你查看的文章已删除

常见的canvas优化——模糊问题、旋转效果

canvas常见优化方案——模糊问题、旋转效果、离屏、自定义图片尺寸

实践demo——“canvas离屏、旋转效果实践——旋转的雪花”

2017-12-18 16:27:35更新关于模糊问题

前几天研究html2Canvas的时候刚好赶上作者发布新版本,发现新版本截屏出来的效果比我对旧版本处理后(画布尺寸都设为2倍)的效果更好。
扒源码的时候发现他们并没有直接设为两倍尺寸,而是先获取当前dom结构的scale,用当前dom的scale去设置canvas的画布尺寸比。
我自己手机上测试时打印出来的dom的scale显示为3倍尺寸,所以我设置canvas两倍画布尺寸的时候,其实还是会模糊的,不过对比1倍尺寸的是要清晰很多了。

canvas显示模糊问题——画布尺寸设为显示尺寸的两倍即可

问题原因

查阅canvas的API就可以知道,想要获得精确地线条,必须对线条是如何描绘出来的有所理解。

首先要清楚一点:canvas画线时的定位定的是线条中线的位置,根据线条的宽度再向两边延伸,如果延伸出去的线条没有占满1px,不足的部分将会以实际笔触颜色的一半色调来填充。所以最后我们实际看到的效果就是:1px的线条变宽了,且变模糊了,效果如左图所示:

解决办法

根据问题原因我们知道:只要从线条中线开始向外延伸部分占满1px,就不会出现线条变宽且模糊的问题了。

最简单的办法是画线时根据需求将线条定位移动0.5px,不过这是治标不治本的方法,只能用来验证这个方法是不是正确的。

我们还可以将画布尺寸设为显示尺寸的2倍,这相当于用画图时的两个像素点去填充实际显示的一个像素点,这样就能很好的解决canvas显示模糊的问题了。

canvas.setAttribute('width', x * 2);
canvas.setAttribute('height', y * 2);
canvas.style.width = x + 'px';
canvas.style.height = y + 'px';

用这种方法要记得:各种布局尺寸也要做相应变化。

离屏canvas

定义离屏canvas,在离屏canvas上设定画布尺寸并绘制canvas图片:

var offScreenCanvas = document.createElement('offScreenCanvas');
var offScreenCtx = offScreenCanvas.getContext('2d');

然后将画好的离屏canvas绘制到实际显示的canvas上:

ctx.drawImage(offScreenCanvas, 0, 0, offScreenCanvas.width, offScreenCanvas.height,
    0, 0, canvas.width, canvas.height);

好处

一是可以不受限于html标签及实际显示尺寸,画出一个标准尺寸的大图,然后自适应到实际显示的canvas上; 二是离屏canvas的缓存效果可以大大提升canvas的性能(当然像上述那样粗糙的代码,是体现不出这一效果的)。

不足

离屏canvas一定要画好之后才能绘制到实际显示的canvas上,这就导致哪些有延时的元素不方便这样用(如图片、自定义字体等)。针对这一问题,目前我还没有找到好的解决办法。

图片尺寸问题

刚开始画图的时候很纠结的一个问题就是:canvas画png图片时,不同屏幕尺寸要配多大的图、配几套。后来在解决上述“离屏canvas”的问题后,这个问题也就迎刃而解了:drawImage函数可以设定将图片绘制成多大的,而不限定于图片本身的尺寸。

这个问题解决之后,就只需要一套图片就好了,还可以使图片大小自适应屏幕、随显示界面缩放。

canvas旋转效果——改变了画布坐标系

canvas中有两个很好用的东西:旋转和保存状态。

以画圆的不同角度的半径为例,正常情况下我们要根据圆半径、线的角度和圆心的位置计算得出线的端点坐标P1{x1,y1}、P2{x2,y2},然后画一条P1到P2的线,代码中的计算量不小。不过canvas中我们有更好的解决办法:

1.定位笔触到圆心位置{x,y}

ctx.translate(x,y)

2.根据线的角度旋转画布angle圈(angle=1时表示顺时针旋转一圈)

ctx.rotate(Math.PI*2 * angle);

3.画一条{0,0}到{r,0}的线即可

ctx.beginPath();
ctx.lineTo(0, 0);
ctx.lineTo(r, 0);
ctx.stroke();

canvas旋转方式画线步骤解读:

笔触定位相当于是定画布原点的位置,旋转画布则是以原点为圆心顺时针旋转了x/y坐标系,旋转后的效果是将x正半轴与要画的线重合,自然就相当于直接画一条{0,0}到{r,0}的线。

另外一定要注意

修改画布坐标系(定原点、旋转画布)之前一定要保存状态,画完线后一定要重载状态!不然你会很容易被自己改过的坐标系玩死的。

版权声明

本文资源来源互联网,仅供学习研究使用,版权归该资源的合法拥有者所有,

本文仅用于学习、研究和交流目的。转载请注明出处、完整链接以及原作者。

原作者若认为本站侵犯了您的版权,请联系我们,我们会立即删除!

原文标题

常见的canvas优化——模糊问题、旋转效果

原文链接

https://segmentfault.com/a/1190000009396591

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • js实现截图并保存图片(html转canvas、canvas转image)

    从入门到进错门
  • 创建canvas设置canvas尺寸绘制图形Canvas库

    Canvas是常见的前端技术,但是由于API众多,使用复杂,且对程序员的数学功底、空间想象能力乃至审美都有一定要求,所以真正擅长canvas的前端并不多,但并不...

    MudOnTire
  • Canvas的HelloWorld文本的样式文本的测量总结

    孙亖
  • 如何使用腾讯云45元代金券购买带宽按量计费的云主机?

    对于收到腾讯云45元代金券,想要尝试一下云主机使用体验用户。可以阅读本教程,了解如何使用腾讯云45元代金券,购买带宽按量计费的云主机。

    贺嘉
  • .NET面试题解析(01)-值类型与引用类型

    3. delegate是引用类型还是值类型?enum、int[]和string呢?

    莫问今朝
  • BigData-消息队列框架Apache Kafka入门、原理解析

    需要server.properties中设置delete.topic.enable=true否则只是标记删除。

    MiChong

扫码关注云+社区

领取腾讯云代金券