码迷,mamicode.com
首页 > 其他好文 > 详细

图片-滑动-解锁-组件-vue-canvas

时间:2020-02-25 09:14:03      阅读:365      评论:0      收藏:0      [点我收藏+]

标签:alt   doc   next   ros   info   inner   鼠标移动   math   背景   

<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_20200224232124.png?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);//再画到正方形的下边线的左侧
        ctx.lineTo(x,y);//再画到正方形的起始点 形成闭环
        // ctx.clip();//用剪刀裁剪
        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()" />

效果:

技术图片

 

 手机端:

技术图片

 

 睡觉。。。

图片-滑动-解锁-组件-vue-canvas

标签:alt   doc   next   ros   info   inner   鼠标移动   math   背景   

原文地址:https://www.cnblogs.com/fqh123/p/12359804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!