js canvas实现橡皮擦效果


Posted in Javascript onDecember 20, 2018

本文实例为大家分享了canvas实现橡皮擦效果的具体代码,供大家参考,具体内容如下

html部分

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8" />
<meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 
<title>My Canvas 0.1</title>
<style type="text/css">
html,body,div,img{
 margin:0;
 padding:0;
}
a,a:hover{
 text-decoration:none;
}
.background{
 width:100%;
 position:fixed;
 top:0;
 left:0;
}
</style>
</head>
 
<body>
<img src="images/background.png" class="background resizeContainer"/>
<div id="J_cover" class="resizeContainer"></div>
<script type="text/javascript" src="js/zepto.js"></script>
<script type="text/javascript" src="js/lottery.js"></script>
<script type="text/javascript">
var canvas = {
 init : function(){
 var self = this;
 var node = document.getElementById('J_cover'),
 canvas_url = 'images/cover.png',
 type = 'image';
 
 var lottery = new Lottery(node, canvas_url, type, window_w, window_h, self.callback);
  lottery.init();
 },
 callback : function(){
 $('#J_cover').hide();
 }
}
var window_h, window_w;
$(document).ready(function(){
 window_w = $(window).width();
 window_h = $(window).height();
 
 $('.resizeContainer').width(window_w).height(window_h);
 
 canvas.init();
});
</script>
</body>
</html>

lottery.js

function Lottery(node, cover, coverType, width, height, drawPercentCallback) {
//node:canvas的id,cover:上面一层的图片地址,coverType:'image'or'color',width:canvas宽, height:canvas高, drawPercentCallback:回调函数
 //canvas
 this.conNode = node;
 
 this.background = null;
 this.backCtx = null;
 
 this.mask = null;
 this.maskCtx = null;
 
 this.lottery = null;
 this.lotteryType = 'image';
 
 this.cover = cover || "#000";
 this.coverType = coverType;
 this.pixlesData = null;
 
 this.width = width;
 this.height = height;
 
 this.lastPosition = null;
 this.drawPercentCallback = drawPercentCallback;
 
 this.vail = false;
}
 
