最近写项目要用到类似于淘宝店破的我的页面,在顶部用户执行下拉操作时顶部背景图会放大并高度增加的效果,松开时回弹到原来的大小。先上效果:
效果主要利用一下几个事件:
@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; } }
标签:动画,clientMoveY,顶部,页面,用户,value,手指,放大,图片 From: https://www.cnblogs.com/duzhaoquan/p/17919368.html