前言

最近在研究图片滑动解锁 登录,说是要用阿里的那个验证,但是还是想自己手写下这个Demo

效果图是这样的:

本来是想用canvas 来实现的,但是类,后来还想用css 和图片来代替canvas

其实思路就这样的:

那个缺陷的滑块位置 是随机的 根据 图片的宽高 产生 随机 数当然是定位 : left,top.,然后距离最左边的距离 moveToLeft,

最后滑动的距离和这个距离作比较,看看是否相等 。。然后就好了......

vue 中滑动开始 start 开始计算时间 - 》 想右滑动的距离等于滑块滑动的距离

思路其实也不难,就放上代码吧:

<template>
<section class="code_bg">
<div class="slide-box">
<div class="slide-img-block">
<div class="slide-img-div">
<div class="slide-img-nopadding">
<img class="slide-img" id="slideImg" :src="img">
<div class="slide-block" id="slideBlock"></div>
<div class="slide-box-shadow" id="cutBlock"></div>
</div>
</div>
</div>
<div class="scroll-background slide-img-hint-info" id="slideHintInfo" style="height: 0px;">
<div class="slide-img-hint">
<div class="scroll-background slide-icon" id="slideIcon"></div>
<div class="slide-text">
<span class="slide-text-type greenColor" id="slideType">验证通过:</span>
<span class="slide-text-content" id="slideContent">用时0.4s</span>
</div>
</div>
</div>
<i class="iconfont icon-refresh" @click="resImg"></i>
<!-- 滑块 -->
<div class="slideBox" ref="slideBox">
<div class='slide'
@touchstart="touchStart($event)"
@touchmove="touchMove($event)"
@touchend="touchEnd($event)" :style="{'left':moveToLeft+'px'}" ref="slide">
<i class="iconfont "></i></div>
<div class="slideBg" :style="{'width':moveToLeft+'px'}"></div>
<div class="textBg" v-show="moveToLeft>0">拖动左边滑块完成上方拼图</div>
<span class="default" v-show="moveToLeft===0">拖动左边滑块完成上方拼图</span>
</div>
</div>
</section>
</template> <script>
export default {
name: "slideBox",
data() {
return {
msg: "滑动",
moveToLeft: 0, //滑动距离
starX: 0, //初始距离
slideBoxWidth: 0,
slideWidth: 0,
resultX: "",
slideBlock: "",
cutBlock: "",
imgWidth: "",
imgHeight: "",
slideIcon: "", // 图标
slideType: "", // 失败
slideContent: "", //正文
slideHintInfo: "", //弹出
isSuccess: true,
startTamp: "", //开始时间
endTamp: "", //结束时间
timer: "", // 用时解开
img: "", // 图片
imgList: [
"http://www.keaitupian.net/uploads/allimg/170120/1A12A959-0.jpg",
"http://www.keaitupian.net/uploads/allimg/150409/15124TD2-3.jpg",
"http://www.keaitupian.net/uploads/allimg/150409/15124U2E-0.jpg",
"http://www.keaitupian.net/uploads/allimg/150409/15124RI8-4.jpg",
"http://www.keaitupian.net/uploads/allimg/170120/1A5142649-1.jpg",
"http://www.keaitupian.net/uploads/allimg/161207/1_161207173815_3.jpg",
"http://www.keaitupian.net/uploads/allimg/161207/1_161207173815_4.jpg",
"http://www.keaitupian.net/uploads/allimg/160804/09321051Z-0.jpg",
"http://www.keaitupian.net/uploads/allimg/160804/0932105013-1.jpg"
]
};
},
mounted() {
let _this = this;
setTimeout(() => {
this.$loading.close();
}, 500);
_this.slideBoxWidth = _this.$refs.slideBox.clientWidth;
_this.slideWidth = _this.$refs.slide.clientWidth;
_this.cutBlock = document.getElementById("cutBlock"); // 裁剪区域
_this.slideBlock = document.getElementById("slideBlock"); // 裁剪的图片
_this.imgWidth = document.getElementById("slideImg").offsetWidth; // 图片宽
_this.imgHeight = document.getElementById("slideImg").offsetHeight; // 图片高
_this.slideIcon = document.getElementById("slideIcon"); // 正确、失败的图标
_this.slideType = document.getElementById("slideType"); // 正确、失败
_this.slideContent = document.getElementById("slideContent"); // 正确、失败的正文
_this.slideHintInfo = document.getElementById("slideHintInfo"); // 弹出
_this.resImg();
},
methods: {
touchStart(e) {
let _this = this;
console.log("zzzz:" + e.targetTouches[0].pageX);
let starX = e.targetTouches[0].pageX;
_this.starX = starX;
_this.startTamp = new Date().valueOf();
if (_this.isSuccess) {
_this.cutImg();
}
},
touchMove(e) {
let _this = this;
console.log("yyyy:" + e.targetTouches[0].pageX); let ToLeft = e.targetTouches[0].pageX - _this.starX; //变化后的坐标减去初始坐标
let slideBoxW = Math.floor(_this.slideBoxWidth - _this.slideWidth - 1); //计算大盒子宽度
if (ToLeft < 0) {
ToLeft = 0; //滑块不能超出大盒子左边
_this.slideBlock.style.left = "0px";
}
if (ToLeft >= 0 && ToLeft <= slideBoxW) {
_this.slideBlock.style.left = ToLeft + "px";
} if (ToLeft > slideBoxW) {
ToLeft = slideBoxW; //滑块不能超出大盒子右边
}
_this.moveToLeft = ToLeft;
console.log("离开的" + _this.resultX);
},
touchEnd() {
let _this = this;
let ToLeft = _this.moveToLeft;
if (_this.resultX > ToLeft - 4 && _this.resultX < ToLeft + 4) {
_this.isSuccess = true;
_this.endTamp = new Date().valueOf();
_this.timer = ((_this.endTamp - _this.startTamp) / 1000).toFixed(1);
// 裁剪图片(拼图的一块)
_this.slideBlock.style.opacity = "0";
// _this.slideBlock.style.transition = "opacity 0.6s";
// 裁剪的区域(黑黑的那一块)
_this.cutBlock.style.opacity = "0";
_this.cutBlock.style.transition = "opacity 0.6s";
// 正确弹出的图标
_this.slideType.className = "slide-text-type greenColor";
_this.slideType.innerHTML = "验证通过:";
_this.slideContent.innerHTML = "用时" + _this.timer + "s";
setTimeout(function() {
_this.cutBlock.style.display = "none";
_this.slideBlock.style.left = "0px";
//_this.reToNewImg();
_this.$toast({
message: "验证通过"
});
}, 600);
//_this.options.success && _this.options.success();
} else {
_this.isSuccess = false;
// 设置样式
// 裁剪图片(拼图的一块)
_this.slideBlock.style.left = "0px";
// 错误弹出的图标 _this.slideType.className = "slide-text-type redColor";
_this.slideType.innerHTML = "验证失败:";
_this.slideContent.innerHTML = "拖动滑块将悬浮图像正确拼合";
_this.slideBlock.style.left = "0px";
_this.resImg();
}
// 设置样式
_this.slideHintInfo.style.height = "22px";
setTimeout(function() {
_this.slideHintInfo.style.height = "0px";
}, 1300);
//离开的时候回到初始位置
_this.moveToLeft = 0;
},
cutImg() {
var _this = this;
_this.cutBlock.style.display = "block";
var cutWidth = _this.cutBlock.offsetWidth; // 裁剪区域宽
var cutHeight = _this.cutBlock.offsetHeight; // 裁剪区域高
// left
_this.resultX = Math.floor(
Math.random() * (_this.imgWidth - cutWidth * 2 - 4) + cutWidth
);
// top
var cutTop = Math.floor(
Math.random() * (_this.imgHeight - cutHeight * 2) + cutHeight
);
// 设置样式
_this.cutBlock.style.cssText =
"top:" +
cutTop +
"px;" +
"left:" +
_this.resultX +
"px; display: block;";
_this.slideBlock.style.top = cutTop + "px";
_this.slideBlock.style.backgroundPosition =
"-" + _this.resultX + "px -" + cutTop + "px";
_this.slideBlock.style.opacity = "1";
},
resImg() {
let _this = this;
_this.isSuccess = true;
let newImg = _this.imgList[Math.round(Math.random() * 8)];
_this.img = newImg;
_this.slideBlock.style.backgroundImage = "url(" + newImg + ")";
_this.slideBlock.style.opacity = "0";
_this.cutBlock.style.display = "none";
}
}
};
</script> <style lang="scss" scoped> // 上面的滑块
.code_bg {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 20;
// 图片
.slide-box {
display: block;
position: relative;
top: 25%;
background: #fff;
padding: 5% 0;
.slide-btn {
height: 44px;
width: 44px;
background-position: 0 -84px;
cursor: pointer;
display: block;
position: absolute;
left: 0;
top: -9px;
-moz-box-shadow: none;
box-shadow: none;
border-radius: 13px;
z-index: 399;
}
.icon-refresh {
display: block;
font-size: 0.4rem;
margin-left: 6%;
margin-top: 1%;
color: #d0caec;
}
.slide-img-div {
width: 100%;
height: 3rem;
padding: 0 5%;
position: relative;
border-left: 1px solid #fff;
border-right: 1px solid #fff;
img {
width: 100%;
height: 100%;
}
.slide-box-shadow {
display: none;
position: absolute;
width: 0.8rem;
height: 0.8rem;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.3);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.8) inset;
}
.slide-block {
opacity: 0;
position: absolute;
top: 0;
left: 2px;
width: 0.8rem;
height: 0.8rem;
border-radius: 0.08rem;
background-repeat: no-repeat;
background-attachment: scroll;
border: 1px solid rgba(255, 255, 0, 0.8);
background-size: 100% 3rem;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4),
0 0 10px 0 rgba(90, 90, 90, 0.4);
box-sizing: border-box;
z-index: 10;
}
.slide-img-nopadding {
position: relative;
width: 100%;
height: 100%;
}
}
.slide-icon {
float: left;
height: 22px;
width: 26px;
}
.slide-img-hint {
-webkit-font-smoothing: subpixel-antialiased;
font-size: 12px !important;
line-height: 22px !important;
margin: 0 auto;
position: relative;
}
.slide-text {
text-align: left !important;
color: #4b3f33;
}
.slide-img-hint-info {
height: 22px;
width: 260px;
background-position: 0 -674px;
height: 0;
overflow: hidden;
position: absolute;
bottom: 1px;
transition: height 0.3s;
z-index: 11;
}
.redColor {
color: red;
}
.greenColor {
color: green;
}
}
// 滑块
.slideBox {
z-index: 20;
height: 0.89rem;
border: 1px solid #d5d3e2;
margin: 0.1rem 0 0.2rem 0;
line-height: 0.89rem;
background: #d0caec;
color: #fff;
font-size: 16px;
position: relative;
top: 30%;
width: 90%;
left: 5%;
.slide {
height: .86rem;
width: 0.8rem;
background: #fff;
position: absolute;
top: 0px;
left: 0;
i {
width: 0;
height: 0;
border-width: 10px;
border-style: dashed dashed dashed solid;
border-color: transparent transparent transparent #d0caec;
position: absolute;
top: 50%;
left: 50%;
margin: -0.2rem 0 0 -0.05rem;
}
}
.slideBg {
height: 0.89rem;
background: linear-gradient(
to top right,
#cddc39 0%,
#8bc34a 25%,
#ffeb3b 100%
);
}
.textBg {
height: 0.89rem;
width: 100%;
text-align: center;
position: absolute;
top: 0;
}
.default {
height: 0.89rem;
position: absolute;
top: 0;
left: 15%;
width: 70%;
text-align: center;
}
}
}
</style>

