用`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...

相关推荐
Justinc.1 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge8 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia17 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫18 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
光影少年37 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_38 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891140 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾41 分钟前
前端基础-html-注册界面
前端·算法·html
Rattenking42 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
Dragon Wu44 分钟前
前端 Canvas 绘画 总结
前端