Lottery.prototype = {
 createElement: function(tagName, attributes) {
  var ele = document.createElement(tagName);
  for (var key in attributes) {
   ele.setAttribute(key, attributes[key]);
  }
  return ele;
 },
 
 getTransparentPercent: function(ctx, width, height) {
  var imgData = ctx.getImageData(0, 0, width, height),
   pixles = imgData.data,
   transPixs = [];
 
  for (var i = 0, j = pixles.length; i < j; i += 4) {
   var a = pixles[i + 3];
   if (a < 128) {
    transPixs.push(i);
   }
  }
  return (transPixs.length / (pixles.length / 4) * 100).toFixed(2);
 },
 
 resizeCanvas: function(canvas, width, height) {
  canvas.width = width;
  canvas.height = height;
  canvas.getContext('2d').clearRect(0, 0, width, height);
 },
 
 resizeCanvas_w: function(canvas, width, height) {
  canvas.width = width;
  canvas.height = height;
  canvas.getContext('2d').clearRect(0, 0, width, height);
 
  if (this.vail) this.drawLottery();
  else this.drawMask();
 },
 
 drawPoint: function(x, y, fresh) {
  this.maskCtx.beginPath();
  this.maskCtx.arc(x, y, 20, 0, Math.PI * 2);
  this.maskCtx.fill();
 
  this.maskCtx.beginPath();
 
  this.maskCtx.lineWidth = 60;
  this.maskCtx.lineCap = this.maskCtx.lineJoin = 'round';
 
  if (this.lastPosition) {
   this.maskCtx.moveTo(this.lastPosition[0], this.lastPosition[1]);
  }
  this.maskCtx.lineTo(x, y);
  this.maskCtx.stroke();
 
  this.lastPosition = [x, y];
 
  this.mask.style.zIndex = (this.mask.style.zIndex == 20) ? 21 : 20;
 },
 
 bindEvent: function() {
  var _this = this;
  var device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
  var clickEvtName = device ? 'touchstart' : 'mousedown';
  var moveEvtName = device ? 'touchmove' : 'mousemove';
  if (!device) {
   var isMouseDown = false;
   _this.conNode.addEventListener('mouseup', function(e) {
    e.preventDefault();
 
    isMouseDown = false;
    var per = _this.getTransparentPercent(_this.maskCtx, _this.width, _this.height);
 
    if (per >= 80) {//在大于等于80%的时候调用回调函数
     if (typeof(_this.drawPercentCallback) == 'function') _this.drawPercentCallback();
    }
   }, false);
  } else {
   _this.conNode.addEventListener("touchmove", function(e) {
    if (isMouseDown) {
     e.preventDefault();
    }
    if (e.cancelable) {
     e.preventDefault();
    } else {
     window.event.returnValue = false;
    }
   }, false);
   _this.conNode.addEventListener('touchend', function(e) {
    isMouseDown = false;
    var per = _this.getTransparentPercent(_this.maskCtx, _this.width, _this.height);
    if (per >= 80) {//在大于等于80%的时候调用回调函数
     if (typeof(_this.drawPercentCallback) == 'function') _this.drawPercentCallback();
    }
   }, false);
  }
 
  this.mask.addEventListener(clickEvtName, function(e) {
   e.preventDefault();
 
   isMouseDown = true;
 
   var x = (device ? e.touches[0].pageX : e.pageX || e.x);
   var y = (device ? e.touches[0].pageY : e.pageY || e.y);
 
   _this.drawPoint(x, y, isMouseDown);
  }, false);
 
  this.mask.addEventListener(moveEvtName, function(e) {
   e.preventDefault();
 
   if (!isMouseDown) return false;
   e.preventDefault();
 
   var x = (device ? e.touches[0].pageX : e.pageX || e.x);
   var y = (device ? e.touches[0].pageY : e.pageY || e.y);
 
   _this.drawPoint(x, y, isMouseDown);
  }, false);
 },
 
 drawLottery: function() {
  if (this.lotteryType == 'image') {
   var image = new Image(),
    _this = this;
   image.onload = function() {
    this.width = _this.width;
    this.height = _this.height;
    _this.resizeCanvas(_this.background, _this.width, _this.height);
    _this.backCtx.drawImage(this, 0, 0, _this.width, _this.height);
    _this.drawMask();
   }
   image.src = this.lottery;
  } else if (this.lotteryType == 'text') {
   this.width = this.width;
   this.height = this.height;
   this.resizeCanvas(this.background, this.width, this.height);
   this.backCtx.save();
   this.backCtx.fillStyle = '#FFF';
   this.backCtx.fillRect(0, 0, this.width, this.height);
   this.backCtx.restore();
   this.backCtx.save();
   var fontSize = 30;
   this.backCtx.font = 'Bold ' + fontSize + 'px Arial';
   this.backCtx.textAlign = 'center';
   this.backCtx.fillStyle = '#F60';
   this.backCtx.fillText(this.lottery, this.width / 2, this.height / 2 + fontSize / 2);
   this.backCtx.restore();
   this.drawMask();
  }
 },
 
 drawMask: function() {
  if (this.coverType == 'color') {
   this.maskCtx.fillStyle = this.cover;
   this.maskCtx.fillRect(0, 0, this.width, this.height);
   this.maskCtx.globalCompositeOperation = 'destination-out';
  } else if (this.coverType == 'image') {
   var image = new Image(),
    _this = this;
   image.onload = function() {
    _this.resizeCanvas(_this.mask, _this.width, _this.height);
 
    var android = (/android/i.test(navigator.userAgent.toLowerCase()));
 
    _this.maskCtx.globalAlpha = 1;//上面一层的透明度,1为不透明
    _this.maskCtx.drawImage(this, 0, 0, this.width, this.height, 0, 0, _this.width, _this.height);
 
    //---以下一段为在上面一层上写字
    // var fontSize = 50;
    // var txt = '123123';
    // var gradient = _this.maskCtx.createLinearGradient(0, 0, _this.width, 0);
    // gradient.addColorStop("0", "#fff");
    // gradient.addColorStop("1.0", "#000");
 
    // _this.maskCtx.font = 'Bold ' + fontSize + 'px Arial';
    // _this.maskCtx.textAlign = 'left';
    // _this.maskCtx.fillStyle = gradient;
    // _this.maskCtx.fillText(txt, _this.width / 2 - _this.maskCtx.measureText(txt).width / 2, 100);
 
    // _this.maskCtx.globalAlpha = 1;
 
    _this.maskCtx.globalCompositeOperation = 'destination-out';
   }
   image.src = this.cover;
  }
 },
 
 init: function(lottery, lotteryType) {
  if (lottery) {
   this.lottery = lottery;
   this.lottery.width = this.width;
   this.lottery.height = this.height;
   this.lotteryType = lotteryType || 'image';
 
   this.vail = true;
  }
  if (this.vail) {
   this.background = this.background || this.createElement('canvas', {
    style: 'position:fixed;top:0;left:0;background-color:transparent;'
   });
  }
 
  this.mask = this.mask || this.createElement('canvas', {
   style: 'position:fixed;top:0;left:0;background-color:transparent;'
  });
  this.mask.style.zIndex = 20;
 
  if (!this.conNode.innerHTML.replace(/[\w\W]| /g, '')) {
   if (this.vail) this.conNode.appendChild(this.background);
   this.conNode.appendChild(this.mask);
   this.bindEvent();
  }
  if (this.vail) this.backCtx = this.backCtx || this.background.getContext('2d');
  this.maskCtx = this.maskCtx || this.mask.getContext('2d');
 
  if (this.vail) this.drawLottery();
  else this.drawMask();
 
  var _this = this;
  window.addEventListener('resize', function() {
   _this.width = document.documentElement.clientWidth;
   _this.height = document.documentElement.clientHeight;
 
   _this.resizeCanvas_w(_this.mask, _this.width, _this.height);
  }, false);
 }
}

