看完这本攻略,Canvas新手小白也可以创建惊人特效

栏目: Html5 · 发布时间: 7年前

内容简介:作者本人的干货,一般人我不给他看。(开玩笑的)canvas是一个很实用的工具,难可以难到头发掉光,简单可以简单到几行代码就能给人眼前一亮的效果。这里是作者在开发canvas的道路上遇过的坑,以及如何用简易地使用canvas做一些日常任务,比如分享图片的自定义,又比如大家喜欢的X炸天的粒子特效(不知道算不算,反正很COOL就是了)。大家都知道Canvas可以做流畅的动画,功能很强大,但是Canvas中并没有像Dom那样可以帮助我们调试的工具。不过现在mac有一款web inspector(

作者本人的干货,一般人我不给他看。(开玩笑的)

canvas是一个很实用的工具,难可以难到头发掉光,简单可以简单到几行代码就能给人眼前一亮的效果。这里是作者在开发canvas的道路上遇过的坑,以及如何用简易地使用canvas做一些日常任务,比如分享图片的自定义,又比如大家喜欢的X炸天的粒子特效(不知道算不算,反正很COOL就是了)。

看完这本攻略,Canvas新手小白也可以创建惊人特效

No.1 Canvas的正确打开方式

大家都知道Canvas可以做流畅的动画,功能很强大,但是Canvas中并没有像Dom那样可以帮助我们调试的工具。不过现在mac有一款web inspector( webkit.org/downloads// )可以调试canvas,有兴趣的同学可以去试一下。

不过这里还有一种方式可以帮助大家调试Canvas。Canvas其实就是一块绘板,随便你在上面画什么。但是又不像PS那样有辅助线,因此定位很艰辛。

看完这本攻略,Canvas新手小白也可以创建惊人特效

创建网格

  • mark api:
    • context.fillStyle
    • context.textAlign
    • context.font
    • context.textBaseline
    • context.fillRect
    • context.fillText

因此,手动给Canvas加上网格,不就可以了!这里我们可以创建一个绘制网格的方法,然后每次render的时候调用,这样就可以对图形的定位有一个直观的感受了。再也不用抓瞎。

首先我们要计算好网格的数量,将所有计算好的网线放入一个数组中。虽然我们也可以动态计算,网格的位置,但是从性能上考虑,canvas中凡是在绘图之前可以确认的位置都提前计算好,这样可以提高性能。这里我留了一点空间给坐标值,因此并不是全屏的网格。

let Grids=[]
function initGrid(cap,width,height,lineWidth){
  const colNum=Math.ceil(width/cap)-1
  const rowNum=Math.ceil(height/cap)-1
  for(let i=1;i<=colNum;i++){
    Grids.push([[cap*i-1, 0,lineWidth,colNum*cap],[i*cap,cap*i-1,colNum*cap+5,"top"]]) 
  }
  for(let i=1;i<=rowNum;i++){
    Grids.push([[ 0,cap*i-1,rowNum*cap,lineWidth],[i*cap,rowNum*cap+5,cap*i-1,"middle"]])
  }
}
initGrid(cap,canvasWidth,canvasHeight,lineWidth);
复制代码

计算并保存好信息之后,我们就要开始画线了。对于线的宽度最好是双数,然后位置偏1px,然线居中,因为.5px在有些机子上性能不好,比如四舍五入一类的,容易有偏差。

function createGrid(){
  context.fillStyle = 'green';
  context.textAlign="center"
  context.font="24px Arial"
  Grids.forEach((grid)=>{
     context.textBaseline=grid[1][3]
     context.fillRect( grid[0][0],grid[0][1], grid[0][2], grid[0][3])
     context.fillText (grid[1][0],grid[1][1], grid[1][2]);   
  })
}
复制代码
看完这本攻略,Canvas新手小白也可以创建惊人特效

画一个几何图形

  • mark api:
    • context.beginPath();
    • context.moveTo (50, 50);
    • context.lineTo (450, 450);
    • context.closePath()

注意这里beginPath是一切新开始的意思,也就是当前图和上一个操作已经没有了任何关系。closePath就是结束的意思,一切回到最初开始的地方,就是最先开始的那个点。lineTo就是画线的意思,两个点之间画一条直线。我们可以搭配moveTo使用,moveTo就是移动到当前点,但是并不绘制任何内容。

如果我们只是绘制图形,并无其他操作,比如每段路径的颜色不一样或者是填充颜色不一样,那么moveTo和beiginPath的作用差不多,但是如果是,那么每次都需要beginPath一下,切断与上一个路径的联系,否则会以最后的设置的填充色路径色为主。

那么问题来了我直接closePath可以吗?当然不行,你可以说开始就开始,但不能说结束就结束!closePath最大的作用就是连接路径最后一个点和路径最开始的点。

看完这本攻略,Canvas新手小白也可以创建惊人特效

橡皮擦

因为Canvas是画布,所以每次画面更新时都是擦干净,再画下一幅画,不然就会重叠。大家想想一下帧动画,就是1s中N幅画划过的动态感,变成了会动的动画。如果是jpg这种不透明的图片还可以一层层覆盖,如果是png透明的图片,一层层就会堆叠在一起。所以橡皮擦的功能时必不可少的。

  • mark api:
    • context.clearRect (x,y,width,height);

其实就是画一个矩形,矩形所在的地方图像消失。

看完这本攻略,Canvas新手小白也可以创建惊人特效

在线玩耍地址:

See the Pencanvas No.1 by cherryvenus (@cherryvenus) onCodePen.

No.2 Canvas的实用工具

Canvas中有几个小知识点,非常的实用,而且应该是日常开发中基本上都要使用的。

看完这本攻略,Canvas新手小白也可以创建惊人特效

Canvas的像素点

首先就是像素的问题,大家有没有遇到过Canvas模糊的问题,尤其是手机,这个现象尤为明显。那么有没有解决方案呢?答案是当然有!而且并不复杂,一个属性就可以搞定!

Canvas的尺寸其实又两个,不知道大家有没有发现。一个时Canvas的大小,一个是Canvas的样式大小。

canvas.width=cWidth
canvas.height=cHeight
canvas.style.width=cWidth
canvas.style.height=cHeight
复制代码

那么这就好解决的。我们的图片如果1:1放在手机上肯定是模的,但是我们会将图片的样式宽度减少一半以上,这样就不模糊了!Canvas也是同理,只要样式大小小于Canvas大小即可。那么小多少呢?有没有一个标准?这个时候就要借用 window.devicePixelRatio 这个参数了,告诉我们屏幕的像素比,如果没有就2,一般来说像素比是2的情况下,Canvas就不会模糊。

const dpr=window.devicePixelRatio||2
canvas.width=cWidth*dpr
canvas.height=cHeight*dpr
canvas.style.width=cWidth
canvas.style.height=cHeight
复制代码

论如何保存Canvas的图像

我们的H5在哪里的传播最多?微信啊!我们经常接到一个功能,让用户保存图片,分享到朋友圈。通常这个图片是用户自己填写内容,然后打印到屏幕上。最后合成,保存的。那么Canvas该如何帮助我们保存图片呢?

Canvas虽然不能直接保存图片,但是却可以生成Base64的文件。我们将Base64放入img标签中,用户就可以自由保存了。

代码也很简单 canvas.toDataURL('image/jpeg');

代码玩耍地址:

See the PenCanvas No.2 by cherryvenus (@cherryvenus) onCodePen.

No.3 save&restore,Canvas的回退功能

Canvas的代码一个不小心就会写好多好多,每次新建一个操作都要写好多内容。这个时候就要看看Canvas的复用操作了,一个是减少操作,还有一个就是减少机器的压力,防止计算量过多。

看完这本攻略,Canvas新手小白也可以创建惊人特效

谈到save&restore,可能大家会有点懵,不知道这个是用来做什么的。也不知道有什么用。我们假想所有的canvas的配置,如fillSytle,strokeStyle的状态都封装在一个对象之中,然后每次save这个对象,就将这个对象push到一个Cavans状态的数组之中,之后我们可能改变了其中的一些属性,然后我们又需要之前的哪个配置,怎么办?再写一遍属性配置吗?不,这个时候我们可以用restore,一键切换至上一个状态。也就是当前的配置全部失效。所有属性值回退到之前的一个状态。我们可以一直restore到默认值,也就是Canvas状态数组空了为止。

代码玩耍地址:

See the Pen Canvas No3 save&restore by cherryvenus (@cherryvenus) onCodePen.

No.4 最常用的drawImage全方位解读

解析图:

看完这本攻略,Canvas新手小白也可以创建惊人特效

个人觉得Canvas中最头疼的就是图片的绘制了,drawImage这个一个方法,就可以帮助我们完成拉伸,剪切,放大,缩小的功能。

drawImage的总参数有9个,但是平时我们可以简写。

第一个参数一定是image,也就是我们的图片对象。其余的几个参数,容易搞混。我们来详细地看下。

参数 作用
dx,dy 这个最好理解,这里是指图片开始绘制的位置,如果设置这两个参数,就是从这个(dx,dy)点开始绘制原始完整的图片
dx,dy,dwidth,dheight 这里除了开始点(dx,dy),还有图片在画布上呈现的大小,这边需要注意,虽然会画完整的图片,但是会按照dwidth和dheight的尺寸来,因此就会产生图片变形的情况。
sx,sy,swidth,sheight,dx,dy,dwidth,dheight 这个比较难以理解,前四个是对原始图片的操作,也就获取原始图片的区域,后四个参数就是图片需要绘制在画布上的位置和大小。也就是图片的所选区域放入画布的所选区域。

玩耍地址:

See the PenCanvas N0.4 by cherryvenus (@cherryvenus) onCodePen.

No5. X炸天的特效

看完这本攻略,Canvas新手小白也可以创建惊人特效
  • mark api:
    • context.getImageData 获取图像信息

这个api是最amazing的方法,因为他帮助我们获取了画布的颜色信息,通过这个信息,我们可以重新创造新的图片。这个方法除了体积大,没啥毛病。因为他的data长度是按照 width(宽)*height(高)*4(rgba四个颜色信息) 组成的。

let info=context.getImageData(x,y,width,height)
//返回
data
width
height
复制代码

这里要避免遍历data( data.forEach ),来处理图片信息,因为很大,浏览器容易卡顿。最好按照定位信息,获取当前坐标的颜色信息。

至于最开始的那个特效,我是借助了matter.js这个库,才能完成的。如果是手写特效的话,不如这个库来的生动有趣。

play地址:

See the Pencanvas No5. COOL by cherryvenus (@cherryvenus) onCodePen.


以上所述就是小编给大家介绍的《看完这本攻略,Canvas新手小白也可以创建惊人特效》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Data Structures and Algorithm Analysis in Java

Data Structures and Algorithm Analysis in Java

Mark A. Weiss / Pearson / 2011-11-18 / GBP 129.99

Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course wa......一起来看看 《Data Structures and Algorithm Analysis in Java》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具