HTML5也出了一段时间,带来了一些新的技术标准,比如HTML5中的Canvas标签,,可以让我们使用Javascript来绘制2D或者3D图形在画布标签和动画中。下面说说对canvas绘图的理解,介绍一些用到的方法,以bar进度条和科幻文字为例。元素不被一些旧浏览器支持,但所有主流浏览器的最新版本都支持它,并且兼容性问题很好。使用canvas标签绘制图形或动画需要一些HTML和JavaScript的基础知识,通过canvasapi,了解canvas绘制原理即可。其实canvas上运动的原理和显示器是一样的,就是一帧一帧地绘制静态图形,而绘制刷新的速度超过了我们人眼的识别速度,所以看起来就像是真的很感动。不同的是显示的刷新是实时的,而画布的刷新需要我们通过js控件手动触发。如果我们只是绘制简单的静态图形,那么这一步不需要我们手动控制刷新。比如我们要让一个矩形从左向右移动,我们可以一开始做最左边的矩形,下一秒再向右画同样的矩形,但是前提是去掉原来的先绘制矩形,然后重新绘制它。通过不断地擦洗和重绘,就会出现运动效果,通过提高速度,就不会被人眼看到了。画布在html文档中由标签创建后是空白的。它是一个固定大小的画布,可以通过width和height来控制宽度和高度。默认大小为300像素×150像素(px)。为了显示,首先需要找到渲染上下文,然后通过js在画布上绘制。元素有一个名为getContext()的方法,用于获取渲染上下文及其绘制函数。getContext()只有一个参数,上下文的格式,对于2D图像,填写'2d'字符串。varcanvas=document.getElementByTagName('canvas')[0];varctx=canvas.getContext('2d');//清除画布context.clearRect(0,0,canvas.width,canvas.height);通过document.getElementByTagName()方法获取元素的DOM对象。通过DOM元素上的getContext()方法访问绘图上下文。看一个条形进度条例子https://codepen.io/zgfrank/pe...varcanvas=document.getElementById('canvas'),context=canvas.getContext('2d'),centerX=canvas.width/2、centerY=canvas.height/2,speed=0.1;functiontext(n){context.save();context.fillStyle="#F47C7C";context.font="40px宋体";context.textAlign="居中";context.textBaseline="中间";context.fillText(n.toFixed(0)+"%",centerX,centerY);context.restore();}functionrectfixed(){context.beginPath();context.rect(50,140,400,20);context.lineWidth=1;context.strokeStyle='白色';context.fillStyle='白色';context.fill();context.stroke();}functionrectmove(speed){context.beginPath();context.rect(50,140,速度*4,20);context.lineWidth=1;context.fillStyle='#F47C7C';context.fill();context.stroke();}(functiondrawFrame(){window.requestAnimationFrame(drawFrame,canvas);context.clearRect(0,0,canvas.width,canvas.height);文本(速度);rectfixed()rectmove(speed)if(speed>100)speed=0;速度+=0.2;}());从代码来看,第一个绘制矩形的API是context.rect(x,y,width,height),分别是x/y坐标,宽高。第一个bar是固定的,第二个bar的宽度随着速度的变化而变化。通过window.requestAnimationFrame循环调动drawFrame函数,实现动画的效果。requestAnimationFrame是一个新的API,功能和setTimeInterval一样,不同的是它会根据浏览器的刷新率自动调整动画时间间隔。也不要忘记调用画布上的clearRect方法来清除前一帧的图案以产生正确的效果。绘制文字的api是给图形上色有两个重要的属性,分别是fillStyle和strokeStyle。fillStyle是设置图形的填充颜色,strokestyle是设置图形的轮廓颜色。通过fill()和stroke()方法,有更多的样式设置可以参考MDN中的canvasAPI。第二个例子是科幻文字效果,https://codepen.io/zgfrank/pe...varcanvas=document.querySelector('#test'),ctx=canvas.getContext('2d');帆布。width=window.innerWidth,canvas.height=window.innerHeight;varshadowColor='rgba(0,0,0,0.08)',//用于覆盖文本的渐变阴影textColor="#33ff33",//文本颜色words="0123456789qwertyuiopasdfghjklzxcvbnm,./;'\[]QWERTYUIOP{}ASDFGHJHJKL:ZXCVBBNM<>?",//随机文本wordsArray=words.split(''),//将文本拆分成一个数组fontSize=18,//字体大小columns=canvas.width/fontSize,//数量文本下降的列=[];//文本行数for(vari=0;icanvas.height&&Math.random()>0.99){drops[i]=0;}滴[我]++;}ctx.restore();}(functiondrawFrame(){window.requestAnimationFrame(drawFrame,canvas);//阴影叠加文字ctx.fillStyle=shadowColor;ctx.fillRect(0,0,canvas.width,canvas.height);drawText();}())上面的代码是实现这个效果的关键:使用fillText()方法绘制随机字符,使用fillRect()方法覆盖一个黑色的矩形,具有透明性,实现了文字。绘制叠加形成阴影的效果。列数是画布宽度/字体大小。在绘图函数中,一开始是逐行绘制的,所以创建的drop数组开头是1,为了从第一行开始绘制,所以刚刷新的时候,从第一行开始绘制行到最后一行。context.fillText(text,i*fontSize,drops[i]*fontSize);fillText()有三个参数,第一个是随机绘制的文本,第二个是文本的X起始坐标,第三个是文本起始坐标的Y起点。所以第一行每段文字的X轴坐标为0,18,36...,Y轴坐标为18,18,18,...。要绘制第二行,将1加1drops数组的值,即第二行的Y轴坐标为(32,32,32...)。以此类推,全屏文字是从第一行绘制到最后一行,fillRect()覆盖的黑色透明矩形有点类似于带有渐变阴影的文字向下运动动画。为了展示重复绘制的效果,需要设置在绘制最后一行时,需要从第一行开始绘制:if(drops[i]*fontSize>canvas.height){drops[i]=0;}但是这样我们会发现每一行文字都是同时绘制的,没有区别,这样就达不到不同列的效果了。为了表现出每一行文字的不同,有些列要先从第一行开始绘制,有些列要从第一行以后再绘制。如何做到这一点?可以增加随机数,判断随机数和是否同时绘制在最后一行,同时满足的列从第一行开始绘制:if(drops[i]*fontSize>canvas.height&&Math.random()>0.99){drops[i]=0;}
认识canvas相关文章