接到一个任务,做一个活动卡片,卡片左右滑动带动卡片上方的任务条走到对应节点:
1、卡片和任务条均为动态生成
2、卡片底部可以左右滑动
3、当一张卡片超过50%的区域展示出来后放手,定位到对应卡片
4、卡片更换完成后,上方任务轴同时更换

这个任务的主要就在数据格式的制定与滑动的判断,不是很难、用vue写的

1.首先写出一个卡片的样式,得到其宽度,获取共有多少张卡片。所有卡片放在一个div里面,div的宽度为(卡片宽度+卡片间距)*卡片数量 width:${cardcount*97}%
2.滑动开始,获取起始位置startX
滑动时,使卡片跟着滑动,transform:translateX(${cardLeft}px),滑动距离超过一个卡片的宽度时,滑动宽度为卡片的宽度
3.滑动结束时,获取结束位置endX,得到滑动的距离disX = endX - startX,判断超过卡片的50%,则滑动一个卡片,否则不滑动。如果此时是第一个卡片还要右滑,或者是最后一个卡片还要左滑,则不滑动
4.滑动一个卡片,任务轴传一个变量,改变当前任务点
核心:

      cardLeft: 0, //现移动距离
      startX: 0, //起始位置
      endX: 0, //结束位置
      nowLeft: 0, //移动时距离
      disX: 0, //总移动距离
      cardWidth: 0,//卡片(移动)宽度
    touchStart(ev) {
      ev = ev || event;
      this.cardWidth = this.$refs.card.offsetWidth / this.cardcount - 10;
      if (ev.touches.length === 1) {
        this.startX = ev.touches[0].clientX;
      }
    },
    touchMove(ev) {
      ev = ev || event;
      // 选项卡宽度
      let cardWd = this.cardWidth;

      if (ev.touches.length === 1) {
        //滑动时距离浏览器左侧实时距离
        let moveDisX = ev.touches[0].clientX;
        this.disX = moveDisX - this.startX;
        let absDisX = Math.abs(this.disX);

        if (this.disX != 0) {
          this.cardLeft = this.disX + this.nowLeft;
          // 滑动超过一个卡片的距离
          if (absDisX >= cardWd) {
            this.cardLeft = this.nowLeft + cardWd * (this.disX / absDisX);
          }
        }
      }
    },
    touchEnd(ev) {
      ev = ev || event;
      if (this.disX === 0) {
        return;
      }
      //卡片宽度-滑动距离
      var cardwd = this.cardWidth;

      if (ev.changedTouches.length == 1) {

        this.endX = ev.changedTouches[0].clientX;
        this.disX = this.endX - this.startX;

        //左滑到头仍要左滑 右滑到头仍要右滑,回到起点
        if (
          this.disX + this.nowLeft >= 0 ||
          this.disX + this.nowLeft <= -cardwd * (this.cardcount - 1)
        ) {
          this.cardLeft = this.nowLeft;
        // 如果距离小于删除按钮一半,强行回到起点 
        } else if (Math.abs(this.disX) < cardwd / 2) {
          this.cardLeft = this.nowLeft;
        } else {
          //大于一半 滑动到最大值
          if (this.disX > 0) {
          //切换任务轴
            this.nowIndex--;
            this.cardLeft = this.nowLeft + cardwd;
            this.nowLeft = this.cardLeft;
          } else {
          //切换任务轴
            this.nowIndex++;
            this.cardLeft = this.nowLeft + cardwd * -1;
            this.nowLeft = this.cardLeft;
          }
        }
      }
    }

html

    <!-- 卡片列表 -->
    <div class="occupied">
      <div
        :style="`width:${cardcount*97}%;transform:translateX(${cardLeft}px)`"
        class="task_card"
        @touchstart="touchStart"
        @touchmove="touchMove"
        @touchend="touchEnd"
        ref="card"
      >
        <card
          class="card"
          v-for="(item,index) in beginnerList"
          :key="index"
          :list="item"
          :lock="index >= progressBar.current"
        ></card>
      </div>
    </div>

页面效果,中间为当前样式,左右任务卡各展示一点:
卡片左右滑动 带动任务条滑动 vue

任务轴,完成的任务白色不透明,未完成的有一点透明度。展示那个卡片对应的原点,出现一个包裹的圈,并将此点展示在中间:
卡片左右滑动 带动任务条滑动 vue

相关文章:

  • 2021-11-20
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-23
  • 2022-12-23
  • 2021-12-16
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-10-20
  • 2021-12-28
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案