Skip to content

关键帧面板:时间 ruler + 跨属性吸附 + 黄色吸附线#175

Merged
appergb merged 1 commit into
mainfrom
feat/keyframe-panel-snapping
Jul 2, 2026
Merged

关键帧面板:时间 ruler + 跨属性吸附 + 黄色吸附线#175
appergb merged 1 commit into
mainfrom
feat/keyframe-panel-snapping

Conversation

@appergb

@appergb appergb commented Jul 1, 2026

Copy link
Copy Markdown
Owner

概要

Inspector 关键帧面板的三个上游编辑器 affordance(Inspector/Keyframes/KeyframesLane.swift)。此前拖动关键帧只吸附播放头。

变更

  • 跨属性吸附:拖动 diamond 时吸附到最近的 {播放头, 片段首/尾, 其他所有属性的关键帧} ±5 帧(上游 snapTargetswhere p != property 跳当前属性轨)。
  • 黄色吸附线:吸附激活时显示 panel 级黄色虚线(上游 snapOverlay dash[4,4],与主时间线 SnapIndicator 视觉一致)。状态提升到 KeyframesPanel(线需跨全部行)。
  • 时间 ruler:静态着色条换成真刻度 ruler,复用现有 chooseTicks(TimelineRuler 1:1 端口)+ formatTimecode 标签(如上游 RulerView 复用 TimelineRuler)。
  • 新增 keyframeSnap.ts(pure snapFrame 最近优先)+ KeyframesRuler.tsx(ResizeObserver 测宽)+ tokens --status-warning(SwiftUI .yellow)。

保留

播放头吸附(现为目标之一)、moveKeyframe 提交、diamond 实时跟随、右键菜单、stamp/clear、拖拽卸载清理。纯前端。

测试

  • snapFrame 单测(最近优先 / tie 确定性 / 边界包含 / 空目标 / 零阈值 / 组合目标)。
  • pnpm build(tsc)绿;pnpm test 218 通过(+ snapFrame 测试)。

Port upstream KeyframesLane's editor affordances (Inspector/Keyframes/
KeyframesLane.swift). Dragging a keyframe diamond previously snapped only to the
playhead; now it snaps to the nearest of {playhead, clip start/end, every OTHER
property's keyframes} within ±5 frames (snapTargets, :201-216), and a panel-wide
yellow DASHED guide line shows while snapped (snapOverlay, :301-313, matching the
main timeline's SnapIndicator). The static tinted strip becomes a real tick ruler
reusing the shared chooseTicks/formatTimecode logic (as upstream's RulerView
reuses TimelineRuler).

- keyframeSnap.ts: pure snapFrame(candidate, targets, threshold) — nearest-wins,
  deterministic ties, null when outside threshold. Unit-tested.
- KeyframesLaneRow: collects cross-property + clip-bound targets (excludes the
  dragged property's own track, 1:1 with `where p != property`); reports the live
  snapped frame up via onSnapChange; clears it on mouseup + mid-drag unmount.
- KeyframesPanel: lifts the snap-frame state (the line must span all rows);
  renders the yellow dashed overlay; swaps the tinted strip for <KeyframesRuler>.
- KeyframesRuler.tsx: ResizeObserver-measured tick ruler, clip-relative frames.
- tokens.css: --status-warning (SwiftUI .yellow / systemYellow).

Preserved: playhead snap (now one target among many), moveKeyframe commit, live
diamond preview, context menu, stamp/clear, drag-cleanup. Frontend only.
Verified: pnpm build (tsc) clean; pnpm test 218 passed (incl. new snapFrame tests).
@appergb appergb merged commit 3ed4a2c into main Jul 2, 2026
2 checks passed
@appergb appergb deleted the feat/keyframe-panel-snapping branch July 2, 2026 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant