要不要一起了解一下Canvas?

      嗯,那个,我是来试水的,跟你们这些大神不能比,所以就为小小白们总结一下Canvas的基础,还望各位多多指教……

第一话   与canvas的初次邂逅

姓名:Canvas

自我介绍:一个默认为宽300,高150的空白画布,可以使用脚本来绘制图形的HTML元素,可以绘制图表、制作图片构图或者制作简单的动画

哦,对了,Canvas说他只是一个容器,本身没有绘制能力,所以他在等一个意中人拿到一个画布,使之具有绘制各种图形的能力,他的意中人应该可以做到以下几点:

 1、 有一个舒适的地方(页面),一般我们最常用html文件

 2、 里面要有标签,作为h5新标签,不太支持较老版本的浏览器,因此稍稍判断以下还是可以的,或者说如果你用的浏览器版本比较新 ,那可以不用写‘你的浏览器不支持canvas’这句话了,同时我们在标签上规定id、宽高,这里的宽高如果拿到外面去设置就会导致canvas变形,所以乖乖仔这里设,至于其他样式设置就拿到外面去吧

<canvas id="canvas" width="400" height="500">
你的浏览器不支持canvas!
</canvas>
复制代码

 3、 获取到这个画布,每个canvas节点都有一个对应的context对象(上下文对象),Canvas API定义在这个context对象上面,所以需要获取这个对象,方法是使用getContext方法。即Canvas.getContext(contextID),参数 contextID 指定了您想要在画布上绘制的类型。当前唯一的合法值是 “2d”,它指定了二维绘图,并且导致这个方法返回一个环境对象,该对象导出一个二维绘图 API。在未来,如果 <canvas> 标签扩展到支持 3D 绘图,getContext() 方法可能允许传递一个 “3d” 字符串参数。

var canvas=document.getElementById('canvas')
//获得画布
var context=canvas.getContext('2d')
复制代码

第二话   他的意中人

  • 跟矩形有关的那点事

在此之前,我们先做一下准备工作:fillReact(坐标x,坐标y,宽,高):一般用于绘制实心的矩形,与fillStyle() 填充颜色搭配使用;strokeReact(坐标x,坐标y,宽,高) : 一般绘制空心的矩形,与strokeStyle() 设置边框颜色搭配使用;

context.benginPath(): 开始路径;context.closePath() : 结束路径,值得注意的是  

1、系统默认在绘制第一个路径的开始点为beginPath                                                 2、如果画完前面的路径没有重新指定beginPath,那么画第其他路径的时候会将前面最近指定的beginPath后的全部路径重新绘制                                                                    3、每次调用context.fill()的时候会自动把当次绘制的路径的开始点和结束点相连,接着填充封闭的部分,这时也就不用调用closePath()了,但是调用strock()不会自动闭合

var canvas=document.getElementById('canvas')
//获得画布
var context=canvas.getContext('2d')
context.beginPath();               // 开始路径
context.fillStyle='yellow'         // 设置要填充的颜色
context.fillRect(100,150,100,100) 
context.fill()                     // 全部填充
复制代码

这样做,我们就可以得到下面这个图

《要不要一起了解一下Canvas?》

再来个空心的像这样的

《要不要一起了解一下Canvas?》

context.beginPath()
context.strokeStyle="red"
context.strokeRect(150,150,100,100)
context.fill()
复制代码

什么?想要个橡皮擦?没问题,满足你

context.clearRect(x,y,width,height)  仅支持矩形

context.clearRect(30,30,50,50)
复制代码

《要不要一起了解一下Canvas?》

矩形的故事先说到这里,下面我们来说说圆形那个家伙

  • 一个球的故事

跟矩形的套路差不多 ,我们常用来画圆的是arc , context.arc(x, y, radius, starAngle,endAngle, anticlockwise)  坐标位置不用介绍了,后面就是半径,开始弧度,结束弧度,顺逆时针

//绘制圆形
context.beginPath()
context.arc(250,250,20,0,Math.PI*2,true)
context.closePath()
context.fillStyle='rgba(0,255,0,0.25)'
context.fill()
复制代码

然后差不多就是这个样子了

《要不要一起了解一下Canvas?》

第三话  贝塞尔的约会

