当前位置: 首页 > 科技观察

Canvas从入门到小猪头

时间:2023-03-18 13:29:29 科技观察

通过本文,你将了解canvas的介绍和比较常用的方法,并使用canvas实现一个小猪头。一、Canvas简介1.1什么是canvasCanvas(画布)是HTML5中的一个新标签,用于在网页上实时生成图片,可以对图片内容进行操作。它是一种可以被JavaScript操作的位图(bitmap)。1.2canvas坐标系canvas坐标系如下图所示,具有以下特点:x轴正方向向右,y轴正方向向下。画布的原点在左上角。为一个像素(网格)创建一个标签1.3Canvas绘制过程获取canvas元素对应的DOM对象,它是一个Canvas对象调用Canvas对象的getContext()方法,返回一个CanvasRenderingContext2D对象,可以绘制图形调用CanvasRenderingContext2D对象绘制方法1.4Canvas的应用领域Canvas是一个神奇的东西,可以应用在很多领域,下面我们一起来聊一聊。游戏:Canvas在基于Web的图像显示方面比Flash更立体、更复杂。Canvas游戏在流畅度和跨平台方面更好。比如这25个canvas游戏可视化库:EchartbannerAdvertising:Canvas实现动态广告效果非常适合图文编辑:后续的Photoshop可以实现100%基于Web的微信阅读,腾讯文档都是通过canvas2.基本功能通过第一章,我对canvas有了初步的了解,本章按照一个人画图的思路进行进化,逐步了解canvas的基本功能,从而更好的使用它来达到一些很酷的效果。2.1坐标系的选择当你要画图的时候,首先要确定坐标系。坐标系选好后就可以开始写了。画布中默认坐标系在左上角(X轴正向右,Y轴正向下),但有时需要变换坐标系才能达到想要的效果更方便。这时候就需要对坐标系进行变换。Canvas提供了以下几种坐标系变换方式:translate(dx,dy):平移坐标系。相当于将原先位于(0,0)的坐标原点移动到(dx,dy)。rotate(angle):旋转坐标系。此方法按角度弧度顺时针旋转坐标系。scale(sx,sy):缩放坐标系。该方法控制坐标系水平缩放sx,垂直缩放sy。transform(a,b,c,d,e,f):允许对当前环境坐标系进行缩放、旋转、移动和倾斜,其中a表示水平缩放,b表示水平倾斜,c表示垂直倾斜,d表示垂直缩放,e表示水平运动,f表示垂直运动。functionmain(){constcanvas=document.getElementById('canvasId');constctx=canvas.getContext('2d');ctx.lineWidth=4;//默认ctx.save();ctx.strokeStyle='#F00';drawCoordiante(ctx);ctx.restore();//平移ctx.save();ctx.translate(150,150);ctx.strokeStyle='#0F0';drawCoordiante(ctx);ctx.restore();//旋转ctx.save();ctx.translate(300,300);ctx.rotate(-Math.PI/2);ctx.strokeStyle='#00F';drawCoordiante(ctx);ctx.restore();//缩放ctx.保存();ctx.translate(400,400);ctx.rotate(-Math.PI/2);ctx.scale(0.5,0.5);ctx.strokeStyle='#000';drawCoordiante(ctx);ctx.restore();}functiondrawCoordiante(ctx){ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(120,0);ctx.moveTo(0,0);ctx.lineTo(0,80);ctx.closePath();ctx.stroke();}main();2.2图形绘制坐标系选定后,就要开始创作大作了,那么允许在画布上绘制什么内容呢?直线函数drawLine(ctx,startX,startY,endX,endY){ctx.moveTo(startX,startY);ctx.lineTo(endX,endY);ctx.stroke();}圆弧函数drawCircle(ctx,x,y,R,startAngle,endAngle){ctx.arc(x,y,R,startAngle,endAngle);ctx.stroke();}curve//贝塞尔曲线乐趣ctiondrawBezierCurve(ctx,cpX1,cpY1,cpX,cpY2,endX,endY){ctx.bezierCurveTo(cpX1,cpY1,cpX,cpY2,endX,endY);ctx.stroke();}//二次曲线函数drawQuadraticCurve(ctx,cpX,cpY,endX,endY){ctx.quadraticCurveTo(cpX,cpY,endX,endY);ctx.stroke();}rectangle//填充矩形函数drawFillRect(ctx,x,y,width,height){ctx.fillRect(x,y,width,height);}//边框矩形函数drawStrokeRect(ctx,x,y,width,height){ctx.strokeRect(x,y,width,height);}string//填充字符串函数drawFillText(ctx,text,x,y){ctx.fillText(text,x,y);}//边框字符串函数drawStrokeText(ctx,text,x,y){ctx.strokeText(text,x,y);}复杂图形绘制-path//使用路径绘制functiondrawFigureByPath(ctx){ctx.beginPath();ctx.moveTo(100,400);ctx.lineTo(200,450);ctx.lineTo(150,480);ctx.closePath();ctx.fill();}functionmain(){constcanvas=document.getElementById('canvasId');constctx=canvas.getContext('2d');ctx.lineWidth=2;ctx.strokeStyle='#F00';ctx.fillStyle='#F00';ctx.font='normal50px宋体';drawLine(ctx,50,10,150,10);ctx.moveTo(150,100);drawCircle(ctx,100,100,50,0,Math.PI);ctx.moveTo(300,100);drawCircle(ctx,250,100,50,0,Math.PI*2);ctx.moveTo(350,150);drawBezierCurve(ctx,200,200,450,250,300,300);ctx.moveTo(50,250);drawQuadraticCurve(,50,400,80,400);drawFillRect(ctx,100,300,100,50);drawStrokeRect(ctx,300,300,100,50);drawFillText(ctx,'I',100,400);drawStrokeText(ctx,'I',300,400);drawFigurexByPath(ct;}2.3填充样式使用canvas绘制图形时,需要添加一些paint,可以通过设置fillStyle属性来设置相应的paint,paint值主要有四种:纯色、线性渐变色、径向渐变色、和位图纯色函数useColorFill(ctx){ctx.save();ctx.fillStyle='#F00';ctx.fillRect(10,10,100,100);ctx.restore();}线性渐变色函数useLinearGradientFill(ctx){ctx.save();constlg=ctx.createLinearGradient(110,10,210,10);lg.addColorStop(0.2,'#F00');lg.addColorStop(0.5,'#0F0');lg.addColorStop(0.9,'#00F');ctx.fillStyle=lg;ctx.fillRect(120,10,100,100);ctx.restore();}径向渐变颜色函数useRadialGradientFill(ctx){ctx.save();constlg=ctx.createRadialGradient(260,60,10,260,60,60);lg.addColorStop(0.2,'#F00');lg.addColorStop(0.5,'#0F0');lg.addColorStop(0.9,'#00F');ctx.fillStyle=lg;ctx.fillRect(230,10,100,100);ctx.restore();}位图填充函数useImageFill(ctx){ctx.save();constimage=newImage();image.src='https://dss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=442547030,98631113&fm=58';image.onload=function(){//创建位图填充constimgPattern=ctx.createPattern(image,'repeat');ctx.fillStyle=imgPattern;ctx.fillRect(340,10,100,100);ctx.restore();}}2.4暂存用画笔画某位美女时,突然灵感来了,需要再画一位帅哥。画美女的颜料、坐标等状态暂存,画帅哥画美女后恢复状态。可以通过canvas中的save()和restore()方法来实现。调用save()方法后,将此时的设置放到一个临时存储栈中,之后就可以放心修改上下文了。当需要绘制之前的上下文时,可以调用restore()方法。//从左到右依次绘制(中间填充新样式,最后一个填充原有样式)functionmain(){constcanvas=document.getElementById('canvasId');constctx=canvas.getContext('2d');ctx.fillStyle='#F00';ctx.fillRect(10,10,100,100);ctx.save();ctx.fillStyle='#0F0';ctx.fillRect(150,10,100,100);ctx.restore();ctx.fillRect(290,10,100,100);}2.5导入外部图像有时需要导入外部图像,然后对外部图像进行像素级别的处理,最后保存。绘制图像:drawImage获取图像数据:getIamgeData将修改后的数据重新填充到Canvas中:putImageData输出位图:toDataURLfunctionmain(){constcanvas=document.getElementById('canvasId');constctx=canvas.getContext('2d');constimage=document.getElementById('image');//绘制图像ctx.drawImage(image,0,0);//获取图像数据constimageData=ctx.getImageData(0,0,image.width,image.height);constdata=imageData.data;for(leti=0,len=data.length;i