完成创建靶点
This commit is contained in:
@@ -249,6 +249,7 @@ const simulShoot2 = async () => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 10px;
|
line-height: 10px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
.hit > text {
|
.hit > text {
|
||||||
transform: scaleX(0.7);
|
transform: scaleX(0.7);
|
||||||
|
|||||||
@@ -1,8 +1,143 @@
|
|||||||
<script setup></script>
|
<script setup>
|
||||||
|
import { ref, onMounted } from "vue";
|
||||||
|
import { getElementRect, calcRing } from "@/util";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
arrows: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
onChange: {
|
||||||
|
type: Function,
|
||||||
|
default: (arrow) => {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const rect = ref({});
|
||||||
|
const arrow = ref(null);
|
||||||
|
const isDragging = ref(false);
|
||||||
|
const dragStartPos = ref({ x: 0, y: 0 });
|
||||||
|
|
||||||
|
// 点击靶纸创建新的点
|
||||||
|
const onClick = async (e) => {
|
||||||
|
if (arrow.value !== null) return;
|
||||||
|
const newArrow = {
|
||||||
|
x: e.detail.x - (rect.value.width * 0.1) / 2,
|
||||||
|
y: e.detail.y - rect.value.top - 10,
|
||||||
|
};
|
||||||
|
newArrow.ring = calcRing(newArrow.x, newArrow.y);
|
||||||
|
arrow.value = newArrow;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 确认添加箭矢
|
||||||
|
const confirmAdd = () => {
|
||||||
|
props.onChange(arrow.value);
|
||||||
|
arrow.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除箭矢
|
||||||
|
const deleteArrow = () => {
|
||||||
|
arrow.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 开始拖拽 - 同样修复坐标获取
|
||||||
|
const startDrag = async (e, index) => {
|
||||||
|
if (!e.touches[0]) return;
|
||||||
|
isDragging.value = true;
|
||||||
|
dragStartPos.value = {
|
||||||
|
x: e.touches[0].clientX,
|
||||||
|
y: e.touches[0].clientY,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拖拽移动 - 同样修复坐标获取
|
||||||
|
const onDrag = async (e) => {
|
||||||
|
if (!isDragging.value || !e.touches[0] || !arrow.value) return;
|
||||||
|
|
||||||
|
let clientX = e.touches[0].clientX;
|
||||||
|
let clientY = e.touches[0].clientY;
|
||||||
|
|
||||||
|
// 计算移动距离
|
||||||
|
const deltaX = clientX - dragStartPos.value.x;
|
||||||
|
const deltaY = clientY - dragStartPos.value.y;
|
||||||
|
|
||||||
|
const length = rect.value.width * 0.9;
|
||||||
|
|
||||||
|
// 更新坐标
|
||||||
|
arrow.value.x = Math.max(0, Math.min(length, arrow.value.x + deltaX));
|
||||||
|
arrow.value.y = Math.max(0, Math.min(length, arrow.value.y + deltaY));
|
||||||
|
arrow.value.ring = calcRing(arrow.value.x, arrow.value.y);
|
||||||
|
|
||||||
|
// 更新拖拽起始位置
|
||||||
|
dragStartPos.value = { x: clientX, y: clientY };
|
||||||
|
};
|
||||||
|
|
||||||
|
// 结束拖拽
|
||||||
|
const endDrag = () => {
|
||||||
|
isDragging.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
const result = await getElementRect();
|
||||||
|
rect.value = result;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view
|
||||||
|
class="container"
|
||||||
|
@click="onClick"
|
||||||
|
@touchmove="onDrag"
|
||||||
|
@touchend="endDrag"
|
||||||
|
>
|
||||||
<image src="../static/bow-target.png" mode="widthFix" />
|
<image src="../static/bow-target.png" mode="widthFix" />
|
||||||
|
|
||||||
|
<view
|
||||||
|
v-for="(arrow, index) in arrows"
|
||||||
|
:key="index"
|
||||||
|
class="arrow-point"
|
||||||
|
:style="{
|
||||||
|
left: (arrow.x !== undefined ? arrow.x : 0) + 'px',
|
||||||
|
top: (arrow.y !== undefined ? arrow.y : 0) + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<view v-if="arrow.x !== undefined && arrow.y !== undefined" class="point"
|
||||||
|
><text>{{ index + 1 }}</text></view
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
<!-- 渲染所有箭矢点 -->
|
||||||
|
<view
|
||||||
|
v-if="arrow"
|
||||||
|
class="arrow-point"
|
||||||
|
:style="{
|
||||||
|
left: arrow.x + 'px',
|
||||||
|
top: arrow.y + 'px',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<!-- 箭矢点 -->
|
||||||
|
<view class="point"> </view>
|
||||||
|
<!-- 编辑按钮组(只在编辑状态下显示) -->
|
||||||
|
<view class="edit-buttons" @click.stop>
|
||||||
|
<text
|
||||||
|
><text :style="{ fontSize: '24px', marginRight: '5px' }">{{
|
||||||
|
arrow.ring
|
||||||
|
}}</text
|
||||||
|
>{{ arrow.ring ? "环" : "" }}</text
|
||||||
|
>
|
||||||
|
<view class="edit-btn confirm-btn" @click.stop="confirmAdd(index)">
|
||||||
|
<image src="../static/arrow-edit-save.png" mode="widthFix" />
|
||||||
|
</view>
|
||||||
|
<view class="edit-btn delete-btn" @click.stop="deleteArrow(index)">
|
||||||
|
<image src="../static/arrow-edit-delete.png" mode="widthFix" />
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="edit-btn drag-btn"
|
||||||
|
@touchstart.stop="startDrag($event, index)"
|
||||||
|
>
|
||||||
|
<image src="../static/arrow-edit-move.png" mode="widthFix" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -10,8 +145,91 @@
|
|||||||
.container {
|
.container {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
|
position: relative;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container > image {
|
.container > image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-point {
|
||||||
|
position: absolute;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
z-index: 1;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 8px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #ff4444;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.point > text {
|
||||||
|
transform: scaleX(0.7);
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-buttons {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
background: #18ff6899;
|
||||||
|
width: 88px;
|
||||||
|
height: 88px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-buttons > text {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
line-height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-btn {
|
||||||
|
transform: translateX(-50%) translateY(-50%);
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-btn > image {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
left: 50%;
|
||||||
|
bottom: -24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
right: -24px;
|
||||||
|
bottom: -24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag-btn {
|
||||||
|
left: 50%;
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -236,7 +236,9 @@ watch(
|
|||||||
<text>组</text>
|
<text>组</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view>选择每组的箭数</view>
|
<view :style="{ marginTop: '5px', marginBottom: '10px' }"
|
||||||
|
>选择每组的箭数</view
|
||||||
|
>
|
||||||
<view class="amount-items">
|
<view class="amount-items">
|
||||||
<view
|
<view
|
||||||
v-for="(item, index) in groupArrows"
|
v-for="(item, index) in groupArrows"
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ const ringColors = [
|
|||||||
"#9B9B9B",
|
"#9B9B9B",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const onEdit = (arrows) => {
|
||||||
|
arrowGroups.value[currentGroup.value][currentArrow.value] = { ring };
|
||||||
|
};
|
||||||
|
|
||||||
const onBack = () => {
|
const onBack = () => {
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
};
|
};
|
||||||
@@ -38,17 +42,22 @@ const onSubmit = () => {
|
|||||||
};
|
};
|
||||||
const onClickRing = (ring) => {
|
const onClickRing = (ring) => {
|
||||||
if (arrowGroups.value[currentGroup.value]) {
|
if (arrowGroups.value[currentGroup.value]) {
|
||||||
arrowGroups.value[currentGroup.value][currentArrow.value] = ring;
|
arrowGroups.value[currentGroup.value][currentArrow.value] = { ring };
|
||||||
clickable.value = arrowGroups.value[currentGroup.value].every(
|
clickable.value = arrowGroups.value[currentGroup.value].every(
|
||||||
(item) => !!item
|
(item) => !!item.ring
|
||||||
);
|
);
|
||||||
if (currentArrow.value < amount.value - 1) {
|
if (currentArrow.value < amount.value - 1) currentArrow.value++;
|
||||||
currentArrow.value++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const deleteArrow = () => {
|
const deleteArrow = () => {
|
||||||
arrowGroups.value[currentGroup.value][currentArrow.value] = "";
|
arrowGroups.value[currentGroup.value][currentArrow.value] = {};
|
||||||
|
};
|
||||||
|
const onEditDone = (arrow) => {
|
||||||
|
arrowGroups.value[currentGroup.value][currentArrow.value] = {
|
||||||
|
...arrow,
|
||||||
|
ring: 10,
|
||||||
|
};
|
||||||
|
if (currentArrow.value < amount.value - 1) currentArrow.value++;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -57,7 +66,7 @@ onMounted(() => {
|
|||||||
groups.value = Number(pointBook.amountGroup.split("/")[0]);
|
groups.value = Number(pointBook.amountGroup.split("/")[0]);
|
||||||
amount.value = Number(pointBook.amountGroup.split("/")[1]);
|
amount.value = Number(pointBook.amountGroup.split("/")[1]);
|
||||||
for (let i = 1; i <= groups.value; i++) {
|
for (let i = 1; i <= groups.value; i++) {
|
||||||
arrowGroups.value[i] = new Array(amount.value).fill("");
|
arrowGroups.value[i] = new Array(amount.value).fill({});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -71,7 +80,10 @@ onMounted(() => {
|
|||||||
:onBack="() => (showTip = true)"
|
:onBack="() => (showTip = true)"
|
||||||
>
|
>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<BowTargetEdit />
|
<BowTargetEdit
|
||||||
|
:onChange="onEditDone"
|
||||||
|
:arrows="arrowGroups[currentGroup]"
|
||||||
|
/>
|
||||||
<view class="title-bar">
|
<view class="title-bar">
|
||||||
<view>
|
<view>
|
||||||
<view />
|
<view />
|
||||||
@@ -92,7 +104,13 @@ onMounted(() => {
|
|||||||
borderColor: currentArrow === index ? '#FED847' : '#eeeeee',
|
borderColor: currentArrow === index ? '#FED847' : '#eeeeee',
|
||||||
borderWidth: currentArrow === index ? '2px' : '1px',
|
borderWidth: currentArrow === index ? '2px' : '1px',
|
||||||
}"
|
}"
|
||||||
>{{ isNaN(arrow) ? arrow : arrow ? arrow + " 环" : "" }}</view
|
>{{
|
||||||
|
isNaN(arrow.ring)
|
||||||
|
? arrow.ring
|
||||||
|
: arrow.ring
|
||||||
|
? arrow.ring + " 环"
|
||||||
|
: ""
|
||||||
|
}}</view
|
||||||
>
|
>
|
||||||
</view>
|
</view>
|
||||||
<text>输入分值的情况下,系统不提供落点稳定性分</text>
|
<text>输入分值的情况下,系统不提供落点稳定性分</text>
|
||||||
|
|||||||
BIN
src/static/arrow-edit-delete.png
Normal file
BIN
src/static/arrow-edit-delete.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 530 B |
BIN
src/static/arrow-edit-move.png
Normal file
BIN
src/static/arrow-edit-move.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 702 B |
BIN
src/static/arrow-edit-save.png
Normal file
BIN
src/static/arrow-edit-save.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
18
src/util.js
18
src/util.js
@@ -282,3 +282,21 @@ export const isGameEnded = async (battleId) => {
|
|||||||
}
|
}
|
||||||
return !isGaming;
|
return !isGaming;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 获取元素尺寸和位置信息
|
||||||
|
export const getElementRect = () => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const query = uni.createSelectorQuery();
|
||||||
|
query
|
||||||
|
.select(".container")
|
||||||
|
.boundingClientRect((rect) => {
|
||||||
|
resolve(rect);
|
||||||
|
})
|
||||||
|
.exec();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const calcRing = (x, y) => {
|
||||||
|
console.log(1111, x, y);
|
||||||
|
return 8;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user