canvas教程

Html5 canvas画图教程14:画面的位移translate,缩放scale,旋转

字号+ 作者:十年灯 来源:jo2 2015-09-07 14:13 我要评论( )

首先说在前头,大家要千万注意标题,是 画面 的位移,缩放和旋转,而 不 是 画布 。画布是指canvas,但画面是指canvas的Context2d对象,他们千万不能混淆。 画面的位移缩放和旋转,即画布不变,而把画布上的那一层画给进行变化。 首先是位移:translate 大家

首先说在前头,大家要千万注意标题,是“画面”的位移,缩放和旋转,而画布。画布是指canvas,但画面是指canvas的Context2d对象,他们千万不能混淆。

画面的位移缩放和旋转,即画布不变,而把画布上的那一层“画”给进行变化。

首先是位移:translate

大家应该了解canvas有个“原点”,即坐标(0,0)的位置,一般是画布的左上角。translate的作用就是把这个“原点”到处移动,他的语法是我们很熟悉的translate(x,y)形式,但他和moveTo方法毫无相同。当原点变化时,画面的一切都会发生偏移。

初看这个方法好像让人莫名其妙,为什么我要移动原点呢?

这里我只说一个很简单的例子:我要在(300,100)处画4个同心圆。

先看不translate的方法:

1
2
3
4
5
ctx.arc(300,100,30,0,Math.PI*2)
.arc(300,100,40,0,Math.PI*2)
.arc(300,100,50,0,Math.PI*2)
.arc(300,100,60,0,Math.PI*2)
.stroke();

以上代码使用了XtendCanvas.js

大家可以看到,代码中有好几个(300,100)坐标值,但如果我们把原点移动到(300,100)的位置,就不用再写这些坐标了:

1
2
3
4
5
6
ctx.translate(300,100)
.arc(0,0,30,0,Math.PI*2)
.arc(0,0,40,0,Math.PI*2)
.arc(0,0,50,0,Math.PI*2)
.arc(0,0,60,0,Math.PI*2)
.stroke();

这里我们首先就把原点移动到了目标坐标(300,100),此时,画面的原点(0,0)就不再是左上角了,而是新的(300,100)。所以我们直接在这个所谓的”原点”处开始画,实际上却是在(300,100)处开始画的。

注意,translate移动的距离其实是“相对”的,也就是说他是在当前的原点坐标基础上进行偏移,比如默认原点坐标是(0,0),那么此时的translate(300,100)就是在(0,0)的基础上进行x轴300的偏移,y轴100的偏移。如果本来原点坐标已经变了,比如变成了(10,20),那同样的translate(300,100)就会把原点变到(10+300,20+100)的位置。

如何把原点再次移回到(0,0)的位置?可以translate(0,0),网友纠正,应该是translate(-300,-100),即刚才移动的坐标取负。也可以通过前几章讲的save,restore方法,建议使用后面的方面,可以避免去找之前移动坐标的负值.

缩放scale

缩放是很容易理解的概念,但在canvas中缩放要记住:缩放是基于“原点”进行的。scale也经常与translate搭配使用。

scale接受两个参数,依次是水平方向的缩放和垂直方向的缩放。参数可以是小数,如果小于1就是缩小,大于1则是放大——等于1则什么都不做,懂吧?

我们试着用translate和scale结合,来画一个椭圆,假设此椭圆宽60高80.

1
2
3
4
var w = 60,= 80,= h/w;
ctx.translate(300,100).scale(1,b)
.arc(0,0,w/2,0,Math.PI*2)
.stroke();

其中的b变量,就是高度与宽的比,这个比例很容易得出,然后我们保持水平不缩放,但把垂直方向放大至b的值,最后就能得到这样一个椭圆

当然你也可以让b=w/h,然后垂直不缩放而缩放水平,最终效果也是一样的。

旋转rotate

旋转也是一个很好理解的概念,而且旋转也是基于原点进行的。

rotate接受一个表示度数的参数——而且是弧度

让我们用rotate把上面的椭圆来旋转一个角度:

1
2
3
4
var w = 60,= 80,= h/w;
ctx.translate(300,100).rotate(Math.PI/9).scale(1,b)
.arc(0,0,w/2,0,Math.PI*2)
.stroke();

结果如图所示:

但是,使用rotate一定要注意我前面说的:旋转是基于原点的!假如我们把上面的代码稍稍改一下:

1
2
3
ctx.rotate(Math.PI/9).translate(300,100).scale(1,b)
.arc(0,0,w/2,0,Math.PI*2)
.stroke();

我们只是把translate和rotate的位置调换了一下,但结果就会是这样:

此时要知道椭圆的确切坐标,就很难了。因为我们旋转的时候,原点还是(0,0),但之后又变成了(300,100)

后记:

scale,translate和rotate经常在一起使用,而且他们都基于原点,所以我把它们放在一起讲了。如果大家想更深入的了解,可以搜索一下canvas画时钟的例子。

另外,他们都可以通过save,restore进行保存或还原。

同时,他们也是先定义后起作用的方法。也就是说,只有先scale,translate和rotate之后画的路径才会有相应变化,不能先画出路径,再企图进行位移或旋转缩放什么的。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • html5canvas核心技术图形、动画与游戏开发源码

    html5canvas核心技术图形、动画与游戏开发源码

    2017-05-02 17:42

  • 打印html5中Canvas的方法

    打印html5中Canvas的方法

    2017-05-01 15:03

  • HTML5+Canvas调用手机拍照功能实现图片上传(下)

    HTML5+Canvas调用手机拍照功能实现图片上传(下)

    2017-04-30 17:00

  • HTML5新特性详解(三)

    HTML5新特性详解(三)

    2017-04-30 16:03

网友点评