scratchers
Version:
经典刮刮卡库, [效果预览](https://codepen.io/liejiayong/pen/eYpOypR)
2 lines (1 loc) • 7.87 kB
JavaScript
"use strict";function t(t){var e=document.createElement("div"),i=function(){for(var t in{webkit:"webkitTransform",Moz:"MozTransform",O:"OTransform",ms:"msTransform",standard:"transform"})if("undefined"!==e[t])return t;return!1}();return!1!==i&&("standard"===i?t:i+t.charAt(0).toUpperCase()+t.substr(1))}var e,i="ontouchstart"in window;document.createTouch||(document.createTouch=function(t,e,i,o,s,r,a){return new n(e,i,{pageX:o,pageY:s,screenX:r,screenY:a,clientX:o-window.pageXOffset,clientY:s-window.pageYOffset},0,0)}),document.createTouchList||(document.createTouchList=function(){for(var t=o(),e=0;e<arguments.length;e++)t[e]=arguments[e];return t.length=arguments.length,t});var n=function(t,e,i,n,o){n=n||0,o=o||0,this.identifier=e,this.target=t,this.clientX=i.clientX+n,this.clientY=i.clientY+o,this.screenX=i.screenX+n,this.screenY=i.screenY+o,this.pageX=i.pageX+n,this.pageY=i.pageY+o};function o(){var t=[];return t.item=function(t){return this[t]||null},t.identifiedTouch=function(t){return this[t+1]||null},t}function s(t){return function(i){var n,o,s;1===i.which&&(("mousedown"===i.type||!e||e&&!e.dispatchEvent)&&(e=i.target),n=t,o=i,(s=document.createEvent("Event")).initEvent(n,!0,!0),s.altKey=o.altKey,s.ctrlKey=o.ctrlKey,s.metaKey=o.metaKey,s.shiftKey=o.shiftKey,s.touches=a(o),s.targetTouches=a(o),s.changedTouches=r(o),e.dispatchEvent(s),"mouseup"===i.type&&(e=null))}}function r(t){var i=o();return i.push(new n(e,1,t,0,0)),i}function a(t){return"mouseup"===t.type?o():r(t)}function c(){!function(){for(var t=[window,document.documentElement],e=["ontouchstart","ontouchmove","ontouchcancel","ontouchend"],i=0;i<t.length;i++)for(var n=0;n<e.length;n++)t[i]&&void 0===t[i][e[n]]&&(t[i][e[n]]=null)}(),window.addEventListener("mousedown",s("touchstart"),!0),window.addEventListener("mousemove",s("touchmove"),!0),window.addEventListener("mouseup",s("touchend"),!0)}c.multiTouchOffset=75,i||new c;module.exports=class{constructor(t=null,e){this.config=Object.assign({},{width:300,height:150,awardUrl:"",awardColor:"#ffffff",awardMsg:"特等奖",font:"bold 30px Arial",fontColor:"#ffffff",coverUrl:"",coverColor:"#cccccc",radius:28,duration:500,percent:60,unit:"px",containerClass:"jy-scraping-container",mode:"default",onReady:()=>{},onProgress:()=>{},onSuccess:()=>{}},e),this.el=t,this.parent=null,this.cCover=null,this.cDisplayer=null,this.width=this.config.width,this.height=this.config.height,this.point={left:0,top:0,prevX:0,prevY:0},this.pixelRatio=1,this.isDown=!1,this.isReady=!1,this.isDone=!1,this.lock=!0,this._init()}setLock(t){if("boolean"!=typeof t)return new Error(" the paramtar must be Boolean false or true");const{canvas:e}=this.cDisplayer;this.lock=t,e.style.opacity=t?0:1}set(t={awardUrl:this.config.awardUrl,msg:this.config.awardMsg,coverUrl:this.config.coverUrl}){const{awardUrl:e,msg:i,coverUrl:n}=t;this.setLock(!0),this.setCover(n),setTimeout(()=>{this.setAward({url:e,msg:i})},30)}setCover(t=this.config.coverUrl){const e=this,{ctx:i,widthReal:n,heightReal:o}=this.cCover;t?e.loadImg(t,(function({image:t,width:e,height:s}){i.save(),i.globalCompositeOperation="source-over",i.drawImage(t,0,0,e,s,0,0,n,o),i.restore()}),(function(){console.log("the cover image load error.")})):(i.save(),i.globalCompositeOperation="source-over",i.fillStyle=this.config.coverColor,i.fillRect(0,0,n,o),i.restore()),i.canvas.style.opacity="1"}setAward(t={url:this.config.awardUrl,msg:this.config.awardMsg}){const e=this,{ctx:i,widthReal:n,heightReal:o}=this.cDisplayer,{awardColor:s}=this.config,{url:r,msg:a}=t;this.config.awardMsg=a,this.config.awardUrl=r,"transparent"!==s&&(i.save(),i.fillStyle=s,i.fillRect(0,0,n,o),i.restore()),r?e.loadImg(r,(function({image:t,width:s,height:r}){i.drawImage(t,0,0,s,r,0,0,n,o),e._drawMsg()}),(function(){console.log("the award image load error.")})):e._drawMsg()}_drawMsg(){const{awardMsg:t,fontColor:e}=this.config;if(!t)return;const{ctx:i,widthReal:n,heightReal:o}=this.cDisplayer;let{font:s,fontSize:r}=this;i.font=s;let a=(n-i.measureText(t).width)/2,c=(o-r)/2;i.fillStyle=e,i.textAlign="start",i.textBaseline="top",i.fillText(t,a,c,n)}loadImg(t="",e=(()=>{}),i=(()=>{})){const n=new Image;n.setAttribute("crossorigin","anonymous"),n.src=`${t}?timestamp=${Date.now()}`,n.onload=()=>{e({image:n,width:n.width,height:n.height})},n.onerror=()=>{i(),console.error("Image loading fail.")}}clear(){const{canvas:e}=this.cCover,{duration:i}=this.config;if(i>=0){const n=t("transition");e.style[n]=`all ${i/1e3}s linear`,e.style.opacity="0",setTimeout(()=>{this._clearAll()},i)}else this._clearAll()}_clearAll(){const{canvas:e}=this.cCover,i=t("transition");e.style[i]="none",this.isDone=!1,this.lock=!0,this.config.onSuccess()}_complete(){const{percent:t}=this.config,e=this._pixelPercent();e>=t&&(this.isDone=!0,this.clear()),this.config.onProgress(e)}_pixelPercent(){const{ctx:t}=this.cCover,e=t.getImageData(0,0,this.width,this.height).data,i=e.length;let n=[];for(let t=0;t<i;t+=4)e[t+3]<128&&n.push(e[t+3]);return(n.length/(i/4)*100).toFixed(2)}_drawPoint({x:t,y:e,radius:i}){const{ctx:n}=this.cCover;n.save(),"default"===this.config.mode&&n.beginPath(),n.arc(t,e,i,0,2*Math.PI),"default"===this.config.mode&&n.closePath(),n.fill(),n.restore()}_getPostion(t){if(!t||t&&!t.clientX)return{x:0,y:0,radius:0};const{radius:e}=this.config,{pixelRatio:i}=this.cCover,{top:n,left:o}=this.point;let s=Math.abs(t.clientX-o)*i,r=Math.abs(t.clientY-n)*i;return s=s.toFixed(2),r=r.toFixed(2),this.isDown||(this.point.prevX=s,this.point.prevY=r),{x:s,y:r,radius:e}}_event(){const{canvas:t}=this.cCover;t.addEventListener("touchstart",this._eventDown.bind(this),{passive:!1}),t.addEventListener("touchmove",this._eventMove.bind(this),{passive:!1}),t.addEventListener("touchend",this._eventUp.bind(this),{passive:!1}),t.addEventListener("touchcancel",this._eventUp.bind(this),{passive:!1}),t.addEventListener("touchleave",this._eventUp.bind(this),{passive:!1})}_eventUp(t){if(t.preventDefault(),this.lock)return;const{ctx:e}=this.cCover;e.globalCompositeOperation="source-over",this.isDown=!1}_eventDown(t){if(t.preventDefault(),this.lock)return;this.isReady||(this.isReady=!0,this.config.onReady());const{ctx:e}=this.cCover;"sector"===this.config.mode&&e.beginPath(),e.globalCompositeOperation="destination-out";const i=this.parent.getBoundingClientRect();this.point.left=i.left,this.point.top=i.top,this._drawPoint(this._getPostion(t.changedTouches[0])),this.isDown=!0}_eventMove(t){t.preventDefault(),this.lock||this.isDown&&!this.isDone&&(this._drawPoint(this._getPostion(t.changedTouches[0])),this._complete())}_createCanvas(){const t=document.createElement("canvas"),e=t.getContext("2d"),{width:i,height:n}=this,o=(c=(a=e).backingStorePixelRatio||a.webkitBackingStorePixelRatio||a.mozBackingStorePixelRatio||a.msBackingStorePixelRatio||a.oBackingStorePixelRatio||a.backingStorePixelRatio||1,(window.devicePixelRatio||1)/c),s=i*o,r=n*o;var a,c;return e.scale(o,o),t.setAttribute("width",s),t.setAttribute("height",r),t.style.cssText="position:absolute;top:0;left:0;width:100%;height:100%",this.pixelRatio=o,{canvas:t,ctx:e,width:i,height:n,pixelRatio:o,widthReal:s,heightReal:r}}_createDOM(){const{width:t,height:e,unit:i,containerClass:n}=this.config,o=this.el,s=document.createElement("div");let r=null,a=null;s.style.cssText=`position:relative;margin:0 auto;text-align:center;width:${t}${i};height:${e}${i};overflow:hidden;`,s.className=n,r=this._createCanvas(),a=this._createCanvas(),s.appendChild(a.canvas),s.appendChild(r.canvas),o.appendChild(s),this.parent=s,this.cCover=r,this.cDisplayer=a}_params(){let t=this.config.font,e=t.match(/(\d+)px/g)[0];e=e.replace("px","")*this.pixelRatio,e=Number(e.toFixed(1)),this.font=t.replace(/(\d+)px/g,`${e}px`),this.fontSize=e}_init(){if(!this.el)return new Error("the.el is not found.");this._createDOM(),this.setAward(),this.setCover(),this._event(),this._params()}};