hldy_app/component/public/game/ceshi1.vue

131 lines
3.0 KiB
Vue

<template>
<view id="arc-wrapper" @touchstart="onStart" @touchmove.prevent="onMove" @touchend="onEnd">
<!-- 父容器旋转 -->
<view id="arc" :style="{ transform: `rotate(${rotation}deg)` }">
<view v-for="(item, idx) in items" :key="idx" class="arc-item" :style="getItemStyle(idx)">
<!-- 文字反向旋转,保持水平 -->
<view class="item-content" :style="{
transform: `rotate(${-rotation}deg)`,
transformOrigin: 'center center'
}">
<text>{{ item }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
getCurrentInstance
} from 'vue';
const items = ['A', 'B', 'C', 'D', 'E'];
const radius = 100;
const rotation = ref(0);
const startAngle = ref(0);
const centerLocal = {
x: 0,
y: 0
};
const centerScreen = {
x: 0,
y: 0
};
const instance = getCurrentInstance();
// 获取半圆容器在屏幕中的中心坐标
onMounted(() => {
uni.createSelectorQuery()
.in(instance)
.select('#arc')
.boundingClientRect(rect => {
centerLocal.x = rect.width / 2;
centerLocal.y = rect.height;
centerScreen.x = rect.left + centerLocal.x;
centerScreen.y = rect.top + centerLocal.y;
})
.exec();
});
// 计算触摸点相对于屏幕圆心的角度
function calcAngle(x, y) {
const dx = x - centerScreen.x;
const dy = y - centerScreen.y;
return Math.atan2(dy, dx) * 180 / Math.PI; // rotate() 基于度数 :contentReference[oaicite:6]{index=6}
}
function onStart(e) {
const {
clientX,
clientY
} = e.touches[0];
startAngle.value = calcAngle(clientX, clientY);
}
function onMove(e) {
const {
clientX,
clientY
} = e.touches[0];
const current = calcAngle(clientX, clientY);
rotation.value += current - startAngle.value;
startAngle.value = current;
}
function onEnd() {
// 可加惯性或回正逻辑
}
// 计算每个子项在半圆上的定位
function getItemStyle(idx) {
const per = 180 / (items.length + 1);
const baseAngle = -90 + per * (idx + 1);
const rad = baseAngle * Math.PI / 180;
const x = centerLocal.x + radius * Math.cos(rad);
const y = centerLocal.y + radius * Math.sin(rad);
return {
position: 'absolute',
left: `${x}px`,
top: `${y}px`,
transform: 'translate(-50%,-50%)'
};
}
</script>
<style lang="less" scoped>
#arc-wrapper {
width: 200px;
height: 100px;
position: absolute;
bottom: 300rpx;
right: 100rpx;
overflow: hidden;
z-index: 100;
}
#arc {
width: 200px;
height: 100px;
position: absolute;
bottom: 0;
left: 0;
transform-origin: center bottom;
/* 半圆底部中心为旋转中心 :contentReference[oaicite:7]{index=7} */
}
.arc-item {
/* 可自定义尺寸 */
}
.item-content {
display: flex;
align-items: center;
justify-content: center;
/* 确保 transform-origin 在自身中心 */
transform-box: fill-box;
/* 在某些渲染环境需指定 reference box :contentReference[oaicite:8]{index=8} */
transform-origin: center center;
}
</style>