• Html5 canvas坐标变换解析


    转载    http://jo2.org/html5-canvas-translate-scale-rotate/

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

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

    首先是位移:translate

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

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

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

    先看不translate的方法:

    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)的位置,就不用再写这些坐标了:

    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.

    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把上面的椭圆来旋转一个角度:

    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一定要注意我前面说的:旋转是基于原点的!假如我们把上面的代码稍稍改一下:

    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之后画的路径才会有相应变化,不能先画出路径,再企图进行位移或旋转缩放什么的。

    本文链接: Html5 canvas画图教程14:画面的位移translate,缩放scale,旋转rotate.转载请保留.

  • 相关阅读:
    231. Power of Two
    204. Count Primes
    205. Isomorphic Strings
    203. Remove Linked List Elements
    179. Largest Number
    922. Sort Array By Parity II
    350. Intersection of Two Arrays II
    242. Valid Anagram
    164. Maximum Gap
    147. Insertion Sort List
  • 原文地址:https://www.cnblogs.com/guaziren/p/3658731.html
Copyright © 2020-2023  润新知