用`canvas`实现刮刮乐效果

1. 布局

上面用来显示底部的文字,或者图片也行

然后绝对定位,再放入canvas覆盖

html 复制代码
<style>
    .wrapper {
        position: relative;
        width: 300px;
        height: 250px;
        background-color: #fcc;
    }

    .ticket {
        display: flex;
        position: absolute;
        inset: 0;
    }

    .label {
        margin: auto;
        color: #fff;
        font-size: 66px;
        user-select: none;
    }

    canvas {
        position: absolute;
    }
</style>

<body>
    <div class="wrapper">
        <div class="ticket">
            <span class="label">一等奖</span>
        </div>
    </div>
<body>

2. 创建画布

传入的参数是父容器,让他们的大小一致

js 复制代码
function createScratchTicket(wrapper) {
    const cvs = document.createElement('canvas')
    const ctx = cvs.getContext('2d')
    cvs.width = wrapper.clientWidth
    cvs.height = wrapper.clientHeight

    // 绘制刮奖区域
    ctx.fillStyle = '#999'
    ctx.fillRect(0, 0, cvs.width, cvs.height)

    return cvs
}

3. 设置样式

注意globalCompositeOperation这个属性,他可以让我们选择后面画的图与前面的图之间的绘制关系

js 复制代码
function setStyle(ctx) {
    // 什么颜色都行
    ctx.fillStyle = 'transparent'
    ctx.lineWidth = 15
    ctx.lineCap = 'round'
    ctx.lineJoin = 'round'
    ctx.globalCompositeOperation = 'destination-out'
}

这是MDN的描述

developer.mozilla.org/zh-CN/docs/...

也就是说,设置了这个属性,当我们往画布上填充新的内容时,就能产生涂抹效果

4. 初始化

把画布放入容器中,然后设置上面的样式,再绑定事件

js 复制代码
 function init() {
    const wrapper = document.querySelector('.wrapper')
    const cvs = createScratchTicket(wrapper)
    const ctx = cvs.getContext('2d')
    wrapper.appendChild(cvs)

    setStyle(ctx)
    bindEvent(cvs, ctx)
}

5. 事件

当鼠标按下时,记录位置,鼠标移动时,填充画布,鼠标抬起时,删除事件即可

js 复制代码
  function bindEvent(el, ctx) {
    el.onmousedown = function ({ clientX, clientY }) {
        ctx.moveTo(clientX, clientY)

        el.onmousemove = function ({ clientX, clientY }) {
            ctx.lineTo(clientX, clientY)
            ctx.stroke()
        }

        el.onmouseup = function () {
            el.onmousemove = null
            el.onmouseup = null
        }
    }
}

6. 问题

上面的绑定事件,有个小问题,当你的鼠标移出浏览器时,就不能解绑事件

解决方法就是多绑定一个事件,不过这样你的鼠标刮图时,就不能超出元素了

js 复制代码
function bindEvent(el, ctx) {
    el.onmousedown = function ({ clientX, clientY }) {
        ctx.moveTo(clientX, clientY)

        el.onmousemove = function ({ clientX, clientY }) {
            ctx.lineTo(clientX, clientY)
            ctx.stroke()
        }

        // 移出浏览器或元素时也会解绑
        el.onmouseup = el.onmouseout = function () {
            el.onmousemove = null
            el.onmouseup = null
        }
    }
}

源码:gitee.com/cjl2385/dig...

相关推荐
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
北岛寒沫3 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
everyStudy3 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
(⊙o⊙)~哦4 小时前
JavaScript substring() 方法
前端
无心使然云中漫步4 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者5 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_5 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋6 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120536 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢6 小时前
【Vue】VueRouter路由
前端·javascript·vue.js