From f5b13915e0f6f8ce8499a3530e86c6ed5b572909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 4 Aug 2026 11:41:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A7=92=E8=89=B2=E5=8A=A8?= =?UTF-8?q?=E4=BD=9C=E9=A2=84=E8=A7=88=E5=8A=A0=E8=BD=BD=E4=B8=8E=E4=BA=A4?= =?UTF-8?q?=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后台和创作主页播放器只挂载当前帧与有界预读帧,避免一次换签全部序列。 浏览器播放间隔限制在定时器安全上限,不恢复已移除的最低帧间隔。 创作主页分别跟踪悬停和焦点,并遵循系统减少动态效果偏好。 后台播放按钮扩展为触控友好的四十四像素点击区域。 补充预读窗口、交互状态和减少动态效果回归测试与项目记忆。 --- .../src/components/AdminEditorAssetMedia.tsx | 35 +++--- .../pages/AdminEditorAssetQueryPage.test.tsx | 41 +++++-- apps/admin-web/src/styles/admin.css | 2 + docs/project-memory/shared-memory/pitfalls.md | 3 +- .../CreationLandingView.test.tsx | 102 ++++++++++++++++-- .../creation-home/CreationLandingView.tsx | 85 +++++++++++---- 6 files changed, 219 insertions(+), 49 deletions(-) diff --git a/apps/admin-web/src/components/AdminEditorAssetMedia.tsx b/apps/admin-web/src/components/AdminEditorAssetMedia.tsx index 3b3b41e99..73a837610 100644 --- a/apps/admin-web/src/components/AdminEditorAssetMedia.tsx +++ b/apps/admin-web/src/components/AdminEditorAssetMedia.tsx @@ -269,6 +269,13 @@ function AdminEditorImageSequencePreview({ const currentFrameItem = frameItems[Math.min(frameIndex, frameItems.length - 1)]; const currentFrameKey = currentFrameItem?.key ?? ''; + const mountedFrameKeys = new Set([visibleFrameKey]); + for (let offset = 0; offset < Math.min(3, frameItems.length); offset += 1) { + const item = frameItems[(frameIndex + offset) % frameItems.length]; + if (item) { + mountedFrameKeys.add(item.key); + } + } const handleFrameReady = useCallback((frameKey: string) => { setLoadedFrameKeys((currentKeys) => { @@ -303,7 +310,7 @@ function AdminEditorImageSequencePreview({ if (!isPlaying) { return undefined; } - const frameIntervalMs = durationMs / frames.length; + const frameIntervalMs = Math.min(2_147_483_647, durationMs / frames.length); const timer = window.setInterval(() => { setFrameIndex((currentIndex) => (currentIndex + 1) % frames.length); }, frameIntervalMs); @@ -315,18 +322,20 @@ function AdminEditorImageSequencePreview({ aria-label={`角色动作预览:${entry.label || entry.assetId}`} className="admin-asset-query-preview-media admin-asset-query-sequence-preview" > - {frameItems.map((item) => ( - - ))} + {frameItems + .filter((item) => mountedFrameKeys.has(item.key)) + .map((item) => ( + + ))}
@@ -679,6 +714,7 @@ export function CreationLandingView({ onOpenCommunity, searchKeyword = '', }: CreationLandingViewProps) { + const prefersReducedMotion = usePrefersReducedMotion(); const authUi = useAuthUi(); const isAuthenticated = Boolean(authUi?.user); const normalizedSearchKeyword = searchKeyword.trim().toLocaleLowerCase(); @@ -706,7 +742,9 @@ export function CreationLandingView({ useState('all'); const [selectedShowcaseItem, setSelectedShowcaseItem] = useState(null); - const [activeShowcaseSequenceCardId, setActiveShowcaseSequenceCardId] = + const [hoveredShowcaseSequenceCardId, setHoveredShowcaseSequenceCardId] = + useState(null); + const [focusedShowcaseSequenceCardId, setFocusedShowcaseSequenceCardId] = useState(null); const [selectedShowcaseIndex, setSelectedShowcaseIndex] = useState(0); const [likedShowcaseIds, setLikedShowcaseIds] = useState>( @@ -1095,16 +1133,16 @@ export function CreationLandingView({ type="button" className="creation-landing__asset-card-open" onPointerEnter={() => - setActiveShowcaseSequenceCardId(item.id) + setHoveredShowcaseSequenceCardId(item.id) } onPointerLeave={() => - setActiveShowcaseSequenceCardId((current) => + setHoveredShowcaseSequenceCardId((current) => current === item.id ? null : current, ) } - onFocus={() => setActiveShowcaseSequenceCardId(item.id)} + onFocus={() => setFocusedShowcaseSequenceCardId(item.id)} onBlur={() => - setActiveShowcaseSequenceCardId((current) => + setFocusedShowcaseSequenceCardId((current) => current === item.id ? null : current, ) } @@ -1116,7 +1154,9 @@ export function CreationLandingView({ @@ -1374,6 +1414,7 @@ export function CreationLandingView({ setSelectedShowcaseItem(null)} />