前言

最近在研究图片滑动解锁 登录,说是要用阿里的那个验证,但是还是想自己手写下这个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. VUe兄弟通信

    用过Vue,你肯定知道,Vue组件之间的通信常见的有$dispatch - 通过冒泡的方式传递事件$broadcast - 通过广播的方式向子孙组件传递事件 如果组件之间的关系只是父-子关系,那么di ...

  2. 基于SpringBoot从零构建博客网站 - 整合ehcache和开发注册登录功能

    对于程序中一些字典信息.配置信息应该在程序启动时加载到缓存中,用时先到缓存中取,如果没有命中,再到数据库中获取同时放到缓存中,这样做可以减轻数据库层的压力.目前暂时先整合ehcache缓存,同时预留了 ...

  3. oracle:archiver error. Connect internal only, until freed 原因以及错误的处理方法

    今天小编遇到这个数据原因,通过查找资料解决了,问题原因就是数据默认存储日志的文件夹满了 1.首先通过cmd命令窗口连接超级管理员,sqlplus / as sysdba; 2.查询db_recover ...

  4. 桥接模式下访问虚拟机中的Django项目

    首先需要保证主机和虚拟机能相互Ping通,如果Ping不通,请参考我上篇文章,这里演示的是桥接模式下的方法,如果是NAT模式连接,请参考别处. 1. 虚拟机Linux系统内的Django项目 sett ...

  5. 安装echo框架

    视频地址: https://www.bilibili.com/video/av63492462?p=31 echo文档地址: https://echo.labstack.com/guide/insta ...

  6. k8s-kubectl命令大全

    Kubectl命令行管理对象 类型 命令 描述 基础命令 create 通过文件名或标准输入创建资源. expose 将一个资源公开为一个新的Kubernetes服务. run 创建并运行一个特定的镜 ...

  7. X86逆向3:通过修改关键CALL破解

    软件逆向第一课中我们通过爆破的方式直接破解了程序的登录限制,但这一种方式很不合理,因为你只是破解了登录这一处的验证,如果程序内部还有其他的验证那么你需要再次爆破第二个验证,显然这种方式是很烦人的,如果 ...

  8. Eclipse怎么改变工程保存路径

    1:首先我们要把servers中的Tomcat v8.0 Server at localhost [Stopped]的删除 2:我们再进行加入Tomcat v8.0,,,,直接点击蓝色就弹出下面的页面 ...

  9. java——HashSet类中的常见方法

    package com.xt.set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; publi ...

  10. O040、Migrate Instance 操作详解

    参考https://www.cnblogs.com/CloudMan6/p/5538599.html   Migrate 操作的作用是将instance 从当前的计算节点迁移到其他的计算节点上.   ...