Canvas动画:平移变换旋转

平移动画的方法可以有两种,

  • 一种是直接控制要移动的显示对象的坐标改变
  • 另一种是控制画布的平移

平移动画—改变坐标

var oCanvas = document.getElementById('c1');
var oCtx = oCanvas.getContext('2d');
var x=100,y=100;
var oFishImg = new Image();
oFishImg.src = "images/鱼.png";
oFishImg.onload = function(){
  setInterval(function(){
    oCtx.clearRect(0,0,oCanvas.width,oCanvas.height);
      oCtx.drawImage(oFishImg,x,y);
      x+=2;
  },30);
};

平移动画—translate

通过translate改变画布原点,图像是根据画布原点位置来绘制的,所以每次绘制时图像都会随着画布平移,看起来就像是图像平移了。因为调用变换方法后是不会自动恢复的,所以下一次变换就相当于在上一次变换后的叠加。为此需要手动存储和恢复画布状态。在平移前通过save保存画布状态,平移完成后再调用restore()恢复到保存画布状态,这样每次绘制都是在原画布的基础上实现平移,不会出现叠加的情况。

window.onload=function(){
            var oCanvas = document.getElementById('c1');
            var oCtx = oCanvas.getContext('2d');
            var x=100,y=100;
            var oFishImg = new Image();
            oFishImg.src = "images/鱼.png";
            oFishImg.onload = function(){
              setInterval(function(){
                    oCtx.clearRect(0,0,oCanvas.width,oCanvas.height);
                    oCtx.save();
                    oCtx.translate(x,y);
                    oCtx.drawImage(oFishImg,0,0);
                    oCtx.restore();
                    x+=2;
                },30);
            }
        }

旋转动画

先通过translate改变画布原点,再通过rotate()方法实现绕新的画布原点旋转。
同样需要注意save和restore保存和恢复画布状态

window.onload=function(){
           var oCanvas = document.getElementById('c1');
           var oCtx = oCanvas.getContext('2d');
           var x=100,y=100;
           var angle=0;
           var oFishImg = new Image();
           oFishImg.src = "images/鱼.png";
           oFishImg.onload = function(){
               setInterval(function(){
                   oCtx.clearRect(0,0,oCanvas.width,oCanvas.height);
  oCtx.save();
                   oCtx.translate(x,y);
                   oCtx.rotate(angle*Math.PI/180);
                   oCtx.drawImage(oFishImg,-oFishImg.width/2,-oFishImg.height/2);
                   oCtx.restore();
                   x+=2;
                   angle+=5;
                   },30);
           }
        }

缩放动画

缩放动画有两种实现方法,方法1直接控制图像大小参数不同时间显示大小不同实现绽放动画,方法2调用scale变换缩放画布实现缩放动画。方法1的实现原理很简单就不再细说,下面是方法2的代码

window.onload=function(){
        var oCanvas = document.getElementById('c1');
        var oCtx = oCanvas.getContext('2d');
        var scaleX=100;
        var scaleSpeed=2;
        var oFishImg = new Image();
        oFishImg.src = "images/鱼.png";
        oFishImg.onload = function(){
        setInterval(function(){
            oCtx.clearRect(0,0,oCanvas.width,oCanvas.height);
            oCtx.save();
            oCtx.scale(scaleX/100,scaleX/100);
            oCtx.drawImage(oFishImg,0,0);
            oCtx.restore();
            scaleX-=scaleSpeed;
            if(scaleX<=50 || scaleX>=100) {
                scaleSpeed=-scaleSpeed;
            }
            },30);
        }
    }

综合变换动画

同时变换–某物体同时移动、旋转或缩放等几种变换
链式变换–某物体先移动或旋转,完成后再进行另一种变换
综合变换动画—同时变换
只需要在一次save画布操作后,同时使用多种变换方法。如下面例子同时移动、旋转及缩放。

window.onload=function(){
        var oCanvas = document.getElementById('c1');
        var oCtx = oCanvas.getContext('2d');
        var x=100,y=100;
        var angle=0;
        var scaleX=100;
        var scaleSpeed=2;
        var oFishImg = new Image();
        oFishImg.src = "images/鱼.png";
        oFishImg.onload = function(){
综合变换动画—同时变换
        setInterval(function(){
            oCtx.clearRect(0,0,oCanvas.width,oCanvas.height);
            oCtx.save();
            oCtx.translate(x,y);
            oCtx.rotate(angle*Math.PI/180);
            oCtx.scale(scaleX/100,scaleX/100);
            oCtx.drawImage(oFishImg,-oFishImg.width/2,-oFishImg.height/2);
            oCtx.restore();
            x+=2;
            angle+=5;
            scaleX-=scaleSpeed;
            if(scaleX<=50 || scaleX>=100){
                scaleSpeed=-scaleSpeed;}
            },30);
        }
}

综合变换动画—链式变换

只需要在一次save画布操作后,根据不同时间使用不同的变换方法(计时方式可采用在一个定时器里计算帧数,也是每完成一个变换打开一个新的定时器) 。如下面例子实现先平移,再旋转,然后缩放。

window.onload=function(){
        var oCanvas = document.getElementById('c1');
        var oCtx = oCanvas.getContext('2d');
        var x=100,y=100;
        var angle=0;
        var scaleX=100;
        var scaleSpeed=2;
        var nFrame = 0;
        var oFishImg = new Image();
        oFishImg.src = "images/.png“;
      oFishImg.onload = function(){
综合变换动画—链式变换
 setInterval(function(){
                oCtx.clearRect(0,0,oCanvas.width,oCanvas.height);
                oCtx.save();
                if(nFrame<=100) {
                    x+=2;
                    oCtx.translate(x,y);
                }
                else if(nFrame>100 && nFrame<=200) {
                    angle+=3.6;
                    oCtx.translate(x,y);
                    oCtx.rotate(angle*Math.PI/180);
                }
                else if(nFrame>200) { 
                    scaleX-=scaleSpeed;
                    if(scaleX<=50 || scaleX>=100) {
                        scaleSpeed=-scaleSpeed;
                    }
                    oCtx.translate(x,y)
                    oCtx.scale(scaleX/100,scaleX/100);
                } 

综合变换动画—链式变换

 oCtx.drawImage(oFishImg,-oFishImg.width/2,-oFishImg.height/2);
                oCtx.restore(); 
                nFrame++;
                if(nFrame>=300){
                    nFrame=0;
                } 
                },30);
            }
    }
发布了128 篇原创文章 · 获赞 17 · 访问量 7181

猜你喜欢

转载自blog.csdn.net/weixin_42554191/article/details/103916559