话不多说,直接看代码吧
import { useEffect } from 'react';
import styles from './index.less';export default function Canvas() {function init() {let gj = document.querySelector('.gj');let jp = document.querySelector('#jp') as HTMLElement;let canvas = document.querySelector('#mask') as HTMLCanvasElement;let ctx = canvas?.getContext('2d') as any;// 遮罩层mask设置ctx.fillStyle = '#e0e0e0';ctx.fillRect(0, 0, 200, 100);ctx.fillStyle = '#ffffff';ctx.font = '16px 微软雅黑';ctx?.fillText('刮奖区', 80, 50); // 文字在框中位置// 奖品部分逻辑let arr = ['一等奖', '二等奖', '三等奖', '再来一次'];let randomNum = Math.random() * 100;if (randomNum < 10) {jp.innerHTML = arr[0];} else if (randomNum < 30) {jp.innerHTML = arr[1];} else if (randomNum < 60) {jp.innerHTML = arr[2];} else {jp.innerHTML = arr[3];}// 绘图部分let isDraw = false;canvas.onmousedown = () => (isDraw = true);canvas.onmouseup = () => (isDraw = false);canvas.onmousemove = (e) => {if (isDraw) {writeText(ctx, e, gj);}};} function writeText(ctx: any, e: MouseEvent, gj: HTMLElement) {ctx?.beginPath();let x = e.pageX - gj?.getBoundingClientRect().left;let y = e.pageY - gj?.getBoundingClientRect().top;ctx.globalCompositeOperation = 'destination-out'; // !!! 在后绘制的图形上方显示先绘制的图形, 相交部分由先绘制图形的填充(颜色,渐变,纹理)覆盖ctx?.closePath();ctx?.arc(x, y, 10, 0, Math.PI * 2);ctx?.fill();}useEffect(() => {init();}, []);return (<div className={styles.container}><div className=" text-center text-[16px]">刮刮乐</div><div className="gj mt-4 cursor-pointer"><div id="jp"></div><canvas id="mask" width={200} height={100}></canvas></div></div>);
}
index.less部分
.container {padding: 20px;box-shadow: 4px 4px 4px 4px #eee;overflow: hidden; .gj {margin: 16px auto;width: 200px;height: 100px;#jp {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);font-size: 20px;color: black;}#mask {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}}
}