豫ICP备2024044691号-1
powered by emlog
canvas实现刮奖效果和签名面板
Mins 2019-3-18 14:58 JavaScript

html代码:

<!-- 画布 -->
<canvas id="canvas"></canvas>

<!-- 奖品显示区域 -->
<div class="content">A123456</div>

<!-- 奖品上层显示的图片 -->
<img src="" class="canvasImg">

js代码:

const init = function(){
    // 创建画布
    let canvas = document.querySelector('#canvas');
    let ctx = canvas.getContext('2d');
    canvas.width = 270;
    canvas.height = 90;

    // 填充图片到画布
    let pat = ctx.createPattern(canvasImg, 'no-repeat'); // 第二个参数:no-repeat 的使用方法和 css background 中的 repeat 一样
    ctx.rect(0, 0, 270, 90);
    ctx.fillStyle = pat;
    ctx.fill();

    // 刮奖动作
    const move = (x, y) => {
        ctx.beginPath();
        ctx.globalCompositeOperation = 'destination-out'; // 填充成透明
        ctx.arc(x, y, 15, 0, 2 * Math.PI); // 填充一个半径为15px的圆形区域
        ctx.fill();
        ctx.closePath();
    }

    // 鼠标按下时,才执行刮奖动作
    canvas.onmousedown = () => {
        canvas.onmousemove = (e) => {
            move(e.layerX, e.layerY); // move() 会有一定的性能开销,可以根据项目做适当的防抖
        }
    }

    // 鼠标弹起时不做任何动作
    canvas.onmouseup = () => {
        canvas.onmousemove = () => {}
    }
}

// 一定要先添加监听,再给图片赋值,否则图片未加载完成时执行 init(),canvas无法拿到图片导致填充为黑色
let canvasImg = document.querySelector('.canvasImg');
canvasImg.onload = function(){
    init();
}
canvasImg.src = './76.png';

上面的代码中用到了 canvas 的 ctx.globalCompositeOperation 属性,该属性的作用是将绘制区域设为透明。设想一下,如果移除了该属性,canvas 将会填充指定的颜色,是不是就完成了一个签名模块。