uniApp vue view自定义回弹阻尼效果

本文介绍了在uniApp中使用vue实现view自定义回弹阻尼效果的方法,适用于需要触顶、触底回弹响应的场景。文章详细阐述了实现这一效果的步骤,并提供了相关代码示例。

uniApp vue view自定义回弹阻尼效果



前言

提示:有这个业务需求的时候,看了很多其他的文章有两种,一种是无法真正实现,一种是效果不好,所以自己写了一个。


提示:以下是本篇文章正文内容,下面案例可供参考

一、使用场景

用于现实触顶、触底回弹效果并给出响应的需求

二、使用步骤

代码如下(示例):

<template>
	<view>
		<view class="topv">
			
		</view>
		<view
		class="cover-container"
		:style="[{
			transform: coverTransform,
			transition: coverTransition
		}]"
		@touchstart="coverTouchstart"
		@touchmove="coverTouchmove"
		@touchend="coverTouchend"
		 @scrolltolower='end'
		ref="texts"
		>
			<view class="list">
				<view class="li">1</view>
				<view class="li">2</view>
				<view class="li">3</view>
				<view class="li">4</view>
				<view class="li">5</view>
				<view class="li">6</view>
				<view class="li">7</view>
				<view class="li">8</view>
				<view class="li">9</view>
				<view class="li">1</view>
				<view class="li">2</view>
				<view class="li">3</view>
				<view class="li">4</view>
				<view class="li">5</view>
				<view class="li">6</view>
				<view class="li">7</view>
				<view class="li">8</view>
				<view class="li">9</view>
				<view class="li" id="end"></view>
			</view>
		</view>
		
	</view>
</template>

<script>
	let startY = 0, moveY = 0, pageAtTop = true,top=0,isEnd = false;
export default {
	data() {
		return {
			coverTransform: 'translateY(0px)',
			coverTransition: '0s',
			moving: false,
		};
	},

	components: {},
	props: {},
	onReachBottom(){
		console.log('触底了')
		isEnd = true;
	},
	methods: {
		getDom(dom,callback){
					let query = uni.createSelectorQuery().in(this);
					query.select(dom).boundingClientRect(res => {
						callback(res);
					}).exec();
				},
		/**
		 *  1.关闭bounce避免ios端下拉冲突
		 *  2.由于touchmove事件的缺陷(以前做小程序就遇到,比如20跳到40,h5反而好很多),下拉的时候会有掉帧的感觉
		 *    transition设置0.1秒延迟,让css来过渡这段空窗期
		 *  3.回弹效果可修改曲线值来调整效果,推荐一个好用的bezier生成工具 http://cubic-bezier.com/
		 */
		coverTouchstart(e){
			if(pageAtTop === false){
				return;
			}
			this.coverTransition = 'transform .1s linear';
			startY = e.touches[0].clientY;
			this.getDom('.topv',res=>{
							// console.log(res.top.toFixed(0))
							top = res.top.toFixed(0);
						})
		},
		coverTouchmove(e){
			// console.log(e) 
			moveY = e.touches[0].clientY;
			let moveDistance = moveY - startY;
			if(isEnd){
				// console.log(moveDistance)
				this.moving = true;
				if(moveDistance>0){
					isEnd = false;
					return;
				}
				if(moveDistance <= -80 && moveDistance >- 100){
					moveDistance = 80;
				}
					
				if(moveDistance < 0 && moveDistance >= -80){
					this.coverTransform = `translateY(${moveDistance}px)`;
				}
			}else{
				if(moveDistance < 0){
					this.moving = false;
					return;
				}else{
					if(top<0){
						return;
					}
					this.moving = true;
					if(moveDistance >= 80 && moveDistance < 100){
						moveDistance = 80;
					}
						
					if(moveDistance > 0 && moveDistance <= 80){
						this.coverTransform = `translateY(${moveDistance}px)`;
					}
				}
			}
			
		},
		coverTouchend(){
			if(this.moving === false){
				return;
			}else{
				this.moving = false;
				this.coverTransition = 'transform 0.3s cubic-bezier(.21,1.93,.53,.64)';
				this.coverTransform = 'translateY(0px)';
				setTimeout(()=>{
					if(isEnd){
						console.log('底部回弹回调')
					}else{
						console.log('顶部回弹回调')
					}
				},500)
			}
		}
	}
};
</script>
<style lang="scss">
	.li{
		width: 100%;
		height: 200rpx;
		background-color: #eee;
		text-align: center;
		line-height: 200rpx;
		margin-bottom: 20rpx;
	}
	.cover-container{
		padding: 0 30upx;
		position:relative;
		padding-bottom: 20upx;
	}
	.bntv{
		height: 100px;
	}
</style>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值