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 相关文章推荐
JavaScript 高级语法介绍
Jun 15 Javascript
javascript下高性能字符串连接StringBuffer类
Aug 16 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
Mar 01 Javascript
jQuery截取指定长度字符串的实现原理及代码
Jul 01 Javascript
React.js入门实例教程之创建hello world 的5种方式
May 11 Javascript
最实用的jQuery分页插件
Oct 09 Javascript
详解Weex基于Vue2.0开发模板搭建
Mar 20 Javascript
详解require.js配置路径的用法和css的引入
Sep 06 Javascript
详解vue引入子组件方法
Feb 12 Javascript
Vue框架下引入ActiveX控件的问题解决
Mar 25 Javascript
js常见遍历操作小结
Jun 06 Javascript
JavaScript常用工具函数大全
May 06 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在多维数组中根据键名快速查询其父键以及父键值的代码
2011/05/07 PHP
PHP文件锁函数flock()详细介绍
2014/11/18 PHP
PHP多进程编程总结(推荐)
2016/07/18 PHP
javascript基本语法分析说明
2008/06/15 Javascript
javascript下高性能字符串连接StringBuffer类
2010/08/16 Javascript
基于jquery自定义的漂亮单选按钮RadioButton
2013/11/19 Javascript
js中substring和substr的定义和用法
2014/05/05 Javascript
谈谈JSON对象和字符串之间的相互转换JSON.stringify(obj)和JSON.parse(string)
2015/10/01 Javascript
js操作DOM--添加、删除节点的简单实例
2016/07/08 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
jQuery元素选择器实例代码
2017/02/06 Javascript
Vue2.0实现将页面中表格数据导出excel的实例
2017/08/09 Javascript
Nuxt.js实战详解
2018/01/18 Javascript
Vue精简版风格指南(推荐)
2018/01/30 Javascript
jQuery简单实现根据日期计算星期几的方法
2019/01/09 jQuery
Vue父子传递实例讲解
2020/02/14 Javascript
[41:21]夜魇凡尔赛茶话会 第三期02:看图识人
2021/03/11 DOTA
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
教你学会使用Python正则表达式
2017/09/07 Python
tensorflow训练中出现nan问题的解决
2018/02/10 Python
python实现合并两个排序的链表
2019/03/03 Python
python pandas时序处理相关功能详解
2019/07/03 Python
python2 对excel表格操作完整示例
2020/02/23 Python
python绘制玫瑰的实现代码
2020/03/02 Python
基于PyQT实现区分左键双击和单击
2020/05/19 Python
canvas绘制表情包的示例代码
2018/07/09 HTML / CSS
松本清官方海外旗舰店:日本最大的药妆连锁店
2017/11/21 全球购物
大学生村官事迹材料
2014/01/21 职场文书
销售员求职个人的自我评价
2014/02/19 职场文书
股东合作协议书
2014/04/14 职场文书
学生会主席演讲稿
2014/04/25 职场文书
学校春季防火方案
2014/06/08 职场文书
力学专业求职信
2014/07/23 职场文书
公司向个人借款协议书范本
2014/10/09 职场文书
个人查摆问题及整改措施
2014/10/16 职场文书
CSS3 制作精美的定价表
2021/04/06 HTML / CSS