面板布局更新
This commit is contained in:
1 parent
a417c9119d
commit
7069b168de
18 files changed
+220
-145
No files matched your search
+21
-4
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="timeline">
|
||||
<!-- 控制按钮 -->
|
||||
<Teleport defer to="#timeline-controls-host">
|
||||
<div class="tl-controls">
|
||||
<button class="tl-btn" :class="{ on: store.timeline.playing }" @click="store.togglePlay()" :title="store.timeline.playing ? $t('timeline.pause') : $t('timeline.play')">
|
||||
{{ store.timeline.playing ? '❚❚' : '▶' }}
|
||||
@@ -65,6 +66,7 @@
|
||||
</label>
|
||||
<span class="tl-zoom">{{ zoomLabel }}</span>
|
||||
</div>
|
||||
</Teleport>
|
||||
|
||||
<!-- 时间轴视口 -->
|
||||
<div
|
||||
@@ -145,6 +147,8 @@ type SysLike = { id: number; config: any }
|
||||
const store = useParticleStore()
|
||||
const { t } = useI18n()
|
||||
const vpRef = ref<HTMLElement | null>(null)
|
||||
const viewportWidth = ref(0)
|
||||
let viewportResizeObserver: ResizeObserver | null = null
|
||||
const animationMenuRef = ref<HTMLElement | null>(null)
|
||||
const animationMenuOpen = ref(false)
|
||||
const animationNameDraft = ref('animation')
|
||||
@@ -203,8 +207,21 @@ function onDocumentPointerDown(event: PointerEvent) {
|
||||
if (!animationMenuRef.value?.contains(event.target as Node)) animationMenuOpen.value = false
|
||||
}
|
||||
|
||||
onMounted(() => document.addEventListener('pointerdown', onDocumentPointerDown))
|
||||
onBeforeUnmount(() => document.removeEventListener('pointerdown', onDocumentPointerDown))
|
||||
onMounted(() => {
|
||||
document.addEventListener('pointerdown', onDocumentPointerDown)
|
||||
const viewport = vpRef.value
|
||||
if (!viewport) return
|
||||
viewportWidth.value = viewport.clientWidth
|
||||
viewportResizeObserver = new ResizeObserver(([entry]) => {
|
||||
viewportWidth.value = Math.max(1, entry.contentRect.width)
|
||||
})
|
||||
viewportResizeObserver.observe(viewport)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
document.removeEventListener('pointerdown', onDocumentPointerDown)
|
||||
viewportResizeObserver?.disconnect()
|
||||
viewportResizeObserver = null
|
||||
})
|
||||
|
||||
// 时间轴与固定步长模拟统一读取 Store;默认 1 秒 = 30 帧,与 Spine 对齐。
|
||||
const fps = computed(() => Math.max(1, store.timeline.fps || 30))
|
||||
@@ -258,7 +275,7 @@ function commitPlaybackEnd() {
|
||||
|
||||
// 每像素代表的帧数(视口宽度内放下 viewFrames 帧)
|
||||
function pxPerF() {
|
||||
const vw = vpRef.value?.clientWidth || 600
|
||||
const vw = viewportWidth.value || vpRef.value?.clientWidth || 600
|
||||
return viewFrames.value / vw
|
||||
}
|
||||
|
||||
@@ -494,7 +511,7 @@ function onSpineBarDown(e: PointerEvent, spine: SpineSceneObject) {
|
||||
|
||||
<style scoped>
|
||||
.timeline { height: 100%; background: #12121c; border-top: 1px solid #2a2a3c; display: flex; flex-direction: column; padding: 6px 10px; gap: 4px; }
|
||||
.tl-controls { display: flex; align-items: center; gap: 8px; }
|
||||
.tl-controls { display: flex; width: 100%; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||||
.tl-btn { width: 30px; height: 26px; background: #1e1e2e; border: 1px solid #2e2e44; border-radius: 6px; color: #aab; font-size: 12px; cursor: pointer; }
|
||||
.tl-btn.on { background: #3a5a8c; color: #fff; border-color: #5a7ab8; }
|
||||
.tl-ab-loop { position: relative; }
|
||||
|
||||
Reference in new issue
Block a user