元素只有两个属性
width、height
,当没有设置width、height
时,也就是画布的默认的
width
为300px,height
为150px。
<canvas id="myCanvas" width="200" height="100">
您当前的浏览器不支持canvas
canvas>
ps:canvas 元素本身是没有绘图能力的。所有的绘制工作必须在 脚本(JavaScript) 内部完成
设置canvsa的宽高有两种方式:
标签中通过width
和height
属性来设置,可以不写单位,默认单位为px
<canvas id="myCanvas1" width="200" height="100">
您当前的浏览器不支持canvas
canvas>
<canvas id="myCanvas2" width="200px" height="100px">
您当前的浏览器不支持canvas
canvas>
的宽和高。 <canvas id="canvas" class="canvas">
你的浏览器不支持canvas
canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
canvas.width = 100;
height.height = 100;
var ctx = canvas.getContext('2d');
script>
的宽和高Canvas有2D和3D之分,因此Canvas坐标系统也是有区别的,我们可以通过设置getContext('2d')
让canvas获得一个2d环境。
在Canvas中2D环境中其坐标系统和Web坐标系统,以及和svg的最初坐标系统是一致的。
绘制路径用到的方法
var canvas = document.getElementById('canvas');
canvas.width = 500;
canvas.height = 500;
var ctx = canvas.getContext('2d');
ctx.moveTo(100,100);
ctx.lineTo(200,200);
ctx.lineTo(200,300);
ctx.stroke();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'red';
ctx.moveTo(300,150);
ctx.lineTo(100,450);
ctx.lineTo(500,450);
ctx.closePath();
ctx.stroke();
坑2:ctx.stroke()方法是将我们做出的图从内存中画到画布上。多次使用ctx.stroke()会把之前的内容也重新画一遍,并重叠在原来的画上。
因为已经做好的图依旧 保存在内存 当中,ctx.stroke()仅仅是把内容绘制出来,并没有清除,所以在当要画出第二条线的时候,也会把第一条线再画一遍。
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.moveTo(100,100);
ctx.lineTo(100,200);
ctx.lineTo(200,200);
ctx.strokeStyle="#f00";
ctx.stroke();
ctx.moveTo(400,100);
ctx.lineTo(400,200);
ctx.lineTo(500,200);
ctx.strokeStyle="#00F";
ctx.stroke();
//...
ctx.strokeStyle= 'red';
ctx.stroke();
debugger;
ctx.moveTo(400,100);
//...
执行到第一个ctx.stroke()
执行到第二个ctx.stroke()
方法一:
在所有图像绘制完成后再调用.stroke()
将图像绘制到画布上。
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.moveTo(100,100);
ctx.lineTo(100,200);
ctx.lineTo(200,200);
ctx.strokeStyle= 'red';
ctx.moveTo(400,100);
ctx.lineTo(400,200);
ctx.lineTo(500,200);
ctx.strokeStyle="blue";
ctx.stroke();
方法二:
使用.beginPath()
方法释放之前已经画好的图像。
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.moveTo(100,100);
ctx.lineTo(100,200);
ctx.lineTo(200,200);
ctx.strokeStyle= 'red';
ctx.stroke();
ctx.beginPath();
ctx.moveTo(400,100);
ctx.lineTo(400,200);
ctx.lineTo(500,200);
ctx.strokeStyle="blue";
ctx.stroke();
但是一旦使用了begin清除了之前的路径,可能就无法使用closePath闭合路径了
arc(x,y,r,startAngle,endAngle[,anticlosewise])
案例1
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();
案例2
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.beginPath();
ctx.arc(95,50,40,0,Math.PI,true);
ctx.stroke();
描绘出一个矩形边框。
strokeRect(x, y, width, height)
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'red';
ctx.moveTo(400,400);
ctx.lineTo(500,500);
ctx.stroke();
//描出矩形
ctx.strokeRect(100,100,300,200);
使用strokeRect()绘制矩形,不需要再调用stroke()
复杂一点的案例:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.moveTo(300,50);
ctx.lineTo(350,150);
ctx.moveTo(450,50);
ctx.lineTo(400,150);
ctx.stroke();
//头
ctx.strokeRect(300,150,150,100);
//耳
ctx.strokeRect(280,170,20,40);
ctx.strokeRect(450,170,20,40);
//眼
ctx.beginPath();
ctx.arc(330,180,10,0,2*Math.PI,true);
ctx.stroke();
ctx.beginPath();
ctx.arc(420,180,10,0,2*Math.PI,true);
ctx.stroke();
//嘴
ctx.strokeRect(340,210,70,20);
//身体
ctx.strokeRect(320,250,110,160);
//膀子
ctx.strokeRect(170,280,150,20);
ctx.strokeRect(430,280,150,20);
//脚
ctx.strokeRect(340,410,20,50);
ctx.strokeRect(390,410,20,50);
常用的属性
属性 | 描述 |
---|---|
lineWidth | 设置或返回当前的线条宽度 |
fillStyle | 设置或返回一个区间的填充颜色,使用fill()方法进行填充,支持十六进制,支持rgba |
strokeStyle | 设置或返回画笔的颜色,支持十六进制,支持rgba |
lineCap | 设置或返回线条的结束端点样式 |
lineJoin | 设置或返回两条线相交时,所创建的拐角类型 |
fill() | 给路径围成的区域(不包括使用strokeRect()绘制的矩形)填充颜色 |
fillRect() | 绘制一个有填充色的矩形(也可以给矩形填充颜色,定位宽高一样就行) |
lineWidth 设置的是最终stroke()画笔的宽度。只要是放在stroke()前,那放哪里都无所谓。
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.moveTo(100,100);
ctx.lineTo(200,300);
ctx.lineWidth =10;
ctx.lineTo(400,300);
ctx.stroke();
和fill()配合使用,要填充的区域无需闭合。
只支持一种原生的 图形绘制:矩形。其他所有图形都是由路径(path)形成的。所以使用fill()是无法填充矩形的,填充矩形和填充圆的语法是不一样的。
先用fillStyle="color"
设置填充颜色,再使用fill()
进行填充。
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.moveTo(100,100);
ctx.lineTo(200,300);
ctx.lineWidth = 10;
ctx.lineTo(400,300);
ctx.stroke();
ctx.fillStyle = 'blue';
ctx.fill();
//绘制圆
ctx.beginPath();
ctx.arc(600,200,100,0,2*Math.PI,true);
ctx.fillStyle = 'pink';
ctx.fill();
两条非平行的连线可以构成一个区域。
设置的是最终stroke()画笔的颜色。只要是放在stroke()前,那放哪里都无所谓。
使用strokeStyle的正确打开方式:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'red';
ctx.moveTo(300,150);
ctx.lineTo(100,450);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.moveTo(300,150);
ctx.lineTo(500,450);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'green';
ctx.moveTo(100,450);
ctx.lineTo(500,450);
ctx.stroke();
错误打开方式:
最终起作用的strokeStyle是stroke()前的那一个。
妄想用这种方法画一个三条边不同颜色的三角形是错误的。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'red';
ctx.moveTo(300,150);
ctx.lineTo(500,450);
ctx.strokeStyle = 'green';
ctx.lineTo(100,450);
ctx.strokeStyle = 'blue';
ctx.closePath();
ctx.stroke();
绘制一个带有填充颜色的矩形。
换个思路:当这个带有填充颜色的矩形 定位 和 宽高 与strokeRect()绘制的矩形一样,那不就是填充了嘛。
ctx.lineWidth = 10;
ctx.strokeRect(200,500,300,200);
ctx.fillStyle = 'red';
ctx.fillRect(200,500,300,200);
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//二毛
ctx.moveTo(300,50);
ctx.lineTo(350,150);
ctx.moveTo(450,50);
ctx.lineTo(400,150);
ctx.lineWidth = 3;
ctx.strokeStyle = '#FFD700';
ctx.stroke();
//头
ctx.lineWidth = 1;
ctx.strokeStyle = 'rgba(255,218,185)';
ctx.fillStyle = 'rgba(255,218,185)';
ctx.strokeRect(300,150,150,100);
ctx.fillRect(300,150,150,100);
//耳朵
ctx.fillStyle = 'yellow';
ctx.strokeRect(280,170,20,40);
ctx.fillRect(280,170,20,40);
ctx.strokeRect(450,170,20,40);
ctx.fillRect(450,170,20,40);
//眼睛
ctx.beginPath();
ctx.fillStyle = '#000';
ctx.arc(330,180,10,0,2*Math.PI,true);
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.arc(420,180,10,0,2*Math.PI,true);
ctx.stroke();
ctx.fill();
//嘴
ctx.strokeRect(340,210,70,20);
ctx.fillStyle = 'red';
ctx.fillRect(340,210,70,20);
//身体
ctx.strokeRect(320,250,110,160);
ctx.fillStyle = 'pink';
ctx.fillRect(320,250,110,160);
//膀子
ctx.fillStyle = '#8EE5EE';
ctx.strokeRect(170,280,150,20);
ctx.fillRect(170,280,150,20);
ctx.strokeRect(430,280,150,20);
ctx.fillRect(430,280,150,20);
//脚
ctx.strokeRect(340,410,20,50);
ctx.fillRect(340,410,20,50);
ctx.strokeRect(390,410,20,50);
ctx.fillRect(390,410,20,50);
由于图形转换的三个方法时可以叠加的,构图的环境会越来复杂。所以会配合save和restore方法使用。
平移是改变坐标系的原点。
平移坐标原点到指定的位置。并不是平移
的位置。
translate(x, y)
平移影响的是调用translate(x, y)后,后面在图形的定位。
案例1:
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.translate(0,100);
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
案例2:
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.moveTo(0,0);
ctx.translate(0,100); //改变调用平移的位置
ctx.lineTo(100,100);
ctx.stroke();
旋转是以坐标系原点为圆心,旋转坐标系。如果原点被平移了,那就是以平移后的原点为圆心。
rotate(angle)
rotate() 是旋转正个坐标系
案例1:
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.lineWidth = 10;
ctx.rotate(Math.PI / 180 * 45);
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
案例2:
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.lineWidth = 10;
ctx.translate(100,100);
ctx.rotate(Math.PI / 180 * 45);
ctx.fillRect(100,100,100,100);
这玩意缩放的是坐标系。
scale(x, y)
var canvas = document.getElementById('canvas');
canvas.width = 800;
canvas.height = 800;
var ctx = canvas.getContext('2d');
ctx.translate(10,10);
ctx.scale(0.5,1);
ctx.fillRect(100,100,100,100)
save()和restore()方法是绘制复杂图形必不可少的方法,使用save()在作图之前保存上文的原始环境,包括图形变换和样式。再使用restore()恢复之前的环境。
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.save(); //保存之前的原始环境
ctx.translate(200,300);
ctx.rotate(Math.PI/3);
ctx.scale(0.5,0.5);
ctx.fillStyle = 'yellow';
ctx.fillRect(100,100,200,300);
ctx.restore();
ctx.strokeRect(100,100,200,100);
案例:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.save();
//时钟圆盘
context.translate(300,300);
context.fillStyle = 'pink';
context.arc(0,0,100,0,2*Math.PI,true);
context.fill();
//时钟刻度
context.beginPath();
context.strokeStyle = 'black';
for(var i=0;i<4;i++){
context.rotate(Math.PI/2);
context.moveTo(90,0);
context.lineTo(100,0);
}
context.stroke();
//时针
context.beginPath();
context.strokeStyle = 'blue';
context.moveTo(0,0);
context.lineTo(20,0);
context.stroke();
//分针
context.beginPath();
context.moveTo(0,0);
context.lineTo(0,40);
context.stroke();
context.restore();
渐变可以理解为一种颜色, canvas中有两种渐变:
var linearGradient = ctx.createLinearGradient(xStart,yStart,xEnd,yEnd);
linearGradient.addColorStop(0~1,color);
ctx.fillStyle = linearGradient;
案例1:两种颜色线性渐变
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var linearGradient = ctx.createLinearGradient(100,100,200,200);
linearGradient.addColorStop(0,'rgba(255,0,0,1)');
linearGradient.addColorStop(1,'rgba(0,0,255,1)');
ctx.fillStyle = linearGradient;
ctx.fillRect(0,0,300,300);
案例2:多种颜色线性渐变
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var linearGradient = ctx.createLinearGradient(0,300,300,0);
linearGradient.addColorStop(0,'#FFFF00');
linearGradient.addColorStop(0.5,' #FFB5C5');
linearGradient.addColorStop(1,' #66ccff');
ctx.fillStyle = linearGradient;
ctx.arc(150,150,150,0,2*Math.PI,true);
ctx.fill();
ctx.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd);
linearGradient.addColorStop(0~1,color);
ctx.fillStyle = linearGradient;
案例1:
ctx.arc(400,400,200,0,Math.PI*2,true);
//线性渐变
var radialGradient = ctx.createRadialGradient(400,400,0,400,400,200);
//设置渐变颜色
radialGradient.addColorStop(0,'yellow');
radialGradient.addColorStop(0.3,'red');
radialGradient.addColorStop(0.5,'pink');
radialGradient.addColorStop(0.7,'green');
radialGradient.addColorStop(1,'blue');
//设置渐变作为样式
ctx.fillStyle = radialGradient;
ctx.fill();
案例2:
ctx.arc(400,400,200,0,Math.PI*2,true);
//径向渐变
var radialGradient = ctx.createRadialGradient(400,200,0,400,400,200);
//设置渐变颜色
radialGradient.addColorStop(0,'rgb(255,255,0)');
radialGradient.addColorStop(1,'rgb(0,0,0)');
//设置渐变作为样式
ctx.fillStyle = radialGradient;
ctx.fill();
属性 | 说明 | 值 |
---|---|---|
font | 设置或返回文本内容的当前字体属性 | |
textAlign | 设置或返回文本内容的当前对齐方式 | left,start左对齐; center居中对齐; end,right右对齐; |
textBaseline | 设置或返回在绘制文本时使用的当前文本基线 | top顶对齐; middle居中; bottom底部对齐; |
方法 | 说明 |
---|---|
fillText() | 填充文字 |
strokeText() | 描边文字 |
measureText() | 计算文本宽度 |
案例1:
若是要实现文本水平居中,要先将文本定位到
元素 width/2的位置,再设置
ctx.textAlign = 'center'
才能实现水平居中。
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext('2d');
var str1 = '苟利国家生死以,';
var str2 = '岂因祸福避趋之!'
ctx.font = '50px Microsoft Yahei';
ctx.strokeStyle = 'red';
ctx.textAlign = 'center';
ctx.strokeText(str1,400,350);
ctx.font = '50px SimHei';
ctx.fillStyle = 'blue';
ctx.textAlign = 'center';
ctx.fillText(str2,400,450);
案例2:
获取文本的宽度,以便以后能动态的使文本居中。
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext('2d');
var str2 = '岂因祸福避趋之!';
var strWidth = ctx.measureText(str2).width;
console.log(strWidth);
绘制图片3种方法:
ctx.drawImage(image,x,y)
把图片绘制在(x,y)处。ctx.drawImage(image,x,y,w,h)
把图片绘制在(x,y)处,并缩放为宽w,高hctx,drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh)
把图片中(sx,sy)处的宽sw,高sh的区域,绘制到(dx,dy)处,并缩放为宽dw,高dh。创建元素
var img = new Image();
img.src = '../Drag/upload/44379492.jpg';
在img的回调函数onload中绘制
如果 drawImage 的时候图片还没有完全加载完成,则什么都不会显示,个别浏览器会抛异常。所以一定要在图像加载完成后的回调中绘制图像。
img.onload = function(){
ctx.drawImage(img,0,0);
}
创建一个画刷,进而可以把图片设置到fillStyle中,使用fil()进行填充
var img = new Image();
img.src = '../Drag/upload/44379492.jpg';
img.onload = function(){
ctx.createPattern(img,'repeat/no-repeat/repeat-x/repeat-y');
ctx.fillStyle = pattern;
ctx.fillRect(.....);//或者ctx.fill();
}
参数:repeat/no-repeat/repeat-x/repeat-y就是设置背景图是否重复。
canvas使用clip()
方法进行裁剪区域。
先绘制绘制一个区域A,调用clip()
方法后,所绘制的所有图形,只有在区域A中的部分才会被显示,区域A外部都会被裁剪到。
案例1:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext('2d');
//绘制一个圆形
ctx.arc(300,300,200,0,2*Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
ctx.clip(); //将上面的绘制的区域设置成裁剪区域。
//绘制一个正方形
ctx.fillStyle = 'yellow';
ctx.fillRect(300,300,200,200);
//绘制一个圆
ctx.beginPath();
ctx.arc(500,100,200,0,2*Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
clip()后面所绘制的所有图形都会被裁剪,如果不想被裁剪,那就使用save()和restore()。
案例2:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext('2d');
ctx.save();
ctx.arc(300,300,200,0,2*Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
ctx.clip();
ctx.fillStyle = 'yellow';
ctx.fillRect(300,300,200,200);
ctx.restore();
ctx.beginPath();
ctx.arc(500,100,200,0,2*Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
绘制阴影会用到一下4个属性:
案例1:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
//设置阴影
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowColor = 'rgba(0,0,0,0.5)';
context.shadowBlur = 10;
context.fillStyle = 'rgba(255,0,0,0.5)'; //设置红色半透明。
context.fillRect(200,200,100,100);
context.font = '50px sans-serif';
context.fillText('poorpenguin',400,300);
设置阴影后对后面新的图形或者文字都是默认带阴影的。可以使用save()和restore()还原默认环境。
案例2:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.save();
//设置阴影
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowColor = 'rgba(0,0,0,0.5)';
context.shadowBlur = 10;
context.fillStyle = 'rgba(255,0,0,0.5)'; //设置红色半透明。
context.fillRect(200,200,100,100);
context.restore();
context.font = '50px sans-serif';
context.fillText('poorpenguin',400,300);
Canvas绘制曲线有三种方法:
圆弧:
arc(x,y,r,startAngle,endAngle[,anticlosewise])
二次贝塞尔曲线:
ctx.quadraticCurveTo(x2,y2,x3,y3);
x2,y2是与前面个点连接,x3,y3是与x2,y2的连接,形成的切线斜率构成曲线。
三次贝塞尔曲线:
ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);
分别由前面两个点,后面两个点的斜率构成的曲线。
案例1:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.arc(400,400,100,0,Math.PI/2, true);
context.stroke();
案例2:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.arc(400,400,100,0,Math.PI/2, false);
context.stroke();
案例3:
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.arc(400,400,100,0,Math.PI/2, false);
context.stroke();
context.fill();
Canvas的动画一般就是鼠标和键盘事件+定时器+clearRect()组合实现的。
案例1:一个简单的动画
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas动画--方块四处碰撞title>
<style>
*{
margin: 0;
padding: 0;
}
canvas{
border: 1px solid red;
position: relative;
margin: 50px;
}
style>
head>
<body>
<canvas id="canvas" width="1000" height="800">
canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var rectX = 0,
rectY = 0,
dirX = 1,
dirY = 1,
speed = 10;
isMouseEnterRect = false;
canvas.onmousemove = function(e){
var mouseX = e.offsetX;
var mouseY = e.offsetY;
if(rectX<mouseX && mouseX<rectX+50 && rectY<mouseY && mouseY<rectY+50){
isMouseEnterRect = true;
}else{
isMouseEnterRect = false;
}
}
var timer = setInterval(function(){
if(!isMouseEnterRect){
rectX += speed*dirX;
rectY += speed*dirY;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillRect(rectX,rectY,50,50);
if(rectX+50 >= canvas.width){
dirX = -1;
}else if(rectX<=0){
dirX = 1;
}
if(rectY+50 >= canvas.height){
dirY = -1;
}else if(rectY<=0){
dirY = 1;
}
}
},100);
script>
body>
html>
什么是离屏技术?
通过在离屏Canvas中绘制元素,再复制到显示Canvas中,从而大幅度提高性能的技术。一种思想。
什么时候使用离屏技术?
在一个动画中会有动态场景和静态场景,每一次绘制动态场景的时候也会重新绘制一次静态场景,这样特别浪费资源。所以一般把静态场景绘制在离屏(离屏:不在屏幕上显示的canvas,也就是display:none),更新动态场景后,把静态场景copy过来,而不是重新绘制。
离屏技术用到的三个方法:
ctx.drawImage(canvas,x,y)
把图片绘制在(x,y)处。ctx.drawImage(canvas,x,y,w,h)
把图片绘制在(x,y)处,并缩放为宽w,高hctx,drawImage(canvas,sx,sy,sw,sh,dx,dy,dw,dh)
把图片中(sx,sy)处的宽sw,高sh的区域,绘制到(dx,dy)处,并缩放为宽dw,高dh。对,你没看错,就是绘制图片的三个方法。但是里面绘制的就不是图片而是canvas
案例1:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>canvas动画--方块四处碰撞title>
<style>
*{
margin: 0;
padding: 0;
}
canvas{
border: 1px solid red;
position: relative;
margin: 50px;
}
#bgCanvas{
display: none;
}
style>
head>
<body>
<canvas id="canvas" width="1000" height="800">
您的浏览器不支持canvas
canvas>
<canvas id="bgCanvas" width="1000" height="800">
您的浏览器不支持canvas
canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var bgCanvas = document.getElementById('bgCanvas');
var ctx = canvas.getContext('2d');
var bgctx = bgCanvas.getContext('2d');
//将背景花在离屏上
var drawBg = function(){
for(var i=0;i<canvas.width;i+=10){
for(var j=0;j<canvas.height;j+=10){
bgctx.beginPath();
bgctx.arc(i,j,5,0,Math.PI*2,true);
bgctx.stroke();
}
}
}
drawBg();
var rectX = 0,
rectY = 0,
dirX = 1,
dirY = 1,
speed = 10;
isMouseEnterRect = false;
canvas.onmousemove = function(e){
var mouseX = e.offsetX;
var mouseY = e.offsetY;
if(rectX<mouseX && mouseX<rectX+50 && rectY<mouseY && mouseY<rectY+50){
isMouseEnterRect = true;
}else{
isMouseEnterRect = false;
}
}
var timer = setInterval(function(){
if(!isMouseEnterRect){
rectX += speed*dirX;
rectY += speed*dirY;
ctx.clearRect(0,0,canvas.width,canvas.height);
//将离屏作为背景图
ctx.drawImage(bgCanvas,0,0,bgCanvas.width,bgCanvas.height,0,0,canvas.width,canvas.height);
ctx.fillRect(rectX,rectY,50,50);
if(rectX+50 >= canvas.width){
dirX = -1;
}else if(rectX<=0){
dirX = 1;
}
if(rectY+50 >= canvas.height){
dirY = -1;
}else if(rectY<=0){
dirY = 1;
}
}
},100);
script>
body>
html>