在说约会的故事前,先来认识一下牵线人  线段

 context.moveTo(x,y) context.lineTo(x,y)   

 moveTo(x,y) 移动到某一点,但是它只是代表的作画的起点 lineTo(x,y) 与上面的对应,代表作画的终点,每次画线都从moveTo的点到lineTo的点, 如果没有moveTo那么第一次lineTo的效果和moveTo一样, 每次lineTo后如果没有moveTo,那么下次lineTo的开始点为前一次lineTo的结束点

Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。来见识一下贝塞尔如何?下面是五阶贝塞尔曲线的绘制过程

《要不要一起了解一下Canvas?》

如果觉得太复杂,那我们先来看二阶的,是不是好很多

《要不要一起了解一下Canvas?》

绘制贝塞尔曲线(贝济埃、bezier) context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y) 先来说说个个参数都代表什么  cp1x:第一个控制点x坐标       cp1y:第一个控制点y坐标 cp2x:第二个控制点x坐标       cp2y:第二个控制点y坐标       x:终点x坐标    y:终点y坐标   
如果你想要了解他的算法,可以参考一下这个

http://www.cnblogs.com/wxydigua/p/4204254.html http://www.cnblogs.com/regina1123/p/6256375.html

《要不要一起了解一下Canvas?》

ctx.beginPath();
ctx.moveTo(75,25);  // 开个头
ctx.quadraticCurveTo(25,25,25,62.5);
ctx.quadraticCurveTo(25,100,50,100);
ctx.quadraticCurveTo(50,120,30,125);
ctx.quadraticCurveTo(60,120,65,100);
ctx.quadraticCurveTo(125,100,125,62.5);
ctx.quadraticCurveTo(125,25,75,25);
ctx.stroke();
复制代码

结果如下,还可以吧,没那么丑,至于那个控制点,个人理解为以moveTo为中心,向前向后画曲线,然后就这样了,当然如果想要画更复杂的图,可以在好好研究一下

《要不要一起了解一下Canvas?》

  • 还有一点值得注意,精确画图时,我们要考虑一下线条的像素会不会对你的图有影响?

比如说,我们想要一个1像素的,但是结果却不太像1像素的

《要不要一起了解一下Canvas?》

这是因为计算机不允许出现小于1px的图形,所以他做了一个折中的事:把这两个像素都绘制了。所以,如此一来,本来1px的线条,就成了看起来2px宽的线。也就是说这个1像素为了能生存下去,就向左向右跨了0.5像素,也就成了2像素

《要不要一起了解一下Canvas?》

为了解决这个问题,聪明的人们还是想到了办法的,那就是给需要的地方加上0.5像素,虽然有点麻烦,但是亲测有效

第四话  初识文(文字)阴(阴影)渐(渐变)

  • 我是文字啊

fillText(text, x, y [, maxWidth]) 在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的. 当然如果绘制一个空心的也可以,那就这样strokeText(text, x, y);

ctx.font = "20px Arial";
ctx.textBaseline = "hanging";
ctx.strokeText("Hello ", 50, 50);
复制代码

《要不要一起了解一下Canvas?》

  • 嗯,我是阴影

   context.shadowOffsetX :阴影的横向位移量(默认值为0) context.shadowOffsetY :阴影的纵向位移量(默认值为0) context.shadowColor :阴影的颜色 context.shadowBlur :阴影的模糊范围(值越大越模糊)

《要不要一起了解一下Canvas?》

ctx.shadowOffsetX = 2; //X轴阴影距离,负上,正下
ctx.shadowOffsetY = 2; //Y轴阴影距离,负左,正右
ctx.shadowBlur = 2; //阴影的模糊程度
ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; //阴影颜色
ctx.font = "30px Times New Roman"; //设置字体和字体大小 
ctx.fillStyle = "Black"; 
ctx.fillText("Sample String", 15, 30); //实体文字
ctx.strokeStyle = 'red'; 
ctx.strokeText('Hello world', 15, 100); //边框文字
复制代码

  • 我,我是渐变……

 线性渐变 createLinearGradient(xStart,yStart,xEnd,yEnd)                                          线性渐变颜色addColorStop(offset,color)                                                                   xstart:渐变开始点x坐标                                                                                             ystart:渐变开始点y坐标                                                                                           xEnd:渐变结束点x坐标                                                                                            yEnd:渐变结束点y坐标                                                                                          offset:设定的颜色离渐变结束点的偏移量(0~1)                                                       color:绘制时要使用的颜色

