ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] #### 什么是canvas: • <canvas> 标签定义图形,比如图表和其他图像。 • <canvas> 标签只是图形容器,您必须使用脚本来绘制图形。 • canvas 其实对于HTML来说很简单,只是一个标签元素而已,自己并没有行为,但 却把一个绘图 API 展现给客户端 JavaScript 以使脚本能够把想绘制的东西都绘制 到一块画布上,拥有绘制路径,矩形,圆,字符以及图像等功能。 所有的标签只是 图形的容器,必须使用JavaScript的 API 操作绘图。 标签: <canvas id=“canvas” width=“500” height=“500”></canvas> getContext • 返回一个用于在画布上绘图的环境 <script type="text/javascript"> var c = document.getElementById("canvas"); var obj = c.getContext('2d'); </script> #### canvas方法或属性 #### 矩形 • context.fillRect(x,y,width,height) 绘制“被填充”的矩形 • context.strokeRect(x,y,width,height) 绘制矩形(无填充) • context.clearRect(x,y,width,height) 在给定的矩形内清除指定的像素 #### 颜色、样式 • context.fillStyle=‘#f00f00’ 设置或返回填充绘画的颜色、渐变或模式 • context.strokeStyle=‘green’ 设置或返回笔触的颜色、渐变或模式 • context.lineWidth=10 设置或返回当前的线条宽度 • context.lineJoin=“边界类型” bevel:斜角,round:圆角,miter:尖角 eg: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; } </style> </head> <body> <!--canvas标签相当于是一个画板--> <!--canvas画板的宽高不要用css去定义--> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); //设置填充颜色 cv.fillStyle = 'yellow'; //绘制一个实心矩形 cv.fillRect(100,100,500,300); //设置描边线条颜色 cv.strokeStyle = 'pink'; //设置线条粗细 cv.lineWidth = 5; //绘制一个空心矩形 cv.strokeRect(300,200,400,260); //清理会话区域 cv.clearRect(220,170,200,160); </script> </body> </html> #### 路径 • beginPath() 开始一条路径,或重置当前路径 • closePath() 创建从当前点回到起始点的路径(闭合路径) • moveTo(x,y) 把路径移动到画布中的指定点,不创建线条 • lineTo(x,y) 添加一个新点,创建从该点到最后指定点的线条 • fill() 填充当前绘图(填充路径) • stroke() 绘制已定义的路径(连线路径) eg: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; } </style> </head> <body> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); //开启路径 cv.beginPath(); //指定路径起点 cv.moveTo(30,30); //指定终点 cv.lineTo(160,300); cv.lineTo(290,30); cv.lineTo(420,300); cv.lineTo(550,30); cv.strokeStyle = 'yellow'; cv.lineWidth = 5; //绘制路径 cv.stroke(); </script> </body> </html> eg: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; } </style> </head> <body> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); //开启路径 cv.beginPath(); //指定路径起点 cv.moveTo(30,30); //指定终点 cv.lineTo(160,300); cv.lineTo(290,30); //关闭路径,会将最后一个点和第一个点用直线连接,从而形成一个封闭的空间 cv.closePath(); //边界类型 cv.lineJoin = 'round'; cv.strokeStyle = 'yellow'; cv.lineWidth = 5; //绘制路径 cv.stroke(); cv.fillStyle = 'deepskyblue'; //填充 //cv.fill(); </script> </body> </html> 画板实例: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; position: relative; } #color{ margin-left: 200px; } </style> </head> <body> <input type="color" id="color" /> <input type="range" id="range" min="1" max="20" value="3" /> <span id="r">3</span> <input type="button" id="e" value="橡皮擦" /> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var color = document.getElementById("color"); var range = document.getElementById("range"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); cv.strokeStyle = 'yellow'; cv.lineWidth = 3; canvas.onmousedown = function(e){ var ev = window.event || e; //获得鼠标位置 var mousex = ev.layerX || ev.offsetX; var mousey = ev.layerY || ev.offsetY; //开启路径 cv.beginPath(); //设置起点 cv.moveTo(mousex,mousey); //加鼠标移动事件 canvas.onmousemove = function(e){ var ev = window.event || e; var newx = ev.layerX || ev.offsetX; var newy = ev.layerY || ev.offsetY; cv.lineTo(newx,newy); cv.stroke(); } } //鼠标抬起事件 canvas.onmouseup = function(){ //结束路径 cv.closePath(); //取消鼠标移动事件 canvas.onmousemove = null; } color.onchange = function(){ //将用户选择的颜色设置给画板 cv.strokeStyle = this.value; } range.onchange = function(){ //将用户拖动的值设置给线条粗细 cv.lineWidth = this.value; document.getElementById("r").innerHTML = this.value; } //橡皮擦 document.getElementById("e").onclick = function(){ alert('开始尽情擦黑板吧!'); cv.strokeStyle = '#272822'; } </script> </body> </html> #### 画布控制 • context.scale(scalewidth,scaleheight) 缩放处理 1=100% • context.translate(x,y) 图形位置处理 (平移) • context.rotate(angle) 旋转画布,单位:弧度,默认以画布为圆心旋转 eg: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; position: relative; } </style> </head> <body> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); //缩放 //cv.scale(1.5,0.5); //平移 //cv.translate(-100,200); //旋转(单位是弧度) //360角度 对应 2π弧度 cv.rotate(30*Math.PI/180); cv.strokeStyle = 'yellow'; cv.lineWidth = 5; cv.beginPath(); cv.moveTo(40,40); cv.lineTo(200,300); cv.lineTo(360,40); cv.closePath(); cv.stroke(); </script> </body> </html> #### 画圆弧 画圆弧 • context.arc(x,y,r,sAngle,eAngle,counterclockwise) 创建弧/曲线(用于创建圆形或部分圆) 参数说明: x 圆的中心的 x 坐标。 y 圆的中心的 y 坐标。 r 圆的半径。 sAngle 起始角,以弧度计。(弧的圆形的三点钟位置是 0度)。 eAngle 结束角,以弧度计。 counterclockwise 可选。False = 顺时针,true = 逆时针。 弧度计算公式: 角度*Math.PI/180 eg: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; position: relative; } </style> </head> <body> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); cv.lineWidth = 5; cv.strokeStyle = 'yellow'; //cv.arc(300,200,150,0,90*Math.PI/180); //cv.arc(300,200,150,0,180*Math.PI/180); cv.arc(300,200,150,0,360*Math.PI/180); cv.stroke(); cv.fillStyle = 'greenyellow'; cv.fill(); </script> </body> </html> eg: 饼状图 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; position: relative; } </style> </head> <body> <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); cv.lineWidth = 5; cv.strokeStyle = 'yellow'; cv.beginPath(); cv.moveTo(300,200); cv.arc(300,200,150,0,60*Math.PI/180); cv.closePath(); cv.fillStyle = 'pink'; cv.fill(); cv.beginPath(); cv.moveTo(300,200); cv.arc(300,200,150,60*Math.PI/180,110*Math.PI/180); cv.closePath(); cv.fillStyle = 'greenyellow'; cv.fill(); cv.beginPath(); cv.moveTo(300,200); cv.arc(300,200,150,110*Math.PI/180,220*Math.PI/180); cv.closePath(); cv.fillStyle = 'yellow'; cv.fill(); cv.beginPath(); cv.moveTo(300,200); cv.arc(300,200,150,220*Math.PI/180,300*Math.PI/180); cv.closePath(); cv.fillStyle = 'deepskyblue'; cv.fill(); cv.beginPath(); cv.moveTo(300,200); cv.arc(300,200,150,300*Math.PI/180,360*Math.PI/180); cv.closePath(); cv.fillStyle = 'orangered'; cv.fill(); </script> </body> </html> #### 绘制线: <canvas id="canvas" width="300" height="300"></canvas> <script type="text/javascript"> c = document.getElementById("canvas"); obj = c.getContext('2d'); obj.lineWidth = 10; //线颜色 obj.strokeStyle = "red"; //开始绘制路径 obj.beginPath(); //光标移动到0,0 obj.moveTo(0, 0); //绘制到300,300 obj.lineTo(300, 300); //绘制定义好的路径 obj.stroke(); </script> #### 绘制矩形 <canvas id="canvas" width="300" height="300"></canvas> <script type="text/javascript"> c = document.getElementById("canvas"); //获得绘图对象 obj = c.getContext('2d'); //线宽 obj.lineWidth=2; //颜色 obj.strokeStyle='green'; //绘制开始 obj.beginPath(); //绘制矩形 //参数:x,y,width,height obj.strokeRect(50,50,100,100); //填充颜色 obj.fillStyle="red"; //实心矩形 obj.fillRect(220,220,100,100); </script> #### 文本控制: 设置字体属性 • context.font="40px Arial” 设置对齐方式 • context.textAlign=“left | right | center” 在画布上绘制“被填充的”文本 • context.fillText(text,x,y,maxWidth); 在画布上绘制文本(无填充) • context.strokeText(text,x,y,maxWidth) 设置文字基线 • context.textBaseline=“top | middle | bottom”; 获取文本宽度 • context.measureText(text); eg: <canvas id="canvas" width="800" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); cv.fillStyle = 'yellow'; cv.textAlign = 'center'; cv.textBaseline = 'bottom'; //设置文字大小和字体 cv.font = '50px 黑体'; cv.fillText('后盾人 人人做后盾',300,150,600); cv.lineWidth = 1 cv.strokeStyle = 'white'; cv.moveTo(0,150); cv.lineTo(800,150); cv.stroke(); cv.moveTo(300,0); cv.lineTo(300,500); cv.stroke(); console.log('宽度',cv.measureText('后盾人').width); </script> #### 验证码 eg: <canvas id="canvas" width="200" height="50"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); cv.fillStyle = 'yellow'; cv.font = '30px arial'; var words = 'QWERTYUIOPASDFGHJKLZXCVBNM'; for (var i=0;i<4;i++) { var num = Math.floor(Math.random()*(words.length-1+1-0)+0); //随机位置 var l = Math.floor(Math.random()*((i*50+20)+1-i*50)+i*50); var t = Math.floor(Math.random()*(45+1-30)+30); var r = Math.floor(Math.random()*256); var g = Math.floor(Math.random()*256); var b = Math.floor(Math.random()*256); cv.fillStyle = 'rgb('+r+','+g+','+b+')'; //随机角度 var d = Math.floor(Math.random()*(5+1+5)-5); cv.rotate(d*Math.PI/180); cv.fillText(words[num],l,t); } for (var i=0;i<10;i++) { var startx = Math.floor(Math.random()*201); var starty = Math.floor(Math.random()*51); var endx = Math.floor(Math.random()*201); var endy = Math.floor(Math.random()*51); cv.beginPath(); cv.moveTo(startx,starty); cv.lineTo(endx,endy); cv.closePath(); var r = Math.floor(Math.random()*256); var g = Math.floor(Math.random()*256); var b = Math.floor(Math.random()*256); var o = Math.floor(Math.random()*101); cv.strokeStyle = 'rgba('+r+','+g+','+b+','+o/100+')'; cv.stroke(); } </script> #### 图像控制 向画布上绘制图像、画布或视频 语法 1: 在画布上定位图像: context.drawImage(img,画布x坐标,画面y坐标); 语法 2: 在画布上定位图像,并规定图像的宽度和高度 context.drawImage(img,画布x坐标,画面y坐标,图片width,图片height); 语法 3: 剪切图像,并在画布上定位被剪切的部分 context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); 参数: img 规定要使用的图像、画布或视频。 sx 可选。开始剪切的 x 坐标位置。 sy 可选。开始剪切的 y 坐标位置。 swidth可选。被剪切图像的宽度。 sheight可选。被剪切图像的高度。 x 可选。在画布上放置图像的 x 坐标位置。 y 可选。在画布上放置图像的 y 坐标位置。 width 可选。要使用的图像的宽度。(伸展或缩小图像) height可选。要使用的图像的高度。(伸展或缩小图像) 注意:参数数量不同,x、y的函数不同 eg: <canvas id="canvas" width="800" height="500"></canvas> <img src="qiutian.jpg" id="dog" hidden/> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var dog = document.getElementById("dog"); //也可以手动创建图像资源 //var newimg = document.createElement('img'); //newimg.src = 'qiutian.jpg'; //获得绘画环境(相当于铺了一层画布) var cv = canvas.getContext('2d'); //等图片加载完再去绘制图像 dog.onload = function(){ //绘制图像 //cv.drawImage(dog,20,20); //cv.drawImage(dog,20,20,200,50); cv.drawImage(dog,150,50,200,150,30,30,400,250); } </script> #### 自定义填充 context.createPattern(image,"repeat|repeat-x|repeat-y|no-repeat"); 参数值 参数 描述 image 规定要使用的图片、画布或视频元素。 repeat 默认。该模式在水平和垂直方向重复。 repeat-x 该模式只在水平方向重复。 repeat-y 该模式只在垂直方向重复。 no-repeat 该模式只显示一次(不重复)。 <!DOCTYPE html> <html> <body> <p>要用到的图片:</p> <img src="/i/lamp.gif" id="lamp" /> <p>Canvas:</p> <button onclick="draw('repeat')">Repeat</button> <button onclick="draw('repeat-x')">Repeat-x</button> <button onclick="draw('repeat-y')">Repeat-y</button> <button onclick="draw('no-repeat')">No-repeat</button> <canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"> Your browser does not support the HTML5 canvas tag.</canvas> <script type="text/javascript"> function draw(direction) { var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.clearRect(0,0,c.width,c.height); var img=document.getElementById("lamp") var pat=ctx.createPattern(img,direction); ctx.rect(0,0,150,100); ctx.fillStyle=pat; ctx.fill(); } </script> </body> </html> #### getImageData() 和 putImageData() 下面的代码通过 getImageData() 复制画布上指定矩形的像素数据,然后通过 putImageData() 将图像数据放回画布: 定义和用法 putImageData() 方法将图像数据(从指定的 ImageData 对象)放回画布上。 JavaScript 语法: context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight); 参数值 参数 描述 imgData 规定要放回画布的 ImageData 对象。 x ImageData 对象左上角的 x 坐标,以像素计。 y ImageData 对象左上角的 y 坐标,以像素计。 dirtyX 可选。水平值(x),以像素计,在画布上放置图像的位置。 dirtyY 可选。水平值(y),以像素计,在画布上放置图像的位置。 dirtyWidth 可选。在画布上绘制图像所使用的宽度。 dirtyHeight 可选。在画布上绘制图像所使用的高度。 eg: <!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"> Your browser does not support the HTML5 canvas tag. </canvas> <script> var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.fillStyle="green"; ctx.fillRect(10,10,50,50); function copy() { var imgData=ctx.getImageData(10,10,50,50); ctx.putImageData(imgData,10,70); } </script> <button onclick="copy()">复制</button> </body> </html> #### 图像反色处理 eg: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> canvas{ background: #272822; margin: 0 auto; display: block; position: relative; } </style> </head> <body> <canvas id="canvas" width="1200" height="500"></canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"); var cv = canvas.getContext('2d'); var dog = document.createElement('img'); dog.src = 'qiutian.jpg'; dog.onload = function(){ cv.drawImage(dog,20,20); //获得画布图像信息 var alldata = cv.getImageData(20,20,500,333); //data属性中存储的就是所有像素点的信息 console.log(alldata.data); //[2,3,4,255,2,3,4,255,2,3,4,255] for (var i=0;i<alldata.data.length;i++) { if (i%4!=3) { alldata.data[i] = 255-alldata.data[i]; } } //写入画布信息 cv.putImageData(alldata,600,20); } </script> </body> </html>