为了账号安全,请及时绑定邮箱和手机立即绑定

谁能回答我为什么第一种写法只出现了极少数的星星呢?

563b4566000110c205000268.jpg

563b45680001f77f05000270.jpg

第一张图片用的是逆转的方式,时canvas回到原点,并且我用console打印出来,确实循环绘制了200次星星,每次星星的位置也在画布中,但是画面却只出现数颗星星。

第二张图,采用了save和restore,就画出了大量的星星,请问是怎么回事呢?

正在回答

1 回答

你好! 关于这个问题, 其实是因为Canvas的rotate的中心点是固定不变的,永远在canvas的 坐标为(0,0)处,并且也无法设置旋转中心点,而不是像CSS里面那样默认在元素的中心点。

回到你的源代码中,由于每一次的旋转中心点是一样的,而代码中每一次旋转之前都有一个translate,这样的话肯定会导致fillRect之后,context 复位出现问题。

做了一张图,解释了这么问题,图中 方块1 和方块5 最终位置不一样,所以说明在循环中,每次循环都会影响下一次的Context (context 没有复位成功),所以会导致下一次的渲染位置出现问题,导致位置误差越来越大,并且由于每次rotate的旋转的中心点在(0 ,0), 所以星星的消失很可能是因为后面的星星位置被渲染到了画布之外,其实就是没有啦。

http://img1.sycdn.imooc.com//56719177000162bd24802805.jpg

解决办法就是把 源码中的25 ,26行互换吧,这样先复位rotate ,再复位translate 就没问题啦,不过其实还有一个问题,就是本来直接这样用rotate,很容易会把对象旋转到画布以外,特别是里原点较远的 星星,所以 建议还是 通过简单的变换 来实现 绕自身中心点进行旋转。

比如对象的位置是在( x , y ),宽度为rectWidth,高度为rectHeight, 我们想让他沿着自身旋转 deg个角度;

context.translate(x + rectWidth / 2, y + rectHeight / 2);
context.rotate(deg);
context.beginPath();
context.fillRect(-rectWidth/2, -rectHeight/2, rectWidth, rectHeight);
context.rotate(-deg);
context.translate(-(x + rectWidth / 2), -(y + rectHeight / 2));

或者

context.save();
context.translate(x + rectWidth / 2, y + rectHeight / 2);
context.rotate(deg);
context.beginPath();
context.fillRect(-rectWidth/2, -rectHeight/2, rectWidth, rectHeight);
context.restore()


自己研究的,写的不是很专业 , ~~有些东西自己表达的不是很清楚,见谅哈 


0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

谁能回答我为什么第一种写法只出现了极少数的星星呢?

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信