好啦 ,就先这样吧

vue 图片滑动登录的更多相关文章

  1. Qt浅谈之二十六图片滑动效果

    一.简介 博客中发现有作者写的仿360的代码,觉得其中图片滑动的效果很有意思,特提取其中的代码.并加上类似mac的画面移动的动画效果. 二.详解 1.代码一:界面滑动(QWidget) (1)slid ...

  2. uni-app开发经验分享二十一: 图片滑动解锁插件制作解析

    在开发用户模块的时候,相信大家都碰到过一个功能,图片滑动解锁后发送验证码,这里分享我用uni-app制作的一个小控件 效果如下: 需要如下图片资源 template <template> ...

  3. 循序渐进BootstrapVue,开发公司门户网站(4)--- 使用b-carousel-slide组件实现图片轮播以及vue-awesome-swiper实现图片滑动展示

    在BootstrapVue组件库里面,提供了很多对Bootstrap同等类似的组件封装,其中图片轮播可以采用b-carousel-slide组件实现,而有一些小的图片,如客户/合作伙伴Logo或者友情 ...

  4. javascript效果:手风琴、轮播图、图片滑动

    最近都没有更,就来几个效果充实一下. 都没有进行美化这步. 手风琴: 纯css: <!DOCTYPE html> <html lang="en"> < ...

  5. js实现图片滑动显示效果

    js实现图片滑动显示效果 今天用户提出一个需求,要实现一个滑动显示新闻列表的效果,具体就是图片新闻自动滑动显示,鼠标移上去就停止滑动,移开就继续滑动:效果如下: 第一:先用HTML和CSS实现显示,主 ...

  6. 19个非常有用的 jQuery 图片滑动插件和教程

    jQuery 是一个非常优秀的 Javascript 框架,使用简单灵活,同时还有许多成熟的插件可供选择.其中,最令人印象深刻的应用之一就是对图片的处理,它可以让帮助你在你的项目中加入精美的效果.今天 ...

  7. 推荐一款手机端的图片滑动插件iSlider

    首先先放出中文官方地址   http://be-fe.github.io/iSlider/index.html 这是demo 众所周知,移动端的图片滑动插件有很多,为什么我要推荐这个iSlider呢? ...

  8. 个人学习JQ插件编写成果:little酷炫的图片滑动切换效果

    工作一个多月了,好久没来冒冒泡了,看了@wayong的JQ插件教程,自己编写了一个模仿拉勾网首页广告栏滑动特效的JQ插件,现在跟朋友们分享分享! 先上demo链接:http://runjs.cn/de ...

  9. html、css、js实现手风琴图片滑动

    手风琴图片滑动是我最近学的一个图片的效果,感觉不错,分享给大家. 最终效果见 :http://gjhnstxu.me/squeezebox/demo.html 详细代码如下: html代码: < ...

