- 绘制圆形
使用arc。方法可以在画布上绘制一个圆形,该方法接收6个参数,分别如下表所示:
参数描述
x |
圆的中心的x坐标 |
y |
圆的中心的y坐标 |
r |
圆的半径 |
sAngle |
起始角度,以弧度计算,3点钟位置是0度 |
eAngle |
结束角度,以弧度计算 |
counterclockwis e |
可选,规定应该是顺时针绘制还是逆时针绘制。false=顺时针,true=逆 时针 |
角度转弧度的公式为:n/180x角度
所以如果我们要绘制圆形,那么起始角度为0,结束角度为360度,也就是Math. Pl*2就表示整 圆,如下:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0]; //获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.arc(200,150,50,0,Math.PI*2,false); context.stroke();
</script>
</body>
效果:
- 绘制三角形
绘制三角形,其实就是绘制线条,所以我们用绘制线条的方式就可以绘制出一个三角形,如下:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.moveTo(100,75);
context.lineTo(175,200);
context.lineTo(35,200);
context.fillStyle = "skyblue";
context.fill();//填充方法会自动闭合路径
</script>
</body>
效果:
如果是使用的str oke()方法绘制空心三角形,则需要提前使用closePath()方法将路径闭合 _下
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.moveTo(100,75);
context.lineTo(175,200);
context.lineTo(35,200);
context.closePath();//闭合路径 context.stroke();
</script>
</body>
效果:
- 绘制曲线(扩展)
相对于绘制直线,矩形,圆形等简单图形而言,绘制曲线比较具有挑战性,但是一旦掌握了其原 理,就能创建出许多复杂的图形。贝塞尔曲线在计算机图形学中的作用至关重要,其应用也非常 广泛,如在一些数学软件,矢量绘图软件和三维动画软件中,经常会见到贝塞尔曲线,主要用于 数值分析领域或产品设计和动画制作领域。这里我们将介绍如何在canvas中绘制贝塞尔曲线,包 括二次方曲线和三次方曲线。
其实主要就是对应的两个方法。绘制二次方贝塞尔曲线的语法如下:
context.quadraticCurveTo(cp1x,cp1y,x,y)
quad raticCu rveTo()方法用于绘制二次贝塞尔曲线。二次贝塞尔曲线需要两个点。第一个点是 用于二次贝塞尔计算中的控制点,第二个点是曲线的结束点。也就是说cplx和cply是控制点的 坐标,x和y是终点的坐标。
曲线的开始点是当前路径中最后一个点。如果路径不存在,那么需要使
用beginPath()和moveTo()方法来定义开始点。如下图:
下面是该方法的一个示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid">
您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.strokeStyle = "dark"; context.beginPath();
context.moveTo(0,200); // 这是起点位置
context.quad raticCu rveTo(75,50,300,200); // 第一个点是控制点第二个是终点 context.stroke();
//下面绘制的直线用于表示上面曲线的控制点和控制线,控制点坐标即两直线的交点(75,5
0)
context.strokeStyle = "#ff00ff";
context.beginPath();
context.moveTo(75,50);
context.lineTo(0,200);
context.moveTo(75,50);
context.lineTo(300,200); context.stroke();
</script>
</body>
效果如下:
在上面的示例中,我们通过context.quad raticCu rveTo绘制出来的曲线即二次方贝塞尔曲 线,两条直线为控制线,两直线的交点即曲线的控制点。
绘制三次方贝塞尔曲线的语法如下:
context.bezierCurveTo(cpl1x,cp2y,cp2x,cp2y,x,y);
bezie rCu rveTo()方法用于绘制三次贝塞尔曲线。三次贝塞尔曲线需要三个点。前两个点是用 于三次贝塞尔计算中的控制点,第三个点是曲线的结束点。换句话说,这里的参数cplx和cply 代表的是第一个控制点的坐标,cp2x和cp2y代表的是第二个控制点的坐标,x和y是终点坐标。
曲线的开始点是当前路径中最后一个点。如果路径不存在,那么需要使
用beginPath()和moveTo()方法来定义开始点。如下图所示:
下面是该方法的一个示例:
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.strokeStyle = "dark"; context.beginPath(); context.moveTo(0,200);
context.bezierCurveTo(25,50,75,50,300,200);
context.stroke();
//下面绘制的直线用于表示上面曲线的控制点和控制线,控制点坐标即两直线的交点(75,5 0)
context.strokeStyle = "#ff00ff";
context.beginPath();
context.moveTo(25,50);
context.lineTo(0,200);
context.moveTo(75,50);
context.lineTo(300,200); context.stroke();
</script>
</body>
效果:
在上面的示例中,我们通过context.bezie rCur veTo方法绘制出来的曲线即三次方贝塞尔曲 线,两条直线为控制线,两直线上方的端点即为曲线的控制点。
- 清空画布
使用clea rRect()方法可以清除某个矩形范围内的图形,语法如下:
clea rRect(x坐标,y坐标,矩形长,矩形宽)
具体示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<div>
vbutton onclick="clea rTest()"> 清除 v/button> </div> vscript>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0]; //获取到上下文,创建context对象
let context = canvas.getContext("2d");
let clearTest = function(){ context.clearRect(0,0,400,300);
}
context.moveTo(100,75); context.lineTo(175,200);
context.lineTo(35,200);
context.fillStyle = "skyblue"; context.fill();
v/script> v/body>
效果:点击清除按钮后画布会被清空
14-5-3图像的变换
- 保存和恢复状态
在介绍图像的变换之前,我们先来看一下在canvas里面如何保存和恢复canvas的状态, canvas里面可以使用save()和resto re()方法来保存和恢复canvas的状态。注意, 态是指的一些设置信息,例如当前的颜色设置,应用变形等,恢复也是恢复一些设置。 了的图像是不会有影响的。
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid">
您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d");
context.fillStyle = "blue"; context.fillRect(0,0,100,50);
context.save();//保存的是填充颜色的设置信息 context.fillStyle = "red";
context.fillRect(50,50,100,50);
context. restore();//恢复填充颜色的设置信息
context.fillRect(100,100,100,50);
</script>
</body>
效果:
- 移动坐标空间
在canvas里面画布的坐标空间默认是以画布左上角的(0,0)为原点,但是我们可以通 过tr anslate()方法来移动坐标空间,示例如下:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.fillStyle = "blue";
context.fillRect(0,0,100,50);
context.t ranslate(100,100);//移动坐标原点至 100x100 区域 context.fillRect(0,0,100,50);
</script>
</body>
效果:
这里我们可以利用该方法在画布上绘制10个小球
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d");
let i = 1;
while(i<=10){
context.beginPath(); context.arc(20,20,15,0,Math.PI*2,false); context.fill();
context.closePath();
context.translate(35,0);
i++;
}
</script>
</body>
效果:
这里需要注意一定要书写beginPath()和closePath()来开启和闭合路径,否则会一直在一个 路径上面进行绘制。
- 旋转坐标空间
除了移动坐标空间,还可以旋转坐标空间,通过rotate()方法。旋转的单位也是以弧度为单 位,所以需要将角度换算为弧度。
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d");
let i = 1;
context.t ranslate(200,150);//先将画布的中心点移到中间 while(i<=12){
context.beginPath(); context.arc(20,20,5,0,Math.PI*2,false); context.fill();
context.closePath();
context. rotate(Math.PI*30/180);//每次旋转30度 i++;
}
</script>
</body>
效果:
- 缩放图形
语法为:context.scale(x,y),所代表的含义为小于1为缩小,大于1为放大。x为水平方向的 缩放倍数,y为竖直方向的缩放倍数。
具体示例:绘制一个矩形,放大到200%,再次绘制矩形,放大到200%,重复4次
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid">
您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d");
let i = 1; while(i<=4){ context.strokeRect(5,5,25,15); context.scale(2,2);
i++;
}
</script>
</body>
效果:
14-5-4图像的组合和裁切(扩展)
当两个或两个以上的图形存在重叠区域时,默认情况下一个图形画在前一个图像之上。通过指定 图像globalCompositeOpe ration属性的值可以改变图形的绘制顺序或绘制方
式,globalAlpha可以指定图形的透明度。
globalCompositeOpe ration属性设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像 上。
・源图像为打算放置到画布上的绘图。
・目标图像为已经放置在画布上的绘图。
其中 ctx.globalCompositeOpe ration = 'sou rce-ove r'为默认设置
示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.fillStyle = "r ed";//设置填充颜色为红色 context.fillRect(20,20,75,50);//画出红色矩形 context.fillStyle = "blue";//设置填充颜色为蓝色 context.fillRect(50,50,75,50);//画出蓝色矩形
context.fillStyle = "r ed";//重新将填充颜色改为红色 context.fillRect(150,20,75,50);//画出红色矩形 context.fillStyle = "blue";//将填充颜色修改为蓝色
//设置在源图像的上方显示目标图像 context.globalCompositeOperation = "destination-over"; context.fillRect(180,50,75,50);//画出蓝色矩形
</script>
</body>
效果:
值描述
source-over |
默认。在目标图像上显示源图像。 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的 |
source-atop |
O |
source-in |
在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图 像是透明的。 |
source-out |
在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图 像是透明的。 |
destination-o ver |
在源图像上方显示目标图像。 |
destination-a top |
在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。 |
destination-in |
在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图 像是透明的。 |
destination-o ut |
在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图 像是透明的。 |
lighter |
显示源图像+目标图像。 |
copy |
显示源图像。忽略目标图像。 |
xor |
使用异或操作对源图像与目标图像进行组合。 |
14-5-5颜色和样式选项
- 应用不同线条
通过下面的属性值,可以为线条应用不同的线型,分别为线条的粗细,端点样式,两线段连接处 样式和绘制交点方式
lineWidth = value
lineCap = type
lineJoin = type
miterLimit = value
line-Width = value
设置线条的粗细,默认值为1.0
具体示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid">
您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d");
let i = 1;
for(let j=0;j<=11;j++){
context.strokeStyle = "red";
i++;
context.lineWidth = i;//设置画笔的宽度为i, i每次会自增1
context.beginPath(); context.moveTo(5,i*20); context.lineTo(140,i*20); context.stroke();
context.closePath();
}
</script>
</body>
效果:
lineCap (扩展)
设置端点样式,值有3种,分别是butt, round和square,如下表:
值 |
描述 |
bu廿 |
默认。向线条的每个末端添加平直的边缘 |
round |
向线条的每个末端添加圆形线帽 |
square |
向线条的每个末端添加正方形线帽 |
具体示例: |
|
<body> <!-- |
添加canvas兀素—> |
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0]; //获取到上下文,创建context对象
let context = canvas.getContext("2d");
let lineCap = ["butt","round","square"];
//绘制参考线
context.strokeStyle = "red";
context.beginPath();
//绘制左参考线
context.moveTo(30,10);
context.lineTo(30,150);
//绘制右参考线
context.moveTo(180,10);
context.lineTo(180,150);
context.stroke();
//开始绘制3条直线
context.strokeStyle = "blue";
context.lineWidth = 20;
for(let i=0;i<lineCap.length;i++){ context.lineCap = lineCap[i]; context.beginPath(); context.moveTo(30,30+i*50); context.lineTo(180,30+i*50);
context.stroke();
}
</script>
</body>
效果:
linejoin (扩展)
设置连接处样式,有3个属性值可选,分别是round, bevel和miter,默认值为miter 具体示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid"> 您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.beginPath();
context.lineWidth = 10;
context.lineJoin = "round"; context.moveTo(20,20);
context.lineTo(100,50);
context.lineTo(20,150);
context.stroke();
</script>
</body>
效果:
miterLimit (扩展)
用于设置或返回最大斜接长度。
斜接长度指的是在两条线交汇处内角和外角之间的距离。
注意:只有当linejoin属性为"miter"时,miterLimit才有效。
边角的角度越小,斜接长度就会越大。
为了避免斜接长度过长,我们可以使用miterLimit属性。
如果斜接长度超过miterLimit的值,边角会以linejoin的"bevel"类型来显示(图解3): 图解1 图解2 图解3
- 绘制线性渐变
语法:
context.c reateLinea rGradient(x1,y1,x2,y2) :x1,y1 代表起点。x2,y2代表终点 addColorStop(position,color) :position为颜色位置,取值范围0-1, color为具体颜色 具体示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:1px solid">
您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.beginPath();
//指定渐变区域
let grad = context.createLinearGradient(0,0,0,140);
//添加几个渐变色
grad.addColorStop(0,'rgb(192,80,77)'); grad.addColorStop(0.5,'rgb(155,187,89)'); grad.addColorStop(1,'rgb(128,100,162)');
//将这个渐变设置为填充颜色
context.fillStyle = grad;
//绘制矩形
context.rect(0,0,140,140);
context.fill();
</script>
</body>
let grad = context.createLinearGradient(0,0,140,0);
倾斜的线形渐变
let grad = context.createLinearGradient(0,0,140,140);
- 绘制径向渐变
语法:context.createRadialGradient(x1,y1,门,x2,y2,r2)
x1,y1,门定义了一个以x1,y1为原点,半径为门的圆
x2,y2,r2定义了一个以x2,y2为原点,半径为r2的圆
具体示例:
<body>
<!— 添加canvas兀素 —>
<canvas width="400" height="300" style="border:
您的浏览器不支持canvas元素,请升级您的浏览器
</canvas>
<script>
//在JS中获取canvas元素
let canvas = document.getElementsByTagName('canvas')[0];
//获取到上下文,创建context对象
let context = canvas.getContext("2d"); context.beginPath();
//添加径向渐变
let radialGrad = context.createRadialGradient(200,150,0,200,150,200)
;
//为径向渐变添加颜色
radialGrad.addColorStop(0.0,"red"); radialGrad.addColorStop(0.25,"yellow"); radialGrad.addColorStop(0.5,"blue"); radialGrad.addColorStop(0.75,"green"); radialGrad.addColorStop(1.0,"pink");
//将渐变设置为填充颜色
context.fillStyle = radialGrad; context.fillRect(0,0,400,300);
</script>
</body>
效果:
- 绘制图案
语法:context.createPattern(image,type)
type的取值repeat, repeat-x, repeat-y和no-repeat
示例代码如下: