js 滑动验证

版权声明:来自MarieDreamer https://blog.csdn.net/qq_33514421/article/details/83052247

前言

看到B站的滑动验证,便跟着做了一个。我检查了b站的元素,发现它的背景图片好像是切成了很多块,可能是后台处理的图片放到前端。我这个案例是纯html+css+js做的,可以在后台取随机数为滑动条验证正确的x位置。但是这样做可能安全性不高,以后再研究后台处理图片的方法。希望有大佬看到能够提点。

效果

 思路

1、放置一张背景图片,在图中指定范围内生成一个拼图凹槽(图片)

2、在大图下方放置滑动条,滑动时生成同x位置的拼图图片,并且y位置与拼图凹槽一直,x值随滑动条绑定。

3、当拼图图片x位置与拼图凹槽一致,并且滑动条松开,则成功,否则失败,并还原滑动条,销毁两个拼图图片。

关于如何获取到被“抠”出的那块图片区域,我其实是将图片复制,只显示那个位置的区域,并用css的clip-path属性裁剪出拼图的形状。这个方法很笨,主要我现在对css遮罩不了解。如果有更好的方法会马上优化的,欢迎指正!~

代码

wxml

<view class='info' style='display:{{info?"block":"none"}}'>
  {{info_text}}
</view>

<view class='bar1' 
style="height:{{bar_height+200}}rpx;width:{{bar_width+20}}rpx;border-radius:{{bar_height/2}}rpx;background-image:url(../../images/bg.png);background-size:100% 100%;">
<!-- 活动的拼图 -->
  <view class='pintu1 {{show?"show":"hide"}}' style='margin-left:{{left}}rpx;width:{{ball_width+20}}rpx;height:{{ball_width+20}}rpx;margin-top:{{top}}rpx;' bindtouchstart='touchS' bindtouchmove='touchM' bindtouchend='touchE'>
  <view style='width:{{ball_width+20}}rpx;height:{{ball_width+20}}rpx;background-image:url(../../images/bg.png);background-size:{{bar_width+20}}rpx {{bar_height+200}}rpx;position:absolute;z-index:2;background-repeat:no-repeat;background-position-x:{{-left_random}}rpx;background-position-y:{{-top}}rpx;clip-path: polygon(6% 22%, 31% 22%, 31% 6%, 53% 6%, 53% 22%, 77% 22%, 77% 47%, 93% 47%, 93% 68%, 77% 68%, 77% 93%, 53% 93%,53% 75%,31% 75%,31% 93%,6% 93%,6% 68%,24% 68%,24% 47%,6% 47%)'>
  </view>
  <view style='width:{{ball_width+20}}rpx;height:{{ball_width+20}}rpx;position:absolute;background:gray;clip-path: polygon(5% 21%, 30% 21%, 30% 5%, 54% 5%, 54% 21%, 78% 21%, 78% 46%, 93% 46%, 93% 69%, 78% 69%, 78% 94%, 52% 94%,52% 75%,31% 75%,31% 93%,6% 93%,6% 68%,24% 68%,24% 47%,6% 47%)'>
  </view>
</view>
  <!-- 目标拼图 -->
  <image src="../../images/pintu2_final.png" class='pintu2 {{show?"show":"hide"}}'
  style='margin-left:{{left_random}}rpx;width:{{ball_width+20}}rpx;height:{{ball_width+20}}rpx;margin-top:{{top}}rpx;'></image>
</view>

<!-- 控制条 -->
<view class='bar' style="height:{{bar_height}}rpx;width:{{bar_width}}rpx;border-radius:{{bar_height}}rpx;">
  <view class='ball' id="ball" style='margin-left:{{left}}rpx;width:{{ball_width}}rpx;' bindtouchstart='touchS' bindtouchmove='touchM' bindtouchend='touchE'></view>
</view>

wxss

page{
  background: #eee
}
.bar1{
  background: #fff;
  margin: 50rpx auto;
  padding: 10rpx;
  display: flex;
  position: relative;
  z-index: 1;
}
.bar{
  background: #fff;
  margin: 50rpx auto;
  padding: 10rpx;
  display: flex;
  align-items: center;
  position: relative;
  z-index: 1;
}
.road{
  background: red;
  width:100%;
  height:100%;
}
.ball{
  border-radius: 100%;
  background-color: #aaa;
  height: 100%;
}
.pintu1{
  position: absolute;
  z-index: 3;
}
.pintu2{
  position: absolute;
  z-index: 2;
}
.show{
  display: block;
}
.hide{
  display: none;
}
.info{
  background: black;
  left: 50%;
  transform:translate(-50%, 0);
  opacity: 0.6;
  width: 300rpx;
  height: 200rpx;
  position: absolute;
  z-index: 3;
  top:85rpx;
  border-radius: 10rpx;
  color: white;
  line-height: 200rpx;
  text-align: center;
}

js

Page({

  data: {
    left:0,
    show:0
  },

  onLoad: function (options) {
    
  },
  onReady:function(e){
    let self = this;
    this.setData({
      bar_width : 400,
      bar_height : 50
    })
    //获取小球高度
    var query = wx.createSelectorQuery();
    query.select('#ball').boundingClientRect()
    query.exec(function (res) {
      var h = res[0].height;
      self.setData({
        ball_width: h*2
      })
    })

    const ctx = wx.createCanvasContext('myCanvas')
    ctx.setFillStyle('red')
    ctx.fillRect(10, 10, 150, 75)
    ctx.draw()
  },
  touchS:function(e){
    this.data.start = e.touches[0].pageX;
    this.data.start_left = this.data.left;
    this.setData({
      show:1,
      top: Math.floor(Math.random() * (this.data.bar_height + 180 - this.data.ball_width)),
      left_random: Math.floor(Math.random() * (this.data.bar_width-this.data.ball_width)/2+150)
    })

  },
  touchM:function(e){
    this.data.end = e.touches[0].pageX;
    this.data.move = this.data.end - this.data.start;
    this.data.end_left = this.data.start_left + this.data.move * 2;
    if (this.data.end_left < 0){
      this.setData({
        left: 0
      })
    } else if (this.data.end_left > this.data.bar_width - this.data.ball_width){
      this.setData({
        left: this.data.bar_width - this.data.ball_width
      })
    }else{
      this.setData({
        left: this.data.end_left
      })
    }
  },
  touchE:function(e){
    var info = '';
    let that = this;
    if (this.data.left > this.data.left_random - 10 && this.data.left < this.data.left_random + 10){
      info='success'
    }else{
      info = 'fail'
    }
    this.setData({
      info: 1,
      info_text: info
    })
    setTimeout(function () {
      that.setData({
        info: 0,
        show:0,
        left:0
      })
    }, 1000)
  }

})

猜你喜欢

转载自blog.csdn.net/qq_33514421/article/details/83052247