zoukankan      html  css  js  c++  java
  • 图片-滑动-解锁-组件-vue-canvas

    
    
    <template>
        <div>
            <div id="slide_unloack_wraper">
                <canvas width="310" height="155" id="slide_unloack_wraper1"></canvas>
                <div id="slide_unloack_inner">
                    <canvas width="310" height="155" id="slide_unloack_inner1"></canvas>
                </div>
            </div>
            
            
        </div>
    </template>
    
    <script>
    export default {
        data(){
            return{
                isSuccess:false,//是否滑动成功
            }
        },
        created() {
            
        },
        mounted() {
            // 将两张图片渲染在cavas上
            var canvas = document.getElementById('slide_unloack_wraper1');
            var block = document.getElementById('slide_unloack_inner1');
            var canvas_ctx = canvas.getContext('2d');
            var block_ctx = block.getContext('2d');
            var img = document.createElement('img');
            img.onload = function() {
            canvas_ctx.drawImage(img, 0, 0, 310, 155);
            block_ctx.drawImage(img, 0, 0, 310, 155);
    
            var blockWidth = w + r * 2;//滑块实际宽度
            var _y = y - r * 2 + 2 // 滑块实际的y坐标
            var ImageData = block_ctx.getImageData(x, _y, blockWidth, blockWidth);//拿到滑块的像素数据
            block.width = blockWidth;//将滑块dom元素的宽度设置成滑块的掉
            block_ctx.putImageData(ImageData, 0, _y)
            };
            img.crossOrigin = 'Anonymous';//防止图片报跨域的错
            img.src = 'http://kexiepingtaieposter.hoohui.cn//registFile/fa5df7c9-445d-4b58-97c4-ad8b86a92241/Z0134_2020033134932.jpeg?time='+ new Date();//加事件戳 防止图片报跨域的错
            // 先利用clip()方法裁剪出个方块儿,让大家认识裁剪
            var x = 150, y = 40, w = 42, r = 10, PI = Math.PI;//x坐标、y坐标、正方形的宽、圆的半径、圆周率(3.14...)
            function draw(ctx, operation) {
            ctx.beginPath();//拿笔
            ctx.moveTo(x,y);//把笔尖点到这个点
            ctx.lineTo(x+w/2,y);//笔尖画到  正方形上边线中间
            ctx.arc(x+w/2,y-r+2, r,0,2*PI); //在坐标点(x+w/2,y-r+2)画一个r为半径的圆,角度开始为0,结束角度为2π,顺时针画个圆
            ctx.lineTo(x+w/2,y);//笔尖移动到 正方形上边线中间
            ctx.lineTo(x+w,y);//笔尖画到 正方形的上边线的右侧
            ctx.lineTo(x+w,y+w/2);//笔尖再画到正方形的右边线中间点
            ctx.arc(x+w+r-2,y+w/2,r,0,2*PI) //在合适的位置画个圆
            ctx.lineTo(x+w,y+w/2);//笔尖画到正方形的 右边线中间点
            ctx.lineTo(x+w,y+w);//笔尖画到正方形右边线的底部
            ctx.lineTo(x,y+w);//再画到正方形的下边线的左侧
            
            if(operation=='clip'){
                ctx.lineTo(x,y+w/2+r);
                ctx.arc(x+2,y+w/2,r,0.5*PI,1.5*PI,true) //在合适的位置画个圆 true:逆时针
                ctx.lineTo(x,y+w/2-r);
            }
            ctx.lineTo(x,y);//再画到正方形的起始点 形成闭环
            
            if(operation=='clip'){
                ctx.strokeStyle='black';
                ctx.lineheight='1';
                ctx.stroke();
            }
            ctx.fillStyle = '#fff';//填充背景
            ctx[operation]();
    
            ctx.beginPath();//重新开始画
            ctx.arc(x,y+w/2, r,1.5*PI,0.5*PI) // 只需要画正方形内的半圆就行,方便背景图片的裁剪
            ctx.globalCompositeOperation = "xor";//将原图遮盖出一个缺口
            ctx.fill();//填充颜色 前面没加fillStyle就是白色
            }
            draw(canvas_ctx,"fill");
            draw(block_ctx,"clip");
            // 绘图结束
    
            // 添加事件
            var self=this;
            self.$nextTick(()=>{
                //一、定义了一个获取元素的方法
                function getEle(selector){
                    return document.querySelector(selector);
                }
                //二、获取到需要用到的DOM元素
                var box = getEle("#slide_unloack_wraper"),//容器
                    slider = getEle("#slide_unloack_inner"),//滑块
                    maxMoveX = box.offsetWidth- 64,//解锁可以滑动的距离 64是写死的
                    downX,//用于存放鼠标按下时的位置
                    successUnlockX=[130,170];//成功解锁活动距离
                //三、给滑块添加鼠标按下事件
                slider.onmousedown = mousedownHandler;
                slider.ontouchstart = mousedownHandler;//移动端加touchstart事件
                //3.1鼠标按下事件的方法实现
                function mousedownHandler(e){
                    slider.style.transition = "";
                    var e = e || window.event || e.which;
                    downX = e.clientX ? e.clientX : e.changedTouches[0].clientX;
                    if(!self.isSuccess){
                        //在鼠标按下时,分别给鼠标添加移动和松开事件
                        document.onmousemove = mousemoveHandler;
                        document.onmouseup = mouseupHandler;
                        //添加移动端对应事件
                        document.ontouchmove = mousemoveHandler;
                        document.ontouchend = mouseupHandler;
                    }
                    
                };
                //四、定义一个获取鼠标当前需要移动多少距离的方法
                function getOffsetX(offset,min,max){
                    if(offset < min){
                        offset = min;
                    }else if(offset > max){
                        offset = max;
                    }
                    return offset;
                }
                //3.1.1鼠标移动事件的方法实现
                function mousemoveHandler(e){
                    var e = e || window.event || e.which;
                    var moveX = e.clientX?e.clientX:e.changedTouches[0].clientX;
                    var offsetX = getOffsetX(moveX - downX,0,maxMoveX);
                    slider.style.left = offsetX + "px";
                    // e.preventDefault();
                };
                //3.1.2鼠标松开事件的方法实现
                function mouseupHandler(e){
                    var moveX = e.clientX?e.clientX:e.changedTouches[0].clientX;
                    var endX = getOffsetX(moveX - downX,0,maxMoveX);
                    if(endX <= successUnlockX[1] && endX >= successUnlockX[0]){
                        slider.style.left = endX + "px";
                        success();
                    }
                    if(!self.isSuccess){
                        slider.style.left = 0 + "px";
                        slider.style.transition = "left 0.5s linear";
                    }
                    document.onmousemove = null;
                    document.onmouseup = null;
                    //移除移动端事件
                    document.ontouchmove = null;
                    document.ontouchend = null;
                };
                //五、定义一个滑块解锁成功的方法
                function success(){
                    self.isSuccess = true;
                    //滑动成功时,移除鼠标按下事件和鼠标移动事件
                    slider.onmousedown = null;
                    document.onmousemove = null;
                    //移除移动端事件
                    document.ontouchstart = null;
                    document.ontouchmove = null;
                    self.$emit("successUnlock");
                };
            })
            
        },
        methods: {
            
        },
    }
    </script>
    
    <style scoped>
    #slide_unloack_wraper{
        position: relative;
    }
    #slide_unloack_inner{
        position: absolute;
        left:0;
        top:0;
        touch-action: none;
    }
     
    </style>

    使用:

    import SlideToUnlock from '@/components/slideToUnlock';
    components:{SlideToUnlock},
    <SlideToUnlock @successUnlock="unlockSuccess()" />

    效果:

     手机端:

     睡觉。。。

  • 相关阅读:
    Python面试题目--汇总
    MySQL索引背后的数据结构及算法原理
    Python中的str与unicode处理方法
    消息队列 RabbitMQ
    python采用pika库使用rabbitmq总结,多篇笔记和示例
    SQL总结(一)基本查询
    【IT笔试面试题整理】判断一个树是否是另一个的子树
    【IT笔试面试题整理】有序数组生成最小高度二叉树
    【IT笔试面试题整理】给定二叉树,给每层生成一个链表
    【IT笔试面试题整理】位操作
  • 原文地址:https://www.cnblogs.com/fqh123/p/12359804.html
Copyright © 2011-2022 走看看