底部抽屉,模仿地图

1,155 阅读1分钟

目前uniapp的开发中,当碰到类似地图底部应用的时候,需要实现相应的效果,可能一时没有很好的思路和实现组件,这里就提供一个底部抽屉的组件。

市场demo

抽屉.png

目前提供抽屉源码可以直接放到uniapp的页面中查看滑动效果,组件代码drag-bottom-drawer.vue ,以组件的形式使用。

<template>
	<view class="bar-wrapper">
		<view class="t-box-wrapper" :style="transition+'top:'+( moveY+'px')">
			<view class="drag-handle"
			 :style="'height:'+handleHeight+'px;border-radius: '+handleHeight+'px '+handleHeight+'px 0 0;'"
			 :data-top="moveY"
			 @touchstart.stop="drag_start" 
			 @touchmove.stop="drag_hmove" @touchend.stop="drag_end"
			  @touchcancel.stop="drag_end">_____</view>
			<view id="drag-content" class="drag-content">
				<slot name="content">
				<view style="width: 30vw;height: 30vw; background-color: #0A98D5;"></view>
				<view style="width: 30vw;height: 30vw; background-color: #2C405A;"></view>
				<view style="width: 30vw;height: 30vw; background-color: #4CD964;"></view>
				</slot>
			</view>
		</view>
		
	</view>
</template>

<script>
	export default {
		name: 'rish-bottom-drawer',
		props:{
			 handleHeight:{
				 type:Number,
				 default:20,
			 }
		},
		data() {
			return {
				startY: 0,
				onelineHeight:0 ,
				moveY: - this.handleHeight,
				top: 0,
				transition: 'transition: top 0.1s;',
				windowHeight: '',
				windowWidth : '',
				toTop:true,
				
			}
		},
		mounted() {
			const {
				windowWidth,
				windowHeight
			} = uni.getSystemInfoSync();
			this.windowWidth = windowWidth
			this.windowHeight = windowHeight
			console.log(windowWidth +  "  " +  windowHeight )
			this.onelineHeight = this.windowWidth * 0.3
			this.moveY =  - this.handleHeight - this.onelineHeight
		},
		methods: {
			drag_start(event) {
				// console.log(event)
				this.transition=''
				this.top = event.currentTarget.dataset.top;
				this.startY = event.touches[0].clientY;
			},
			drag_hmove(event) {
				// console.log(event.currentTarget)
				var len = event.touches[0].clientY - this.startY;
				var temp = this.top + len;
				if (temp >= this.handleHeight) {
					temp = this.handleHeight;
				}
				this.toTop = len < 0  ;
				
				const query = uni.createSelectorQuery().in(this);
				query.select('#drag-content').boundingClientRect(data => {
					// console.log(data)
					
					if (temp <= 0 - data.height   - this.handleHeight ) {
						temp = 0 - data.height - this.handleHeight
					}
					
					if (temp <= 0 - (this.windowHeight * 0.8)  -this.handleHeight) {
						temp = 0 - (this.windowHeight * 0.8) - this.handleHeight
					} 
					this.moveY = temp
				}).exec();

			}, 
			drag_end(event){
				this.transition = 'transition: top 0.1s;'
				const query = uni.createSelectorQuery().in(this);
				query.select('#drag-content').boundingClientRect(data => {
					if(this.toTop){
						this.moveY = 0 - data.height
					}else{
					  this.moveY =  - this.handleHeight - this.onelineHeight
					} 
				}).exec();
				
			},
		}
	}
</script>

<style>
	.bar-wrapper {
		bottom: 0;
		left: 0;
		position: fixed;
		width: 100vw;
		
		background-color: #bbb;
	}

	

	.drag-handle {
		height: 30px;
		width: 100vw;
		background-color: #fff;
		border-radius: 30px 30px 0 0;
		box-shadow: rgba(0, 0, 0, 0.25) 0px 0.0625em 0.0625em, rgba(0, 0, 0, 0.25) 0px 0.125em 0.5em, rgba(255, 255, 255, 0.1) 0px 0px 0px 1px inset;
		border-bottom: 1px solid #eee;
		color:#eee;
		font-weight: bold;
		font-size: 20px;
		line-height: 1px;
		text-align: center;
	}

	.t-box-wrapper {
		position: absolute;
		height: 500px;
		max-height: 80vh;
		width: 100vw;
		top: -30px;
		/* bottom: 60px; */
		left: 0;
	}

	.drag-content {
		background-color: #0000FF;
		height: auto;
		max-height: 80vh;
	}
</style>