大家好,欢迎来到IT知识分享网。
文章目录
// 创建canvas标签: <canvas id="canvas" height="400" width="400" style="box-shadow: 0 0 7px 0 #"></canvas>
②找到这张纸:
// 我们现在要使用JS获得这个canvas标签的DOM对象: <script> const canvas = document.getElementById('canvas') </script>
③决定是画二维还是三维的画:
// 通过getContext()方法来获得渲染上下文和它的绘画功能: <script> const ctx = canvas.getContext('2d') // 这里我们先聚焦于2D图形 </script>
一、线形
1、画线形之前,最基本的方法需要知道:
moveTo(x,y):路径绘制命令的起点
lineTo(x,y):路径绘制转折点
stroke():绘制路径
const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // 第一条线性 ctx.moveTo(0,0); // 路径绘制命令的起点 ctx.lineTo(350,50); // 路径绘制转折点 ctx.stroke(); // 绘制路径 // 第二条线形 ctx.moveTo(0,200); ctx.lineTo(50,200); ctx.lineTo(50,150); ctx.lineTo(100,150); ctx.lineTo(100,200); ctx.lineTo(150,200); ctx.lineTo(150,150); ctx.lineTo(200,150); ctx.stroke();
2、线形的样式设置:
strokeStyle = '颜色':设置线的颜色;
lineWidth = 数字:设置线的宽度;
lineCap = 'round/butt/square':设置线帽为圆型/默认/方形;
lineJoin = 'miter/round/bevel':设置线段连接处为默认/圆形/平直形式;
globalAlpha = 数字:设置图案的透明度
需要注意的是:这些样式设置,必须在ctx.stroke()之前给。因为ctx.stroke()是绘制图形轮廓,图形轮廓都已经画出来了,在它之后给是不生效的。
ctx.moveTo(0,200); ctx.lineTo(50,200); ctx.lineTo(50,150); ctx.lineTo(100,150); ctx.lineTo(100,200); ctx.lineTo(150,200); ctx.lineTo(150,150); ctx.lineTo(200,150); ctx.strokeStyle = 'red'; // 线形颜色 ctx.lineWidth = 6; // 线宽 ctx.globalAlpha = 0.5; // 透明度 ctx.lineCap = 'round'; // 线形末端样式圆型 ctx.lineJoin = 'round'; // 线形连接样式圆型 ctx.stroke();
3、不同的线形路径给不同的样式设置-需要知道俩个方法:
beginPath():开启一条新路径,生成之后,图形绘制命令会被指向到新路径上;
closePath():关闭路径,生成闭合路径之后,图形绘制命令又重新指向到上下文中;
// 第一条 ctx.beginPath(); // 开启一条新路径 ctx.moveTo(0,0); ctx.lineTo(350,50); ctx.lineWidth = 1; ctx.strokeStyle = 'blue'; ctx.lineCap = 'butt'; ctx.stroke(); ctx.closePath(); // 关闭路径 // 第二条 ctx.beginPath(); // 开启一条新路径 ctx.moveTo(0,200); ctx.lineTo(50,200); ctx.lineTo(50,150); ctx.lineTo(100,150); ctx.lineTo(100,200); ctx.lineTo(150,200); ctx.lineTo(150,150); ctx.lineTo(200,150); ctx.lineWidth = 5; ctx.strokeStyle = 'red'; ctx.lineCap = 'round'; ctx.stroke(); ctx.closePath(); // 关闭路径
4、画线形三角
画线形三角也是用画线的思路,需要注意首尾点连接起来即可:
ctx.beginPath(); ctx.moveTo(60,60); ctx.lineTo(150,60); ctx.lineTo(150,150); ctx.lineTo(60,60); ctx.stroke(); ctx.closePath();
// 画三角 // 闭合处显示的更衔接一点 ctx.beginPath(); ctx.beginPath(); ctx.moveTo(60,60); ctx.moveTo(60,60); ctx.lineTo(150,60); ctx.lineTo(150,60); ctx.lineTo(150,150); ctx.lineTo(150,150); ctx.lineTo(60,60); ctx.lineTo(60,60); ctx.lineWidth = 5; ctx.closePath(); ctx.strokeStyle = 'red' ctx.lineWidth = 5; ctx.stroke(); ctx.strokeStyle = 'red'; ctx.closePath(); ctx.stroke();
5、画贝塞尔曲线
ctx.beginPath(); ctx.moveTo(100,150); ctx.quadraticCurveTo(250, 10, 300, 100); // 控制点(250,10)结束点(300, 100) ctx.stroke(); ctx.closePath();
2、bezierCurveTo(cpx1,cpy1,cpx2,cpy2,x,y)来绘制三次贝塞尔曲线:
cpx1,cpy1:第一个控制点坐标
cpx2,cpy2:第二个控制点坐标
x,y:结束点坐标
// 三次贝塞尔曲线 ctx.beginPath(); ctx.moveTo(100,150); ctx.bezierCurveTo(200,10, 275,250, 380,150); //控制点1(200,10)控制点2(275,250)结束点(300,100) ctx.stroke(); ctx.closePath(); // 辅助线 ctx.beginPath(); ctx.moveTo(100, 150); ctx.lineTo(200, 10); ctx.lineTo(275, 250); ctx.lineTo(380, 150); ctx.strokeStyle = 'red'; ctx.stroke(); ctx.closePath();
6、画虚线
setLineDash([])方法来绘制虚线,可以接收若干个参数。
数组参数会“铺开”,下标为偶数的项为实线,为奇数项为透明线段,数字的大小代表着线段的长度。
getLineDash()方法可以获得当前虚线设置的样式。如下面虚线样式,得到的结果是[10,5]
ctx.beginPath(); ctx.moveTo(100, 150); ctx.lineTo(200, 10); ctx.lineTo(275, 250); ctx.lineTo(380, 150); ctx.strokeStyle = 'red'; ctx.setLineDash([10, 5]) ctx.stroke(); ctx.closePath();
二、画矩形
1、绘制空心矩形有三种方法
// 绘制三角思路绘制矩形 // strokeRect(x,y,width,height) // stroke()和rect() ctx.beginPath(); ctx1.beginPath(); ctx2.beginPath(); ctx.moveTo(50,50); ctx1.strokeRect(50,50,100,100) ctx2.rect(50,50,100,100); ctx.lineTo(150,50); ctx1.closePath(); setTimeout(() => {
ctx.lineTo(150,150); ctx2.stroke(); ctx.lineTo(150,150); }, 2000); ctx.lineTo(50,150); ctx2.closePath(); ctx.lineTo(50,50); ctx.stroke(); ctx.stroke(); ctx.closePath();
rect()暂时生成了矩形,但必须调用stroke()方法才会绘制出来
三种方式绘制效果如图:
2、绘制填充矩形有俩种方法:
// fillRect()和fillStyle()填充矩形 // rect()和fill()填充矩形 ctx.beginPath(); ctx1.beginPath(); ctx.fillStyle = 'skyblue'; ctx1.rect(50, 50, 100, 100); ctx.fillRect(50, 50, 100, 100); setTimeout(() => {
ctx.closePath(); ctx1.fill(); }, 2000); ctx1.closePath();
fillStyle()填充颜色一定要写在生成矩形fillRect()之前,否则颜色不生效
fill()方法和stroke()方法都是用来绘制出来形状,只不过前者是填充绘制,后者是用线轮廓。
两种方式绘制效果如图:
三、画圆弧⌒⚪
1、画圆弧一般有两种方式
// 1、arc()绘制圆 ctx.beginPath(); ctx.arc(100, 100, 50, 0, [(Math.PI) / 180] * 360); // (Math.PI) / 180 = 1° ctx.stroke(); // 如果此处改为使用fill()方法,那么将会绘制出填充的圆 ctx.closePath(); // 2、arc()绘制圆弧 ctx1.beginPath(); ctx1.arc(100, 100, 50, 0, [(Math.PI) / 180] * 90); // (Math.PI) / 180 = 1° ctx1.stroke(); ctx1.closePath(); // 3、arcTo()绘制圆弧 ctx2.beginPath(); ctx2.moveTo(100, 100); // 定义线段的起点 ctx2.arcTo(150, 50, 200, 200, 45); // 切线交点坐标为(150,50),结束点为(200,200) ctx2.lineWidth = 1; ctx2.stroke(); ctx2.closePath(); // 辅助线 ctx2.beginPath(); ctx2.moveTo(100, 100); ctx2.lineTo(150, 50); ctx2.lineTo(200, 200); ctx2.strokeStyle = 'red'; ctx2.stroke(); ctx2.closePath();
注意事项:
- arcTo()方法是用“开始点”、“控制点”和“结束点”三点所形成夹角,绘制与夹角的两边相切且半径为radius的圆弧。控制点:夹角俩边相交点。
- 弧线的起点是“开始点所在边与圆的切点”,而弧线的终点是“结束点所在边与圆的切点”。
- arcTo()方法绘制的弧线是两个切点之间长度最短的那个圆弧。
- 如果开始点不是弧线起点,arcTo()方法还将添加一条当前端点到弧线起点的直线线段。也就是说,开始点坐标不一定是弧线起点坐标。通俗点讲就是:开始点到弧线起点会有一段直线线段。
2、画椭圆
// 椭圆 ctx.beginPath(); // 旋转角度[(Math.PI)/180]*60 起点[(Math.PI)/180]*0 终点[(Math.PI)/180]*360 ctx.ellipse(100,100,50,100, [(Math.PI)/180]*60, [(Math.PI)/180]*0, [(Math.PI)/180]*360); ctx.stroke(); ctx.closePath(); // 给椭圆填充色stroke()换成fill() // ctx.fillStyle = 'skyblue' // ctx.fill()
四、绘制文本
1、strokeText(), fillStroke()绘制文本
使用strokeText(text,x,y,maxWidth)方法绘制描边文本。
使用fillStroke(text,x,y,maxWidth)方法绘制填充文本。
text:需要绘制的文本
x,y:文本左下角起始坐标
maxWidth:文本最大宽度
// 绘制描边文本 // 绘制填充文本 ctx.beginPath(); ctx1.beginPath(); ctx.font = '50px Verdana'; ctx1.font = '50px Verdana'; ctx.strokeText('Hello Canvas!', 30, 180, 400); ctx1.fillText('Hello Canvas!', 30, 180, 400); ctx.closePath(); ctx1.closePath(); ctx.beginPath(); ctx.font = '20px Verdana'; ctx.strokeText('Helvas!', 30, 280, 400); ctx.closePath();
2、文本样式
.font设置文本大小和字体。
.textAlign设置水平对齐方式,值可选left/right/center/start/end。对齐方式以strokeText()方法中坐标参数为参考。
// 绘制水平居中描边文本 ctx.beginPath(); ctx.font = '50px Verdana'; ctx.textAlign = 'center'; ctx.strokeText('Hello Canvas!', 200, 200, 400); ctx.closePath(); // 辅助线 ctx.beginPath(); ctx.moveTo(200,0); ctx.lineTo(200, 400); ctx.setLineDash([10, 5]) ctx.stroke(); ctx.closePath(); ctx.beginPath(); ctx.moveTo(0,200); ctx.lineTo(400, 200); ctx.setLineDash([10, 5]) ctx.stroke(); ctx.closePath();
// 水平左对齐,垂直上对齐 ctx.beginPath(); ctx.font = '20px Verdana'; ctx.textAlign = 'left'; ctx.textBaseline = 'top'; ctx.strokeText('Hello!', 0, 200, 400); ctx.closePath(); // 水平居中,垂直居中 ctx.beginPath(); ctx.font = '20px Verdana'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.strokeText('Hello Canvas!', 200, 200, 400); ctx.closePath(); // 水平右对齐,垂直下对齐 + 文本绘制方向rtl`(right to left) ctx.beginPath(); ctx.font = '20px Verdana'; ctx.textAlign = 'right'; ctx.textBaseline = 'bottom'; ctx.direction = 'rtl'; ctx.strokeText('Canvas!', 400, 200, 400); ctx.closePath();
measureText(text)方法测量文本的宽度。
text:测量的文本
注意:不是必须显示出文本来才能计算文本的长度,测量结果也不受文本的最大宽度等外界因素的影响,文本长度的测量结果只和文本的font参数相关。
五、样式补充
1、线性渐变色
使用createLinearGradient(x1,y1,x2,y2)来创建线性渐变色。
x1,y1:渐变色起点坐标
x2,y2:终点坐标
使用addColorStop(offset,color)添加渐变色。
offset:偏移值
color:渐变色
// 横向线性渐变色 ctx.beginPath(); const gradient = ctx.createLinearGradient(0,0,400,0); gradient.addColorStop(0, 'skyblue'); gradient.addColorStop(1, '#fffc96'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 400, 400) ctx.closePath();
线形渐变步骤就是:先是使用createLinearGradient创建一个线性渐变对象;然后使用addColorStop添加颜色;然后使用fillStyle设置填充颜色(就是线形渐变对象);最后使用fillRect填充。
2、径向渐变
使用createRadialGradient(x1,y1,r1,x2,y2,r2)方法来创建渐径向渐变色。
x1,y1:开始圆的圆心坐标
r1:开始圆的半径
x2,y2:结束圆的圆心坐标
r2:结束圆的半径
// 径向渐变 ctx.beginPath(); const gradient = ctx.createRadialGradient(200,200, 100, 200, 200, 200); gradient.addColorStop(0, 'skyblue'); gradient.addColorStop(1, '#fffc96'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 400, 400); ctx.closePath();
径向渐变步骤就是:同线形渐变是一样的。先是使用createRadialGradient创建一个径向渐变对象;然后使用addColorStop添加颜色;然后使用fillStyle设置填充颜色(就是径向渐变对象);最后使用fillRect填充。
3、阴影样式
shadowOffsetX = 数字:设置阴影在X轴上的延申距离,正值表示阴影向x轴正方向延申,负值表示阴影向x轴负方向延申。
shadowOffsetY = 数字:设置阴影在Y轴上的延申距离,正值表示阴影向y轴正方向延申,负值表示阴影向y轴负方向延申。
shadowBlur = 数字:设定阴影的模糊度,默认为0。
shadowColor = '颜色':设置阴影的颜色,默认是全透明色。
// 绘制带阴影的线段: ctx.moveTo(50, 50) ctx.lineTo(100, 50) ctx.shadowOffsetX = 10 // 向x轴正方向平移10像素 ctx.shadowOffsetY = 10 // 向y轴正方向平移10像素 ctx.shadowColor = '#ccc' // 设置阴影颜色 ctx.shadowBlur = 3 // 设置阴影模糊度 ctx.lineWidth = 6 ctx.stroke() // 绘制带阴影的文本: ctx.lineWidth = 1 ctx.font = '30px Verdana' ctx.textAlign = 'center' ctx.textBaseline = 'middle' ctx.strokeText('Hello Canvas!', 200, 200, 400)
4、添加指定元素
使用createPattern(pattern,type)方法添加指定元素。
pattern:要添加的元素,可以是图片,视频,canvas对象
type:绘制类型,可选repeat/no-repeat/repeat-x(沿x轴平铺)/repeat-y(沿y轴平铺)
// 添加图片 const img = new Image(); img.src = "https://phper-.cos.ap-guangzhou.myqcloud.com/logoCopy.png"; img.onload = function () {
const ptrn = ctx.createPattern(img, 'repeat'); ctx.fillStyle = ptrn; ctx.fillRect(0, 0, 400, 400); };
六、绘制图片
1、使用drawImage()方法绘制图片
drawImage(img,x,y,width,height,sx,sy,swidth,sheight)可以接收3-9个参数进行拉伸、裁剪等。
img:需要绘制的图片(必填参数)
x,y:绘制的坐标(必填参数)
width,height:图片拉伸宽度、高度
sx,sy:开始裁切的位置
swidth,sheight:要裁切图像的宽高
// 1、绘制基础图片 var img = new Image(); img.src = 'https://phperzlz-.cos.ap-guangzhou.myqcloud.com/apply/logo2.png'; img.onload = function () {
ctx.drawImage(img, 0, 0); // 在(0,0)处绘制原图 }; // 2、绘制拉伸图片 var img = new Image(); img.src = 'https://phperzlz-.cos.ap-guangzhou.myqcloud.com/apply/logo2.png'; img.onload = function () {
ctx.drawImage(img, 0, 0, 400, 400); // 在(0,0)处绘制原图,拉伸至(400, 400)的图片 }; ///3、绘制裁切拉伸图片 var img = new Image(); img.src = 'https://phperzlz-.cos.ap-guangzhou.myqcloud.com/apply/logo2.png'; img.onload = function () {
// 在(50,50)处裁切,裁切成(100,100)的图片;在(0,0)处绘制原图,拉伸至(400, 400)的图片 ctx.drawImage(img, 50, 50, 200, 200,0, 0, 400, 400); }; // 4、通过拿到image的DOM元素,来绘制图片 const img = document.getElementById('img'); img.onload = function () {
ctx.drawImage(img,0, 0); // 在(0,0)处绘制原图 };
2、绘制图片的合成、保存和还原绘画状态、变形、裁剪
合成:在绘制多个图案的时候,就需要考虑先后显示问题。通过globalCompositeOperation来控制谁覆盖谁,值可选:
source-over:在已有图像之上绘制新图像(默认值)
source-in:只会展示新图像与已有图像重叠的部分
source-out:在已有图像之外显示新图像,只有已有图像之外的新图像部分显示,已有图像是透明的
source-atop:在已有图像顶部显示新绘制的图像。已有图像位于新绘制图像之外的部分是不可见的
destination-over:与source-over相反,在已有图像之后绘制新图像
destination-in:与source-in相反,显示的是最开始的已有图像
destination-out:在新绘制图像之外显示已有图像。只有新图像之外的已有图像部分显示,新绘制图像是透明的
destination-atop:在新绘制图像顶部显示已有图像。已有图像位于新绘制图像之外的部分是不可见的
lighter:折叠图像的颜色是有颜色值相加得来的
xor:两个图像重叠部分变为透明的
// 1、source-over ctx.arc(350, 200, 200, 0, [(Math.PI) / 180] * 360) ctx.fillStyle = 'skyblue' ctx.globalCompositeOperation = 'source-over' ctx.fill() ctx.beginPath() ctx.arc(200, 400, 200, 0, [(Math.PI) / 180] * 360) ctx.fillStyle = '#fffc96' ctx.globalCompositeOperation = 'source-over' ctx.fill() ctx.closePath(); // 2、xor ctx.arc(350, 200, 200, 0, [(Math.PI) / 180] * 360) ctx.fillStyle = 'skyblue' ctx.globalCompositeOperation = 'source-over' ctx.fill() ctx.beginPath() ctx.arc(200, 400, 200, 0, [(Math.PI) / 180] * 360) ctx.fillStyle = '#fffc96' ctx.globalCompositeOperation = 'xor' ctx.fill()
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/110675.html










