引子

解决了第一个问题图像灰度处理之后,接着就是做擦除的效果。

思路

一开始想到 Canvas 的画布可以相互覆盖的特性,彩色原图作为背景,灰度图渲染到 Canvas 画布上,然后手指滑动的时候,把接触的部分清除掉,就显示出了背景图。关键的部分是怎么清除画布上已有图像,查询资料发现有两种方式:

  1. 使用 clearRect 方法,会把指定范围所有像素变成透明,并擦除之前绘制的所有内容。
  2. 使用 globalCompositeOperation 属性,该属性设置在绘制新形状时应用合成操作的类型,值为 destination-out 时效果如下:

在上面两种方式中,第一种方式正是功能实现所需要的,但擦除时的边角效果没有第二种方式理想。下面以第二种方式作为示例。

实现

在实现的过程中,发现有几点需要注意:

  • 手机端高清显示处理。
  • 注意 globalCompositeOperation 属性设置的时机,过早设置,可能画布上无法显示内容。
  • 擦除状态的控制,特别是在 PC 端,如果不设置相应状态,鼠标移动的时候就可能发生擦除。

这是示例页面,移动端访问如下:

优化一

一般用户都不会全部进行擦除,而且这种体验也不好,所以擦除面积达到一定百分比时,自动擦除剩余的部分。

擦除效果实际上是改变了已有图像的透明度,可以通过 getImageData 方法查看 Canvas 上图像的像素数据。通过统计符合透明度要求的像素所占百分比,就等效擦除面积的百分比。至于透明度多少算擦除有效,看实际应用场景和所需效果。下面是主要的实现:

  /**
* 获取透明所占百分比,返回一个 <= 1 的值
* @param {object} context canvas 上下文对象
* @param {number} opacity 透明度参考值,初始参考透明值是 128
*/
function getOpacityPercentage (context, opacity = 128) {
var imageData = context.getImageData(0,0,248,415);
var colorDataArr = imageData.data;
var colorDataArrLen = colorDataArr.length;
var eraseArea = [];
// rgba 显示的模式,所以一个像素表示有 4 个分量,透明度是最后一个分量
for(var i = 0; i < colorDataArrLen; i += 4) {
// 严格上来说,判断像素点是否透明需要判断该像素点的 a 值是否等于0,
if(colorDataArr[i + 3] < opacity) {
eraseArea.push(colorDataArr[i + 3]);
}
}
var divResult = eraseArea.length / (colorDataArrLen/4);
// 处理除不尽的情况
var pointIndex = String(divResult).indexOf('.');
if (pointIndex>-1) {
divResult = String(divResult).slice(0,pointIndex+5);
}
return Number(divResult).toFixed(2); }

这是示例页面,移动端访问如下:

优化二

优化一中擦除全部的效果是一下子就不见了,但我在那个游戏里面看到的擦除效果是有一个过程的。于是再折腾了一下。

这是示例页面,移动端访问如下:

参考资料

