IE下及标准浏览器下的图片旋转(二)—— Canvas(1)

 

      文章过长,一篇无法保存。

      IE下及标准浏览器下的图片旋转(一)——滤镜,CSS3

 

3. canvas

 

      canvas 是html5中的新标签,使用canvas之前我们先看下它的定义:<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。这个标 签是用来绘图的,包括2d和3d,拥有很多方法,因为我们只是拿来实现图片的旋转,所以只需要了解其中的3个方法即可,关于canvas的详细使用会写在 以后的篇幅中。

 

      先讲下canvas实现旋转图片的原理:canvas标签相当于创建一个画布,不仅可以在上面画图,还可以插入图片,当我们在canvas中插入了图片,并使用其提供的旋转方法对画布旋转,即可实现旋转图片的目的。

 

      canvas画布旋转式围绕圆点进行的,示例如图:

 

      假 定蓝色方块是canvas标签,当我们对其内容进行旋转时,是旋转的整个画布,但是canvas本身的位置和大小是不会发生变化的,当内容旋转后如果超出 了画布,就会被遮挡住,默认旋转的原点是00坐标,也就是画布的左上角,并且,无论怎样旋转,它的X轴和Y轴都不会改变,即使我们旋转90度或者180 度。会ps的同学可以参考图层旋转,把中心点定在左上角即可。

 

      来看个形象店的图示:

 

 

      默认旋转90度后,内容全部超出画布,将不会显示,X轴和Y轴不变。如下图所示:

 

      

 

 

    先来个示例:

    javascript:

    $(function () {
        var canvas = document.getElementById("img_box").getContext('2d'); 
        var img = new Image(); 
        img.onload = function(){ 
              canvas.drawImage(img,0,0); 
        } 
        img.src = '12.jpg'; 
    })

 

    css:

    #img_box { background: #e5e5e5; }

 

    html:

    <canvas id="img_box" width="400px" height="200px"></canvas>

 

    效果如图:

 


      稍微讲解下代码:

      (1) var canvas = document.getElementById("img_box").getContext('2d'); 
      获取canvas标签并使用2D画图模式

 

      (2) var img = new Image(); 
      创建一个图片对象

 

      (3) img.onload = function(){ } 

      图片加载完后执行函数

 

      (4) canvas.drawImage(img,0,0); 

      drawImage()方法允许在canvas中插入其他图像。参数可以使3个(位移)5个(位移,缩放)或9个(位移,缩放,裁剪)。我们用3个就够了,第一个参数是图片地址,第二个是X轴位移,第三个是Y轴位移,我们让图片和原点(0,0)对齐就可以了。

 

      如果我们把canvas的大小设置的和图片大小一样的话,那么久相当于图片充满了canvas画布,上例中我们的图片是120*90,我们把canvas标签的大小也设成120*90就会成这样:

 

 

      可以看到没有了灰色区域,只有图片。

 

      如果我们要对它旋转就需要用到rotate()方法,rotate(Math.PI)代表顺时针旋转180度,也即是说Math.PI=180度,-Math.PI=-180度,Math.PI/2=90度,以此类推。我们以旋转45度为例:

 

    javascript:

    $(function () {
        var canvas = document.getElementById("img_box").getContext('2d'); ;
        var img = new Image(); 
        img.onload = function(){ 
              canvas.drawImage(img,0,0); 
        } 
        canvas.rotate(Math.PI/4);

        img.src = '12.jpg'; 
    })

 

    css:

    #img_box { background: #e5e5e5; }

 

    html:

    <canvas id="img_box" width="120px" height="90px"></canvas>

 

    效果如图:

 

 

      我们可以看到使用rotate()方法方法旋转后,就如前面的原理如所示,canvas标签大小不变,内容会围绕原点(0,0)旋转整个画布。超出的部分会隐藏掉。由此我们可以推断,当旋转90度时,图片会完全看不到。我们需要把图片再拉回来,并且改变canvas标签的大小为图片旋转后的大小,也就是宽高互换。

 

      因此我们需要使用translate()方法重新设定原点位置。以下以90度旋转为例,如有不明白translate()取值的同学,认真揣摩上面关于原点,XY轴的原理图,XY轴不变。

 

    javascript:

    $(function () {
        var canvas = document.getElementById("img_box").getContext('2d'); ;
        var img = new Image(); 
        img.onload = function(){ 
              canvas.drawImage(img,0,0); 
        } 
        canvas.rotate(Math.PI/2);
        canvas.translate(0,-90);
        img.src = '12.jpg'; 
    })

 

    css:

    #img_box { background: #e5e5e5; }

 

    html:

    <canvas id="img_box" width="90px" height="120px"></canvas>

 

    效果如图:

 

      如果我们需要多次旋转,则需要在每次旋转前将原点复位到原始状态。例如我们进行90度旋转:

      canvas.rotate(Math.PI/2);
      canvas.translate(0,-90);

 

      当我们再次旋转90度时,需要先复位原点,再旋转:

      canvas.translate(0,90);
      canvas.rotate(Math.PI/2);
      canvas.translate(-120,-90);

 

      完整的顺时针旋转360度代码:

      canvas.rotate(Math.PI/2);   //顺时针旋转90度
      canvas.translate(0,-90);   //位移,显示在画布上


      canvas.translate(0,90);   //复位原点(0,0)
      canvas.rotate(Math.PI/2);   //再次旋转90度,此时即是180度
      canvas.translate(-120,-90);   //位移


      canvas.translate(120,90);   //复位原点
      canvas.rotate(Math.PI/2);   //继续旋转90度,此时270度
      canvas.translate(-120,0);   //位移


      canvas.translate(120,0);   //复位原点
      canvas.rotate(Math.PI/2);  //继续旋转90度,此时360度,无需位移

 

      当然,我们也可以先改变中心点,然后旋转画布,最后再插入图片,以旋转90度为例:

 

      translate(90,0);canvas.rotate(Math.PI/2);我们看到如果这样的话,translate的 数值与之前是不同的,原因在于,之前先旋转,中心点是原点,旋转后图片超出被隐藏,我们需要把中心点移动旋转后的视觉位置,在视觉上是向右向下移动(正 数),实际上相对于旋转后的画布是向左向上移动(负数),而先旋转画布的话,我们要提前算好旋转后这个点的位置,然后向右向下移动,因为并未旋转,所以相 对于原点向右向下移动与视觉上的移动方向一致,所以是正数。不明白的同学好好体会体会,看看上面的示例图,自己拿个方形的东西转转,呵呵。

 

      如果每次旋转后都需要手动复位原点,这样也有点太复杂了,算起来有点晕,其实大可不必这样,因为canvas给我们提供了一种复位方法save()和restore()。

 

     save()用来保存canvas的状态(注意是canvas画布,而不是我们画的图或者对图片等的操作),restore()用来恢复。restore()总是会寻找离它最近的save()恢复,并且restore()的个数不能多于save()的个数,这个不难理解,你保存10次恢复11次,肯定会出错嘛。

 

    我们看个示例:

    javascript:

    window.onload = function(){
        var canvas = document.getElementById("cv");

        canvas.height = 250;
        canvas.width = 400;

        var context = canvas.getContext("2d");
        context.save();

        var img1 = new Image(); 
        img1.onload = function(){ 
            context.translate(90,0);
            context.rotate(Math.PI/2);
            context.drawImage(img1,0,0); 
            context.restore();      
        } 
        img1.src = '12.jpg'; 
        
        
        var img2 = new Image(); 
        img2.onload = function(){ 
            context.drawImage(img2,0,0);   
        } 
        img2.src = '13.jpg';     
    };

 

    css:

    #cv { background: #e5e5e5; }

 

    html:

    <canvas id="cv"></canvas>

 

    效果如图:

 

 

      如果我们去掉 img1.onload = function(){ }中的context.restore();  就会变成这样:

 

 

      我 们看到,img1旋转了90度,不加restore(),img2也是旋转90度,加上后img2不受影响,为什么呢?我们往上看,创建canvas画布 后,我们就进行了一次save(),这时我们并没有对canvas画布做任何操作,当img1进行旋转后,画布就成为了旋转90度,如果我们直接加入 img2,那么img2也是在画布旋转90的状态下插入的,如果我们使用restore(),那么canvas画布就会恢复到上一次save()状态(注意,是canvas画布恢复,我们对img1进行的操作不会受影响),这时我们再加入img2,就不会受影响了,这是个很关键的使用方法,复杂的画图都要用到多次save()和restore()。

 

      文章过长,一篇无法保存

      IE下及标准浏览器下的图片旋转(二)—— Canvas(2)

 

posted @ 2014-12-03 11:12  K13  阅读(490)  评论(0编辑  收藏  举报