刮刮乐
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0;"> <title>刮刮乐</title> <style type="text/css"> html,body{ width: 100%; height: 100%; margin:0; padding:0; } .view{ position: relative; width: 100%; height: 100%; overflow: hidden; } .box{ position: absolute; left:0; top:0; width: 100%; height: 100%; background:#000 url("擦除后显示的照片") no-repeat center center; background-size: auto 20%; backface-visibility: hidden; overflow: hidden; } #cas{ opacity: 1; -webkit-transition:opacity .5s; -ms-transition:opacity .5s; -moz-transition:opacity .5s; } .noOp{ opacity: 0 !important; } </style> </head> <body> <div class="view"> <div class="box" id="bb"> <canvas id="cas" ></canvas> </div> </div> <script charset="utf-8"> var canvas = document.getElementById("cas"), ctx = canvas.getContext("2d"); var x1, y1, a = 30, timeout, totimes = 100, distance = 30; var saveDot = []; var canvasBox = document.getElementById("bb"); canvas.width = canvasBox.clientWidth; canvas.height = canvasBox.clientHeight; var img = new Image(); img.src = "最前面的照片"; img.onload = function () { var w = canvas.height*img.width/img.height; ctx.drawImage(img, (canvas.width-w)/2, 0, w, canvas.height); tapClip() }; function getClipArea(e, hastouch){ var x = hastouch ? e.targetTouches[0].pageX : e.clientX; var y = hastouch ? e.targetTouches[0].pageY : e.clientY; var ndom = canvas; while(ndom.tagName!=="BODY"){ x -= ndom.offsetLeft; y -= ndom.offsetTop; ndom = ndom.parentNode; } return { x: x, y: y } } //通过修改globalCompositeOperation来达到擦除的效果 function tapClip() { var hastouch = "ontouchstart" in window ? true : false, tapstart = hastouch ? "touchstart" : "mousedown", tapmove = hastouch ? "touchmove" : "mousemove", tapend = hastouch ? "touchend" : "mouseup"; var area; var x2,y2; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.lineWidth = a * 2; ctx.globalCompositeOperation = "destination-out"; window.addEventListener(tapstart, function (e) { clearTimeout(timeout); e.preventDefault(); area = getClipArea(e, hastouch); x1 = area.x; y1 = area.y; drawLine(x1, y1); this.addEventListener(tapmove, tapmoveHandler); this.addEventListener(tapend, function () { this.removeEventListener(tapmove, tapmoveHandler); //检测擦除状态 timeout = setTimeout(function () { var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); var dd = 0; for (var x = 0; x < imgData.width; x += distance) { for (var y = 0; y < imgData.height; y += distance) { var i = (y * imgData.width + x) * 4; if (imgData.data[i + 3] > 0) { dd++ } } } if (dd / (imgData.width * imgData.height / (distance * distance)) < 0.4) { canvas.className = "noOp"; } }, totimes) }); function tapmoveHandler(e) { clearTimeout(timeout); e.preventDefault(); area = getClipArea(e, hastouch); x2 = area.x; y2 = area.y; drawLine(x1, y1, x2, y2); x1 = x2; y1 = y2; } }) } function drawLine(x1, y1, x2, y2){ // ctx.save(); // if(arguments.length==2){ // saveDot = [[x1, y1]]; // ctx.beginPath(); // ctx.arc(x1, y1, a, 0, 2 * Math.PI); // ctx.fill(); // }else { // saveDot.push([x2,y2]); // if(saveDot.length >= 3){ // ctx.beginPath(); // ctx.moveTo(saveDot[0][0], saveDot[0][1]); // ctx.quadraticCurveTo(saveDot[1][0], saveDot[1][1], saveDot[2][0], saveDot[2][1]); // ctx.stroke(); // saveDot = [saveDot.pop()]; // } // } // ctx.restore(); ctx.save(); ctx.beginPath(); if(arguments.length==2){ ctx.arc(x1, y1, a, 0, 2 * Math.PI); ctx.fill(); }else { ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); } ctx.restore(); } //使用clip来达到擦除效果 function otherClip() { var hastouch = "ontouchstart" in window ? true : false, tapstart = hastouch ? "touchstart" : "mousedown", tapmove = hastouch ? "touchmove" : "mousemove", tapend = hastouch ? "touchend" : "mouseup"; var area; canvas.addEventListener(tapstart, function (e) { clearTimeout(timeout); e.preventDefault(); area = getClipArea(e, hastouch); x1 = area.x; y1 = area.y; ctx.save(); ctx.beginPath(); ctx.arc(x1, y1, a, 0, 2 * Math.PI); ctx.clip(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.restore(); canvas.addEventListener(tapmove, tapmoveHandler); canvas.addEventListener(tapend, function () { canvas.removeEventListener(tapmove, tapmoveHandler); timeout = setTimeout(function () { var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); var dd = 0; for (var x = 0; x < imgData.width; x += distance) { for (var y = 0; y < imgData.height; y += distance) { var i = (y * imgData.width + x) * 4; if (imgData.data[i + 3] > 0) { dd++ } } } if (dd / (imgData.width * imgData.height / (distance * distance)) < 0.4) { canvas.className = "noOp"; } }, totimes) }); function tapmoveHandler(e) { e.preventDefault(); area = getClipArea(e, hastouch); x2 = area.x; y2 = area.y; var asin = a * Math.sin(Math.atan((y2 - y1) / (x2 - x1))); var acos = a * Math.cos(Math.atan((y2 - y1) / (x2 - x1))); var x3 = x1 + asin; var y3 = y1 - acos; var x4 = x1 - asin; var y4 = y1 + acos; var x5 = x2 + asin; var y5 = y2 - acos; var x6 = x2 - asin; var y6 = y2 + acos; ctx.save(); ctx.beginPath(); ctx.arc(x2, y2, a, 0, 2 * Math.PI); ctx.clip(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.restore(); ctx.save(); ctx.beginPath(); ctx.moveTo(x3, y3); ctx.lineTo(x5, y5); ctx.lineTo(x6, y6); ctx.lineTo(x4, y4); ctx.closePath(); ctx.clip(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.restore(); x1 = x2; y1 = y2; } }) } </script></body></html>