fix scale point
This commit is contained in:
40
src/App.vue
40
src/App.vue
@@ -181,8 +181,32 @@ const handleTimelineClick = (e: MouseEvent) => {
|
|||||||
const handleTimelineWheel = (e: WheelEvent) => {
|
const handleTimelineWheel = (e: WheelEvent) => {
|
||||||
if (e.ctrlKey) {
|
if (e.ctrlKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (!timelineRef.value) return;
|
||||||
|
|
||||||
|
const rect = timelineRef.value.getBoundingClientRect();
|
||||||
|
const mouseYInViewport = e.clientY - rect.top;
|
||||||
|
const scrollOffset = timelineRef.value.scrollTop;
|
||||||
|
|
||||||
|
// Position of cursor relative to the content total height before zoom
|
||||||
|
const cursorYInContent = mouseYInViewport + scrollOffset;
|
||||||
|
const oldRulerHeight = rulerHeight.value;
|
||||||
|
|
||||||
|
// Perform zoom change
|
||||||
const delta = e.deltaY > 0 ? -0.2 : 0.2;
|
const delta = e.deltaY > 0 ? -0.2 : 0.2;
|
||||||
timelineZoom.value = Math.min(Math.max(0.5, timelineZoom.value + delta), 15);
|
const newZoom = Math.min(Math.max(0.5, timelineZoom.value + delta), 15);
|
||||||
|
|
||||||
|
if (newZoom === timelineZoom.value) return;
|
||||||
|
|
||||||
|
timelineZoom.value = newZoom;
|
||||||
|
|
||||||
|
// Wait for DOM update or calculate it
|
||||||
|
const newRulerHeight = TOTAL_MINUTES * newZoom;
|
||||||
|
|
||||||
|
// Calculate new scroll position to keep cursor point fixed
|
||||||
|
const newScrollTop = (cursorYInContent / oldRulerHeight) * newRulerHeight - mouseYInViewport;
|
||||||
|
|
||||||
|
timelineRef.value.scrollTop = newScrollTop;
|
||||||
|
|
||||||
updateSettings();
|
updateSettings();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -227,18 +251,6 @@ const handleTimelineWheel = (e: WheelEvent) => {
|
|||||||
@change="loadTimeline"
|
@change="loadTimeline"
|
||||||
class="w-full bg-white border border-[#E5E5E7] rounded-xl px-4 py-2 text-sm font-medium focus:ring-2 focus:ring-[#007AFF]/20 focus:border-[#007AFF] outline-none transition-all"
|
class="w-full bg-white border border-[#E5E5E7] rounded-xl px-4 py-2 text-sm font-medium focus:ring-2 focus:ring-[#007AFF]/20 focus:border-[#007AFF] outline-none transition-all"
|
||||||
/>
|
/>
|
||||||
<div class="flex items-center gap-3 px-1">
|
|
||||||
<span class="text-[10px] font-bold text-[#86868B]">缩放</span>
|
|
||||||
<input
|
|
||||||
type="range"
|
|
||||||
v-model.number="timelineZoom"
|
|
||||||
min="0.5"
|
|
||||||
max="10"
|
|
||||||
step="0.1"
|
|
||||||
@change="updateSettings"
|
|
||||||
class="flex-1 h-1 bg-[#E5E5E7] rounded-full appearance-none cursor-pointer accent-[#007AFF]"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -267,7 +279,7 @@ const handleTimelineWheel = (e: WheelEvent) => {
|
|||||||
<div
|
<div
|
||||||
v-for="img in timelineImages"
|
v-for="img in timelineImages"
|
||||||
:key="img.path"
|
:key="img.path"
|
||||||
class="absolute left-1 right-8 h-1 bg-[#007AFF]/30 rounded-full transition-all"
|
class="absolute left-1 right-8 h-1 bg-[#007AFF]/30 rounded-full"
|
||||||
:class="[
|
:class="[
|
||||||
selectedImage?.path === img.path ? 'bg-[#007AFF]/60 h-2 shadow-sm z-10' : '',
|
selectedImage?.path === img.path ? 'bg-[#007AFF]/60 h-2 shadow-sm z-10' : '',
|
||||||
lockedImage?.path === img.path ? 'bg-[#007AFF] h-2.5 ring-2 ring-[#007AFF]/20 z-20' : ''
|
lockedImage?.path === img.path ? 'bg-[#007AFF] h-2.5 ring-2 ring-[#007AFF]/20 z-20' : ''
|
||||||
|
|||||||
Reference in New Issue
Block a user