轴点功能修复

This commit is contained in:
tianmo committed 2026-10-22 12:04:29 +08:00
1 parent 4d54c87681
commit 2b8fd067b3
16 files changed
+1750 -105

No files matched your search

+17 -13
View File
@@ -55,11 +55,11 @@
<div class="pivot-card-head"><span><span class="pivot-card-icon">◎</span> 轴点坐标(%)</span></div>
<div class="pivot-coords">
<label>X:
<input type="number" min="0" max="100" step="0.1" :value="anchorXText" @input="updateCoord('x', $event)" />
<input type="number" min="-1000" max="1000" step="0.1" :value="anchorXText" @input="updateCoord('x', $event)" />
<span>%</span>
</label>
<label>Y:
<input type="number" min="0" max="100" step="0.1" :value="anchorYText" @input="updateCoord('y', $event)" />
<input type="number" min="-1000" max="1000" step="0.1" :value="anchorYText" @input="updateCoord('y', $event)" />
<span>%</span>
</label>
</div>
@@ -133,9 +133,12 @@ const rotationMode = ref<'static' | 'spin' | 'swing'>('static')
let observer: ResizeObserver | null = null
const clampPercent = (value: number) => Math.min(100, Math.max(0, Number.isFinite(value) ? value : 0))
const anchorXText = computed(() => (clampPercent(props.anchorX * 100)).toFixed(1))
const anchorYText = computed(() => (clampPercent(props.anchorY * 100)).toFixed(1))
// 轴点允许落在图片之外;这里只做 ±1000% 的防护上限。
const COORD_LIMIT_PERCENT = 1000
const clampCoordPercent = (value: number) =>
Math.min(COORD_LIMIT_PERCENT, Math.max(-COORD_LIMIT_PERCENT, Number.isFinite(value) ? value : 0))
const anchorXText = computed(() => clampCoordPercent(props.anchorX * 100).toFixed(1))
const anchorYText = computed(() => clampCoordPercent(props.anchorY * 100).toFixed(1))
function contain(width: number, height: number) {
const ratio = natural.value.w / Math.max(1, natural.value.h)
@@ -162,8 +165,8 @@ const boxStyle = computed(() => ({
const pivotScreen = computed(() => {
const scale = zoom.value / 100
return {
x: stageSize.value.w / 2 + pan.value.x + (clampPercent(props.anchorX * 100) / 100 - 0.5) * fit.value.w * scale,
y: stageSize.value.h / 2 + pan.value.y + (clampPercent(props.anchorY * 100) / 100 - 0.5) * fit.value.h * scale,
x: stageSize.value.w / 2 + pan.value.x + (clampCoordPercent(props.anchorX * 100) / 100 - 0.5) * fit.value.w * scale,
y: stageSize.value.h / 2 + pan.value.y + (clampCoordPercent(props.anchorY * 100) / 100 - 0.5) * fit.value.h * scale,
}
})
@@ -173,13 +176,14 @@ const rotateStyle = computed(() => {
return {
width: `${box.w}px`,
height: `${box.h}px`,
transformOrigin: `${clampPercent(props.anchorX * 100)}% ${clampPercent(props.anchorY * 100)}%`,
transformOrigin: `${clampCoordPercent(props.anchorX * 100)}% ${clampCoordPercent(props.anchorY * 100)}%`,
}
})
function setAnchor(x: number, y: number) {
emit('update:anchorX', Math.min(1, Math.max(0, Number.isFinite(x) ? x : 0)))
emit('update:anchorY', Math.min(1, Math.max(0, Number.isFinite(y) ? y : 0)))
const limit = COORD_LIMIT_PERCENT / 100
emit('update:anchorX', Math.min(limit, Math.max(-limit, Number.isFinite(x) ? x : 0)))
emit('update:anchorY', Math.min(limit, Math.max(-limit, Number.isFinite(y) ? y : 0)))
}
function updateFromPointer(event: PointerEvent) {
@@ -275,12 +279,12 @@ function pickPreset(preset: { x: number; y: number }) {
}
function isPreset(preset: { x: number; y: number }) {
return Math.abs(clampPercent(props.anchorX * 100) - preset.x) < 0.05
&& Math.abs(clampPercent(props.anchorY * 100) - preset.y) < 0.05
return Math.abs(clampCoordPercent(props.anchorX * 100) - preset.x) < 0.05
&& Math.abs(clampCoordPercent(props.anchorY * 100) - preset.y) < 0.05
}
function updateCoord(axis: 'x' | 'y', event: Event) {
const value = clampPercent(Number((event.target as HTMLInputElement).value))
const value = clampCoordPercent(Number((event.target as HTMLInputElement).value))
if (axis === 'x') emit('update:anchorX', value / 100)
else emit('update:anchorY', value / 100)
}