react+canvas实现刮刮乐效果


话不多说,直接看代码吧
cpp 复制代码
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>
  );
}
cpp 复制代码
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%);
      }
    } 
}
相关推荐
admin and root4 小时前
「AI安全篇」实战AntiDebug自动化JS逆向加解密MCP
javascript·人工智能·网络安全·自动化·漏洞挖掘·cnvd·src赏金
前端snow4 小时前
ai agent --- postgreSQL 关系型数据库
前端
卷无止境5 小时前
ECharts:把数据变成故事的可视化利器
前端
Eric_见嘉5 小时前
在职前端 Skill 和 MCP 分享
前端·后端·agent
liangshanbo12155 小时前
面试题:如何优化 Webpack 的打包速度?
前端·webpack·node.js
wengad6 小时前
从 wangEditor 迁到 wangEditor-next
前端·javascript·vue.js
行者-全栈开发7 小时前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
计算机魔术师8 小时前
AMD砸82亿买下李飞飞,这次不卖芯片卖什么?
前端
hzxpaipai8 小时前
杭州企业官网怎么建设?从策划到上线的5步建站方法
运维·服务器·前端·网络
怕浪猫8 小时前
2026年金九银十,我面了22个前端
前端·javascript·面试