根据[微信小程序滑动验证拼图(有效果图)] 修改完成的,为了改变频繁操作dome造成的卡顿使用了movable-area组件,没有使用canvas组件(主要是不太会)(https://blog.youkuaiyun.com/qq_43764578/article/details/120471704?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1.no_search_link
)
JS部分
Page({
data: {
imgList: [
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202104/80642e30c182eb62948ca941ccbcba52--4043580224.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202104/d7185ba6c042dcdf7dc1af813c5ed89d--2870795461.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202104/7b722352e7d17c51833d951ffb354c5f--1662194361.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202104/1b920a15c1e443e37ebf70a8623a332b--4148142530.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202111/0babd389b7490b572faf32e6d5fce229--3317554742.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202111/a86c79d06f12e4307c8eb552397835e0--4065678709.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202110/99dec0a5be0bde3a83fdd95216c3cbdb--2113994346.jpg',
'http://cdn-ali-img-shstaticbz.shanhutech.cn/bizhi/staticwp/202109/dd4e103a0de0a14e4c70cd6f07a64558--358028365.jpg'
],
slidebel:false,//滑动弹窗
canfile_image:'',//正在使用的图片
canfile_x:'',//x返回 60 至 240 之间的数
canfile_y:'',//y返回 0 至 50 之间的数
slide_clientX:0,//移动位置
slide_status:0,//0 停止操作 1 触发长按 2 正确 3 错误
initX: 0
},
// 弹窗
visidlisd(e){
this.setData({
slidebel:!this.data.slidebel
})
if(this.data.slidebel){
this.slide_tap()
}
},
pxToRpx(px){
return px * 750 / wx.getSystemInfoSync().windowWidth;
},
// 画布
slide_tap(e){
var that = this
let imgList = that.data.imgList
let canfile_index = Math.round(Math.random() * 8) // 0 - 8
that.setData({
slide_clientX: 0,
initX: 0,
canfile_x: that.pxToRpx(Math.round(Math.random() * 130 + 60)),
canfile_y: that.pxToRpx(Math.round(Math.random() * 54)),
canfile_image: imgList[canfile_index]
})
},
// 滑动开始的变化中
bindchangeSku(e){
this.setData({
slide_clientX: this.pxToRpx(e.detail.x) > 500 ? 500 : this.pxToRpx(e.detail.x)
})
},
// 滑动开始
slide_start(e){
this.setData({
slide_status:1
})
},
//滑动结束
slide_chend(e){
var that = this
var cliextX;
if(that.data.slide_clientX < 1){
that.data.slide_status = 0
return false
}
if(that.data.slide_clientX > 500){
cliextX = 500
}else{
cliextX = that.data.slide_clientX
}
if(((that.data.canfile_x + 10) > cliextX) && ((that.data.canfile_x - 10) < cliextX)){
// 正确
that.setData({
slide_status:2,
slide_clientX:that.data.canfile_x,
})
setTimeout(function () {
that.setData({
slidebel:false,
})
},1000)
}else{
// 错误
that.setData({
slide_status:3,
})
}
setTimeout(function () {
that.setData({
slide_status:0,
initX: 0,
slide_clientX:0,
})
},1200)
},
})
WXML部分
<button bindtap="visidlisd">滑动验证</button>
<!-- 滑动验证弹窗 -->
<view class="slide_model" wx:if="{{slidebel}}">
<view>
<movable-area class="canvas_img" style="width: 600rpx;height: 336rpx;">
<image src="{{canfile_image}}" style="width: 600rpx;height: 336rpx;"></image>
<movable-view direction="all" damping="100" style="width: 100rpx;height:100rpx" disabled x="{{canfile_x + 'rpx'}}"
y="{{canfile_y + 'rpx'}}">
<view class="canvas_view"></view>
</movable-view>
<movable-view direction="all" damping="100" disabled x="{{slide_clientX + 'rpx'}}" y="{{canfile_y + 'rpx'}}">
<view class="canfile_image"
style="background-image: url({{canfile_image}});background-size: 600rpx 336rpx; background-position: -{{canfile_x}}rpx -{{canfile_y}}rpx;">
</view>
</movable-view>
</movable-area>
<movable-area class="canvas_slide">
<view class="canvas_width"
style="width:600rpx;{{slide_status == 1?'background:#d1e9fe;border-color:#1991fa':''}}{{slide_status == 2?'background:#d2f4ef;border-color:#52ccba;color:#52ccba':''}}{{slide_status == 3?'background:#fce1e1;border-color:#f57a7a;color:#f57a7a':''}}">
<view>{{slide_status == 0 ? '拖动左边滑块完成上方拼图' : slide_status == 2 ? '验证成功' : slide_status == 3 ? '验证失败' : ''}}
</view>
</view>
<movable-view direction="horizontal" damping="100" x="{{initX}}" bindtouchstart="slide_start" bindtouchend="slide_chend"
bindchange="bindchangeSku">
<view class="canvas_kus" wx:if="{{slide_status < 2}}"
style="{{slide_status > 0?'background:#1991fa;border-color:#1991fa;color:#ffffff':''}}">
<van-icon name="down" class="arrowIconRight" />
</view>
</movable-view>
</movable-area>
<!-- <view class="canvas_guil">
<view bindtap="visidlisd" class="cuIcon-roundclose">关闭</view>
<view bindtap="slide_tap" class="cuIcon-refresh">刷新</view>
</view> -->
</view>
</view>
WXSS部分
/* 滑动验证 */
.slide_model {
width: 100%;
padding-top: 20vh;
height: 80vh;
z-index: 10;
position: fixed;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.4);
display: flex;
align-items: flex-start;
justify-content: center;
}
.slide_model>view {
float: left;
z-index: 1;
position: relative;
width: calc(600rpx + 60rpx);
background-color: #fff;
border-radius: 10rpx;
}
#firstCanvas {
z-index: 1 !important;
}
.canvas_img {
width: 600rpx;
height: 336rpx;
position: relative;
margin: 30rpx 30rpx 0;
}
.canvas_view {
width: 100rpx;
height: 100rpx;
position: absolute;
background: #fff;
opacity: 0.4;
box-shadow:inset 2px 2px 5px rgb(29, 28, 28);
z-index: 0;
}
.canfile_image {
width: 100rpx;
height: 100rpx;
position: absolute;
left: 0;
z-index: 3;
box-shadow: 0px 2rpx 54rpx rgba(0, 0, 0, 0.2);
}
.canvas_kus {
border-radius: 4rpx;
width: 80rpx;
height: 80rpx;
background-color: #fff;
font-size: 36rpx;
font-weight: 700;
position: absolute;
left: 0;
top: 0;
border: 2rpx solid #ddd;
color: #45494c;
line-height: 90rpx;
text-align: center;
transition: 0.1s all linear;
}
.arrowIconRight{
transform: rotate(-90deg);
font-weight: 600;
}
.canvas_width {
position: absolute;
left: 0;
top: 0;
height: 80rpx;
background-color: #f7f9fa;
width: 0;
border: 1px solid #e4e7eb;
line-height: 80rpx;
text-align: center;
font-size: 32rpx;
color: #45494c;
border-radius: 4rpx;
}
.cuIcon-back_android {
transform: rotate(180deg);
}
.canvas_slide {
width: 540rpx;
height: 86rpx;
margin: 30rpx;
position: relative;
}
.canvas_guil {
width: 100%;
border-top: 1px solid #f4f4f4;
height: 100rpx;
display: flex;
align-items: center;
float: left;
font-size: 46rpx;
color: #666;
}
.canvas_guil>view {
margin-left: 30rpx;
}