之前公司項目有一個刮獎小游戲的需求,因此有了本文記錄該“刮刮樂”游戲的實現過程。
話不多說,先上Demo 和 項目源碼 .
2. 實現
我們創建一個 ScrapAward 類,通過傳入 option 和調用其 restart() 方法實現重新開始。
(1)定義 option 參數及 ScrapAward 結構
class ScrapAward { constructor(userOption) { this.option = { canvasId: 'canvas', // canvas的id backgroundImageUrl: '', // 背景圖url width: 320, // canvas寬度 height: 160, // canvas高度 backgroundSize: '100% 100%', coverImage: { // 覆蓋圖層背景圖url url: '', width: 320, height: 160, }, callback: () => {}, // 刮獎完成的回調函數 }; this.ctx = null; this.init(userOption); // 初始化 } // 初始化方法 init(userOption) { } // 重新開始也是一次初始化 restart(userOption) { if (userOption) { this.init(userOption); } else { this.init({}); } }}
(2) init 初始化
首先合并用戶的配置 userOption 和默認 option , 等背景圖片加載完成后調用 fillCanvas()
方法繪制覆蓋層的圖片后設置 canvas 的背景圖。
當上述行為完成后,我們便監聽鼠標或者touch事件。刮獎這一行為其實是canvas對鼠標或者touch的移動路徑進行繪畫,只不過是將繪畫的路徑變成了透明,這種效果我們通過設置 ctx.globalCompositeOperation = 'destination-out';
即可實現。
init(userOption) { // 合并用戶配置 if (Object.assign) { Object.assign(this.option, userOption); } else { extend(this.option, userOption, true); } // 定義一系列變量 let that = this, img = (this.img = new Image()), //背景圖片 imgLoaded = false, //背景圖是否加載完成 canvas = (this.canvas = document.querySelector(`#${this.option.canvasId}`)), hastouch = 'ontouchstart' in window ? true : false, tapstart = hastouch ? 'touchstart' : 'mousedown', tapmove = hastouch ? 'touchmove' : 'mousemove', tapend = hastouch ? 'touchend' : 'mouseup', coverImg = (this.coverImg = new Image()), hasDone = false, // 是否刮獎完畢 coverImgLoad = false; that.mousedown = false; //鼠標的mousedown事件或者touchmove事件是否開啟 // 移除事件監聽,用于重新開始 if (this.canvas) { this.canvas.removeEventListener(tapstart, eventDown); this.canvas.removeEventListener(tapend, eventUp); this.canvas.removeEventListener(tapmove, eventMove); } coverImg.src = this.option.coverImage.url; coverImg.crossOrigin = 'Anonymous'; // 解決一些跨域問題 img.src = this.option.backgroundImageUrl; var w = (img.width = this.option.width), h = (img.height = this.option.height); this.canvasOffsetX = canvas.offsetLeft; this.canvasOffsetY = canvas.offsetTop; canvas.width = w; canvas.height = h; this.ctx = canvas.getContext('2d'); let ctx = this.ctx; this.img.addEventListener('load', backgroundImageLoaded); this.option.coverImage.url && this.coverImg.addEventListener('load', coverImageLoaded); // 背景圖片加載完成后 function backgroundImageLoaded(e) { imgLoaded = true; fillCanvas(); canvas.style.background = 'url(' + img.src + ') no-repeat'; canvas.style.backgroundSize = that.option.backgroundSize || 'contain'; } // 覆 主站蜘蛛池模板: 长治县| 老河口市| 江源县| 正镶白旗| 汝阳县| 福建省| 灵川县| 宜川县| 永济市| 南郑县| 周口市| 宜春市| 新和县| 长泰县| 台南市| 开平市| 淄博市| 英超| 卓尼县| 黔江区| 广德县| 塔城市| 会昌县| 波密县| 界首市| 云梦县| 伊宁县| 白玉县| 高清| 中西区| 乳山市| 贵州省| 东宁县| 新沂市| 嘉善县| 扶风县| 尚义县| 临桂县| 巫溪县| 水富县| 朝阳市|