fix:定位弹窗

main
CHINAMI-3V5PQ9A\Administrator 2024-02-02 17:30:40 +08:00
parent 5471fee5cc
commit 9c787c8f7b
24 changed files with 1172 additions and 42 deletions

View File

@ -12,7 +12,8 @@
"style": { "style": {
"navigationBarTitleText": "", "navigationBarTitleText": "",
"enablePullDownRefresh": false, "enablePullDownRefresh": false,
"navigationStyle": "custom" "navigationStyle": "custom",
"disableScroll": true
} }
}, },

View File

@ -1,82 +1,464 @@
<template> <template>
<view class="container"> <view class="container">
<view class="imb-header" :style="{'paddingTop':menuButtonTop?menuButtonTop+'rpx':0}"> <view class="imb-header" :style="{paddingTop:menuButtonTop+'rpx'}">
<view class="imb-car-info"> <view class="imb-car-info">
<view class="imb-car-info-left"> <view class="car-info-item">
<image src="../../static/mine/avater.png" mode="aspectFit" class="iamge-logo"></image> <view class="car-info-item-text">
<view class="imb-car-info-left-text"> <text>虚拟体验车辆</text>
<text>欢迎来到爱摩保</text> </view>
<text style="color: rgba(43,43,53,0.6);font-size: 24rpx;">登录/注册享受更多优质服务</text> <image src="../../static/common/home_che_icon_more.png" mode="aspectFit" class="more-img">
</image>
</view>
</view>
</view>
<view class="imb-map">
<map name="amap" :scale="18" :longitude="carPosition.longitude" :latitude="carPosition.latitude" class="map"
:markers="maker" :enable-indoorMap="true"></map>
<view class="menu">
<view class="carFind" @click="openPopup($refs.popup)">
<image src="../../static/imb/carFind.png" mode="aspectFit" class="image"></image>
<text>寻车</text>
</view>
<view class="share">
<image src="../../static/imb/share.png" mode="aspectFit" class="image"></image>
<text>分享</text>
</view>
</view>
</view>
<wwBottomDrawer :transitionTime="0.3" :proportionShow='0.5' :dragHandleHeight="20" :dragLength="50">
<slot>
<view class="Panel">
<view class="Panel-feature">
<image src="https://rzyx-tycm.bj.bcebos.com/moto/home_pic1.png" mode="scaleToFill"
class="feature-1"></image>
<image src="https://rzyx-tycm.bj.bcebos.com/moto/home_pic2.png" mode="scaleToFill"
class="feature-2"></image>
</view>
<view>
<view class="main-title">
<view class="main-title-left">
<text>摩旅推荐</text>
</view>
<view class="main-title-right" @click="goBack('/pages/circle/views/eventsGather/index',1)">
<text>更多</text>
<uni-icons type="right" size="12"></uni-icons>
</view>
</view>
</view>
<view class="recommend-list">
<view class="recommend-list-item" v-for="(item,index) in recommend" :key="index">
<image
src="https://tse1-mm.cn.bing.net/th/id/OIP-C.AomAEAxJDq3dzvj4XxazTgHaE8?w=289&h=194&c=7&r=0&o=5&pid=1.7"
mode="scaleToFill" class="image"></image>
<view class="item-box">
<view class="item-text">
<text>团线招募</text>
<text>10月17日发团昆明大理香格里拉ehr</text>
</view>
<view class="item-date">
<text>2023/09/22 10:00:00</text>
</view>
</view>
<view class="item-type">
摩旅
</view>
</view>
</view>
<view>
<view class="main-title">
<view class="main-title-left">
<text>安驾推荐</text>
</view>
<view class="main-title-right">
<text>更多</text>
<uni-icons type="right" size="12"></uni-icons>
</view>
</view>
</view>
<view class="recommend-list">
<view class="recommend-list-item" v-for="(item,index) in recommend" :key="index">
<image
src="https://tse1-mm.cn.bing.net/th/id/OIP-C.AomAEAxJDq3dzvj4XxazTgHaE8?w=289&h=194&c=7&r=0&o=5&pid=1.7"
mode="scaleToFill" class="image"></image>
<view class="item-box">
<view class="item-text">
<text>团线招募 </text>
<text>10月17日发团昆明大理香格里拉</text>
</view>
<view class="item-date">
<text>2023/09/22 10:00:00</text>
</view>
</view>
<view class="item-type" :style="{backgroundColor:'#658CFF'}">
安驾
</view>
</view>
</view> </view>
</view> </view>
<view class="imb-car-info-right"> </slot>
<view class="imb-car-info-right-text"> </wwBottomDrawer>
<text>注册/登录</text> <!-- vip弹窗 -->
<uni-popup ref="popup">
<view class="vip-popup">
<view class="popup-title">
<h4 class="title">开通VIP提示</h4>
<text class="text">该功能为爱摩保VIP用户专享 您可以开通VIP或虚拟体验该功能</text>
</view>
<view class="vip-menu">
<view class="vip-menu-item">
<image src="../../static/imb/vip1.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip2.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip3.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip4.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip5.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip6.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip7.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
<view class="vip-menu-item">
<image src="../../static/imb/vip8.png" mode="scaleToFill" class="menu-img"></image>
<text>盗抢保障</text>
</view>
</view>
<view class="vip-button">
<view class="vip-button-left">
<text>虚拟体验</text>
</view>
<view class="vip-button-right">
<text>开通VIP</text>
</view> </view>
</view> </view>
</view> </view>
</uni-popup>
</view>
<view class="imb-map">
<map name="amap"></map>
</view>
</view> </view>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { getMenuButton, rpxTopx } from "@/utils/common.js" import { getMenuButton, rpxTopx } from "@/utils/common.js"
import { ref } from "vue"; import { ref } from "vue";
import wwBottomDrawer from "@/uni_modules/ww-bottom-drawer/components/ww-bottom-drawerapp/ww-bottom-drawerapp.vue"
import { userData } from "./hook/userData"
// let menuButtonInfo = uni.getMenuButtonBoundingClientRect() // let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
const { openPopup, carPosition, maker } = userData()
let menuButtonTop = ref(0) let menuButtonTop = ref(0)
const recommend = ref([{}, {}, {}, {}])
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
let menuButtonInfo = uni.getMenuButtonBoundingClientRect() let menuButtonInfo = uni.getMenuButtonBoundingClientRect()
menuButtonTop.value = rpxTopx(menuButtonInfo.top) + rpxTopx(menuButtonInfo.height) menuButtonTop.value = rpxTopx(menuButtonInfo.top)
// #endif // #endif
</script> </script>
<style>
page {
height: 100%;
background-color: antiquewhite;
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .container {
height: 100%;
display: flex;
flex-direction: column;
.imb-header { .imb-header {
background-image: url(../../../src/static/common/top-bg.png); background: url(https://rzyx-tycm.bj.bcebos.com/moto/bg08.png);
// height: 240rpx; // height: 216rpx;
background-size: 100% 106%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
.imb-car-info { .imb-car-info {
display: flex; display: flex;
padding: 24rpx; padding: 0 36rpx 36rpx;
justify-content: space-between; justify-content: space-between;
.imb-car-info-left { .car-info-item {
display: flex; display: flex;
align-items: flex-end;
.imb-car-info-left-text { .car-info-item-text {
display: flex; color: #fff;
flex-direction: column; font-size: 44rpx;
color: #08080D; margin-right: 12rpx;
} }
.iamge-logo { .more-img {
width: 96rpx; height: 20rpx;
height: 112rpx; width: 20rpx;
padding-right: 6rpx;
} }
} }
.imb-car-info-right { }
.imb-car-info-right-text { }
width: 176rpx;
height: 64rpx; .imb-map {
border-radius: 8rpx; height: 46%;
border: 1rpx solid; // flex: 1;
line-height: 64rpx; width: 100%;
position: relative;
map {
width: 100%;
height: 100%;
}
.menu {
position: absolute;
bottom: 50rpx;
left: 24rpx;
background-color: #fff;
box-shadow: 0rpx 6rpx 40rpx 0rpx rgba(0, 0, 0, 0.13);
font-size: 20rpx;
padding: 10rpx 16rpx;
.carFind,
.share {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.share {
margin-top: 22rpx;
}
.image {
width: 44rpx;
height: 44rpx;
}
}
}
.Panel {
width: 100%;
// height: 80vh;
max-height: 80vh;
padding: 10rpx 24rpx;
box-sizing: border-box;
overflow: auto;
overscroll-behavior: contain;
.Panel-feature {
display: flex;
width: 100%;
.feature-1,
.feature-2 {
height: 252rpx;
width: 100%;
z-index: 1;
}
.feature-2 {
margin-left: -44rpx;
z-index: 0;
}
}
.main-title {
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
padding: 25rpx 0;
.main-title-left {
position: relative;
font-weight: 600;
&::before {
content: '';
background-image: url(../../../static/circle/icon-title.png);
display: inline-block;
width: 34rpx;
height: 32rpx;
position: absolute;
top: -6rpx;
left: -12rpx;
}
}
.main-title-right {
font-size: 24rpx;
color: #86898C;
display: flex;
align-items: center;
}
}
.recommend-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.recommend-list-item {
width: 48.5%;
display: flex;
flex-direction: column;
border-radius: 16rpx 16rpx 16rpx 16rpx;
background-color: #fff;
overflow: hidden;
position: relative;
margin-bottom: 20rpx;
.image {
width: 100%;
height: 218rpx;
}
.item-box {
padding: 20rpx 24rpx;
.item-text {
color: #252931;
font-weight: 600;
font-size: 28rpx;
user-select: text;
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
}
.item-date {
color: #86898C;
font-size: 24rpx;
padding-top: 16rpx;
}
}
.item-type {
background-color: #4ED17F;
color: #fff;
width: 68rpx;
height: 36rpx;
font-size: 22rpx;
padding: 2rpx;
border-radius: 0 0 0 16rpx;
text-align: center; text-align: center;
color: #20519C; line-height: 36rpx;
font-size: 28rpx; position: absolute;
border-image: linear-gradient(90deg, rgba(30, 80, 153, 1), rgba(60, 109, 198, 1)) 1 1; top: 0;
right: 0;
} }
} }
} }
} }
}
.vip-popup {
width: 100%;
background: #FFFBF6;
border-radius: 48rpx 48rpx 48rpx 48rpx;
overflow: hidden;
.popup-title {
width: 100%;
height: 192rpx;
background: linear-gradient(180deg, #FFF4E2 0%, #FFF5E4 100%);
background-size: 100% 100%;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 108rpx;
box-sizing: border-box;
color: #333333;
.title {
margin-bottom: 12rpx;
font-size: 40rpx;
font-weight: 550;
}
.text {
font-size: 24rpx;
}
}
.vip-menu {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
padding: 28rpx;
.vip-menu-item {
display: flex;
flex-direction: column;
width: calc(100%/ 4);
// margin-right: 20rpx;
align-items: center;
font-size: 26rpx;
margin: 18rpx 0;
.menu-img {
width: 80rpx;
height: 80rpx;
margin-bottom: 10rpx;
}
}
.vip-menu-item:nth-of-type(4n+0) {
margin-right: 0;
}
}
}
.vip-button {
display: flex;
padding: 32rpx;
width: 100%;
box-sizing: border-box;
justify-content: space-between;
.vip-button-left,
.vip-button-right {
padding: 26rpx 54rpx;
width: 48%;
border-radius: 48rpx 48rpx 48rpx 48rpx;
text-align: center;
box-sizing: border-box;
}
.vip-button-left {
border: 2rpx solid #4ED17F;
color: #4ED17F;
// margin-right: 24rpx;
}
.vip-button-right {
background-color: #3E3E3E;
color: #FFD9B6;
}
}
::v-deep .uni-popup__wrapper {
width: 80%;
} }
</style> </style>

View File

@ -0,0 +1,26 @@
import { ref, onMounted, shallowRef, watchEffect, watch } from 'vue';
export function userData() {
const popup = ref(null)
const carPosition = ref({
longitude: 116.307503,
latitude: 39.984104
})
const maker = ref([{
id: 0,
longitude: 116.307503,
latitude: 39.984104,
iconPath: 'https://rzyx-tycm.bj.bcebos.com/moto/map_pic.png',
width: 122,
height: 122
}])
function openPopup(el : any) {
el.open('center')
}
return {
openPopup,
carPosition,
maker
}
}

View File

@ -10,7 +10,7 @@
<image src="../../../static/circle/icon_bar05.png" mode="aspectFit" class="bar06"></image> <image src="../../../static/circle/icon_bar05.png" mode="aspectFit" class="bar06"></image>
</view> </view>
<scroll-view scroll-y="true" class="scroll-Y" refresher-enabled scroll-with-animation <scroll-view scroll-y="true" class="scroll-Y" refresher-enabled scroll-with-animation
refresher-background="#F8F8FA" @refresherrestore="refresherrestore"> refresher-background="#F8F8FA">
<view class="hotTopic"> <view class="hotTopic">
<view class="topicList"> <view class="topicList">
<view class="topicList-item"> <view class="topicList-item">
@ -119,7 +119,8 @@
const { const {
handPreviewImage, handPreviewImage,
eventsItem, eventsItem,
goBack goBack,
selectNav
} = userData() } = userData()
interface Props { interface Props {
resource : string[] resource : string[]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

BIN
src/static/imb/carFind.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/static/imb/share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
src/static/imb/vip1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
src/static/imb/vip2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
src/static/imb/vip3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
src/static/imb/vip4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
src/static/imb/vip5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
src/static/imb/vip6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
src/static/imb/vip7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
src/static/imb/vip8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -0,0 +1,26 @@
## 1.7.12022-07-01
新加个属性 proportionMiniShow 不能再下滑的内容比例默认是0使用见demo满足用户反馈需求
## 1.72022-05-27
用户反馈nvue的动画时间无效问题修复
## 1.6.32022-05-25
修订版本预设高度的时候提前上个反馈中不同环境渲染速度不同速度逻辑优化。提供menuHeight 单位px 见demo ,主要是针对用户的闪的优化提供新的字段
## 1.6.22022-05-24
提供外层解决初始收缩时的看到展-收的过程。修订版本1.开放initTop方法组件300ms调用外层可以根据自己的渲染速度提前调用2.或者给菜单根节点固定高度外层不用处理见demo。 用户反馈的需求建议用第2种自己根据内容计算好菜单高度预设下。见demo的app-expand.vue
## 1.6.12022-05-18
专门针对支付宝小程序添加canDrag其他的小程序使用同样有效果。底部抽屉是否能够滑动默认true 。见demo的使用
## 1.62022-05-18
支付宝支持。之前提供的app-expand.vue页面的长抽屉的滑动思路我用新版的hbuilder测试了下发现scroll-y="false" scroll-y="true"都是无效的在等hbuilder官方回应。针对菜单里面有scroll-view的我得到通知后回复
## 1.52022-05-18
兼容支付宝小程序的map滑动不顺畅的问题
## 1.42022-05-16
1.transitionShow换成transitionTime完成剩下的展开收缩时间单位s
2.dragLength 手指滑动收缩或者展开需要滑动的最短距离px
3.isExpand 外部可以修改值对菜单收缩或者展开
## 1.32022-05-13
根据使用反馈情况,添加收缩展开菜单的时间属性 transitionShow。见demo
## 1.22022-05-09
1.ww-bottom-drawerapp添加isExpand的属性可以控制初始的时候不收缩。
2.针对反馈的内容过长怎么使用菜单demo提供个app-expand.vue可以参考思路。
## 1.12022-04-19
1.新增一个app插件专门给原生app使用解决uni的原生map遮挡。见demo
2.vue开发的话可以使用原始组件通用。

View File

@ -0,0 +1,162 @@
<template>
<view class="drawer-content">
<view class="drawer-content-drag" :style="transition + 'top:' + (dragTop + 'px')" @touchstart="drag_start"
@touchmove.stop="drag_move" @touchend="drag_end" @touchcancel="drag_end" :data-top="dragTop">
<view class="drag-handle" :style="
'height:' +
dragHandleHeight +
'px;'
">
<view class="drag-handle-line"></view>
</view>
<view id="drag-content" class="drag-content">
<slot>
</slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'ww-bottom-drawer',
props: {
dragHandleHeight: {
type: Number,
default: 20,
},
proportionShow: { //
type: Number,
default: 0.3,
},
},
watch: {
proportionShow() {
const {
windowWidth,
windowHeight
} = uni.getSystemInfoSync();
this.windowWidth = windowWidth
this.windowHeight = windowHeight
this.foldHeight = this.windowWidth * this.proportionShow
}
},
data() {
return {
startY: 0,
foldHeight: 0, // proportionShow
dragTop: -this.dragHandleHeight,
top: 0,
transition: 'transition: top 0.1s;',
windowHeight: '',
windowWidth: '',
toTop: true,
}
},
mounted() {
const {
windowWidth,
windowHeight
} = uni.getSystemInfoSync();
this.windowWidth = windowWidth
this.windowHeight = windowHeight
this.foldHeight = this.windowWidth * this.proportionShow
this.dragTop = -this.dragHandleHeight - this.foldHeight
},
methods: {
drag_start(event) {
this.transition = "";
this.top = event.currentTarget.dataset.top;
this.startY = event.touches[0].clientY;
},
drag_move(event) {
// console.log(event.currentTarget)
var len = event.touches[0].clientY - this.startY;
var temp = this.top + len;
if (temp >= this.dragHandleHeight) {
temp = this.dragHandleHeight;
}
this.toTop = len < 0;
const query = uni.createSelectorQuery().in(this);
query
.select("#drag-content")
.boundingClientRect((data) => {
if (temp <= 0 - data.height - this.dragHandleHeight) {
temp = 0 - data.height - this.dragHandleHeight;
}
if (temp <= 0 - this.windowHeight * 0.8 - this.dragHandleHeight) {
temp = 0 - this.windowHeight * 0.8 - this.dragHandleHeight;
}
this.dragTop = temp;
})
.exec();
return false;
},
drag_end(event) {
this.transition = "transition: top 0.2s;";
const query = uni.createSelectorQuery().in(this);
query
.select("#drag-content")
.boundingClientRect((data) => {
if (this.toTop) {
this.dragTop = 0 - data.height - 20;
} else {
this.dragTop = -this.dragHandleHeight - this.foldHeight;
}
})
.exec();
return false;
},
}
}
</script>
<style lang="scss">
.drawer-content {
bottom: 0;
left: 0;
position: fixed;
width: 100vw;
}
.drag-handle {
height: 20px;
width: 100vw;
background-color: transparent;
border-radius: 15px 15px 0 0;
color: #eee;
font-weight: bold;
font-size: 20px;
line-height: 1px;
display: flex;
justify-content: center;
align-items: center;
.drag-handle-line {
width: 60rpx;
height: 8rpx;
margin-top: 10rpx;
background: #dfe5f1;
border-radius: 4rpx;
}
}
.drawer-content-drag {
position: absolute;
height: 60vh;
max-height: 80vh;
width: 100vw;
left: 0;
background-image: url(https://rzyx-tycm.bj.bcebos.com/moto/bg05.png);
background-size: 100% 100%;
}
.drag-content {
background-color: transparent;
height: auto;
max-height: 80vh;
}
</style>

View File

@ -0,0 +1,453 @@
<template>
<view>
<!-- #ifdef MP-ALIPAY -->
<view class="drawer-content" @touchstart.stop="drag_start" @touchmove.stop="drag_move" @touchend.stop="drag_end"
@touchcancel="drag_end" :data-top="dragTop" :style="transition + 'bottom:' + (dragTop + 'px')">
<view id="drag-content" class="drag-content" ref="drag-content">
<view class="drag-handle drag-handle-ali" :style="
'height:' +
dragHandleHeight +
'px;'
">
<view class="drag-handle-line"></view>
</view>
<slot>
</slot>
</view>
</view>
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<view class="drawer-content" @touchstart="drag_start" @touchmove.stop="drag_move" @touchend="drag_end"
@touchcancel="drag_end" :data-top="dragTop"
:style="transition + 'bottom:' + (dragTop + 'px;') + styleCss()">
<view id="drag-content" class="drag-content" ref="drag-content">
<view class="drag-handle" :style="
'height:' +
dragHandleHeight +
'px;'
">
<view class="drag-handle-line"></view>
</view>
<slot>
</slot>
</view>
</view>
<!-- #endif -->
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom');
// #endif
export default {
name: 'ww-bottom-drawerapp',
props: {
dragHandleHeight: {
type: Number,
default: 20,
},
proportionShow: { //
type: Number,
default: 0.5,
},
proportionMiniShow: { //
type: Number,
default: 0.0,
},
proChangeWidth: {
type: Boolean,
default: false,
},
dragLength: { // 50px
type: Number,
default: 50,
},
canDrag: { // 50px
type: Boolean,
default: true,
},
isExpand: { //
type: Boolean,
default: false,
},
transitionTime: { //
type: Number,
default: 0.3,
},
menuHeight: {
type: Number,
default: 0,
}
},
watch: {
isExpand(newVal, oldVal) {
console.log(this.dragTop)
if (newVal != this.isDrawerOpen) {
console.log("isExpand" + newVal)
this.$nextTick(() => {
this.toTop = newVal;
this.expand_end()
})
}
}
},
data() {
return {
contentHeight: 0,
startY: 0,
dragTop: 0,
dragTopTemp: 0,
transition: '',
windowHeight: 0,
windowWidth: 0,
toTop: true,
isDrawerOpen: false,
timer: null,
}
},
created() {
if (this.menuHeight != 0) {
//this.dragTop = -Number((1 - this.proportionShow) * (this.menuHeight + this.dragHandleHeight));
console.log(this.dragTop)
}
},
beforeMount() {
},
unmounted() {
if (this.timer) {
clearInterval(this.timer);
}
},
mounted() {
const {
windowWidth,
windowHeight
} = uni.getSystemInfoSync();
this.windowWidth = windowWidth
this.windowHeight = windowHeight
if (!this.isExpand) {
this.$nextTick(() => {
this.initTop() //-
setTimeout(() => {
this.initTop() //-
}, 300)
})
}
this.callExpand(this.isExpand)
},
methods: {
initTop() {
// #ifndef APP-NVUE
const query = uni.createSelectorQuery().in(this);
query
.select("#drag-content")
.boundingClientRect((data) => {
this.contentHeight = data.height
this.transition = ""
this.dragTop = -Number((1 - this.proportionShow) * this.contentHeight);
this.callExpand(this.dragTop == 0)
})
.exec();
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['drag-content'], (ret) => {
this.contentHeight = ret.size.height
this.transition = ""
this.dragTop = -Number((1 - this.proportionShow) * this.contentHeight);
this.callExpand(this.dragTop == 0)
console.log(this.contentHeight)
})
// #endif
},
handleTap2() {},
styleCss() {
//vue
// #ifdef APP-NVUE
// if (this.isDrawerOpen) {//
// return "transform: translateY(0px);transition-property: transform;transition-duration: 3s;"
// }else{//
// return "transform: translateY(50%);transition-property: transform;transition-duration: 3s;"
// }
// #endif
return ''
},
drag_start(event) {
console.log(this.canDrag)
if (!this.canDrag) {
return
}
if (this.timer) {
clearInterval(this.timer);
}
this.transition = "";
this.dragTopTemp = this.dragTop;
// #ifdef APP-NVUE
this.startY = event.touches[0].screenY;
// #endif
// #ifndef APP-NVUE
this.startY = event.touches[0].clientY;
// #endif
},
drag_move(event) {
if (!this.canDrag) {
return
}
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['drag-content'], (ret) => {
var len = (event.touches[0].screenY - this.startY);
if (this.isDrawerOpen) { //
if (len > 0) { //
this.toTop = len < this.dragLength;
} else {
this.toTop = true;
}
} else {
if (len < 0) { //
this.toTop = Math.abs(len) > this.dragLength;
} else {
this.toTop = false;
}
}
this.contentHeight = ret.size.height
let temp = this.dragTopTemp - len
if (temp > 0) {
temp = 0
} else if (temp < -this.contentHeight + 30) {
temp = -this.contentHeight + 30
}
var temp_ = Number(temp)
var ss_ = -Number((1 - this.proportionMiniShow) * this.contentHeight);
if (Number(temp_) < ss_) {
this.dragTop = ss_
} else {
this.dragTop = temp_
}
})
// #endif
// #ifndef APP-NVUE
const query = uni.createSelectorQuery().in(this);
query
.select("#drag-content")
.boundingClientRect((data) => {
var len = (event.touches[0].clientY - this.startY);
//
if (this.isDrawerOpen) { //
if (len > 0) { //
this.toTop = len < this.dragLength;
} else {
this.toTop = true;
}
} else {
if (len < 0) { //
this.toTop = Math.abs(len) > this.dragLength;
} else {
this.toTop = false;
}
}
this.contentHeight = data.height
let temp = this.dragTopTemp - len
if (temp > 0) {
temp = 0
} else if (temp < -this.contentHeight + 30) {
temp = -this.contentHeight + 30
}
var temp_ = Number(temp)
var ss_ = -Number((1 - this.proportionMiniShow) * this.contentHeight);
if (Number(temp_) < ss_) {
this.dragTop = ss_
} else {
this.dragTop = temp_
}
})
.exec();
// #endif
return false;
},
drag_end(event) {
if (!this.canDrag) {
return
}
this.expand_end()
return false;
},
animationTop(from, to, callback) {
if (this.timer) {
clearInterval(this.timer);
}
if (from == to) {
this.dragTop = to
callback && callback();
return
}
console.log(from + " - " + to)
let time = this.transitionTime * 100;
//
var interval = 20;
//
var allCount = time / interval;
//
var step = (to - from) / allCount;
console.log(from + " - " + to + " step:" + step)
//
var count = 0;
let self = this
this.timer = setInterval(function() {
count++;
self.dragTop = from + step * count;
console.log(from + " - " + to + " count:" + count + " dragTop:" + self.dragTop)
//
if (count >= allCount) {
//
clearInterval(self.timer);
self.dragTop = to
//
callback && callback();
}
}, interval);
},
expand_end() {
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['drag-content'], (ret) => {
this.transition = `transition: bottom ${this.transitionTime}s;`
console.log(ret)
if (this.transitionTime <= 0.3) { //nvue
this.contentHeight = ret.size.height
if (this.toTop) {
this.dragTop = 0
} else {
this.dragTop = -Number((1 - this.proportionShow) * this.contentHeight);
}
this.callExpand(this.dragTop == 0)
} else {
this.transition = ''
this.contentHeight = ret.size.height
if (this.toTop) {
//this.dragTop = 0
this.animationTop(this.dragTop, 0, () => {
this.callExpand(this.dragTop == 0)
})
} else {
let dragTop_ = -Number((1 - this.proportionShow) * this.contentHeight);
this.animationTop(this.dragTop, dragTop_, () => {
this.callExpand(this.dragTop == 0)
})
}
}
})
// #endif
// #ifndef APP-NVUE
const query = uni.createSelectorQuery().in(this);
query
.select("#drag-content")
.boundingClientRect((data) => {
this.transition = `transition: bottom ${this.transitionTime}s;`
this.contentHeight = data.height
if (this.toTop) {
this.dragTop = 0
} else {
this.dragTop = -Number((1 - this.proportionShow) * this.contentHeight);
}
this.callExpand(this.dragTop == 0)
})
.exec();
// #endif
},
//
callExpand(expand) {
this.$emit("callExpand", {
value: expand
});
this.isDrawerOpen = expand
}
}
}
</script>
<style lang="scss">
.drawer-content {
bottom: 0;
left: 0;
display: flex;
position: fixed;
width: 750rpx;
background-color: #0A98D5;
}
.drag-handle-ali {
background-color: #666;
}
.drag-handle {
height: 20px;
width: 750rpx;
background-color: transparent;
border-radius: 15px 15px 0 0;
color: #eee;
font-weight: bold;
font-size: 20px;
line-height: 1px;
display: flex;
justify-content: center;
align-items: center;
.drag-handle-line {
width: 60rpx;
height: 8rpx;
margin-top: 10rpx;
background: #dfe5f1;
border-radius: 4rpx;
}
}
.drawer-content-drag {
display: flex;
width: 750rpx;
left: 0;
position: absolute;
}
.drawer-content-drag1 {
display: flex;
width: 750rpx;
background-color: #000000;
}
.drag-content {
background-color: #f2f2f2;
// padding: 32rpx 24rpx;
// box-sizing: border-box;
// overflow: auto;
}
</style>

View File

@ -0,0 +1,79 @@
{
"id": "ww-bottom-drawer",
"name": "底部抽屉",
"version": "1.7.1",
"description": "地图底部,底部抽屉,自适应",
"keywords": [
"地图底部,底部抽屉,仿地图底部拉起,一句代码,使用简单"
],
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": "",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
}
},
"displayName": "简洁-可拖动底部抽屉",
"repository": "",
"engines": {
"HBuilderX": "^3.3.0"
},
"uni_modules": {
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
}
}
}
}
}