換了新工做之後,專一前端開發,日常空閒時間也比較多,能夠多鑽研一下技術,寫一下博客。最近在學習canvas,參考網上的slotmachine插件,用canvas實現了一個簡單抽獎小遊戲。html
知識點前端
步驟canvas
一、準備好圖片,首先是機器的外觀、以及滾動的獎項圖片,我一共準備了6種,獎項圖片按照必定的規律命名,這樣方便處理瀏覽器
二、準備好canvas畫布,設置好基本的CSS樣式,完成之後大概是這樣子。ide
PS:這裏我設置了canvas的背景色,方便看到效果,完成品會去掉背景色,由於背景咱們要設置成機器學習
三、計算好位置,繪製背景圖、以及獎勵項目邊框,繪製完大概是這樣子優化
PS:要注意的一點是,繪製背景要等到圖片加載完才能繪製(這不是廢話嗎!),繪製邊框要等到背景繪製完,否則會被覆蓋掉。動畫
四、繪製獎項圖片,位置和邊框位置一致,完成效果大體是這樣ui
五、加上點擊事件、點擊開啓關閉切換,完成效果見頂部,done!spa
待優化
獎項切換的效果沒有實現,就是獎勵上下滾動的效果
總結
試水canvas,蠻有趣的,打開了新世界的大門。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>SlotMachine</title> <style> body { background: gray; } #test { background: #fff; width: 100%; max-width: 551px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } </style> </head> <body> <canvas id="test" width="533" height="411"> 您的瀏覽器不支持Canvas,如今都什麼年代了 </canvas> <script> ; (function () { let canvas = document.querySelector('#test'); //引入縮放比例計算,兼容多種終端 let scaling = { w: canvas.clientWidth / canvas.width, h: canvas.clientHeight / canvas.height }; if (canvas.getContext) { let ctx = canvas.getContext('2d'); let bg = new Image(); let imgs = { left: new Image(), middle: new Image(), right: new Image() }; let flag = { left: 1, middle: 1, right: 1, max: 6 }; let ps = { left: [70, 160], middle: [185, 160], right: [295, 160] }; let interval = 1000 / 10; let timer = { left: null, middle: null, right: null }; //繪製圖片 function drawImg(img, x, y) { ctx.drawImage(img, x, y, img.width, img.height); } //繪製背景 function drawBg(img) { let pattern = ctx.createPattern(img, 'no-repeat'); ctx.fillStyle = pattern; ctx.fillRect(0, 0, 533, 411); } //繪製圖片邊框 function drawBorder(x, y, w, h) { ctx.save(); ctx.strokeStyle = '#000000'; ctx.lineWidth = 4; ctx.strokeRect(x, y, w, h); ctx.restore(); } //判斷點擊是否在圖片範圍內 function isPointInPath(x, y, x1, y1) { return x <= x1 && x + 100 >= x1 && y <= y1 && y + 100 >= y1; } //動畫開始 function start(key) { timer[key] = setInterval(function () { flag[key] === flag.max ? flag[key] = 1 : flag[key]++; imgs[key].src = './img/slot' + flag[key] + '.png'; }, interval); } //動畫中止 function stop(key) { clearInterval(timer[key]); timer[key] = null; } //初始化 function init() { bg.src = './img/machine.png'; bg.onload = () => { drawBg(bg); drawBorder(ps.left[0], ps.left[1], 100, 100); drawBorder(ps.middle[0], ps.middle[1], 100, 100); drawBorder(ps.right[0], ps.right[1], 100, 100); imgs.left.src = './img/slot6.png'; imgs.left.onload = () => { drawImg(imgs.left, ps.left[0], ps.left[1]); }; imgs.middle.src = './img/slot6.png'; imgs.middle.onload = () => { drawImg(imgs.middle, ps.middle[0], ps.middle[1]); }; imgs.right.src = './img/slot6.png'; imgs.right.onload = () => { drawImg(imgs.right, ps.right[0], ps.right[1]); }; }; canvas.addEventListener('click', function (e) { //引入縮放比例計算,兼容多種終端 let x1 = e.offsetX / scaling.w; let y1 = e.offsetY / scaling.h; for (let key in ps) { if (ps.hasOwnProperty(key)) { let item = ps[key]; if (!isPointInPath(item[0], item[1], x1, y1)) continue; if (timer[key]) { stop(key); } else { start(key); } } } }); } init(); } })(); </script> </body> </html>