Canvas入门
2016-06-28 11:46
405 查看
Canvas是HTML5的新功能,没机会用过,趁有空来学习了解一下。
抽空做了个小练习:使用纯CSS和Canvas画哆啦A梦
首先是在HTML中使用标签:
然后使用JavaScript来在canvas上边进行绘制:
centerx,centery,radius, //圆心x,y坐标,半径
startingAngle,endingAngle, //开始角度,结束角度。开始角度0位于直角坐标系x轴右边。
anticlockwise = false //可选参数:是否逆时针绘制。默认false,以顺势针方向绘制
)
这里要额外注意:anticlockwise参数可以改变绘制的方向,但是下图中的pi定义是不变的
也就是说,
而
例如:
注意:beginPath()和closePath()不一定要成对使用。beginPath()单纯的表示开始规划一段新的路径;closePath()表示结束当前路径,若当前路径没闭合则自动闭合。
另外:context.fill()方法对于没有闭合的图形,会自动将其首位相连,再填充。所以即使画的时候没有使用closePath()来闭合图形,也是可以填充的。
context.fillRect(x,y,width,height);左上角坐标x,y,矩形宽高。直接绘制一个当前填充状态的矩形
context.strokeRect(x,y,width,height);左上角坐标x,y,矩形宽高。直接绘制一个当前状态的描边矩形
注意:canvas的颜色能够使用所有css识别的颜色方式。可以使用rgba(0,256,0,0.5)这种方式来设置透明度。
lineCup = butt(default) | round | square 线条两端的形状 = 无 | 突出圆形 | 突出方形 。
注意:只在线条开始 结尾处起效。连接处无效。
lineJoin = miter(default) | bevel | round 两条线相接时的状态 = 无 | 平凸 | 圆角
当lineJoin = miter的时候,下边这个属性miterLimit才有效
miterLimit = 10; 默认值是10。当使用miter的时候,所产生的内角和外角之间的距离。当大于10px,会自动换成bevel方式显示。一般只有需要显示非常尖锐的角的时候才需要修改这个值。
图形变换的方式:
位移: translate(x,y) 远点移动到x,y的位置
旋转: rotate(deg) 旋转deg的读书
缩放: scale(sx,sy) 在横向进行sx倍缩放,在纵向进行sy倍缩放。
注意:这里的图形变换,变换的是坐标原点。所以会相互叠加的。比如translate两次,第二次就会在第一次结果的基础上进行变换。为了避免这种问题,就要使用context.save()和context.restore();
例如:
注意:context.save()和context.restore();必须成对出现,context.save()表示保存目前的状态。context.restore()表示回到保存的状态。
关于scale()的特殊性:
scale()是有一定的副作用的:当你使用scale缩放的时候,不仅会放大图像本身,对于图像携带的数值属性,也会按照相应的倍数进行放大,比如线宽,原点坐标等。解决方式:对于外边框,放弃设置。对于原点坐标,使用translate,配合save和restore。而不要直接使用(100,100)之类的会被放大的坐标。
更高级的变换方式就涉及变换矩阵了。这里先不做展开。
例如:
使用方法跟线性渐变一样。
context.arc(
centerx,centery,radius, //圆心x,y坐标,半径
startingAngle,endingAngle, //开始角度,结束角度。开始角度0位于直角坐标系x轴右边。
anticlockwise = false //可选参数:是否逆时针绘制。默认false,以顺势针方向绘制
)
另外还有srcTo
context.arcTo(
x1,y1,x2,y2, //如下图,0点是目前所在的点。1点和2点坐标作为参数传入。1位控制点,2为结束点
radius); //半径
看图可知,0,1,2三个点构成了两条辅助线,从而确定生成的圆弧。圆弧切于这两条辅助线(或他们的延长线),而不一定切于0,2这两个点。
例子:使用它来绘制月亮的内弧
贝塞尔曲线可以直接设置0,1,2三个点,并且保证0,2就是弧线的起始,结束点,所以很多情况下很好用。这种情况下曲线并非标准圆弧,而是由控制点的坐标来决定的。
使用方法:
详情可以看这里的互动查看工具
贝塞尔三次曲线
使用方法:
详情可以看这里的互动查看工具
上边的代码中,font的默认值是”20px sans-serif”,但是实际上最多可以设置5个值:
文本对齐
文本的度量
绘制阴影不用单独调用绘制函数,只需要设定上边这些状态,绘制的时候就会有。
透明度&遮盖
剪辑区域
可以制作探照灯效果
非零环绕原则
清空
canvasplus
Artisan JS
Rgraph
抽空做了个小练习:使用纯CSS和Canvas画哆啦A梦
首先是在HTML中使用标签:
<canvas id="mycanvas" width="800" height="800" style="其他style"> 你的浏览器不支持canvas,请更换或升级浏览器。 </canvas>
然后使用JavaScript来在canvas上边进行绘制:
<script> window.onload = function(){ //初始化canvas var canvas = document.getElementById("mycanvas"); //也可以在这里设置canvas的宽高 canvas.width = 800; canvas.height = 800; //指定绘制2d图形 var context = canvas.getContext("2d"); //开始绘制一段直线 //开始一段路径(第一个beginPath()可以省略,但是为了代码一致性还是留着) context.beginPath(); //画笔移动到100 100 (跟在beginPath()后边的这个moveTo()用lineTO()其实也一样,因为beginPath()会将坐标清空,lineTo()表示从上一个坐标划线过来,因为清空了,所以也只是选定那个点。) context.moveTo(100,100); //画到700 700 context.lineTo(700,700); //context.colsePath();可以没有 //设置线条宽度5px 线条颜色为red context.lineWidth = 5; context.strokeStyle = "red"; //绘制一个闭合三角形:绘制闭合图形的时候,最好将他放在beginPath和closePath之间,而不是直接lineTO闭合。因为当lineWidth比较宽的时候,lineTo闭合之后会有小瑕疵(缺口). //开始一段新的路径 context.beginPath(); context.moveTo(100,100); context.lineTo(700,700); context.lineTo(100,700); //下边这句可以删了,closePath()会自动闭合。 //context.lineTo(100,100); //路径结束,自动闭合 context.closePath(); context.strokeStyle = "red"; //设置填充颜色为red context.fillStyle = "red"; //填充 context.fill(); //调用stroke方法进行绘制: context.strock(); //这里要注意: //1.当调用strock()的时候,他会绘制所有的状态,例如上边的一条直线和一个三角形。 //2.如果这两个图形有不同的设置,例如strokeStyle的颜色不通,那么就要注意使用beginPath()表示下边的三角形是一个新的路径,这样他的strokeStyle才不会覆盖上边的直线。 } </script>
绘制弧线和圆
context.arc(centerx,centery,radius, //圆心x,y坐标,半径
startingAngle,endingAngle, //开始角度,结束角度。开始角度0位于直角坐标系x轴右边。
anticlockwise = false //可选参数:是否逆时针绘制。默认false,以顺势针方向绘制
)
这里要额外注意:anticlockwise参数可以改变绘制的方向,但是下图中的pi定义是不变的
也就是说,
context.arc(300,300,200,0,1.5*Math.PI)的绘制结果是第二三四象限的3/4个圆;
而
context.arc(300,300,200,0,1.5*Math.PI,true)绘制的结果将会是只有第一象限的的1/4个圆。
例如:
<script> window.onload = function(){ var canvas = document.getElementById("mycanvas"); canvas.width = 800; canvas.height = 800; var context = canvas.getContext("2d"); //画一段弧线 context.lineWidth = 5; context.strokeStyle = "red"; context.arc(300,300,200,0,1.5*Math.PI) context.stroke(); //画半圆。 context.lineWidth = 5; context.strokeStyle = "red"; //当使用了beginPath()和closePath()之后,如果画完未闭合,则自动闭合。 context.beginPath(); context.arc(300,300,200,0,1.5*Math.PI); context.closePath(); //先填充颜色,再使用stroke描边,否则会填充颜色会盖住1/2的边,导致lineWidth变细为1/2 context.fillStyle = "red"; context.fill(); context.stroke(); //好的习惯是先设定坐标(moveTo,lineTo);然后设定所有属性(线宽,线色,填充色);最后调用绘画动作(填充,描边) } </script>
注意:beginPath()和closePath()不一定要成对使用。beginPath()单纯的表示开始规划一段新的路径;closePath()表示结束当前路径,若当前路径没闭合则自动闭合。
另外:context.fill()方法对于没有闭合的图形,会自动将其首位相连,再填充。所以即使画的时候没有使用closePath()来闭合图形,也是可以填充的。
绘制矩形
context.rect(x,y,width,height);设置左上角坐标x,y,矩形宽高。规划一个矩形路径context.fillRect(x,y,width,height);左上角坐标x,y,矩形宽高。直接绘制一个当前填充状态的矩形
context.strokeRect(x,y,width,height);左上角坐标x,y,矩形宽高。直接绘制一个当前状态的描边矩形
<script> window.onload = function(){ var canvas = document.getElementById("mycanvas"); canvas.width = 800; canvas.height = 800; var context = canvas.getContext("2d"); //绘制矩形 //当使用了beginPath()和closePath()之后,如果画完未闭合,则自动闭合。 context.beginPath(); context.rect(300,300,200,0,1.5*Math.PI); context.closePath(); //先填充颜色,再使用stroke描边,否则会填充颜色会盖住1/2的边,导致lineWidth变细为1/2 context.fillStyle = "red"; context.fill(); context.stroke(); //好的习惯是先设定坐标(moveTo,lineTo);然后设定所有属性(线宽,线色,填充色);最后调用绘画动作(填充,描边) } </script>
注意:canvas的颜色能够使用所有css识别的颜色方式。可以使用rgba(0,256,0,0.5)这种方式来设置透明度。
线条属性
lineWidth 线宽lineCup = butt(default) | round | square 线条两端的形状 = 无 | 突出圆形 | 突出方形 。
注意:只在线条开始 结尾处起效。连接处无效。
lineJoin = miter(default) | bevel | round 两条线相接时的状态 = 无 | 平凸 | 圆角
当lineJoin = miter的时候,下边这个属性miterLimit才有效
miterLimit = 10; 默认值是10。当使用miter的时候,所产生的内角和外角之间的距离。当大于10px,会自动换成bevel方式显示。一般只有需要显示非常尖锐的角的时候才需要修改这个值。
图形变换
在实际画图中,都推荐使用:1.先画出一个基本的标准图形。2.再由图形变换得到所需图形。这样的方式。图形变换的方式:
位移: translate(x,y) 远点移动到x,y的位置
旋转: rotate(deg) 旋转deg的读书
缩放: scale(sx,sy) 在横向进行sx倍缩放,在纵向进行sy倍缩放。
注意:这里的图形变换,变换的是坐标原点。所以会相互叠加的。比如translate两次,第二次就会在第一次结果的基础上进行变换。为了避免这种问题,就要使用context.save()和context.restore();
例如:
context.save(); context.translate(100,100); context.fillRect(0,0,400,400); context.restore();
注意:context.save()和context.restore();必须成对出现,context.save()表示保存目前的状态。context.restore()表示回到保存的状态。
关于scale()的特殊性:
scale()是有一定的副作用的:当你使用scale缩放的时候,不仅会放大图像本身,对于图像携带的数值属性,也会按照相应的倍数进行放大,比如线宽,原点坐标等。解决方式:对于外边框,放弃设置。对于原点坐标,使用translate,配合save和restore。而不要直接使用(100,100)之类的会被放大的坐标。
更高级的变换方式就涉及变换矩阵了。这里先不做展开。
填充,渐变
fillStyle和strokeStyle, 不仅能够设置颜色值,还能够设置其他填充方式。线性渐变
//第一步设置渐变开始结束的坐标 var grd = context.createLinearGradient(xstart,ystart,xend,yend); //第二步设置渐变模式,颜色 grd.addColorStop(stop,color);
例如:
<script> window.onload = function(){ var canvas = document.getElementById("mycanvas"); canvas.width = 800; canvas.height = 800; var context = canvas.getContext("2d"); //设置一个渐变首尾坐标 var grd = context.createLinearGradient(0,0,800,800); //设置渐变过程 grd.addColorStop(0.0,'red'); grd.addColorStop(0.25,'black'); grd.addColorStop(0.5,'blur'); grd.addColorStop(0.75,'green'); grd.addColorStop(1.0,'yellow'); //使用渐变填充并画出矩形 context.fillStyle = grd; context.fillRect(0,0,800,800); } </script>
径向渐变
//第一步设置渐变开始结束的坐标。分别是两个圆,从一个圆到另一个圆的径向渐变。 var grd = context.createRadialGradient(x0,y0,r0,x1,y1,r1); //第二步设置渐变模式,颜色 grd.addColorStop(stop,color);
使用方法跟线性渐变一样。
使用图片、画布或video填充
createPattern,创造一个填充方式//图片填充 createPattern(img,repeat-style) //其中,repeat-style有4个值:no-repeat,repeat-x,repeat-y,repeat //canvas画布。同样的方法,以canvas来填充 createPattern(canvas,repeat-style) //使用video来填充 createPattern(video,repeat-style)
曲线的绘制
绘制一段弧线
首先是之前学过的arccontext.arc(
centerx,centery,radius, //圆心x,y坐标,半径
startingAngle,endingAngle, //开始角度,结束角度。开始角度0位于直角坐标系x轴右边。
anticlockwise = false //可选参数:是否逆时针绘制。默认false,以顺势针方向绘制
)
另外还有srcTo
context.arcTo(
x1,y1,x2,y2, //如下图,0点是目前所在的点。1点和2点坐标作为参数传入。1位控制点,2为结束点
radius); //半径
看图可知,0,1,2三个点构成了两条辅助线,从而确定生成的圆弧。圆弧切于这两条辅助线(或他们的延长线),而不一定切于0,2这两个点。
例子:使用它来绘制月亮的内弧
贝塞尔曲线 Bezier(更好用)
贝塞尔二次曲线贝塞尔曲线可以直接设置0,1,2三个点,并且保证0,2就是弧线的起始,结束点,所以很多情况下很好用。这种情况下曲线并非标准圆弧,而是由控制点的坐标来决定的。
使用方法:
context.moveTo(x0,y0) //初始点 context.quadraticCurveTo( x1,y1, //控制点 x2,y2); //结尾点
详情可以看这里的互动查看工具
贝塞尔三次曲线
使用方法:
context.moveTo(x0,y0) //初始点 context.bezierCurveTo( x1,y1, //控制点1 x2,y2); //控制点2 x3,y3); //结尾点
详情可以看这里的互动查看工具
文字的渲染
使用之前的渲染方式,配合下边的文字相关函数即可context.font = "bold 40px Arial"; //fillText也会使用fillStyle的设置 context.fillText(string,x,y,[maxlen]);//实心文字,最后一个参数可选。最长宽度(px) //strokeText也会使用strokeStyle的设置 context.strokeText(string,x,y) //空心文字,最后一个参数可选。最长宽度(px)
上边的代码中,font的默认值是”20px sans-serif”,但是实际上最多可以设置5个值:
context.font = font-style font-variant font-weight font-size font-family //其中font-styke : normal(default) italic(斜体字) oblique(倾斜字体) //其中font-variant : normal(default) small-caps(用小号大写字母显示小写字母) //其中font-weight : lighter normal(default) bold bolder 100-900 //但是大多数浏览器目前并不支持这么多种粗细,一般只有normal(400) bold(700)两种 //其中font-size : 20px 2em 120% //font-family : 支持多种字体备选 支持@font-face向浏览器注入新字体。 web安全字体(大部分浏览器都支持的字体)
文本对齐
//水平对齐 context.textAlign = left center right; //垂直对齐 context.textBaseline = top middle bottom alphabetic(default)
文本的度量
//返回该文本的真实宽度 context.measureText(string).width
Canvas的高级内容
阴影//阴影颜色 context.shadowColor //阴影的位移,数字 context.shadowOffsetX context.shadowOffsetY //阴影模糊程度,数字越大越模糊 context.shadowBlur
绘制阴影不用单独调用绘制函数,只需要设定上边这些状态,绘制的时候就会有。
透明度&遮盖
//默认1不透明 context.golbalAlpha = 1; //遮盖 globalCompositionOperation = "source-over" (default) //后画的盖住先画的 //上边属性改为"destination-over" 则变成先画的覆盖后画的。一共有11个值,查文档用。
剪辑区域
//剪切出一片渲染区域,只在区域内渲染,其他部分不渲染。一般先设定一段闭合区域,然后fill,然后clip context.clip();
可以制作探照灯效果
非零环绕原则
清空
//清空该区域 context.clearRect(x,y,width,height) //检测x,y构成的坐标点是否在路径里边 context.isPointInPath(x,y) //添加事件 canvas.addEventListener("mouseup",detect); //获取鼠标点击在canvas中的位置: var x = event.clientX - canvas.getBoundingClientRect().left; var y = event.clientY - canvas.getBoundingClientRect().top;
更多Canvas内容
图形库canvasplus
Artisan JS
Rgraph
相关文章推荐
- HTML5中在客户端验证文件上传的大小
- html5 web数据存储
- HTML5调用摄像头实例
- 页面元素查找之Selectors API
- 使用ajax实现用户登录验证(升级版)
- Canvas 在高清屏下绘制图片变模糊的解决方法
- 关于前端的思考与感悟
- 新时代编辑神器:Atom
- rem : web app适配的秘密武器
- jquery高级应用之Deferred对象
- 又被事件冒泡坑了一把,这次要彻底弄懂浏览器的事件流
- 移动端点击事件全攻略,这里的坑你知多少?
- 原生js结合html5制作小飞龙的简易跳球
- 使用canvas实现仿新浪微博头像截取上传功能
- HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)
- 三个不常见的 HTML5 实用新特性简介
- 低版本IE正常运行HTML5+CSS3网站的3种解决方案