`motionContextToDocs`: `y` track copies `opacity` when a node animates both (key lookup has no word boundary)

Đã đóng Phù hợp với người mới
#6,756 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@Muzzy5150 đang làm issue này rồi.

Từ ngày 30/10/2026.

  • #6800 của @Muzzy5150 — đang mở
  • #6810 của @MoonPointer-Byte — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
node.js, typescript
Lĩnh vực
backend, testing

Hướng nghiên cứu

Bắt đầu với dist/figma/motionContextToDocs.js và kiểm tra arrayAfterKey, scalarAfterKey cùng phần tra cứu balancedBlock được mô tả trong issue. Chạy trường hợp tái hiện được cung cấp với package và kiểm tra track y được xuất ra. Công việc hoàn tất khi các giá trị và thời điểm của track khớp với các mảng mong đợi khi opacity và y xuất hiện cùng nhau.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

In @hyperframes/core (dist/figma/motionContextToDocs.js), arrayAfterKey, scalarAfterKey and the
balancedBlock(transition, ${prop}: {) lookup search for the key with a plain regex or substring,
with no word boundary. When a Figma node animates opacity and y together, the search for y: [
matches inside opacity: [ (and y: { inside opacity: {), so the y track gets the opacity values
and timing. Letters that should rise 120px move 1px. Any key that ends another key is exposed the same
way.

The verify-motion.mjs check in the /figma skill passes the wrong translation: on our test it
scored the broken output higher than the corrected one (16.28 dB against 15.89 dB worst segment),
because the fade dominates the motion energy it compares.

Minimal reproduction
// repro.mjs — run: node repro.mjs <path to an installed @hyperframes/core>
const core = process.argv[2];
const { motionContextToDocs } = await import(core + "/dist/figma/index.js");
const snippet = '<motion.div initial={{ opacity: 0, y: 120, }} animate={{ opacity: [0, 0, 1, 1], y: [120, 120, 0, 0], }} transition={{ opacity: { duration: 4.5, times: [0, 0.0444, 0.1333, 1], ease: ["linear", "easeOut", "linear"], repeat: Infinity }, y: { duration: 4.5, times: [0, 0.0444, 0.2222, 1], ease: ["linear", "easeOut", "linear"], repeat: Infinity }, }} />';
const response = {
  nodes: [{ nodeId: "1:2", nodeName: "Box", nodeType: "FRAME", codeSnippets: { motionDev: snippet } }],
  timelineCohorts: [{ rootNodeId: "1:1", durationMs: 4500, loopMode: "loop", memberNodeIds: ["1:2"] }],
};
console.log(JSON.stringify(motionContextToDocs(response, { selectorFor: () => "#box" }), null, 1));

The snippet has the same shape as what get_motion_context returns for a layer with a fade and a
rise in Figma Motion.

Steps to reproduce
  1. npm pack @hyperframes/[email protected] && tar xzf hyperframes-core-0.8.217.tgz && (cd package && npm install --omit=dev)
  2. node repro.mjs ./package
  3. Look at the y track.
Expected behavior

y track: values [120, 120, 0, 0], times [0, 0.0444, 0.2222, 1].

Actual behavior

y track: values [0, 0, 1, 1], times [0, 0.0444, 0.1333, 1]: the opacity track, copied.

Environment
✓ Version          CLI 0.8.181 (plugin) · @hyperframes/core 0.8.181 and 0.8.217 both affected
✓ Node.js          v24.22.0 (darwin arm64)
✓ CPU              8 cores · Apple M3
✓ FFmpeg           ffmpeg 6.0
✓ Chrome           chrome-headless-shell mac_arm 152.0.7977.30
Additional context

A fix that keeps the current parsing: anchor the key so it cannot match inside a longer identifier,
for example new RegExp(`(?<![\\w$])${escapeRegExp(key)}\\s*:\\s*\\[`) in arrayAfterKey, the same
in scalarAfterKey, and the same guard in the balancedBlock lookup for ${prop}: {. Our workaround
until then is to reorder the snippet so the y entry comes before opacity, which changes no value.
It would also help if verify-motion.mjs compared the emitted tweens property by property against
the get_motion_context keyframes, since a frame-energy score cannot see a swapped track.

Ngôn ngữ chính
TypeScript
Star
54.1k
Fork
4.9k
Merge trung bình
6 giờ 41 phút
Pull request đã merge (30 ngày)
794

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của heygen-com/hyperframes

Tất cả issue của heygen-com/hyperframes

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.