在 Quar Animator 中設計與製作動畫
Quar Animator 是一款 2D 向量動畫編輯器;其 MCP 工具可以讀取和編輯使用者的雲端專案。你的工作方式就像一位能看到自己作品的動態設計師:規劃、建構、查看、修正、動畫化、檢視動態、匯出。每次「查看」都是來自伺服器的圖片 — 請相信它,而不是你原本想製作的內容。
如果 quar-animator 工具無法使用,請告知使用者,並引導他們參考本技能的 README 進行設定(在 https://api.animator.quar.pro/mcp 連線 MCP);請不要臨時用其他方式建立檔案。
工作循環
- 讀取。 使用
list_projects(或建立新專案create_project {name}— 提供使用者editorUrl,可在其編輯器中開啟;標記為stillUploading的專案尚無版本,其影片仍在從編輯器上傳:在取得版本前無法開啟),然後使用get_scene_context {project_id}。注意seq— 將其作為base_seq傳遞給每次編輯,以便編輯會在尚未看到變更時失敗,而不會套用到未察覺的變更上。注意frameRate、duration、artboardTimelines,以及哪些被鎖定(使用者的內容:未經要求請勿更動)。 - 規劃 在動手之前:考慮畫面(artboard 尺寸)、佈局、調色板、字體、什麼會移動以及何時移動。用幾行文字為使用者寫下規劃。參考
reference/design.md和reference/motion.md;對於已知類型的作品,請遵循recipes/中的配方。 - 透過空運行建構。 為一個連貫的步驟(背景、佈局、文字…)執行一次
apply_edit_batch,並設定dry_run: true。這不會儲存任何內容,只會回傳將發生的變更,即placed— 每個新增或變更的節點在結果中的at和bounds,用於在儲存前測量佈局 — 以及一張圖片(preview_frame;可使用preview_node顯示單一 artboard 或節點;preview_size最大 1024)。使用自訂的id(例如"id": "title")來add_node,以便後續批次中的操作可以參考它們。 - 查看與修正。 根據
reference/design.md中的檢查清單評估圖片:對齊、間距、層級、對比度、是否有內容被裁切。修正批次並再次空運行,直到正確為止。然後移除dry_run發送,並附上message(例如「佈局:標題、副標題與 Logo」)。 - 以同樣方式製作動畫:在批次中使用
animate操作(每個屬性一次,一次設置整條曲線),在關鍵時刻使用preview_frame進行空運行,然後提交。 - 檢視動態。 使用
count: 8–12(分散在其繪製的整個時間軸上 — artboard 自己的時間軸)或精確的frames(最多 16 格)來render_preview,會產生一個帶標籤的接觸片(使用count時,最後一格為第 N 幀,匯出輸出不會播放該幀)。檢查節奏、重疊、停頓、是否有跳動,以及循環時最後一幀是否與第一幀匹配。使用animate、move_keyframes、set_easing進行修正。 - 匯出(使用
export,然後用get_export {export_id, wait: true}),並閱讀其詳細資訊:Lottie 無法繼承的內容(unsupported:節點類型、帶有效果的圖層、混合模式)、幀數、尺寸。立即將連結提供給使用者 — 該連結僅在一個小時內有效;再次get_export會產生一個新的連結。 - 告知使用者 你製作了什麼,用幾行文字說明,並告知每個步驟都是一個他們可以復原的版本(
list_versions、restore_version)。
保持批次的目的性:每個有意義的步驟建立一個版本(不是每個形狀一個版本,也不是一次盲目地完成整個作品)。一個批次最多包含 500 個操作,並且是全部或無。
呼叫方式
參數彼此並列 — 不要嵌套在 options 物件中。
create_project {name}
get_scene_context {project_id, page?, node?, depth?}
get_node {project_id, node, page?} (每個儲存的屬性及其關鍵影格)
get_timeline {project_id, page?, node?, property?} (每個關鍵影格,及其緩動函數;單一屬性的)
get_animatable_properties {node_type} (類型可動畫化的屬性:骨架也包含 x, y)
list_fonts {} (可以繪製文字的系列及其字重)
measure_text {text, font_family?, font_weight?, font_size?, letter_spacing?, line_height?, box_width?}
(每個字形的 x 位置和 advance、行寬、上升、下降)
apply_edit_batch {project_id, ops: [...], base_seq?, message?, dry_run?, preview_frame?,
preview_page?, preview_node?, preview_size?}
render_frame {project_id, frame?, node?, page?, size?, transparent?}
render_preview {project_id, frames? | count?, node?, page?, size?, transparent?}
capture_canvas {project_id, frame?, page?} (使用者的開放編輯器繪製內容;如果無回應則使用已儲存版本)
export {project_id, format, node?, frame?, start_frame?, end_frame?, fps?, width?, height?}
get_export {export_id, wait?, include_file?}
list_versions {project_id}
restore_version {project_id, seq}
一個操作是 {"op": <name>, …其參數};每個操作可以有自己的 page(批次本身沒有 page)。這些操作是編輯工具的名稱:add_node、update_node、set_style、delete_node、duplicate_node、group_nodes、mask_nodes、ungroup_node、reorder_node、set_pivot、convert_to_outlines、
add_keyframe、animate、remove_keyframe、move_keyframes、set_easing、clear_animation、
add_page、delete_page、rename_page、duplicate_page、set_document、
set_artboard_duration、add_bone、pose_bone、set_ik_target、bind_mesh(一個批次中最多 20 個 bind_mesh 操作和 60 個圖層:一次綁定多個形狀)、unbind_mesh、
set_video_clip(如下)。get_bindings 讀取每個綁定圖層跟隨的骨骼;綁定的圖層可以被刪除(其綁定關係也會一起移除)。如果名稱衝突(例如一個形狀和一個骨骼都叫「左大腿」),請使用 id。
[
{ "op": "add_node", "type": "rectangle", "id": "card", "parent": "frame", "x": 0, "y": 0,
"width": 640, "height": 360, "cornerRadius": 24, "fill": "#1f1d29" },
{ "op": "set_style", "node": "card",
"effects": [{ "type": "drop-shadow", "color": "#07060b", "offsetY": -16, "blur": 40, "opacity": 0.4 }] },
{ "op": "animate", "node": "card", "property": "y",
"keyframes": [{ "frame": 0, "value": -120 }, { "frame": 18, "value": 0, "easing": "easeOutCubic" }] },
{ "op": "animate", "node": "card", "property": "scale",
"keyframes": [{ "frame": 0, "value": { "x": 0.9, "y": 0.9 } }, { "frame": 18, "value": { "x": 1, "y": 1 } }] },
{ "op": "animate", "node": "card", "property": "fill",
"keyframes": [{ "frame": 0, "value": "#1f1d29" }, { "frame": 18, "value": "#a855f7" }] }
]
值:x、y、rotation、opacity、尺寸使用數字;position 和 scale 使用 {x, y};fill 和 stroke 使用 "#rrggbb"。效果:drop-shadow 和 inner-shadow 接受 color、offsetX、offsetY、blur、spread、opacity;layer-blur 接受 radius。
容易出錯的事實
- Y 軸向上。 節點的
x、y是其中心點 — 對大多數形狀和 artboard 來說是中心。Y 值越大,在螢幕上越高。(svg路徑資料是例外:Y 軸向下,如同 SVG 檔案中,在節點自己的中心點周圍的空間中。) - 兩個座標空間。
at和bounds(在get_scene_context和空運行的placed中)是頁面座標;節點的x、y— 以及其上的關鍵影格 — 是在其父節點的空間中。在一個不在頁面中心的 artboard 或群組內部,兩者不同:請圍繞節點自己的x/y(使用get_node)進行關鍵影格設置,而不是其at。 - 子節點由後往前繪製:較晚的同級節點在上方。先新增背景,最後新增焦點形狀,或者使用
reorder_node {node, to: "front"|"back"|…, index?}重新排序。 - Artboard 預設為白色,除非指定填色:使用
"fill": "none"可獲得透明背景(適用於 App 的 Lottie、貼紙)。 - 樞紐點。 縮放和旋轉是圍繞節點的位置(即其樞紐點)進行,對大多數形狀來說是中心。若要將樞紐點設在其他位置 — 例如肢體的關節處、Logo 在地板上擠壓、文字向右增長 — 使用
set_pivot {node, at: "bottom"}(在其自身的邊界框上:left、top-right…)或{node, x, y}(頁面上的一個點);節點在螢幕上的位置會保持不變。群組、矩形和圖片可以使用樞紐點;將其他任何東西先放入群組(group_nodes {nodes: [it], id}— 其群組在樞紐點設定前位於其父節點的原點),然後再設定群組的樞紐點。在動畫化旋轉或縮放之前設定樞紐點:動畫化的旋轉會圍繞樞紐點發生。(update_node無法變更父節點:使用reorder_node {node, parent}移動節點,並保持其位置。) - 遮罩。
mask_nodes {nodes, mask?, mode?}將節點和一個遮罩(一個形狀、文字或圖片;當未指定名稱時使用最前方的節點)放入一個群組,該群組只會顯示遮罩內部的內容 — 用於揭示效果、漸層遮罩、畫框中的圖片、物件隱藏在邊緣後方。遮罩本身不會被繪製;對它進行動畫化(調整其大小、位置、縮放)來實現揭示效果。mode:clip(使用其輪廓)、alpha(使用其透明度:漸層淡入淡出效果)、luminance(白色顯示,黑色隱藏)。 rotation是逆時針旋轉的度數,按照寫入的方式進行補間:0 → 360 是一整圈;−360 則是順時針一圈。- 漸層:
angle0° 從左到右,90° 從下到上(270° 從上到下)。 - 陰影:
offsetY為負值將陰影置於下方。 letterSpacing單位為像素(在 100 px 字體大小下,−2 是緊湊的顯示字距)。- 路徑會保持其自己的中心作為其位置:關鍵影格
x/y應圍繞其當前值設定(使用get_scene_context的at讀取),而不是圍繞 0。 - 文字和字體。 文字在使用 Inter 字體(始終可用:100 到 900 的所有字重,400 和 700 有斜體)或編輯器中的 Google Fonts(
list_fonts:系列及其字重 — 僅有正體;缺少的字重會使用最接近的字重)時,會以其自身的系列進行繪製、排版和測量。伺服器會在文件首次使用 Google 字體時獲取該字體。文字的寬度是精確的(包含 advance、kerning、字母間距);高度是行框(行數 × 字體大小 ×lineHeight)。不在列表中的系列會使用 Inter 繪製和測量,回傳中會說明(fonts):請從列表中選擇,或者在使用者的專案在其編輯器中開啟時使用capture_canvas檢查使用者自己的字體。measure_text設置文字但不放置它:每個字形的x和advance,每行的寬度,字體的上升和下降 — 用於遊標、底線和將單詞匹配到特定寬度。convert_to_outlines {node}將文字轉換為字母路徑組(<id>-1…,以其字母命名),用於逐字母動畫:錯開時間、重新著色其中一個、彈跳一個。此操作不可逆。 - 時間軸。
duration和frameRate是文件的設定。頁面頂部的每個 artboard 都會播放自己的時間軸 — 其圖層的關鍵影格,以其自身的長度(artboardTimelines;set_artboard_duration {artboard, duration};在設定之前使用文件的持續時間)。一個 N 幀的時間軸可以包含 0…N 的關鍵影格;匯出和投影片播放幀 0…N−1,因此對於循環,關鍵影格 N 必須等於幀 0。在關鍵影格設定超過時間軸結尾之前,請延長時間軸(使用set_document {duration}設定頁面的時間軸)。 - 投影片。 在編輯器的簡報和影片匯出中,以及在對包含多個 artboard 的頁面進行 GIF 和 PNG 序列匯出時(沒有
node,沒有範圍),artboard 會一個接一個播放 — 最前方的先播放(圖層面板頂部),每個播放自己的長度,並適應第一個 artboard 的尺寸。之後新增的 artboard 會出現在前方,因此它會先播放:使用index: 0新增後續投影片,或使用reorder_node重新排序它們。artboardTimelines會按照播放順序列出它們。使用node匯出單個 artboard。MP4 和 WebM 是從編輯器(檔案 › 匯出)匯出的,而不是從 MCP。 easing是進入到一個關鍵影格時,從前一個影格開始的曲線。名稱請參考reference/motion.md;[x1, y1, x2, y2]指定一個立方貝塞爾曲線。一個帶有 overshoot 的緩動函數(easeOutBack)進入到一個已經是 overshoot 狀態的關鍵影格時,會造成雙重 overshoot:請使用easeOutCubic進入峰值,並使用彈性緩動函數進行穩定。- 影片。 一個影片圖層(
"type": "video":使用者匯入的 MP4、MOV 或 WebM,或動畫 GIF)是一張在其剪輯播放時播放的圖片,並且在其剪輯之外不顯示任何內容,除非設定為保持最後一幀。get_scene_context會提供其video:包含file、gif、length(秒)、以及其clip—start(開始播放的幀)、end(停止播放的幀)、offset(從影片開頭剪去的秒數)、duration(一次播放的影片秒數)、speed、loop和loopFor(循環播放的秒數)、hold(結束後最後一張圖片是否保留)— 以及其關聯的sound(時間軸上的一個剪輯,會隨之移動)。使用set_video_clip {node, moveTo?, trimStart?, trimEnd?, speed?, loop?, hold?, stopAt?, unlinkSound?}變更剪輯 — 參數為時間軸上的幀,並按 loop、speed、moveTo、trimStart、trimEnd、hold、stopAt 的順序應用:moveTo設定其開始的幀;trimStart設定其第一幀,結束位置保持不變(正值會剪去影片開頭的內容,負值則播放更多內容);trimEnd設定其停止的幀(負值剪去結尾,正值播放更多內容,直到影片結尾 — 或者,搭配loop,則循環直到該幀:{loop: true, trimEnd: 300}會填滿一個 10 秒的投影片)。speed範圍 0.25–4(聲音會保持音高);hold: true保留最後一張圖片;stopAt在特定幀結束,保留該幀顯示的畫面(例如 GIF 凍結在某個位置);loop: false對 GIF 也會使其保持靜止。- 其聲音會跟隨每次變更,並且其播放所在的時間軸會被延長以播放到結束(結果會顯示
timelineLengthened)。unlinkSound: true會將聲音獨立出來。 除此之外,影片圖層就是一個圖片:可以移動、調整大小(width、height)、設定圓角(cornerRadius)、淡入淡出、adjustments、效果、混合模式、遮罩(它也可以作為遮罩)、樞紐點和關鍵影格,與圖片相同 — 但不能拉動角落,也不能綁定骨架。duplicate_node會同時複製其聲音;delete_node會刪除其聲音。
…
[翻譯內容因原文截斷而結束]