另一个zepto.js是库函数文件,可网上自行查找

出来的效果如图

js canvas实现橡皮擦效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
可输入的下拉框
Jun 19 Javascript
Jquery 1.42 checkbox 全选和反选代码
Mar 27 Javascript
解决ExtJS在chrome或火狐中正常显示在ie中不显示的浏览器兼容问题
Jan 11 Javascript
Js与Jq 获取页面元素值的方法和差异对比
Apr 30 Javascript
用NODE.JS中的流编写工具是要注意的事项
Mar 01 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
Feb 24 Javascript
图文介绍Vue父组件向子组件传值
Feb 17 Javascript
Vue.js中关于侦听器(watch)的高级用法示例
May 02 Javascript
vue 2.5.1 源码学习 之Vue.extend 和 data的合并策略
Jun 04 Javascript
使用jquery-easyui的布局layout写后台管理页面的代码详解
Jun 19 jQuery
搭建Vue从Vue-cli到router路由护卫的实现
Nov 14 Javascript
5个你不知道的JavaScript字符串处理库(小结)
Jun 01 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
Dec 20 #Javascript
Cocos2d实现刮刮卡效果
Dec 20 #Javascript
浅谈Fetch 数据交互方式
Dec 20 #Javascript
cocos2dx+lua实现橡皮擦功能
Dec 20 #Javascript
element-ui table span-method(行合并)的实现代码
Dec 20 #Javascript
fetch 如何实现请求数据
Dec 20 #Javascript
JS闭包经典实例详解
Dec 20 #Javascript
You might like
用PHP和MySQL保存和输出图片
2006/10/09 PHP
mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别
2009/04/24 PHP
解析PHP 使用curl提交json格式数据
2013/06/29 PHP
PHP获取中国时间(上海时区时间)及美国时间的方法
2017/02/23 PHP
laravel自定义分页效果
2017/07/23 PHP
关于document.cookie的使用javascript
2008/04/11 Javascript
Jquery作者John Resig自己封装的javascript 常用函数
2009/11/09 Javascript
js更优雅的兼容
2010/08/12 Javascript
鼠标经过tr时,改变tr当前背景颜色
2014/01/13 Javascript
jQuery动画特效实例教程
2014/08/29 Javascript
jquery实现鼠标滑过显示二级下拉菜单效果
2015/08/24 Javascript
javascript仿百度输入框提示自动下拉补全
2016/01/07 Javascript
JavaScript事件 &quot;事件对象&quot;的注意要点
2016/01/14 Javascript
jQuery遍历DOM节点操作之filter()方法详解
2016/04/14 Javascript
jQuery实现简单弹窗遮罩效果
2017/02/27 Javascript
jQuery插件zTree实现的基本树与节点获取操作示例
2017/03/08 Javascript
微信小程序 Animation实现图片旋转动画示例
2018/08/22 Javascript
javacript replace 正则取字符串中的值并替换【推荐】
2018/09/13 Javascript
JavaScript 对引擎、运行时、调用堆栈的概述理解
2018/10/22 Javascript
详解Vue源码中一些util函数
2019/04/24 Javascript
基于vue 实现表单中password输入的显示与隐藏功能
2019/07/19 Javascript
JavaScript实现京东放大镜效果
2019/12/03 Javascript
JavaScript数组去重实现方法小结
2020/01/17 Javascript
js面试题之异步问题的深入理解
2020/09/20 Javascript
[56:21]LGD vs IG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
深入理解Python中的内置常量
2017/05/20 Python
python处理按钮消息的实例详解
2017/07/11 Python
Python Socket实现简单TCP Server/client功能示例
2017/08/05 Python
详解Python学习之安装pandas
2019/04/16 Python
python 无损批量压缩图片(支持保留图片信息)的示例
2020/09/22 Python
Paradox London官方网站:英国新娘鞋婚礼鞋品牌
2019/08/29 全球购物
无工作经验者个人求职信范文
2013/12/22 职场文书
2014年话务员工作总结
2014/11/19 职场文书
女方家长婚礼答谢词
2015/09/29 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书
Java Spring读取和存储详细操作
2022/08/05 Java/Android