| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- <template>
- <movable-area class="suspension-area" :style="areaStyle">
- <movable-view
- class="suspension-view"
- direction="all"
- :x="x"
- :y="y"
- :inertia="props.inertia"
- :out-of-bounds="true"
- :disabled="false"
- :scale="false"
- :style="{
- width: `${props.imageWidth}px`,
- height: `${props.imageHeight}px`,
- }"
- @change="onChange"
- @click="handleClick">
- <slot />
- </movable-view>
- </movable-area>
- </template>
- <script setup lang="ts">
- import { ref, onMounted, computed } from 'vue';
- // 定义props
- interface Props {
- imageSrc?: string;
- imageWidth?: number; // 使用px单位,不再支持rpx
- imageHeight?: number; // 使用px单位,不再支持rpx
- x?: number; // x坐标(距离屏幕左边的距离,px单位)
- y?: number; // y坐标(距离屏幕顶部的距离,px单位)
- inertia?: boolean;
- snapThreshold?: number;
- bgColor?: string;
- borderRadius?: string;
- }
- const props = withDefaults(defineProps<Props>(), {
- imageSrc: '/static/logo.png',
- imageWidth: 50, // 默认宽度 50px
- imageHeight: 50, // 默认高度 50px
- x: 10, // 默认距离左边 10px
- y: 200, // 默认距离顶部 200px
- inertia: false,
- snapThreshold: 30,
- bgColor: 'transparent',
- borderRadius: '0',
- });
- // 响应式状态
- const x = ref<number>(props.x); // movable-view的x坐标(距离左边)
- const y = ref<number>(props.y); // movable-view的y坐标(距离顶部)
- // 屏幕尺寸
- const screenWidth = ref<number>(0);
- const screenHeight = ref<number>(0);
- // movable-area 样式
- const areaStyle = computed(() => {
- return {
- width: `${screenWidth.value}px`,
- height: `${screenHeight.value}px`,
- position: 'fixed',
- top: '0',
- left: '0',
- zIndex: '999',
- };
- });
- // 初始化时获取屏幕尺寸
- onMounted(() => {
- const systemInfo = uni.getSystemInfoSync();
- screenWidth.value = systemInfo.windowWidth;
- screenHeight.value = systemInfo.windowHeight;
- });
- // movable-view 位置变化事件
- const onChange = (e: any) => {
- // if (e.detail) {
- // // 直接更新位置
- // x.value = e.detail.x;
- // y.value = e.detail.y;
- // console.log(x.value, y.value);
- // 标记为正在拖动
- // isDragging.value = true;
- // }
- };
- // 触摸结束事件(拖动结束)
- const onTouchEnd = () => {
- // 拖动结束后进行边界检查和吸附
- // applyBoundaryAndSnap();
- // isDragging.value = false;
- };
- // 点击事件
- const handleClick = () => {
- // 触发点击事件
- console.log('悬浮按钮被点击', { x: x.value, y: y.value });
- };
- </script>
- <style>
- .suspension-area {
- /* 移除 pointer-events: none,确保可以正常接收拖动事件 */
- pointer-events: none;
- }
- .suspension-view {
- display: flex;
- justify-content: center;
- align-items: center;
- overflow: hidden;
- background-color: v-bind('props.bgColor');
- border-radius: v-bind('props.borderRadius');
- pointer-events: auto;
- }
- </style>
|