不放大的3连靶

This commit is contained in:
kron
2025-12-05 15:24:42 +08:00
parent 19902d5bed
commit 8c22eb0877
3 changed files with 180 additions and 62 deletions

View File

@@ -0,0 +1,111 @@
<script setup>
import { ref, computed } from "vue";
const props = defineProps({
diameter: {
type: Number,
default: 90,
},
});
const side = computed(() => {
return props.diameter / 10;
});
const rings = ["X", "10", "9", "8", "7", "6"];
</script>
<template>
<view
class="container circle"
:style="{
width: diameter + 'vw',
height: diameter + 'vw',
background: '#00BAE9',
}"
>
<view
class="circle"
:style="{
background: '#FF5665',
width: side * 8 + 'vw',
height: side * 8 + 'vw',
}"
>
<view class="rings" :style="{ transform: `translateX(-${side}vw)` }">
<text
v-for="(ring, index) in rings"
:key="ring"
:style="{
width: side + 'vw',
transform: `translateX(${
index === 0 ? side / 2 : index === 1 ? side / 4.5 : 0
}vw)`,
}"
>{{ ring }}</text
>
</view>
<view
class="circle"
:style="{
background: '#FF5665',
width: side * 6 + 'vw',
height: side * 6 + 'vw',
}"
>
<view
class="circle"
:style="{
background: '#FDDC61',
width: side * 4 + 'vw',
height: side * 4 + 'vw',
}"
>
<view
class="circle"
:style="{
background: '#FDDC61',
width: side * 2 + 'vw',
height: side * 2 + 'vw',
}"
>
<view
class="circle"
:style="{
background: '#FDDC61',
width: side + 'vw',
height: side + 'vw',
}"
>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<style scoped>
.container {
position: relative;
}
.rings {
position: absolute;
display: flex;
align-items: center;
left: 50%;
}
.rings > text {
font-size: 24rpx;
color: #333;
text-align: center;
}
.circle {
border: 1rpx solid #3e3e3e66;
box-sizing: border-box;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@@ -43,18 +43,18 @@ const onClick = async (e) => {
) { ) {
return; return;
} }
if (props.id === 7 || props.id === 9) { // if (props.id === 7 || props.id === 9) {
// 放大并通过滚动将点击位置置于视窗中心 // // 放大并通过滚动将点击位置置于视窗中心
scale.value = 1.5; // scale.value = 1.4;
const viewportH = rect.value.width; // 容器高度等于宽度100vw // const viewportH = rect.value.width; // 容器高度等于宽度100vw
const contentH = scale.value * rect.value.width; // 内容高度 // const contentH = scale.value * rect.value.width; // 内容高度
const clickYInContainer = e.detail.y - rect.value.top; // const clickYInContainer = e.detail.y - rect.value.top;
let target = clickYInContainer * scale.value - viewportH / 2; // let target = clickYInContainer * scale.value - viewportH / 2;
target = Math.max(0, Math.min(contentH - viewportH, target)); // target = Math.max(0, Math.min(contentH - viewportH, target));
setTimeout(() => { // setTimeout(() => {
scrollTop.value = target > 180 ? target + 10 : target; // scrollTop.value = target > 180 ? target + 10 : target;
}, 200); // }, 200);
} // }
const newArrow = { const newArrow = {
x: (e.detail.x - 6) * scale.value, x: (e.detail.x - 6) * scale.value,
y: (e.detail.y - rect.value.top - capsuleHeight.value - 6) * scale.value, y: (e.detail.y - rect.value.top - capsuleHeight.value - 6) * scale.value,
@@ -63,10 +63,9 @@ const onClick = async (e) => {
const side = rect.value.width; const side = rect.value.width;
newArrow.ring = calcRing( newArrow.ring = calcRing(
props.id, props.id,
newArrow.x / scale.value - rect.value.width * 0.05, newArrow.x / scale.value - side * 0.05,
newArrow.y / scale.value - rect.value.width * 0.05, newArrow.y / scale.value - side * 0.05,
rect.value.width * 0.9, side * 0.9
(10 * scale.value) / 2
); );
arrow.value = { arrow.value = {
...newArrow, ...newArrow,
@@ -128,10 +127,9 @@ const onDrag = async (e) => {
); );
arrow.value.ring = calcRing( arrow.value.ring = calcRing(
props.id, props.id,
arrow.value.x / scale.value - rect.value.width * 0.05, arrow.value.x / scale.value - side * 0.05,
arrow.value.y / scale.value - rect.value.width * 0.05, arrow.value.y / scale.value - side * 0.05,
rect.value.width * 0.9, side * 0.9
(10 * scale.value) / 2
); );
arrow.value.x = arrow.value.x / side; arrow.value.x = arrow.value.x / side;
@@ -148,7 +146,7 @@ const endDrag = (e) => {
const getNewPos = () => { const getNewPos = () => {
if (props.id === 7 || props.id === 9) { if (props.id === 7 || props.id === 9) {
if (arrow.value.y > 1.4) if (arrow.value.y >= 1.33)
return { left: "-12px", bottom: "calc(50% - 12px)" }; return { left: "-12px", bottom: "calc(50% - 12px)" };
} else { } else {
if (arrow.value.y > 0.88) { if (arrow.value.y > 0.88) {
@@ -217,7 +215,6 @@ onMounted(async () => {
class="point" class="point"
:style="{ minWidth: 10 * scale + 'px', minHeight: 10 * scale + 'px' }" :style="{ minWidth: 10 * scale + 'px', minHeight: 10 * scale + 'px' }"
> >
</view>
<view v-if="arrow" class="edit-buttons" @touchstart.stop> <view v-if="arrow" class="edit-buttons" @touchstart.stop>
<view class="edit-btn-text"> <view class="edit-btn-text">
<text>{{ arrow.ring === 0 ? "M" : arrow.ring }}</text> <text>{{ arrow.ring === 0 ? "M" : arrow.ring }}</text>
@@ -240,11 +237,16 @@ onMounted(async () => {
<view class="edit-btn delete-btn" @touchstart.stop="deleteArrow"> <view class="edit-btn delete-btn" @touchstart.stop="deleteArrow">
<image src="../static/arrow-edit-delete.png" mode="widthFix" /> <image src="../static/arrow-edit-delete.png" mode="widthFix" />
</view> </view>
<view class="edit-btn drag-btn" @touchstart.stop="startDrag($event)"> <view
class="edit-btn drag-btn"
@touchstart.stop="startDrag($event)"
>
<image src="../static/arrow-edit-move.png" mode="widthFix" /> <image src="../static/arrow-edit-move.png" mode="widthFix" />
</view> </view>
</view> </view>
</view>
</movable-view> </movable-view>
<!-- <view class="test-view"></view> -->
</movable-area> </movable-area>
</scroll-view> </scroll-view>
</template> </template>
@@ -286,9 +288,6 @@ onMounted(async () => {
.arrow-point { .arrow-point {
position: absolute; position: absolute;
display: flex;
justify-content: center;
align-items: center;
} }
.point { .point {
@@ -304,6 +303,7 @@ onMounted(async () => {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
transition: all 0.1s linear; transition: all 0.1s linear;
position: relative; position: relative;
transform: translate(-50%, -50%);
} }
.point > text { .point > text {
@@ -372,4 +372,12 @@ onMounted(async () => {
right: -12px; right: -12px;
bottom: -12px; bottom: -12px;
} }
.test-view {
position: absolute;
top: 29px;
left: 138px;
width: 115px;
height: 115px;
background-color: #ff000055;
}
</style> </style>

View File

@@ -1,4 +1,3 @@
import websocket from "@/websocket";
import { isGamingAPI, getGameAPI } from "@/apis"; import { isGamingAPI, getGameAPI } from "@/apis";
export const formatTimestamp = (timestamp) => { export const formatTimestamp = (timestamp) => {
@@ -411,8 +410,8 @@ const calcNormalBowTarget = (x, y, diameter, arrowRadius) => {
const arrowCenterY = y + arrowRadius; const arrowCenterY = y + arrowRadius;
// 计算靶心坐标(靶纸中心) // 计算靶心坐标(靶纸中心)
const centerX = diameter / 2; const centerX = (diameter + arrowRadius * 2) / 2;
const centerY = diameter / 2; const centerY = (diameter + arrowRadius * 2) / 2;
// 计算弓箭圆心到靶心的距离 // 计算弓箭圆心到靶心的距离
const deltaX = arrowCenterX - centerX; const deltaX = arrowCenterX - centerX;
@@ -451,8 +450,8 @@ const calcHalfBowTarget = (x, y, diameter, arrowRadius, noX = false) => {
const arrowCenterY = y + arrowRadius; const arrowCenterY = y + arrowRadius;
// 计算靶心坐标(靶纸中心) // 计算靶心坐标(靶纸中心)
const centerX = diameter / 2; const centerX = (diameter + arrowRadius * 2) / 2;
const centerY = diameter / 2; const centerY = (diameter + arrowRadius * 2) / 2;
// 计算弓箭圆心到靶心的距离 // 计算弓箭圆心到靶心的距离
const deltaX = arrowCenterX - centerX; const deltaX = arrowCenterX - centerX;
@@ -484,11 +483,11 @@ export const calcTripleBowTarget = (
arrowRadius, arrowRadius,
noX = false noX = false
) => { ) => {
const side = diameter * 0.31; const side = diameter * 0.327; // 115 / 351
if (y / diameter >= 0.649) { if (y / diameter >= 0.649) {
return calcHalfBowTarget( return calcHalfBowTarget(
x - diameter * 0.355, x - diameter * 0.338,
y - diameter * 0.693, y - diameter * 0.675,
side, side,
arrowRadius, arrowRadius,
noX noX
@@ -496,17 +495,17 @@ export const calcTripleBowTarget = (
} }
if (y / diameter >= 0.31) { if (y / diameter >= 0.31) {
return calcHalfBowTarget( return calcHalfBowTarget(
x - diameter * 0.355, x - diameter * 0.338,
y - diameter * 0.356, y - diameter * 0.337,
side, side,
arrowRadius, arrowRadius,
noX noX
); );
} }
if (y / diameter >= -0.025) { if (y / diameter >= -0.026) {
return calcHalfBowTarget( return calcHalfBowTarget(
x - diameter * 0.355, x - diameter * 0.338,
y - diameter * 0.018, y - diameter * 0,
side, side,
arrowRadius, arrowRadius,
noX noX
@@ -544,7 +543,7 @@ export const calcPinBowTarget = (x, y, diameter, arrowRadius, noX = false) => {
return r1 || r2 || r3; return r1 || r2 || r3;
}; };
export const calcRing = (bowtargetId, x, y, diameter, arrowRadius) => { export const calcRing = (bowtargetId, x, y, diameter, arrowRadius = 5) => {
if (bowtargetId < 4) { if (bowtargetId < 4) {
return calcNormalBowTarget(x, y, diameter, arrowRadius); return calcNormalBowTarget(x, y, diameter, arrowRadius);
} else if (bowtargetId < 7) { } else if (bowtargetId < 7) {