学过数学,或者是比较了解js 的同学都知道贝塞尔曲线,当然,在数学里面,这是一门高深的学问,js里面的贝塞尔曲线一般是用来做动画的,其实别的地方也有体现,比如说Photoshop里面的钢笔工具,CorelDraw里面的贝塞尔工具等等,canvas中,也是有体现的
当然,如果是单纯的画一条曲线,也可以用前面的方法:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.arc(100,100,100,0,90*Math.PI/180,false); ctx.stroke(); ctx.beginPath(); ctx.moveTo(103,103); ctx.arcTo(183,83,162,182,40); ctx.stroke();
如果要画一个弯弯曲曲的线条就费劲了,这才有下面的主角登场:
quadraticCurveTo(cpx,cpy,x,y) 二次贝塞尔曲线
参数:cpx,cpy 表示第一个控制点,x,y 表示结束点
加上起点,就是3个点控制一条曲线,其实这个跟arcTo的用法差不多,不同的地方就是arcTo是需要指定圆弧的半径的,因为它是2条线中画一个圆与直线的切点形成的曲线,那这个二次贝塞尔曲线的画图原理是什么呢?咱们一起来画一画:
二次贝塞尔曲线的大致规律:从起始点出发,曲线越靠近控制点,曲线越陡,然后慢慢远离控制点,曲线随即越来越平缓,直到结束点,并且此曲线会与起始点和结束点相切
这个控制点是不是有点像一个磁铁一样,吸引着这条曲线的运动,俗话说耳闻不如一见,咱们试一下:
ctx.moveTo(50,50); ctx.lineTo(70,120); ctx.lineTo(200,80); ctx.stroke(); ctx.beginPath(); ctx.moveTo(50,50); ctx.quadraticCurveTo(70,120,200,80); ctx.stroke();
看看,是不是这样的,当然,曲线弯曲的程度是多少是有公式的,但是我们不需要关心,只需要记住一点就够了:曲线靠近控制点,曲线越陡,远离控制点,曲线越平,哦了!
再次提示一下,arcTo与quadraticCurveTo的区别,现在是否明白?
现在我们来介绍一下三次贝塞尔曲线:
bezierCurveTo(cpx1,cpy1,cpx2,cpy2,x,y) 三次贝塞尔曲线
参数:cpx1,cpy1表示第一个控制点,cpx2,cpy2表示第二个控制点 x,y表示结束点
包括起始点一起4个点来决定一条曲线,这个跟二次贝塞尔曲线的原理是一样一样的,只是多一个控制点,其精髓还是那句话:曲线靠近控制点,曲线越陡,远离控制点,曲线越平
先来一个简单的例子吧(来个U形):
ctx.moveTo(20,20); ctx.bezierCurveTo(20,100,200,100,200,20); ctx.stroke();
如上图,第一张是效果图,第二张是原理图,曲线从起始点开始,下方有一个控制点,则曲线越陡,到第二个控制点与曲线的切线的点的位置,因为受2个控制点的影响,曲线开始慢慢变平缓,因为2控制点刚好对称,所以到中间点,曲线出于水平,然后继续受2个控制点的作用,其中第二个控制点的作用越来越大,知道第一个控制点与曲线的切线点位置,曲线继续受到第二个控制点的作用,反向受力,到结束点,额,听不懂,好吧,不懂就不懂吧,记住那句总结性的话就行了!
其经典例子莫过于正弦图(用2个贝塞尔曲线,一个正U一个反U):
ctx.beginPath(); ctx.moveTo(20,150); ctx.bezierCurveTo(20,50,150,50,150,150); ctx.stroke(); ctx.beginPath(); ctx.moveTo(150,150); ctx.bezierCurveTo(150,250,280,250,280,150); ctx.stroke();
当然,三次贝塞尔曲线不知道能画U形图,而是任意曲线都能画,只有你想不到,没有画不了的,哈哈,脑洞打大一下吧!
都说作画作画的,不能老是做水墨画啊,我喜欢颜色,五彩缤纷的颜色,恩,canvas也是可以的,canvas和css3一样都可以设置渐变,这样一来,看到彩虹是不是就不远了,嘻嘻
我们先看看css3的渐变是怎么设置的,然后对比一下canvas的渐变,我们都知道渐变分为线性渐变和径向渐变,我们一一来比较:
线性渐变:
.box1{ width:500px; height:50px; background: -webkit-linear-gradient(left, red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%); }
css3可以指定颜色,支持各种颜色格式,且可以指定颜色所在位置,不仅如此,css3还可以指定渐变的方向:
.box1{ width:500px; height:50px; background: -webkit-linear-gradient(45deg , red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%); }
方向可以用角度来定义,45度角是从左下到右上进行渐变
径向渐变:
.box2{ width:300px; height:200px; background:-webkit-radial-gradient(red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%); }
渐变原点为中心,渐变颜色为百分百之间的颜色渐变
可以看出,径向渐变是以中心为原点,一圈一圈向外扩散,同样支持自定义颜色,支持各种颜色格式,支持指定位置,也是可以设置原点和渐变方式(圆形,椭圆):
.box2{ width:300px; height:200px; background:-webkit-radial-gradient(bottom left, ellipse,red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%); }
原点左下,渐变形状为椭圆
.box2{ width:300px; height:200px; background:-webkit-radial-gradient(bottom left, circle,red 0%, #0F0 20%,rgb(51,102,255) 50%, rgba(204,255,0,0.8) 100%); }
原点左下,渐变形状为圆形
以上只是简单列举一下css3的渐变样式,当然css3的渐变肯定不止这些,这里主要是想对比一下canvas的渐变样式,顺便科普一下!
canvas的渐变相对要简单一些,没有那么多的花花肠子:
createLinearGradient(x1,y1,x2,y2) 创建线性渐变
参数:x1,y1 表示渐变起始点 x2,y2 表示渐变结束点
createRadialGradient(x1,y1,r1,x2,y2,r2) 创建径向渐变
参数:x1,y1 表示渐变开始圆心坐标,r1表示渐变开始圆的半径 x2,y2 表示渐变结束圆心坐标,r2表示渐变结束圆的半径
gradient.addColorStop(stop,color) 规定gradient 对象中的颜色和位置
参数: stop 取值0-1之间,表示渐变中开始与结束之间的位置 color表示渐变颜色
注意,这里添加渐变颜色的对象并不是context,而是gradient
怎么用呢?看线性渐变一个小例子:
这个科普一个误区:
ctx.fillRect(50,50,200,50); var line = ctx.createLinearGradient(50,50,200,50); line.addColorStop(0,'red'); line.addColorStop(0.2 ,'#0F0'); line.addColorStop(0.5 ,'rgb(51,102,255)'); line.addColorStop(1 ,'rgba(204,255,0,0.8)');
这样是错误的,什么都出不来!
照理说,应该是先创建一个图像,然后给这个图形加渐变色,一般的规律都如此,比如画画,比如css,但是canvas不一样,重点来了:canvas凡是设置样式的,必须放在绘图前面 ,怎么理解这句话?
绘图的方法: fill() , fillRect() , stroke() , strokeRect() , rect()
那设置:比如文字类字体,字体大小,字体颜色,字体阴影,渐变色 路径类如线条,矩形,圆形,背景,渐变等等
所以正确的格式是:
var line = ctx.createLinearGradient(50,50,200,50); line.addColorStop(0,'red'); line.addColorStop(0.2 ,'#0F0'); line.addColorStop(0.5 ,