《要不要一起了解一下Canvas?》

let can=document.getElementById('Canvas')
let ctx=Canvas.getContext('2d')
let bg = ctx.createLinearGradient(0, 0, 0, 200); 
bg.addColorStop(0, 'black'); // 开始颜色
bg.addColorStop(0.6, '#fff’); //结束颜色 ctx.fillStyle = bg; ctx.fillRect(10, 10, 100, 100); 复制代码

径向渐变(发散)context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd)           径向渐变(发散)颜色rg.addColorStop(offset,color)                                           xStart:发散开始圆心x坐标                                                                                     
      yStart:发散开始圆心y坐标                                                                             radiusStart:发散开始圆的半径                                                                                xEnd:发散结束圆心的x坐标                                                                                     yEnd:发散结束圆心的y坐标                                                                             radiusEnd:发散结束圆的半径                                                                                 offset:设定的颜色离渐变结束点的偏移量(0~1)                                                         color:绘制时要使用的颜色

《要不要一起了解一下Canvas?》

var bg1 = ctx.createRadialGradient(100, 100, 0, 100, 100, 50);
bg1.addColorStop(0, '#FF5F98');
bg1.addColorStop(0.75, '#FF0188');
bg1.addColorStop(1, 'rgba(255,1,136,0)');
ctx.fillStyle = bg1; 
ctx.fillRect(0,0,150,150);
复制代码

第五话   千变万化

这里先了解一下状态:对于canvas 的状态就是当前画面应用的所有样式和变形的一个快照,操作状态有两个方法:save() 和 restore (),前者是用来保存当前状态,后者用来恢复刚才保存的状态,他们都可以多次调用,举个例子

ctx.fillStyle = 'black'; 
ctx.fillRect(20, 20, 150, 150); 
ctx.save(); //保存当前状态 
ctx.fillStyle= '#fff’; ctx.fillRect(45, 45, 100, 100); ctx.restore(); //恢复到刚才保存的状态 ctx.fillRect(70, 70, 50, 50);复制代码

然后就这样了

《要不要一起了解一下Canvas?》

位移了解一下?   ctx.translate(x, y); //更改canvas的原点 

for(var i = 1; i< 4; i++) { 
ctx.save(); 
//使用save方法保存状态,让每次位移时都针对(0,0)移动。 
ctx.translate(100*i, 0); 
ctx.fillRect(0, 50, 50, 50);
ctx.restore(); 
}
复制代码

《要不要一起了解一下Canvas?》

缩放也了解一下吧 ctx.scale(x, y); //基于原点缩放,x、y是两个轴的缩放倍数

var ctx = document.getElementById('canvas').getContext('2d’); ctx.fillStyle = 'red’; 
ctx.scale(0.8, 1.2); 
ctx.beginPath(); 
ctx.arc(75, 75, 60, 0, Math.PI * 2); ctx.fill();
复制代码

《要不要一起了解一下Canvas?》

第六话 有情人终成眷属

《要不要一起了解一下Canvas?》

我们来简单结合一下图形做一个好看的效果,像这样的

《要不要一起了解一下Canvas?》

怎么样是不是还可以,那就上代码

let can=document.getElementById('can')
let context=can.getContext('2d')
//绘制颜色板
for(let i=0;i<6;i++){
   for(let j=0;j<6;j++){
	context.fillStyle='rgb('+Math.floor(255-42.5*i)+','+Math.floor(255-42.5*j)+',0)'
	context.fillRect(i*25,j*25,25,25)
    }
}
//绘制圆形
for(var i=0;i<10;i++){
   for(var j=0;j<10;j++){
	context.strokeStyle='rgb(0,'+Math.floor(255-42.5*i)+','+Math.floor(255-42.5*j)+')'
	context.beginPath()
	context.arc(12.5+j*25,180+i*25,10,0,Math.PI*2,true)
	context.stroke()
  }
}
复制代码

最后经过不懈的努力,他们就变成了这个样纸,代码找不到了,反正就是拼在一起就好了^_^

《要不要一起了解一下Canvas?》

嗯,总结到此先告一段落,希望对你有帮助……

    原文作者:算法小白
    原文地址: https://juejin.im/post/5ae3d31b51882567154765f4
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