第一张图片用的是逆转的方式,时canvas回到原点,并且我用console打印出来,确实循环绘制了200次星星,每次星星的位置也在画布中,但是画面却只出现数颗星星。
第二张图,采用了save和restore,就画出了大量的星星,请问是怎么回事呢?
你好! 关于这个问题, 其实是因为Canvas的rotate的中心点是固定不变的,永远在canvas的 坐标为(0,0)处,并且也无法设置旋转中心点,而不是像CSS里面那样默认在元素的中心点。
回到你的源代码中,由于每一次的旋转中心点是一样的,而代码中每一次旋转之前都有一个translate,这样的话肯定会导致fillRect之后,context 复位出现问题。
做了一张图,解释了这么问题,图中 方块1 和方块5 最终位置不一样,所以说明在循环中,每次循环都会影响下一次的Context (context 没有复位成功),所以会导致下一次的渲染位置出现问题,导致位置误差越来越大,并且由于每次rotate的旋转的中心点在(0 ,0), 所以星星的消失很可能是因为后面的星星位置被渲染到了画布之外,其实就是没有啦。
解决办法就是把 源码中的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()
自己研究的,写的不是很专业 , ~~有些东西自己表达的不是很清楚,见谅哈