Canvas 帧动画(封装成对象),绘制图片(drawImage())


person.js(封装的外部JS文件):

(function( w ) {
    
    // 混入式继承( copy继承 )
    function extend( o1, o2 ) {
        for ( var key in o2 ) {
            if ( o2.hasOwnProperty( key ) ) {
                o1[ key ] = o2[ key ];
            }
        }
    }

    /*
     * constructor { Person } 人构造函数
     * param { ctx: Context } 绘制环境
     * param { img: Image } 绘制的图像
     * param { widthFrame: number } 图像一排有多少个人
     * param { heightFrame: number } 图像一列有多少个人
     * param { x: number } 指定人物绘制的x轴坐标
     * param { y: number } 指定人物绘制的y轴坐标
     * param { renderWidth: number } 人物绘制时的宽
     * param { renderHeight: number } 人物绘制时的高
     * param { speed: number } 人物行走的速度
     * */
    function Person( ctx, img, widthFrame, heightFrame, x, y, renderWidth, renderHeight, speed ) {

        this.ctx = ctx;
        this.img = img;
        this.widthFrame = widthFrame;
        this.heightFrame = heightFrame;

        // 图像绘制时的坐标和大小
        this.x = x;
        this.y = y;
        this.renderWidth = renderWidth;
        this.renderHeight = renderHeight;

        // 行走的速度
        this.speed = speed || 5;

        // 求一个人的宽和高
        this.width = this.img.width / this.widthFrame;
        this.height = this.img.height / this.heightFrame;

        // 当前绘制某个方向的第几帧
        this.currentFrame = 0;

        // 当前行走的方向,默认是第一排的方向
        this.direction = 0;

        // 绑定事件
        this._bind();
    }

// 给原型扩充方法
    extend( Person.prototype, {

        // 绘制方法
        draw: function() {

            this.ctx.drawImage( this.img,
                this.width * this.currentFrame, this.height * this.direction, this.width, this.height,
                this.x, this.y, this.renderWidth, this.renderHeight);

        },

        // 绑定事件
        _bind: function() {

            var self = this;

            document.addEventListener( 'keydown', function( e ) {

                // 根据按键切换行走方向
                switch ( e.keyCode ) {
                    case 37:
                        self.direction = 1;
                        break;
                    case 38:
                        self.direction = 3;
                        break;
                    case 39:
                        self.direction = 2;
                        break;
                    case 40:
                        self.direction = 0;
                        break;
                }

            } );
        },

        // 更新小人下一阵绘制时的数据
        update: function() {

            switch ( this.direction ) {

                // 向下走,y轴加
                // 当小人向下出画布,那么从上边再走出来
                case 0:
                    this.y += this.speed;
                    this.y = this.y > this.ctx.canvas.height? -this.height: this.y;
                    break;

                // 向左走,x轴减
                // 当小人向左走出画布,那么从右边再走出来
                case 1:
                    this.x -= this.speed;
                    this.x = this.x < -this.width? this.ctx.canvas.width: this.x;
                    break;

                // 向右走,x轴加
                // 当小人向右走出画布,那么从左边再走出来
                case 2:
                    this.x += this.speed;
                    this.x = this.x > this.ctx.canvas.width? -this.width: this.x;
                    break;

                // 向上走,y轴减
                // 当小人向上出画布,那么从下边再走出来
                case 3:
                    this.y -= this.speed;
                    this.y = this.y < -this.height? this.ctx.canvas.height: this.y;
                    break;
            }

        }

    } );

    // 对外暴露Person
    w.Person = Person;

}( window ));


demo.html(利用person.js实现帧动画):
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        canvas {
            border:1px solid red;
        }
        img {
            display: none;  /* 隐藏img标签,让图像在canvas画布上显示 */
        }
    </style>
</head>
<body>
    <canvas id="cvs" width="500" height="500"></canvas>
    <img src="./imgs/NPC5.png">
    <script src="person.js"></script>
    <script>
        var cvs = document.getElementById('cvs');
        var ctx = cvs.getContext('2d');
        var img = document.querySelector('img');

        // 必须要在图片加载完毕之后,才能使用
        img.onload = function() {
            var person = new Person( ctx, img, 4, 4, 50, 50, 50, 50 );

            setInterval( function() {

                // 清除画布
                ctx.clearRect( 0, 0, cvs.width, cvs.height );

                // 绘制
                person.draw();
                person.currentFrame = ++person.currentFrame >= person.widthFrame? 0 : person.currentFrame;  //帧动画效果

                // 计算下一次绘制时,小人的位置
                person.update();  //更新位置

            }, 100);
        }
    </script>
</body>
</html>

imgs/NPC.png:




阅读更多
个人分类: Canvas
上一篇Canvas 帧动画,绘制图像(drawImage())
下一篇Canvas 状态保存(save()),状态回滚(restore())
想对作者说点什么? 我来说一句

Canvas中的drawImage

Canvas drawImage

zhaoruda zhaoruda

2017-04-18 22:17:38

阅读数:3120

没有更多推荐了,返回首页

关闭
关闭