1.ctx.drawImage的三种方式,要在img.onload = function(){}中使用。
<canvas id="cvs" width="500" height="500"></canvas>
<img src="./imgs/example.jpg">
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
var img = document.querySelector('img');
/*
* 绘制图像,有三种使用方式。
* */
// JavaScript 语法 1
// 在画布上定位图像:
// context.drawImage(img, x, y);
// 必须要在img图像下载完毕之后使用
/*img.onload = function() {
ctx.drawImage( img, 10, 10 );
}*/
// JavaScript 语法 2
// 在画布上定位图像, 并规定图像的宽度和高度:
// context.drawImage(img, x, y, width, height);
// 必须要在img图像下载完毕之后使用
/*img.onload = function() {
ctx.drawImage( img, 10, 10, 200, 200 );
}*/
// JavaScript 语法 3
// 剪切图像, 并在画布上定位被剪切的部分:
// context.drawImage(img, sx, sy, swidth, sheight, x, y, width, height);
// 必须要在img图像下载完毕之后使用
img.onload = function() {
ctx.drawImage(img,
300, 100, 400, 400,
10, 10, 200, 200);
}
</script>
2.在画布上画出行走的小女孩
效果如下:
所用素材:
下面看代码如何实现:
<body>
<canvas id="cvs" width="500" height="500"></canvas>
<img src="./imgs/NPC5.png">
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
var img = document.querySelector('img');
img.onload = function() {
var i = 0;
var singleWidht = img.width / 4;
var singleHeight = img.height / 4;
setInterval(function() {
row = Math.floor((i / 4));
col = i % 4;
console.log(row, col);
// 0,0;0,1;0,2;0,3;1,0;1,1;1,2;1,3;
// 绘制新的图像时,需要先清除画布
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(img, col * singleWidht, row * singleHeight, singleWidht, singleHeight, 20, 20, singleWidht, singleHeight);
i++;
if (i > 15) {
// 最后一帧时,回到第一个
i = 0;
console.log('-----------');
}
}, 300);
}
</script>
</body>
3.帧动画对象版本,使用extend自定义函数给原型扩展方法
<body>
<canvas id="cvs" width="500" height="500"></canvas>
<img src="./imgs/NPCrabbitbaby.png">
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
var img = document.querySelector('img');
// 混入式继承( 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 } 人物绘制时的高
* */
function Person( ctx, img, widthFrame, heightFrame, x, y, renderWidth, renderHeight ) {
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.width = this.img.width / this.widthFrame;
this.height = this.img.height / this.heightFrame;
// 当前绘制某个方向的第几帧
this.currentFrame = 0;
// 当前行走的方向,默认是第一排的方向
this.direction = 0;
}
// 给原型扩充方法
extend( Person.prototype, {
// 绘制方法
draw: function() {
this.ctx.drawImage( this.img,
0, 0, this.width, this.height,
this.x, this.y, this.renderWidth, this.renderHeight);
}
} );
</script>
<script>
// 必须要在图片加载完毕之后,才能使用
img.onload = function() {
var person = new Person( ctx, img, 4, 4, 50, 50, 200, 200 );
person.draw();
}
</script>
</body>
4.ctx.save()与ctx.restore()
<body>
<canvas id="cvs" width="500" height="500"></canvas>
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
/*
* 状态保存:
* ctx.save();
* 把当前的状态(绘制环境的所有属性)copy一份进行保存。
* */
/*
* 状态回滚:
* ctx.restore();
* 把最近保存的一次状态作为当前状态。
* */
ctx.save();
// 修改状态
ctx.lineWidth = 10;
ctx.strokeStyle = 'blue';
ctx.lineCap = 'round';
// // 修改之后绘制一条线
ctx.moveTo( 10, 10 );
ctx.lineTo( 310, 10 );
ctx.stroke();
ctx.save();
// // 修改状态
ctx.lineWidth = 3;
ctx.strokeStyle = 'pink';
// // 修改之后再绘制一条线
ctx.beginPath();
ctx.moveTo( 10, 50 );
ctx.lineTo( 310, 50 );
ctx.stroke();
// // // 回滚
ctx.restore();
// // 回滚之后再绘制一条线
ctx.beginPath();
ctx.moveTo( 10, 100 );
ctx.lineTo( 310, 100 );
ctx.stroke();
// // 再回滚
ctx.restore();
// // 再回滚之后再绘制一条线
ctx.beginPath();
ctx.moveTo( 10, 150 );
ctx.lineTo( 310, 150 );
ctx.stroke();
</script>
</body>
5.ctx.translate(x轴平移量,y轴平移量)平移
<body>
<canvas id="cvs" width="500" height="500"></canvas>
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
/*
* 平移坐标轴:
* ctx.translate( x轴平移量,y轴平移量 )
* 备注:已绘制的图形不会受到影响,平移会累加。
* */
ctx.fillRect(10, 10, 50, 50);
// 画出坐标轴原点,做为参考
ctx.arc(0, 0, 2, Math.PI * 0, Math.PI * 2);
ctx.fill();
// 平移坐标轴之后,按照同样的坐标绘制一个填充矩形
ctx.translate(100, 100);
// 画出坐标轴原点,做为参考
ctx.arc(0, 0, 2, Math.PI * 0, Math.PI * 2);
ctx.fill();
ctx.fillRect(10, 10, 50, 50);
// // 再平移坐标轴,再按照同样的坐标绘制一个填充矩形
ctx.translate(100, 100);
// 画出坐标轴原点,做为参考
ctx.arc(0, 0, 2, Math.PI * 0, Math.PI * 2);
ctx.fill();
ctx.fillRect(10, 10, 50, 50);
</script>
</body>
6.ctx.rotate(旋转的弧度)旋转
<body>
<canvas id="cvs" width="500" height="500"></canvas>
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
/*
* 旋转坐标轴:
* ctx.rotate( 旋转的弧度 )
* 备注:已绘制的图形不会受到影响,旋转会累加。
* */
ctx.translate( 100, 100 );
ctx.fillRect( 0, 0, 50, 50 );
// 旋转坐标轴,再按照同样的坐标绘制填充矩形
ctx.rotate( Math.PI / 6 );
ctx.fillStyle = 'pink';
ctx.fillRect( 0, 0, 50, 50 );
// 旋转坐标轴,再按照同样的坐标绘制填充矩形
ctx.rotate( Math.PI / 6 );
ctx.fillStyle = 'green';
ctx.fillRect( 0, 0, 50, 50 );
</script>
</body>
7.缩放ctx.scale(x轴缩放的比值,y轴缩放的比值)
<body>
<canvas id="cvs" width="500" height="500"></canvas>
<script>
var cvs = document.getElementById('cvs');
var ctx = cvs.getContext('2d');
/*
* 缩放坐标轴:
* ctx.scale( x轴缩放的比值,y轴缩放的比值 )
* 备注:已绘制的图形不会受到影响,缩放会累加。
* */
ctx.translate( 100, 100 );
ctx.fillRect( 0, 0, 50, 50 );
// 缩放坐标轴,再按照同样的坐标绘制填充矩形
// 坐标轴平移了一次
ctx.translate( 12.5, 12.5 );
ctx.scale( 0.5, 0.5 );
ctx.fillStyle = 'pink';
ctx.fillRect( 0, 0, 50, 50 );
// 缩放坐标轴,再按照同样的坐标绘制填充矩形
ctx.scale( 0.5, 0.5 );
ctx.fillStyle = 'blue';
ctx.fillRect( 0, 0, 50, 50 );
</script>
</body>