Canvas 橡皮擦效果的更多相关文章

  1. 2015.4.25-2015.5.1 字符串去重,比例圆设计,中奖机和canvas橡皮擦效果等

    1.字符串去重,html模板取值   2.javascript正则表达式之$1...$9   3.jquery插件   4.返回上一页并刷新 解决方法: <a href ="javas ...

  2. canvas 橡皮擦效果制作

    擦除一定数量后全部消失的有用 imageData 方法的 我把代码贴在最下面 <!DOCTYPE html> <html> <head> <meta char ...

  3. Unity 实现橡皮擦效果

    我所实现的橡皮擦效果是设置图片某点的像素的透明度为0,来简单实现擦除效果的: 下面是效果 首先需要注意两点:1:设置 Main Camera 的 projection 属性为Orthographic ...

  4. CodePen 作品秀:Canvas 粒子效果文本动画

    作品名称——Shape Shifter,基于 Canvas 的粒子图形变换实验.在页面下方的输入框输入文本,上面就会进行变换出对应的粒子效果文本动画. CodePen 作品秀系列向大家展示来自 Cod ...

  5. HTML5 Canvas动画效果演示

    HTML5 Canvas动画效果演示 主要思想: 首先要准备一张有连续帧的图片,然后利用HTML5 Canvas的draw方法在不同的时间 间隔绘制不同的帧,这样看起来就像动画在播放. 关键技术点: ...

  6. HTML5 Canvas动画效果演示 - 流浪的鱼 - 博客频道 - CSDN.NET

    HTML5 Canvas动画效果演示 - 流浪的鱼 - 博客频道 - CSDN.NET HTML5 Canvas动画效果演示

  7. HTML5 Canvas动画效果实现原理

    在线演示 使用HTML5画布可以帮助我们高速实现简单的动画效果.基本原理例如以下: 每隔一定时间绘制图形而且清除图形,用来模拟出一个动画过程,能够使用context.clearRect(0, 0, x ...

  8. HTML5 Canvas时间效果

    Canvas 时间效果: function clockTest() { var canvas = document.getElementById('canvas'); if (!(canvas &am ...

  9. canvas可视化效果之内阴影效果

    canvas可视化效果之内阴影效果 楔子 在之前的一个轨道交通可视化项目中,运用到了很多绘制技巧. 可以参考 之前的一篇文章 <利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果> ...

随机推荐

  1. css文本强制两行超出就显示省略号,不显示省略号

    1. 强制一行的情况很简单 overflow:hidden; //超出的隐藏 text-overflow:ellipsis; //省略号 white-space:nowrap; //强制一行显示 2. ...

  2. 【LeetCode】验证二叉搜索树

    [问题]给定一个二叉树,判断其是否是一个有效的二叉搜索树. 假设一个二叉搜索树具有如下特征:节点的左子树只包含小于当前节点的数.节点的右子树只包含大于当前节点的数.所有左子树和右子树自身必须也是二叉搜 ...

  3. java课程之团队开发冲刺阶段2.5

    总结昨天进度: 1.昨天对课前提醒的基本框架已经搭好,剩下的就是对如何提醒进行设置 遇到的困难: 1.在一些细节地方,代码有点犯浑,将Preferences的文件写错了,导致在用switch开关得到时 ...

  4. 【转】CSS实现自适应分隔线的N种方法

    1.伪元素+transform:translateX(-100%); 主要原理是设置文本居中text-align: center;,然后给定两个伪元素,分别绝对定位,那么此时伪元素也是跟随着水平居中的 ...

  5. python刷LeetCode:13. 罗马数字转整数

    难度等级:简单 题目描述: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II  ...

  6. P3241 [HNOI2015]开店

    题解:动态点分治 建立点分树 每个点维护点分树子树内节点到这个节点和父亲节点距离的前缀和 二分查找锁定合法区间 对每个祖先分治中心查询路径和然后减去不合法子树内的路径和 注意:求大量LCA时用树剖 不 ...

  7. JSP变量、方法和类的声明,JSP程序片,JSP表达式

    参考文章 http://c.biancheng.net/view/1431.html http://c.biancheng.net/view/1433.html http://c.biancheng. ...

  8. Git 小课堂 002——别名

    昨天我们聊了聊 Git 的文件存储,今天我们聊聊 Git 的别名.不知道你是不是熟悉别名,如果你经常使用命令行做一些事情,有一些复杂的命令,或者是一些简单的操作,往往用一些别名方法就很方便很容易,下面 ...

  9. logrus日志框架

    目录 logrus介绍 logrus配置 日志打印 HOOK机制 Gin日志 Fatal处理 线程安全 logrus介绍 golang标准库的日志框架非常简单,仅仅提供了print,panic和fat ...

  10. 7)给tab下面添加一个子非模态对话框

    1)还是沿袭(6)那个代码 2)下面是步骤: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·~~~~~~~~~~~~~~~~~~~~~~~~~~~ 然后,修改这个对 ...