[移动端抽奖刮刮卡] Html5 Canvas 实现的可刮涂层效果

2021-07-09 11:37:37 浏览数 (1)

产品背景

亲,像下面这种有关移动互联网迅猛发展的报告,最近见得很多吧?在座各位作为互联网行业的弄潮儿,看完是不是很有历史使命感和紧迫感呢?简直热血喷张、跃跃欲试,甚至有一种“不移动不成活”的冲动吧?!

gteffect00

其实互动活动移动化已经不再是一种未知的趋势,而是可以用数据证明的。为了让我们的用户有更完美的体验,互动活动必须延伸到移动端!

创意诞生

大部分互动活动为了吸引用户都祭出了“抽奖大礼”这个杀手锏,这种方式虽然老套,但是老而弥坚。然而,这一已经非常成熟的形式,在向移动端移植的时候,我们却遇到了实际问题:

第一是实现方式。过去Flash技术开发的大转盘、老虎机之类的东东,在移动端的兼容性简直惨不忍睹,但是换做 JS 开发,又面临时间成本太高、效率太低的窘境,无法快速应对多样且善变的定制化需求。

第二是表现方式。移动端的小屏幕,无法承担过于复杂的抽奖界面设计,用户如果连内容都看不清楚,就更别提参与的热情了。

gteffect01.jpg

那么,既要抽奖,又要兼顾移动端体验,更要兼备清晰的表现形式及创新点,我们该怎么办?

gteffect02

经过若干次头脑风暴和会议讨论,结合多次交互测试,一个 Good Idea 终于诞生了! LOOK !这就是亮闪闪的移动端互动活动抽奖刮刮卡!下面请欣赏全家福:)

gteffect03

亲,请用硬币使劲的刮屏幕,就可以刮出巨奖哦……刮坏 7 块屏幕者可以召集神龙!”这只是个玩笑!用手指涂抹就可以刮出奖啦,妈妈再也不用担心刮奖弄脏我的指甲!

gteffect04

技术实现手段

gteffect05

代码实现

代码语言:javascript复制
(function(bodyStyle) {
    bodyStyle.mozUserSelect = 'none';
    bodyStyle.webkitUserSelect = 'none';
 
    var img = new Image();
    var canvas = document.querySelector('canvas');
    canvas.style.backgroundColor='transparent';
    canvas.style.position = 'absolute';
 
    img.addEventListener('load', function(e) {
        var ctx;
        var w = img.width,
            h = img.height;
        var offsetX = canvas.offsetLeft,
            offsetY = canvas.offsetTop;
        var mousedown = false;
 
        function layer(ctx) {
            ctx.fillStyle = 'gray';
            ctx.fillRect(0, 0, w, h);
        }
 
        function eventDown(e){
            e.preventDefault();
            mousedown=true;
        }
 
        function eventUp(e){
            e.preventDefault();
            mousedown=false;
        }
 
        function eventMove(e){
            e.preventDefault();
            if(mousedown) {
                if(e.changedTouches){
                    e=e.changedTouches[e.changedTouches.length-1];
                }
                var x = (e.clientX   document.body.scrollLeft || e.pageX) - offsetX || 0,
                    y = (e.clientY   document.body.scrollTop || e.pageY) - offsetY || 0;
                with(ctx) {
                    beginPath()
                    arc(x, y, 5, 0, Math.PI * 2);
                    fill();
                }
            }
        }
 
        canvas.width=w;
        canvas.height=h;
        canvas.style.backgroundImage='url(' img.src ')';
        ctx=canvas.getContext('2d');
        ctx.fillStyle='transparent';
        ctx.fillRect(0, 0, w, h);
        layer(ctx);
 
        ctx.globalCompositeOperation = 'destination-out';
 
        canvas.addEventListener('touchstart', eventDown);
        canvas.addEventListener('touchend', eventUp);
        canvas.addEventListener('touchmove', eventMove);
        canvas.addEventListener('mousedown', eventDown);
        canvas.addEventListener('mouseup', eventUp);
        canvas.addEventListener('mousemove', eventMove);
    });
    img.src ='';
})(document.body.style);

需要判断是否刮完时用这段代码替换原代码的eventUp事件处理函数:

代码语言:javascript复制
e.preventDefault();
mousedown = false;
var data=ctx.getImageData(0,0,w,h).data;
for(var i=0,j=0;i< data.length;i =4){
    if(data[i] && data[i 1] && data[i 2] && data[i 3]){
        j  ;
    }
}
if(j<=w*h*0.1){
    alert('ok');
}

这段代码中的0.1是10%的意思,在涂层的面积小于等于10%时,就弹出窗口,表示刮完了

0 人点赞