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%);
      }
    } 
}
相关推荐
子洋11 分钟前
AI Agent 介绍
前端·人工智能·后端
徐同保15 分钟前
使用n8n自动发邮件
前端
dly_blog1 小时前
setup 函数完整指南!
前端·javascript·vue.js
霍理迪1 小时前
基础CSS语法
前端·css
粟悟饭&龟波功1 小时前
【GitHub热门项目精选】(2025-12-19)
前端·人工智能·后端·github
流浪法师121 小时前
MyPhishing-Web:AI 驱动的钓鱼邮件检测可视化平台
前端·人工智能
写代码的jiang1 小时前
【无标题】实战:Vue3 + Element Plus 实现树形选择器全量预加载与层级控制
前端·javascript·vue.js
晚烛2 小时前
实战前瞻:构建高可靠、低延迟的 Flutter + OpenHarmony 智慧交通出行平台
前端·javascript·flutter
WHOVENLY2 小时前
【javaScript】- 作用域[[scope]]
前端·javascript
来杯三花豆奶2 小时前
Vue3 Pinia 从入门到精通
前端·javascript·vue.js