Canvas 是HTML5的核心技术技术所在,用于在网页上进行绘制图形,自身并不具备绘制功能,canvas须依靠javascript才能绘制出图形;canvas也提供了多种绘制路径、矩形、圆形、字符以及添加图像的方法;
有多强大? Flappy Bird游戏我想对大家来说可能在熟悉不过,看似简单而难度极大的这款Flappy Bird的HTML5版仅仅需要65行js代码;
1,画线,简单图形
图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。
首先,创建路径起始点。然后使用画图命令去画出路径。之后你把路径封闭。一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
以下是所要用到的函数:
beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
closePath()
闭合路径之后图形绘制命令又重新指向到上下文中。
stroke()
通过线条来绘制图形轮廓。
fill()
通过填充路径的内容区域生成实心的图形。
moveTo(x,y)
将笔触移动到指定的坐标x以及y上。
lineTo(x,y)
绘制一条从当前位置到指定x以及y位置的直线。
arc(x,y,radius,startAngle,endAngle,anticlockwise)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
2,贝塞尔曲线
这本是上一节,画线的内容,但是维基了一下,内容太过庞大,甚至不是隶属于前端的一个知识点。贝塞尔曲线,起源于汽车设计,这之前是没有一个理论体系,能描述,传播,俩个一模一样,任意的曲线。
其原理就是,用有限的点,控制唯一的曲线,点越多,能描述的曲线越多。
canvs的api有
quadraticCurveTo(cp1x, cp1y, x, y)
绘制贝塞尔曲线,cp1x,cp1y为控制点,x,y为结束点。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
绘制二次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
附上原理(感兴趣的了解):http://www.html-js.com/article/1628
3,变形
简单说,canvas本身有一套坐标轴系统,有自己的x轴,y轴,原点,单位,所谓变形,就指这个坐标轴位置,角度的变化,变化之后,再以相同的坐标值画图,位置当然不同。
save()
restore()
save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。
移动
translate(x, y)(圆心偏移)translate方法接受两个参数。x是左右偏移量,y是上下偏移量。
旋转
rotate(angle)(坐标轴旋转)这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
缩放
scale(x, y)(改变坐标轴单位大小)scale方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
4,图片,文字的绘制
图片,这里跟js的api多少有些重合了,因为不属于特性,我简单介绍几个方法吧,不过,它可以,将图片进行自定义编辑。
引入图像到canvas里需要以下两步基本操作:
获得一个指向HTMLImageElement的对象或者另一个canvas元素的引用作为源,也可以通过提供一个URL的方式来使用图片
使用drawImage()函数将图片绘制到画布上。
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
ctx.beginPath();
ctx.moveTo(30,96);
ctx.lineTo(70,66);
ctx.lineTo(103,76);
ctx.lineTo(170,15);
ctx.stroke();
}
img.src = 'images/backdrop.png';
}
注:坐标轴,背景为图片,折线图为绘制。
5,动画
这里又分简单和复杂动画,不过,核心原理大同小异,即,渲染方法被迅速循环调用,快速及时渲染新画面,跟小时候,快速翻动小人书,产生动画的机理是一样的,只不过,这里是快速的画出来,一帧一帧的画。
步骤:
清空 canvas
保存 canvas 状态(这里,可以吧canvas想象成是一只画笔,保存画笔的角度,颜色,供以后使用)
绘制动画图形(animated shapes)
恢复 canvas 状态
快速渲染的函数可以有如下选择:
当设定好间隔时间后,function会定期执行。
在设定好的时间之后执行函数
requestAnimationFrame(callback)
告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。
太阳系
思路:用date对象作为变化原子,每一次调用连续变化有规律的值,通过对这个值的加工,做出简单的动画。
高级动画,则是有直线速度和加速度一说,思路是,把坐标设为自己(当前被绘画对象),速度也为自己的属性,循环调用方法,用速度改变坐标,循环绘画,达到匀速运动的效果,加速度,则再高一阶思维,坐标为自己属性,速度也为自己的属性,加速度也为自己的属性,每一次调用方法,由加速度改变速度,再用改变后的速度,修改坐标,循环绘画形成加速运动的效果。
一个绘画对象结构如下:
原理是,所有的形被计算机分成割成像素,而每个像素用4个1byes值(按照红,绿,蓝和透明值的顺序表示; 这就是"RGBA"格式) 来代表。
计算机会将所有的颜色值存入数组,而所有的美图工具,都是操作的这些数组里的元素。达到照片反色,切割,魔图各种各样效果。
ImageData 对象包含这几个属性
width(图片宽度,单位是像素)
height(图片高度,单位是像素)
data(存储像素的数组)
一个简单的图片选择器
function pixelFunction(){
var img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'img/rhino.jpg';
var canvas = document.getElementById('studyCanvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
};
var color = document.getElementById('color');
function pick(event) {
var x = event.layerX;
var y = event.layerY;
var pixel = ctx.getImageData(x, y, 1, 1);//获取当前鼠标的一行一列行有4个值
var data = pixel.data;
var rgba = 'rgba(' + data[0] + ',' + data[1] +
',' + data[2] + ',' + data[3] + ')';
color.style.background = rgba;
color.textContent = rgba;
}
canvas.addEventListener('mousemove', pick);
}
7,交互(大多不支持)
基本就是,可以与canvs上某一个区域,发送交互,做到类似,按钮触发事件的效果,但是,这个属性在绝大多数web浏览器都无效,包括chrome也需要解禁才能触发。
解禁方式如下:
8,dataUrl的制作
这一点,至关有用,通常我们从服务器下载一张图片的思路是,图片存在盘符,路径存在数据库,用a标签,引用路径,下载图片,这样做的弊端是,访问用户过多,或者,无效图片过多,将产生大量垃圾数据。