Canvas 橡皮擦效果

引子

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

思路

一开始想到 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);

  }

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

优化二

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

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

参考资料

原文地址:https://www.cnblogs.com/thyshare/p/12272855.html

时间: 2024-08-29 10:16:46

Canvas 橡皮擦效果的相关文章

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

1.字符串去重,html模板取值 2.javascript正则表达式之$1...$9 3.jquery插件 4.返回上一页并刷新 解决方法: <a href ="javascript:location.href=document.referrer;"> 5.用webstorm写的手机网站 怎样能用手机预览呢? 解决方法:布署到wamp,xamp,iis上,然后用浏览器生成二维码,扫一扫就可以打开.假如是javaweb项目,挂上tomcat手机直接访问你机子的ip. 6.比例

canvas 橡皮擦效果制作

擦除一定数量后全部消失的有用 imageData 方法的 我把代码贴在最下面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> body{ overflow: hidden; } #canvas{ display: block; margin: 0

Unity 实现橡皮擦效果

我所实现的橡皮擦效果是设置图片某点的像素的透明度为0,来简单实现擦除效果的: 下面是效果 首先需要注意两点:1:设置 Main Camera 的 projection 属性为Orthographic 2:设置Canvas 的Render Mode 为 Screen Space - Camera 然后找一张图片,导入Unity 中并修改它的读写权限,创建Raw Imager 这样启动之后就可以测试效果了. 附上代码:(代码中有解释) 1 using AYUI.UIFrame; 2 using DG

HTML5 Canvas动画效果实现原理

在线演示 使用HTML5画布可以帮助我们高速实现简单的动画效果.基本原理例如以下: 每隔一定时间绘制图形而且清除图形,用来模拟出一个动画过程,能够使用context.clearRect(0, 0, x, y)方法来刷新须要绘制的图形 首先是绘制图形的方法,例如以下: function myAnimation() { ctx.clearRect(0, 0, canvas_size_x, canvas_size_y); if (x_icon < 0 || x_icon > canvas_size_

Cocos2dx 实现擦除即橡皮擦效果的实现

Cocos2dx实现橡皮擦效果的实现 DionysosLai([email protected])  2014/8/25 之前项目在做一个绘本游戏,要求实现擦除效果,具体效果可以参考绘本<我是一只暴龙>,当时由于项目比较紧,是直接拿网上代码来用(感谢仁兄Zrong的入门之引,具体博文,详见地址,http://zengrong.net/post/2067.htm).当时,没有对其做一些具体优化工作,一些原理,也是似懂非懂.今天,在工作之余,重写了代码,并从始至末将知识点理清楚,务必要求自己能够搞

canvas仪表盘效果

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>canvas仪表盘动画效果</title> <style type="text/css"> html, body { width: 100%; height: 100%; margin: 0; } canvas { display: none; border: 1p

HTML5 canvas流体力学效果

某人用Java搞了一个流体力学的演示:http://grantkot.com/MPM/Liquid.html. 下面是 HTML 5版的流体力学演示(推荐使用Chrome浏览器浏览): 效果演示 <canvas width="400" height="400" id="liquid"></canvas><script> /** * This version: * Copyright Stephen Sincla

基于HTML5 Canvas粒子效果文字动画特效

之前我们分享过很多超酷的文字特效,其中也有利用HTML5和CSS3的.今天我们要来分享一款基于HTML5 Canvas的文字特效,输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的文字动画,相当酷的动画效果. 在线预览   源码下载 实现的代码. html代码: <canvas class="canvas"></canvas> <div class="help"> ?</div> <div c

7个惊艳的HTML5 Canvas动画效果及源码

HTML5非常强大,尤其是现在大部分浏览器都支持HTML5和CSS3,用HTML5制作的动画也多了起来.另外,Canvas上绘制图形非常简单,本文就分享了一些强大的HTML5 Cnavas动画,一起来看看. 1.HTML5 Canvas瀑布动画 超逼真 这是一个很逼真的HTML5瀑布动画,基于Canvas实现的,效果相当酷. 在线演示   /   源码下载 2.HTML5 Canvas彩色像素进度条动画 这也是一款基于HTML5 Canvas的动画特效,它是一个很有创意的HTML5进度条,大家可