canvas:
用于绘制图标,游戏,动画等特效
ie9之前浏览器不支持canvas
官方网站:http://caniuse.com
实例demo库:http://codepen.io(H5开源动画库)
第一步:html中创建canvas标签,定义好宽高。
<canvas class="canvas1" width="500" height="500"></canvas>
第二步:js中拿到画布,获取画布的上下文对象(画笔),(画布是2D平面的)
<script>
var oCanvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas1.getContext('2d');
</script>
第三步:绘制图案
ctx.moveTo(x, y); 移动到 x,y坐标点 (画笔落笔位置)
ctx.lineTo(x, y); 从当前点绘制直线到x,y点 (落笔位子到这个点的直线)
ctx.lineWidth = 20; 设置线段宽度
ctx.closePath(); 闭合当前路径 和回到起始点的区别 (如果是人为闭合,会出现缺口)
ctx.stroke(); 描边 (显示出绘制图案线条,默认黑色)
ctx.fill(); 填充颜色(默认黑色)
ctx.strokeStyle = 'blue'; 设置线条颜色为蓝色
ctx.fillStyle = 'green'; 设置填充颜色为绿色
ctx.beginPath() ; 开始一个新的路径
重点:
1.fill和stroke方法都是作用在当前的所有子路径;(其实就是说如果不使用beginPath()方法,后写的属性同样会全部作用(非覆盖)到之前的路径。
2.完成一条路径后要重新开始另一条路径时必须使用beginPath()方法,betinPath开始子路劲一个新的集合;(在一个路径里绘制多个图案,一些属性会取最后图案设置的属性如线宽和填充颜色,线颜色)
用线条绘制矩形会有代码冗余。canvas有直接的绘制矩形属性:
ctx.rect(x, y, dx, dy); (与画笔起点无关)
ctx.fillRect(x, y, dx, dy); //开启新路径 填充画
ctx.strokeRect(x, y, w, h);//开启新路径 描边画
有了画图,当然少不了橡皮檫:
ctx.clearRect(x, y, dx, dy);
小练习:实现一个小矩形下落:(控制y坐标实现下落)
使用canvas做动画,我们始终操作的是一个canvas元素,不会频繁的操作太多的dom元素,性能更好。
var canvas1 = document.getElementsByTagName('canvas')[0];
var ctx = canvas1.getContext('2d');
var w = canvas1.width;
var h = canvas1.height;
var y = 100;
function drawRect(y) {
ctx.fillRect(100, y, 30, 30);
}
var timer = setInterval(function () {
ctx.clearRect(0, 0, w, h);
drawRect(y);
y += 1;
if (y > 470) {
clearInterval(timer);
drawRect(470);
}
}, 10)
画完矩形,我们来画弧形吧~
arc(x, y, r, 起始弧度, 结束弧度,弧形的方向 )
角 以弧度计,0顺时针 1逆时针
ctx.arc(100,100,100,0,Math.PI,0)
圆心为(100,100),半径R=100,起始弧度为0,顺时针弧度一个π(Math.PI)
小点:这里的弧度表示需要用到Math.PI,专门表示弧度。顺时针时候0可以省略不写,逆时针时。如逆时针90度,则表示的是顺时针270度的图形
画完圆弧,我们来画圆角吧:
ctx.arcTo(x1, y1, x2, y2, r)
绘制的弧线与当前点和x1,y1连线,x1,y1和x2,y2连线都相切
如CSS3中 border-radius 的样式:(其中的x,y就是moveTo的值,而且最后只剩下moveTo到圆弧尾部的部分,x2,y2的部分也不存在)
了解贝塞尔曲线(很好玩):
由于用计算机画图大部分时间是操作鼠标来掌握线条的路径,与手绘的感觉和效果有很大的差别。即使是一位精明的画师轻松绘出各种图形,拿到鼠标想随心所欲的画图也不是一件容易的事。这一点是计算机万万不能代替手工的工作,所以到目前止人们只能颇感无奈。使用贝塞尔工具画图很大程度上弥补了这一缺憾。
贝塞尔曲线贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。它通过控制曲线上的个点(起始点、终止点以及两个相互分离的中间点)来创造、编辑图形。其中起重要作用的是位于曲线中央的控制线。这条线虚拟的,中间与贝塞尔曲线交叉,两端是控制端点。移动两端的端点时贝塞尔曲线改变曲线的曲率(弯曲的程度);移动中(也就是移动虚拟的控制线)时,贝塞尔曲线在起始点和终止点锁定的情况下做均匀移动。注意,贝塞尔曲线上的所有控制点节点均可编辑。这种“智能化”的矢量线条为艺术家提供了一种理想的图形编辑与创造的工具。(来源百度)
quadraticCurveTo(x1, y1,ex, ey ) 二次贝塞尔曲线 x1,y1 控制点 ex,ey 结束点
bezierCurveTo(x1, y1, x2, y2, ex, ey) 三次贝塞尔曲线 x1,y1,x2,y2 控制点 ex,ey 结束点
坐标轴转换(画布也是能移动的):
ctx.save() //拷贝画布,在平移前先拷贝一份放入栈内存中(数据结构特点:先进后出);
ctx.translate(dx,dy) //平移画布,移动的不是canvas标签的位置,而是背景画布,也就是说border看上去没动,但是绘制的
容整体平移;
ctx.scale(2,1) //画布缩放,在xy轴上的缩放倍数,除了图形大小,位置也受影响;
ctx.restore(); //恢复画布,从栈中取出save()方法储存的图形状态并恢复(如果多个save则从最近的save开始恢复);
这个时候上面的代码还是保持不变,后面的代码会在恢复的画布中绘制;
ctx.roate(Maath.PI) //旋转当前绘图(不是画布),在画之前旋转,需要写前面;
setTransform(a,b,c,d,e,f) //先重置之前所有的属性,对齐进行统一的变换;
(参数:水平缩放,水平倾斜,垂直倾斜,垂直放,水平移动,垂直移动)-- 口诀:so亲亲so咦咦
transform(a,b,c,d,e,f) //这个则在原来变换的基础上再进行新的变换;一般用setTransform比较好控制;
画布也能填充背景图案:
createPattern(image,"repeat|repeat-x|repeat-y|no-repeat") img元素(Image对象),canvas元素,video元素(有图形的)
// /--------核心语法--------
var fill = ctx.createPattern(oImg,'no-repeat'); //oImg为图片引入
ctx.fliiStyle = fill;
背景渐变:
createLinearGradient(x1, y1, x2, y2); 线性渐变 必须在填充渐变的区域里定义渐变, 否则 没有效果
createRadialGradient(x1, y1, r1, x2, y2, r2); 径向渐变
bg.addColorStop(p, color);
var canvas1 = document.getElementsByTagName('canvas')[0];
var ctx = canvas1.getContext('2d');
var w = canvas1.width;
var h = canvas1.height;
var bg = ctx.createLinearGradient(0,0,w,h);
bg.addColorStop(0,'red');
bg.addColorStop(0.5,'orange');
bg.addColorStop(0,'green');
ctx.fillStyle = bg;
ctx.fillRect(0,0,w,h);