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 Event学习第六章 事件的访问
Feb 07 Javascript
Jquery 1.42 checkbox 全选和反选代码
Mar 27 Javascript
javascript两种function的定义介绍及区别说明
May 02 Javascript
jQuery性能优化的38个建议
Mar 04 Javascript
jQuery使用post方法提交数据实例
Mar 25 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
Sep 04 Javascript
JavaScript中对象的不同创建方法
Aug 12 Javascript
Angular2 PrimeNG分页模块学习
Jan 14 Javascript
underscore之function_动力节点Java学院整理
Jul 11 Javascript
JavaScript实现多重继承的方法分析
Jan 09 Javascript
Vue绑定用户接口实现代码示例
Nov 04 Javascript
详解Vue的options
May 15 Vue.js
浅谈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中获取主机名、协议及IP地址的方法
2014/11/18 PHP
PHP图像裁剪缩略裁切类源码及使用方法
2016/01/07 PHP
Joomla框架实现字符串截取的方法示例
2017/07/18 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
TP5(thinkPHP5框架)实现显示错误信息及行号功能的方法
2019/06/03 PHP
JavaScript Array Flatten 与递归使用介绍
2011/10/30 Javascript
JQuery筛选器全系列介绍
2013/08/27 Javascript
如何在指定的地方插入html内容和文本内容
2013/12/23 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
2014/02/07 Javascript
JavaScript编程中容易出BUG的几点小知识
2015/01/31 Javascript
JS实现鼠标箭头变成一个燃烧烛光效果的方法
2015/02/28 Javascript
js脚本分页代码分享(7种样式)
2015/08/19 Javascript
果断收藏9个Javascript代码高亮脚本
2016/01/06 Javascript
基于 Node.js 实现前后端分离
2016/04/23 Javascript
AngularJS Bootstrap详细介绍及实例代码
2016/07/28 Javascript
JavaScript鼠标事件,点击鼠标右键,弹出div的简单实例
2016/08/03 Javascript
简单实现JS计算器功能
2016/12/21 Javascript
vue2.x集成百度UEditor富文本编辑器的方法
2018/09/21 Javascript
vue使用高德地图根据坐标定位点的实现代码
2019/08/22 Javascript
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
jQuery+ajax实现文件上传功能
2020/12/22 jQuery
python访问mysql数据库的实现方法(2则示例)
2016/01/06 Python
解决项目pycharm能运行,在终端却无法运行的问题
2019/01/19 Python
OpenCV 边缘检测
2019/07/10 Python
Python Web静态服务器非堵塞模式实现方法示例
2019/11/21 Python
HTML5的结构和语义(1):前言
2008/10/17 HTML / CSS
Lookfantastic香港官网:英国知名美妆购物网站
2018/06/19 全球购物
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
大学生职业生涯规划书范文
2014/01/04 职场文书
初三家长会邀请函
2014/01/18 职场文书
婚前财产公证书
2014/04/10 职场文书
男性健康日的活动方案
2014/08/18 职场文书
银行竞聘上岗演讲稿
2014/09/12 职场文书
2014年人事科工作总结
2014/11/19 职场文书
法制教育观后感
2015/06/17 职场文书
大学生奶茶店创业计划书
2019/06/25 职场文书