课程内容
3.1.Canvas 进阶
3.1.1.canvas 回顾
什么是canvas 元素?作用是什么?
在HTML5中,Canvas元素用于在网页上绘制图形,该元素强大之处在于可以直接在HTML上进行图形操作,具有极大的应用价值。
canvas 元素使用脚本JavaScript 在网页上绘制图像。
canvas 元素是一个画布,而画布是一个矩形区域,可以控制其每一像素。
canvas 元素拥有绘制路径、矩形、圆形、字符以及添加图像的方法,可以创建丰富的图形引用。
eg:
<canvas id="canvas" width="800" height="600" style="border:1px solid #000;"></canvas>
使用canvas 绘制图形
在绘制图形之前,首先建立一个画布,获取上下文
代码如下:
<canvas id="canvas" width="800" height="600" style="border:1px solid #000;"></canvas>
<script>
window.onload = function(){
var canvas = document.getElementById('canvas').getContext('2d');
}
</script>
绘制直线
绘制直线
moveTo(x,y);
lineTo(x,y);
strokeStyle = "black"
stroke();
代码:
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(750,550);
cxt.strokeStyle = "black";
cxt.stroke();
</script>
ctx.lineWidth :
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(0,0);
10
cxt.lineTo(350,150);
cxt.lineWidth = 5;
cxt.strokeStyle = "black";
cxt.stroke();
</script>
绘制矩形
绘制矩形
cxt.fillRect(x,y,width,height)
x:左上角的x轴坐标
y:左上角的y轴坐标
width:矩形宽度
height:矩形高度
线条绘制矩形
绘制矩形
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.lineTo(200,200);
cxt.lineTo(50,200);
cxt.lineTo(50,50);
cxt.strokeStyle = "black";
cxt.stroke();
</script>
11
填充绘制矩形
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.lineTo(200,200);
cxt.lineTo(50,200);
cxt.lineTo(50,50);
cxt.fillStyle = "black";
cxt.fill();
</script>
给填充绘制的矩形加边框
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.moveTo(50,50);
cxt.lineTo(200,50);
cxt.lineTo(200,200);
cxt.lineTo(50,200);
cxt.lineTo(50,50);
cxt.lineWidth = 5;
cxt.strokeStyle = "red";
12
cxt.fillStyle = "black";
cxt.stroke();
cxt.fill();
</script>
3.1.2.canvas 高级内容(一)
绘制圆形
绘制圆形
cxt.arc(x,y,r,stratAngle,endAngle,counterclockwise);
x:圆心的x坐标
y:圆心的y坐标
r:圆的半径
startAngle:起始角,以弧度记(时钟的3点钟方向位置),开始为0
endAngle:结束角,以弧度记
counterclockwise:有两个值,一个是true 为逆时针,一个是false 为顺时针,默认值为false
,想要顺时针的话,可以不填
绘制弧线
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.arc(200,200,100,0,0.5*Math.PI);
cxt.lineWidth = 5;
cxt.strokeStyle = "block"
cxt.stroke();
</script>
13
绘制圆
线条圆
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.arc(200,200,100,0,Math.PI*2);
cxt.strokeStyle = "block"
cxt.stroke();
</script>
填充圆
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.arc(200,200,100,0,Math.PI*2);
cxt.fillStyle = "block"
cxt.fill();
</script>
14
路径绘制图形
beginPath();//丢弃任何当前定义的路径并且开始一条新的路径。它把当前的点设置为 (0,0)。
closePath();//如果画布的子路径是打开的,closePath()
通过添加一条线条连接当前点和子路径起始点来关闭它。如果子路径已经闭合了,这个方法不做任何事
情。
没有beginPath()的情况下
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.fillStyle = "block"
cxt.arc(200,200,100,0,Math.PI*2);
cxt.fill();
cxt.fillStyle = "blueviolet"
cxt.arc(300,300,50,0,Math.PI*2);
cxt.fill();
</script>
15
有beginPath()的情况下:
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.fillStyle = "block"
cxt.arc(200,200,200,0,Math.PI*2);
cxt.fill();
cxt.beginPath();
cxt.fillStyle = "red"
cxt.arc(400,400,100,0,Math.PI*2);
cxt.fill();
</script>
16
绘制多边形
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.strokeStyle = "block"
cxt.beginPath()
cxt.moveTo(100,100)
cxt.lineTo(400,200)
cxt.lineTo(300,300)
cxt.lineTo(140,200)
cxt.closePath();
cxt.stroke();
</script>
绘制弧线
<script>
var canvas = document.getElementById('canvas')
var cxt = canvas.getContext('2d');
cxt.strokeStyle = "block"
cxt.beginPath()
cxt.arc(200,200,200,0,Math.PI*0.5);
cxt.closePath();
cxt.stroke();
</script>
17
canvas 图像操作
通过js来获取图片
<canvas id="canvas" width="650" height="550" style="border:1px solid #000;"></canvas>
<script>
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext('2d');
var img = new Image();
img.src = "img/bg.png";
img.onload = function(){
cxt.drawImage(img,0,0)
}
</script>
<img src="img/bg.png" id="img" style="display: none;" />
<canvas id="canvas" width="650" height="550" style="border:1px solid #000;"></canvas>
<script>
window.onload = function(){
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext('2d');
var img = document.getElementById('img');
cxt.drawImage(img,0,0)
}
</script>
在画布上定位图像
canvas图像
图像:
图像是由扫描仪、摄像机等输入设备捕捉实际画面而产生的数字图像,是由像素点阵构成的位图。
在画布上定位图像的语法:
cxt.drawImage(image,dx,dy)
注意:与createPattern(img,repeat-
style)图像填充不同,context.drawImage(image,dx,dy)创建的是一个对象,createPattern(img,repeat-
style)是把图片当成背景图片填充。
例:
18
image :规定要使用的图像、画布或视频。
x : 在画布上放置图像的 x 坐标位置。
y : 在画布上放置图像的 y 坐标位置。
在画布上定位图像,并规定图像的宽度和高度的语法
19
canvas图像
图像:
图像是由扫描仪、摄像机等输入设备捕捉实际画面而产生的数字图像,是由像素点阵构成的位图。
在画布上定位图像,并规定图像的宽度和高度的语法:
cxt.drawImage(img,x,y,width,height);
document.getElementById("pic").onload=function(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("pic");
ctx.drawImage(img,10,10,240,160);
};
image :规定要使用的图像、画布或视频。
x : 在画布上放置图像的 x 坐标位置。
y : 在画布上放置图像的 y 坐标位置。
width : 可选。要使用的图像的宽度。(伸展或缩小图像)
height : 可选。要使用的图像的高度。(伸展或缩小图像)
剪切图像,并在画布上定位被剪切的部分的语法
canvas图像
图像:
图像是由扫描仪、摄像机等输入设备捕捉实际画面而产生的数字图像,是由像素点阵构成的位图。
剪切图像,并在画布上定位被剪切的部分的语法:
cxt.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
20
img : 规定要使用的图像、画布或视频。
sx : 可选。开始剪切的 x 坐标位置。
sy : 可选。开始剪切的 y 坐标位置。
swidth : 可选。被剪切图像的宽度。
sheight : 可选。被剪切图像的高度。
x : 在画布上放置图像的 x 坐标位置
y : 在画布上放置图像的 y 坐标位置。
width : 可选。要使用的图像的宽度。(伸展或缩小图像)
height : 可选。要使用的图像的高度。(伸展或缩小图像)
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var img=document.getElementById("pic");
ctx.drawImage(img,90,130,90,80,20,20,90,80);
image :规定要使用的图像、画布或视频。
sx : 可选。开始剪切的 x 坐标位置。
sy : 可选。开始剪切的 y 坐标位置。
swidth : 可选。被剪切图像的宽度。
sheight : 可选。被剪切图像的高度。
x : 在画布上放置图像的 x 坐标位置。
y : 在画布上放置图像的 y 坐标位置。
width : 可选。要使用的图像的宽度。(伸展或缩小图像)
height : 可选。要使用的图像的高度。(伸展或缩小图像)
在canvas 里面显示视频画面
21
<video id="video" controls width="270" >
<source src="video/mov_bbb.mp4" type='video/mp4'>
<source src="video/mov_bbb.ogg" type='video/ogg'>
</video>
<script>
var v=document.getElementById("video");
var c=document.getElementById("myCanvas");
ctx=c.getContext('2d');
v.addEventListener('play', function() {
var i=window.setInterval(function() {
ctx.drawImage(v,0,0,270,135)
},20);
},false);
v.addEventListener('pause',function() {
window.clearInterval(i);
},false);
v.addEventListener('ended',function() {
clearInterval(i);
},false);
</script>
3.2.Canvas 进阶
3.2.1.canvas 高级内容(二)
在canvas 里面绘制文字
fillText:绘制文字
fillText(string,x,y)
<script>
var canvas = document.getElementById('canvas');
var cxt = canvas.getContext("2d");
window.onload = function(){
canvas.width = 1420;
canvas.height = 768;
drawText(cxt,'你好,美女!',200,100,"orange");
22
}
function drawText(cxt,string,x,y,color){
cxt.fillStyle = color
cxt.font = "bold 72px 微软雅黑";
cxt.fillText(string,x,y);
}
</script>
font-style 规定字体样式
存在值:normal | italic//斜体 | oblique//倾斜
font-variant 规定字体变体
存在值:normal | small-caps //小型大写
font-weight 规定字体的粗细
存在值:normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
font-size / line-height 规定字号和行高,以像素计。
font-family 规定字体系列
isPointInPath()
isPointInPath
context.isPointInPath(x,y)
用于判断一个点是否在规划的当前路径内
x:测试的 x 坐标
y:测试的 y 坐标
23
clearRect()
clearRect()
clearRect() 方法清空给定矩形内的指定像素。
语法:
context.clearRect(x,y,width,height);
x : 要清除的矩形左上角的 x 坐标
y : 要清除的矩形左上角的 y 坐标
width : 要清除的矩形的宽度,以像素计
height : 要清除的矩形的高度,以像素计
点击获取鼠标位置
getBoundingClientRect()方法
语法:这个方法没有参数
rectObject = object.getBoundingClientRect();
返回值类型:TextRectangle对象,每个矩形具有四个整数性质( 上, 右 , 下,和左
)表示的坐标的矩形,以像素为单位。
在canvas获取鼠标点击后的位置的方法(canvas标准方法)
var x = event.clientX - canvas.getBoundingClientRect().left;
var y = event.clientY - canvas.getBoundingClientRect().top;
3.3.Canvas 进阶
3.3.1.canvas 高级内容(三)
剪辑区域
剪辑区域
24
定义和用法:
clip() 方法从原始画布中剪切任意形状和尺寸。
一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域
)。
语法:
context.clip()
使用刚才的路径,把它剪切为当前的绘制环境
例:
25
globalCompositeOperation
globalCompositeOperation
globalCompositeOperation = "source-over" (default)
值:destination-over source-atop source-in source-out destination-over destination-atop destination-in
destination-out lighter copy xor
globalCompositeOperation当指绘制的图像发生重叠时所产生的效果
source-
over:这是非常符合常理的覆盖形态,就是说若图形发生重叠时,后面绘制的图形会覆盖到前面绘制的图
形
26
source-over : 默认。在目标图像上显示源图像。
source-atop
: 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的
source-in
: 在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图
像是透明的。
source-out
: 在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图
像是透明的。
destination-over : 在源图像上方显示目标图像。
destination-atop
: 在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。
destination-in
: 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图
像是透明的。
destination-out
: 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图
像是透明的。
lighter : 显示源图像 + 目标图像。
copy : 显示源图像。忽略目标图像。
xor : 显示源图像和目标图像不相交的地方,相交处透明
27
阴影
阴影
例:
28
shadowColor 设置或返回用于阴影的颜色
shadowOffsetX 设置或返回阴影距形状的水平距离
shadowOffsetY 设置或返回阴影距形状的垂直距离
shadowBlur 设置或返回用于阴影的模糊级别
路径方向和剪纸效果
路径方向和剪纸效果
例:
29
globalAlpha
globalAlpha
globalAlpha=1;(default)
默认是1,用于设置图形透明度 透明数值范围(0-1)
例:
30
贝塞尔曲线
二次贝塞尔曲线 quadraticCurveTo()
定义和用法
quadraticCurveTo() 方法通过使用表示二次贝塞尔曲线的指定控制点,向当前路径添加一个点。
31
二次贝塞尔曲线需要两个点。第一个点是用于二次贝塞尔计算中的控制点,第二个点是曲线的结束
点。曲线的开始点是当前路径中最后一个点。如果路径不存在,那么请使用 beginPath() 和 moveTo()
方法来定义开始点。
语法:
cxt.quadraticCurveTo(cpx,cpy,x,y)
cpx:贝塞尔控制点的 x 坐标
cpy:贝塞尔控制点的 y 坐标
x: 贝塞尔结束点的 x 坐标
y: 贝塞尔结束点的 y 坐标
三次贝塞尔曲线 bezierCurveTo()
定义和用法
bezierCurveTo() 方法通过使用表示三次贝塞尔曲线的指定控制点,向当前路径添加一个点。
三次贝塞尔曲线需要三个点。前两个点是用于三次贝塞尔计算中的控制点,第三个点是曲线的结束
点。曲线的开始点是当前路径中最后一个点。如果路径不存在,那么请使用 beginPath() 和 moveTo()
方法来定义开始点。
语法:
cxt.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
32
cp1x : 第一个贝塞尔控制点的 x 坐标
cp2x : 第二个贝塞尔控制点的 x 坐标
x : 结束点的 x 坐标
cp1y : 第一个贝塞尔控制点的 y 坐标
cp2y : 第二个贝塞尔控制点的 y 坐标
y : 结束点的 y 坐标
3.4.Canvas 进阶
3.4.1.canvas 高级内容(四)
canvas 动画效果
canvas动画效果
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<canvas id="canvas" width="600" height="600"></canvas>
<script>
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d')
var y = 0
var color = "black"
setInterval(function(){
33
y++
fillArc(y,color)
},20)
function fillArc(y,color){
ctx.clearRect(0,0,600,600)
ctx.beginPath()
ctx.arc(300,300-y,5,0,2*Math.PI)
ctx.fillStyle = color
ctx.fill()
}
fillArc(y)
</script>
</body>
</html>
碰撞运动
碰撞运动
所谓碰撞运动即是当物体碰撞到地板或者墙壁边缘时发生的速度的改变。
我们可以想象一下,假设一个有一定质量的小球从高空做自由落体运动,然后碰撞到地板之后速度就
会发生变化,小球就会弹起来。在这个碰撞过程中,我们让小球有一个能量的损失,由这个想象,我们就
来模拟这个实验:
首页我们需要最简单的几步:(创建一个画布)
34
我们要想让小球有运动,那么就需要改变小球在Y轴上的值,所以我们首先需要定义一个全局变量,
这个变量就是小球的一个对象。
当我们创建好画布之后,我们可以先来写几个函数,我们先想象一下我们需要几个函数,首先,假如
我们就直接在画布上画一个圆,但是我们的运动是发生在这个小圆身上的,如果直接这样绘制,则无法
获取到这个圆,所以这里我们用函数进行一个绘制,假设这个函数名为render,但是如果用函数绘制小圆
,我们就会发现当我们调用setInterval()函数的时候,会每执行一次动画就会调用一次这个render,也就是
说没执行一次就会创建一个新的小圆,那样当动画开始执行的时候,我们就会看到画布上会创建很多的
小圆,那么这样的效果就不是我们想要的效果的了,这时候我们应该怎么做呢?那么这时候,我们就需
要当动画没执行一次就对画布进行一次刷新操作,我们就引进了context.clearRect()函数,该函数对一个
矩形控件内的图像进行一次刷新操作。
这样,我们这个画小球的操作就完成了。
接下来我们还需要一个函数,这个函数就是记载了小球做自由落体运动的轨迹,我们给一个函数名叫
update;
那么这个函数所需要做的事就是记录这个小球的运动轨迹,我们让小球的起始Y坐标点的值,加上这
个速度,就可以让小球运动起来了,然后我们需要注意的是,假设画布的底部就是地板,那么小球到达地
板后就会被反弹,这时,我们就需要改变这个小球的运动方向。所以这个函数我们可以这么写
35
我们来解释一下这段代码:
ball.vy +=
ball.g:我们学过物理的之后,我们做自由落体的时候是有一个重力加速度的,假设没有这句代码,那么
小球做的则是匀速直接运动,而并不是自由落体运动,所以我们让速度加上这个重力加速度,那么小球
在Y轴上的速度就会有一个加速度,就模拟了自由落体运动。
ball.y = 768-ball.r:这句代码是小球碰撞到地板后,以该点作为小球的起始点然后向上反弹。
ball.vy = -ball.vy *
0.7:这句代码就是把速度重新赋值为一个负值,而且模拟一个摩擦系数为0.7,这样就会有能量损失,小
球就会往反方向运动。
那么其他代码就很好理解了。
最后我们需要用setInterval()函数调用这两个函数。
由这个动画我们可以扩展另一个动画,假设canvas画布每个边缘都是墙壁,还有小球在运动的过程中
不会有任何能量的损失,也就是说上述例子ball.vy = -ball.vy *
0.7这句代码去掉0.7这个摩擦系数,那么就可以实现小球一旦碰到墙壁就会反弹的效果,小球就会在这
个画布里无休息的进行运动。