随机推荐

  1. C语言Ⅰ博客作业07

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9933 我在这个课程的目 ...

  2. 【java基础学习001】概述

    001.1    一个简单的Java程序 public class hello { public static void main(String[] args) { System.out.printl ...

  3. SQL Server解惑——为什么你的查询结果超出了查询时间范围

    原文:SQL Server解惑--为什么你的查询结果超出了查询时间范围 废话少说,直接上SQL代码(有兴趣的测试验证一下),下面这个查询语句为什么将2008-11-27的记录查询出来了呢?这个是同事遇 ...

  4. SQL Server 2019 Linux Docker 在主机上以其他非根用户的身份运行容器

    docker logs mssql2019SQL Server 2019 will run as non-root by default.This container is running as us ...

  5. Maven学习存档(1)——安装

    一.安装 1.1 jdk的下载与安装 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html 版本:maven2 ...

  6. Adaboost推导

    AdaBoost算法推导过程: https://www.jianshu.com/p/0d850d85dcbd

  7. ubuntu切换root用户

    方法一:sudo su命令 方法二:sudo -i 方法三:su root

  8. jvm调试相关:jmap失效下找到alternatives神器

    1.使用 jmap <pid>出现的错误日志:很明显是版本问题 Error attaching to process: sun.jvm.hotspot.runtime.VMVersionM ...

  9. JAVA问题String literal is not properly closed by a double-quote

    String literal is not properly closed by a double-quote 这个错误:string字串没有以双引号结束String DBURL = "jd ...

  10. hive用户自定义函数

    一.UDF 1.显示所有函数:show functions ; 2.显示指定函数的帮助:$hive>desc function current_database(); 3. 什么是 UDF? 当 ...