【H5】 canvas实现刮刮乐效果

【H5】 canvas实现刮刮乐效果

效果图如下:

在这里插入图片描述

全部实现代码如下:复制粘贴即可运行!

代码内有步骤详解哦!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <img src="1.jpg" width="400" id= 'img' alt="">
    <input type="text" name="" id="txt">
    <!-- <canvas></canvas> -->
    <script>
        const oImg = document.getElementById('img');
        const txt = document.getElementById( 'txt' );
        //oImg.readyState 图片加载状态
        if( oImg.readyState ==="complete" ){
            draw(); //true表示已经加载完成 执行draw()方法
        }else{
            //图片加载完成执行draw方法
            oImg.onload = draw;
        }

        function draw(){    //等图片加载完成后再添加canvas画布在上面
            let can = document.createElement('canvas'); //创建一个canvas画布
            can.width = oImg.width; //等于图片的宽高
            can.height = oImg.height;
            can.style.position = "absolute";    //canvas画布设置浮动会漂浮在图片上
            can.style.left = oImg.offsetLeft + "px"; //保存与画布位置一致
            can.style.top = oImg.offsetTop + "px";
            //找到图片的父级:parentNode  在oImg子元素前面添加canvas标签:insertBefore
            oImg.parentNode.insertBefore( can,oImg ) //在img前面去插入canvas标签
            let ctx = can.getContext('2d');
            ctx.fillStyle = "#bbb"; //刮刮乐的颜色
            ctx.fillRect( 0,0,oImg.width,oImg.height) //填充宽度

            //合成:处理合成图片的透明样式;
            //拖拽的时候,canvas图层显示透明;destination-out:新图形与原图形重叠部分透明
            ctx.globalCompositeOperation = "destination-out";
            ctx.strokeStyle = "#eee";   //触笔的颜色 随便  因为它终究变成透明
            ctx.lineWidth = 30;     //拖动时开始画线的线宽
            ctx.lineCap = "round"  //这两步是把画笔变成圆形

            //按下,移动,抬起事件
            can.onmousedown = function(e){
                e = e || window.event;  //兼容低版本IE浏览器
                //e.pageX距离文档右边缘; offsetLeft:canvas画布距离文档的右边距离
                let x = e.pageX - can.offsetLeft;   //得到的x是在canvas上的坐标值
                let y = e.pageY - can.offsetTop;
                ctx.beginPath();
                // ctx.moveTo(  x,y )//从哪里开始来画
                ctx.arc( x,y,15,0,6.3,false );  //点第一下是画一个圆
                ctx.fill();
                //按下后拖拽
                can.onmousemove  = function( e ){   //拖动时一直执行下面
                    e = e || window.event;  //兼容低版本IE浏览器
                    ctx.beginPath();    //拖动时开始画线
                    ctx.moveTo(x,y); //起始点   
                    ctx.lineTo(e.pageX - can.offsetLeft,e.pageY - can.offsetTop); //移动的过程

                    //每次移动的时候,样式所在的坐标;
                    x = e.pageX - can.offsetLeft;   //第二次渲染刮图片效果的起始点应该在上一次的终止点
                    y = e.pageY - can.offsetTop;
                    ctx.stroke();   //弹出图形并恢复画布
                }
                document.onmouseup = function(){
                    //抬起后将事件注销
                    can.onmousemove = null;
                    this.onmouseup = null;
                    check();    //完成后通过像素计算刮过的的百分比
                }
            }
            function check(){   
                //获取画布的像素列表
                let data = ctx.getImageData( 0,0,can.width,can.height).data;
                let n = 0;  //计算透明像素的个数
                for( let i = 0;i<data.length;i+=4 ){    //感觉这一步比较消耗性能
                    //RGBA
                    if( data[i]== 0 && data[i+1] ==0 && data[i+2] ==0&&data[i+3] ==0 ){
                        n++
                    }
                }
                let f = n*100/(can.width*can.height);  //算出所刮的面积的占比;
                txt.value = `刮开面积:${f.toFixed(2)}%`;
                //刮开面积的比例
                if( f > 30 ){   //如果所刮的面积大于30%   则将canvas画布整体清除fillRect
                    ctx.beginPath();
                    ctx.fillRect( 0,0,can.width , can.height )
                    txt.value = "刮开面积大于30%,全部显示"
                }
            }
        }
    </script>
</body>
</html>
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值