在做运营活动的相关功能时,刮刮乐也是常客了。本篇文章主要是总结用vue实现刮刮乐功能的思路和方法。
关键canvasAPI
globalCompositeOperation = 'destination-out'; //橡皮擦模式
代码内容
<script setup>
import { ref, onMounted } from 'vue'
onMounted(() => {
let canvas = document.querySelector('#canvas');
let context = canvas.getContext('2d');
// 绘制涂层
context.beginPath();
context.fillStyle = 'grey';
context.fillRect(0, 0, 400, 300);
//计算已经擦除的面积与原画布面积占比
const calcClearArea = () => {
//获取canvas 的像素信息
const pixels = context.getImageData(0, 0, 400, 300).data;
let transparentPixels = 0;
for (let i = 0; i < pixels.length; i += 4) {
if (pixels[i + 1] < 128) {
transparentPixels++
}
}
console.log((transparentPixels / pixels.length * 4 * 100).toFixed(2))
return (transparentPixels / pixels.length * 4 * 100).toFixed(2)
}
//清除涂层
const clear = (alpha) => {
return () => {
context.save();
context.globalCompositeOperation = "source-in";
context.fillStyle = context.fillStyle + (alpha -= 1).toString(16);
context.fillRect(0, 0, 400, 300);
context.restore();
if (alpha > 210) {
requestAnimationFrame(clear(alpha))
}
}
}
// 监听鼠标移动事件
canvas.addEventListener('mousemove', (e) => {
// 当鼠标左键按下&&移动鼠标时,清除鼠标附近涂层
if (e.which === 1 && e.button === 0) {
const x = e.clientX, y = e.clientY;
context.globalCompositeOperation = 'destination-out';
context.beginPath();
// 清除以鼠标位置为圆心,半径为10px的圆的范围
context.arc(x - 200, y, 10, 0, Math.PI * 2);
context.fill();
}
})
canvas.addEventListener("mouseup", (e) => {
const pixels = calcClearArea();
if (pixels >= 30) {
requestAnimationFrame(clear(255));
}
})
})
</script>
<template>
<div class="page">
<div class="img">
<img src="./images/1.png" style="width:400px;height:300px;" />
</div>
<canvas id="canvas" width="400" height="300"></canvas>
</div>
</template>
<style scoped>
.page {
position: relative;
}
.img {
width: 400px;
height: 300px;
position: absolute;
left: 0;
z-index: -1;
}
</style>