顶部图片随着下拉放大

发布时间 2023-12-21 16:30:36作者: 不停奔跑的蜗牛

最近写项目要用到类似于淘宝店破的我的页面,在顶部用户执行下拉操作时顶部背景图会放大并高度增加的效果,松开时回弹到原来的大小。先上效果:

效果主要利用一下几个事件:

@touchstart 当用户手指按下时

@touchmove 当用户手指移动过程中

@touchend 当用户手指抬起时

这几个事件会记录用户手指在屏幕和页面上的位置信息,还有一个uniapp的生命周期事件onPageScroll()监听页面滚动。

!!!这几个事件一定要绑定在最外层的标签上,监听整个页面!!!

JS代码逻辑

let clientMoveY = 0 //按下时的位置(上一次的位置)
const start = (e: TouchEvent) => {
  console.log('start-----')
  clientMoveY = e.changedTouches[0].clientY
}
const move = (e: TouchEvent) => {
  if (clientMoveY === 0) {
    clientMoveY = e.changedTouches[0].clientY
    return
  }
  // 本次手指移动的位置和上次移动的位置对比 <0 证明用户在下拉
  if (clientMoveY - e.changedTouches[0].clientY < 0) {
    // 拿到下拉的距离
    const distance = (clientMoveY - e.changedTouches[0].clientY) * 0.5
    //放大1.5倍大小
    if (imgWidth.value < 1.5) {
      sheight.value -= distance
      imgWidth.value -= distance / 300
    } else {
      //超过1.5倍就return 优化性能
      return
    }
  } else {
    return
  }
  // 上边的代码执行结束之后再把本次手指的位置赋值给data中,用来下一次对比
  clientMoveY = e.changedTouches[0].clientY
}

 结束拖拽时返回弹到原图大小

const end = (e: unknown) => {
  clientMoveY = 0
  // 当图片的高度大于400的时候手指抬起再调用函数
  if (sheight.value > 300) {
    // 执行动画
    isPlay.value = true
    //动画结束后把顶部图片的高度和放大比例该会原来的值
    setTimeout(() => {
      sheight.value = 300
      imgWidth.value = 1
      // 并把动画的class名取消掉
      isPlay.value = false
    }, 505)
  }
}

 HTML

<div class="good-detail op-fullscreen" @touchstart="start" @touchmove="move" @touchend="end">
    <div :class="{ banner: true, isPlay: isPlay }" :style="{ height: sheight + 'px' }">
      <img
        id="zoomingImage"
        :src="goods.imgUrl"
        :class="{ isPlay: isPlay }"
        :style="{ height: sheight + 'px', transform: `scale(${imgWidth})` }"
      />
    </div>
  </div>

 这里我们需要先定义一个动画,当用户手指抬起是执行这个动画:

.banner {
    width: 100%;
    overflow: hidden; //防止图片放大,宽度被撑开
    background-size: cover;
    position: relative;
    img {
      width: 100%;
      max-height: 500px;
      position: absolute;
      bottom: 0;
    }
  }
  // 一个动画
  .isPlay {
    animation: big 0.5s 1 alternate ease-in-out forwards;
  }
  @keyframes big {
    100% {
      transform: scale(1);
      height: 300px;
    }
  }