圖片-滑動-解鎖-組件-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()" />

效果:

 

 手機端:

 

 睡覺。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM