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%);
      }
    } 
}
相关推荐
书山有路_邓41 分钟前
vscode 如何鼠标双击时选择带有-的
前端
张三风啊3 小时前
vue config 接口地址配置
前端·javascript·vue.js
多情码农无情键3 小时前
浏览器漫谈HTML--2.2从表单标签看vue的响应式系统 理论+实战
前端·javascript·html
Uluoyu3 小时前
Vue.Draggable使用nested-with-vmodel进行拖拽
前端·javascript·vue.js
北极糊的狐3 小时前
vue页面成绩案例(for渲染表格/删除/添加/统计总分/平均分/不及格显红色/输入内容去首尾空格trim/输入内容转数字number)
前端·javascript·vue.js
边洛洛4 小时前
路由传参、搜索、多选框勾选、新增/编辑表单复用
前端·javascript·vue.js
breakthrough_014 小时前
创建一个简单的 Nuxt.js 应用
开发语言·javascript·ecmascript
OEC小胖胖5 小时前
Vue 3 中 onUnload 和 onPageScroll 使用详解
前端·javascript·vue.js·前端框架·web
秋田君6 小时前
uniapp中使用Mescroll实现下拉刷新与上拉加载项目实战
javascript·uni-app
川石教育7 小时前
Vue前端开发-slot传参
前端·vue.js·前端框架·前端开发·slot组件