canvas教程

使用CANVAS实现交互性圆形马赛克效果(2)

字号+ 作者:H5之家 来源:H5之家 2017-01-06 16:00 我要评论( )

关于 _getColor() 函数,这里使用了 CanvasRenderingContext2D.getImageData() : CircleSplit.prototype._getColor = function (x, y) {...var pixelData = this.sourceCanvas.getContext(2d).getImageData(parseI

关于 _getColor() 函数,这里使用了 CanvasRenderingContext2D.getImageData() :

CircleSplit.prototype._getColor = function (x, y) { ... var pixelData = this.sourceCanvas.getContext('2d').getImageData(parseInt(x), parseInt(y), 1, 1).data; return 'rgb(' + pixelData[0] + ',' + pixelData[1] + ',' + pixelData[2] + ')'; }

如下图:

假设左上角起始点为(x, y),一个方格为一个像素,那么 getImageData(x, y, 1, 1).data 就会返回 [255,0,0,255] ,代表Red=255,Alpha=255。如果 getImageData(x, y, 2, 2).data 就会返回 [255,0,0,255, 255,0,0,255, 255,0,0,255, 255,0,0,255] 长度为16的数组,每4个为一组代表一个像素上的rgba值。 getImageData() 就是一个能帮助我们对canvas进行像素级别操作的API函数。

一些基于canvas的“刮刮卡”插件,也是 getImageData() 的应用:在图片上绝对定位一个灰色的canvas,代表刮刮卡蒙层;通过对手指触摸的像素点的alpha值进行修改来实现被“刮“开的效果。当然这里的修改需要使用到配套的 putImageData() 函数;同时对整个canvas像素中alpha值为0的像素点的百分比 进行统计,可以完成刮开了80%就展示全部图片的效果。

实现

上面是大致的实现思路,和编码的思想过程。为了表达出我自己在完成一个功能的时候,是如何从无到有,定义属性,定义API的。只是自己的一点经验,希望有帮助。

如果你对这些知识不熟悉,却也感兴趣的话,可以参考该项目 代码

问题与优化

github上的代码与上面讲的思路一致,但是会有些不一样,主要是在功能实现之后,发现了一个需要优化的地方。

渲染速度在 _render() 渲染循环中,我们对所有的circles进行遍历。但是当整副图片分裂次数很彻底时,会有上万个圆,会导致每个渲染循环里的计算时间过长,导致下一个渲染循环在理想的时间后才执行,从而导致了卡顿的感觉。于是为了解决这个问题,引入了 renderingCircles 数组,将被标记的circle全部插入这个数组中,渲染循环中只关心这里的值,用额外的存储空间换更短的计算时间。

显示模糊最先的实现中,两个canvas得尺寸是根据mountNode决定的, canvas.width `canvas.height`被设为和mountNode一样的维度值。于是在一些设备上显示出明显的边缘锯齿。这里的解决方案就是设置canvas的宽和高为两倍于mountNode的宽高,然后通过style去设置canvas显示成和mountNode一样的尺寸。这里就是canvas的自身的宽高属性和canvas style的宽高之前的区别的理解和应用。

图片跨域问题

在canvas操作图片时,可能会碰到这样的错误信息:Unable to get image data from canvas because the canvas has been tainted by cross-origin data.

关于这个的 官方解释 是:在canvas上可以绘制没有跨域许可的图片资源(images without CORS approval),但是这样做会“感染(taints)”的canvas,而在感染的(tainted)canvas上调用 toBlog() , toDataURL() , getImageData() 会抛出上面的安全方面的错误。

在 CircleSplit.setImage(imageUrl) 时,可能就会碰到这个问题。

解决方案,首先需要图片有跨域许可。这个需要在提供图片服务的server上进行配置。这里不多介绍,有跨域许可的图片被加载时,在控制台上应该能看到:(这里我使用的七牛的图片)

其次,需要在加载图片时,设置crossOrigin属性:

var image = new Image(); image.crossOrigin = 'anonymous'; image.onload = function () {}; image.src = imageUrl; 应用

其实个人很喜欢最后完成的交互效果(有点强迫症,喜欢不断的戳掉泡泡),于是将这个小效果做了一个简单的H5页面,在年底这个时间点里,讲述和回顾在2016年的大事件。你也可以来体验下: 2016-recap


分享给小伙伴们:

本文标签: CANVAS/">CANVAS

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

  • 本类最热新闻

  •  

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • Android开发面试题:Drawable、Bitmap、Canvas和Paint的关系

      Android开发面试题:Drawable、Bitmap、Canvas和Paint的关系

      2017-01-06 16:02

    • 3样章.pdf.pdf 全文免费在线阅读

      3样章.pdf.pdf 全文免费在线阅读

      2017-01-06 15:01

    • canvas如何转存为图片!

      canvas如何转存为图片!

      2017-01-06 14:06

    • 【网盘资源】HTML5 Canvas核心技术 图形、动画与游戏开发.pdf

      【网盘资源】HTML5 Canvas核心技术 图形、动画与游戏开发.pdf

      2017-01-06 14:06

    网友点评
    0