unibest/src/pages/demo/page/floating-bubble.vue

89 lines
2.2 KiB
Vue
Raw Normal View History

2024-02-04 16:00:27 +08:00
<route lang="json5">
{
layout: 'default',
style: { navigationBarTitleText: '页面悬浮球' },
}
</route>
<template>
<view>
<movable-area class="movable-area">
<movable-view
:style="`--size:${ballSize}px`"
class="movable-view"
direction="all"
:x="x"
:y="y"
@change="onChange"
@touchend.prevent="onTouchEnd"
>
<view class="w-full h-full rounded-full bg-green-400"></view>
</movable-view>
</movable-area>
<view>页面其他元素</view>
<view>可以正常触发点击事件吗答案是可以的</view>
<button @click="onClick">按钮</button>
<view>{{ x }}</view>
<view>{{ y }}</view>
<view @click="onSet">点击设置</view>
</view>
</template>
<script lang="ts" setup name="FloatingBubble">
const { windowHeight, windowWidth } = uni.getSystemInfoSync()
const ballSize = 60
const x = ref(windowWidth - ballSize) // 靠右侧
const y = ref(windowHeight - ballSize - 20) // 距离底部20px
const middleX = (windowWidth - ballSize) / 2
const onChange: UniHelper.MovableViewOnChange = (e) => {
const { x: _x, y: _y } = e.detail
x.value = _x
y.value = _y
}
// TODO: 期望最终落点不靠左右两边时,会自动回到两边,有一定的动画效果
const onTouchEnd = (e) => {
console.log('onTouchEnd', e)
// TODO为啥这里设置的不生效了原生不会移动到设置的地方onSet里面可以。这里直接执行onSet也不行
// 这里被我解决了
const tid = setTimeout(() => {
if (x.value < middleX) {
x.value = 0
} else {
x.value = windowWidth - ballSize
}
clearTimeout(tid)
}, 0)
}
const onClick = () => {
uni.showToast({
title: 'yes',
icon: 'none',
})
}
const onSet = () => {
x.value = 100
y.value = 100
}
</script>
<style lang="scss">
.movable-area {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 100%;
pointer-events: none; // 设置area元素不可点击则事件便会下移至页面下层元素
.movable-view {
width: var(--size);
height: var(--size);
pointer-events: auto; // 必须设置,否则无法点击
}
}
</style>