morph-ppt について
morph-pptは、Morphトランジションを使ったPowerPoint作成のためにofficecli-pptxを拡張するスキルです。スライド間での図形名の一致、動きの計画、Morph固有の挙動と表示上の制約を扱います。
主な機能
- 01名前によるスライド間の図形対応
- 02アクターの移動と退場の計画
- 03Morphスライドトランジションの設定
- 04シーン・アクター・スライド用接頭辞の使用
- 05Morph表示上の制約確認
活用シーン
- 01図形がスライド間を移動するデッキの作成
- 02連続するスライド間でのビジュアル要素の変化
- 03対応ビューア向けMorphデッキの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ iofficeai/ officecli --skill morph-pptインストール後、Claude Code で/morph-pptを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
reference/decision-rules.mdmorph-helpers.pymorph-helpers.shpptx-design.mdreference/styles/bw--brutalist-raw/build.shbw__brutalist_raw.pptxstyle.mdreference/styles/bw--mono-line/build.shbw__mono_line.pptxstyle.mdreference/styles/bw--swiss-bauhaus/build.shbw__swiss_bauhaus.pptxstyle.mdreference/styles/bw--swiss-system/style.mdreference/styles/dark--architectural-plan/build.shdark__architectural_plan.pptxstyle.mdreference/styles/dark--aurora-softedge/style.mdreference/styles/dark--blueprint-grid/build.shdark__blueprint_grid.pptxstyle.mdreference/styles/dark--circle-digital/build.shdark__circle_digital.pptxstyle.mdreference/styles/dark--cosmic-neon/build.shdark__cosmic_neon.pptxstyle.mdreference/styles/dark--cyber-future/build.shdark__cyber_future.pptxstyle.md詳細
OfficeCLI Morph-PPT スキル
このスキルは officecli-pptx の上に載るシーン層です。 pptx のハードルール(ビジュアル提供の最低基準:タイトル ≥ 36pt / 本文 ≥ 18pt / タイトル ≥ 本文の 2 倍、33.87×19.05cm の 12 列グリッド、標準パレット、チャート選択の判断表、コネクタの標準、シェルのエスケープ、常駐+バッチ、Delivery Gate 1–5a)はすべて継承されており、ここで再説明することはしません。このファイルでは、Morph に必要な追加分のみを扱います。スライド間のシェイプ名バインディング、Scene Actors とコンテンツのプレフィックス付与、ゴースト運用の規律、transition=morph の CLI の癖、52 種類のスタイルのビジュアルライブラリの参照、そして Morph 固有の新鮮な目で確認する Gate 5b の拡張です。
pptx の基本ルールで扱われている内容は、本文中で → see pptx v2 §X と示しています。まだ読んでいない場合は、先に skills/officecli-pptx/SKILL.md を読んでください。
セットアップ
officecli が見つからない場合:
- macOS / Linux:
curl -fsSL https://d.officecli.ai/install.sh | bash - Windows (PowerShell):
irm https://d.officecli.ai/install.ps1 | iex
officecli --version で確認してください(PATH が反映されていない場合は、新しいターミナルを開いてください)。インストールに失敗した場合は、https://github.com/iOfficeAI/OfficeCLI/releases からバイナリをダウンロードしてください。
⚠️ ヘルプ優先ルール
このスキルが教えるのは Morph のワークフロー(いつシェイプ名を一致させるべきか、いつゴーストにするべきか、CLI がいつ自動でプレフィックスを付けるか)であり、すべてのコマンドフラグではありません。 プロパティ名、列挙値、プリセットに確信が持てない場合は、推測する前にヘルプを参照してください。
officecli help pptx slide # authoritative for: transition, advanceTime, advanceClick, background
officecli help pptx transition # transition / transitionDuration / transitionSpeed (Parent: slide)
officecli help pptx shape # name, preset, x/y/width/height, fill, rotation, opacity, animation
officecli help pptx animation # preset + trigger + duration values
officecli help pptx <element> --json # machine-readable schema
ヘルプはインストール済みの CLI のバージョンを反映します。スキルとヘルプの記述が食い違う場合は、ヘルプが優先されます。 このファイル中のすべての --prop X= は officecli help pptx <element> で検証済みです。具体的な確認事項:transition=morph は slide に指定できる値として一覧にあり、advanceTime / advanceClick も有効です。transition は実在する要素です(officecli help pptx transition、親: slide、set/get 対応)。これは transition、transitionDuration、transitionSpeed を公開しています。トランジションの設定には高レベルのパス set <slide> --prop transition=morph を使い、速度・時間の調整には、組み合わせた省略形 transition=morph-slow(または -fast、もしくは transition=morph-<DUR_MS>)を使います。速度と時間は transition プロパティ上でこの省略形を通じてのみ設定し、独立したサブプロパティとしては設定しません。どちらも読み戻し時に往復します。transition=morph-slow/-fast は transitionSpeed=slow/fast として読み戻され、transition=morph-<DUR_MS>(例:morph-1500)は transitionDuration=1500 として読み戻されます。
メンタルモデルと継承
pptx v2 を継承します。 先に skills/officecli-pptx/SKILL.md を読んでおいてください。このスキルは、スライド・シェイプ・チャート・コネクタの追加、@name= / @id= によるアドレス指定、パスの引用、batch ヒアドキュメントの利用、フロー用コネクタでの tailEnd=triangle の使用、Delivery Gate 1–5a の実行、[AGENT-ERROR] と [RENDERER-BUG] と [SKILL gap] の切り分けができていることを前提としています。これらのいずれかに馴染みがない場合は、先に pptx v2 を読んでください。
pptx v2 から継承される内容(再度説明しないこと):
- 視覚的な配信基準の下限:タイトル ≥ 36pt / 本文 ≥ 18pt / タイトル ≥ 2× 本文、表紙の情報量、コントラストの下限、
\$\t\nのリテラル禁止、スライドあたりアニメーション 1 つ以下 / 600ms 以下。 - グリッド計算:33.87 × 19.05cm、端の余白 ≥ 1.27cm、ブロック間の間隔 ≥ 0.76cm、ネガティブスペース ≥ 20%。N 枚のカードグリッドの場合:
col = (33.87 − 2·margin − (N−1)·gap) / N。 - 4 種の標準パレット(Executive navy / Forest & moss / Warm terracotta / Charcoal minimal)。モーフデッキでは
reference/styles/から別のムードを選んでもかまいませんが、コントラストのルールは引き続き適用されます。 - チャート選択表:縦棒・横棒・折れ線・円・散布図・大きな数字の KPI の使い分け。
> 3 系列 + > 8 カテゴリの場合は分割する。 - コネクタの基本規則:
shape=straight|elbow|curve、始点・終点に@id=を使用(C-P-6)、すべてのフローにtailEnd=triangle。 - シェル エスケープの 3 層:
$はシングルクォートで囲む、batch にはヒアドキュメントを使う、実際の改行には<a:br/>を使う。 - 常駐モードと batch は 12 操作以内、
<<'EOF'のシングルクォートで囲んだデリミタを使う。 - Delivery Gate 1-5a(スキーマ、トークンの grep、ハイパーリンクの rPr、スライド順、暗背景上の暗色文字)。完了を宣言する前に、各ゲートが OK を出力していることを確認する。
- 既知の問題 C-P-1..7(ハイパーリンクの rPr、チャートの spPr 警告、アニメーション時間の読み戻し、アニメーションの削除、コネクタの列挙値、コネクタの
@name=、チャート色のレンダラー正規化)。 - 原因の切り分け:
[AGENT-ERROR]と[RENDERER-BUG]と[SKILL gap]。
モーフ固有の領域 — 本スキルが担当する内容(pptx v2 に対する差分):
- スライドをまたぐシェイプ名の結び付け。 PowerPoint のモーフエンジンは、隣接するスライドの間で同一の
name=を持つシェイプを対応付け、位置・サイズ・回転・塗り・不透明度を補間します。一致する名前がない場合、アニメーションは発生せず、単純なフェードになります。これは CLI の機能ではなく、ワークフローの規律です。 - 名前空間の接頭辞:
!!scene-*(永続的な装飾、ゴーストにならない)/!!actor-*(変化した後に退場するコンテンツ)/#sN-*(スライド単位のコンテンツ、スライド N+1 ではゴーストになる)。addの前に名前を計画しておくこと。 - ゴースト位置
x=36cm(33.87cm のキャンバスの右端の外)。!!接頭辞のシェイプは決して削除せず、キャンバス外へ移動させてモーフの退場アニメーションが再生されるようにする。 transition=morphの自動接頭辞の癖。 CLI はモーフスライド上のすべてのシェイプの先頭に!!を自動的に付加します(#s1-titleは!!#s1-titleとして保存される)。@name=のパスセレクタは引き続き解決されます。get .../shape[@name=#s1-title]はシェイプを返します(一致は接尾辞/接頭辞を許容します)。読み戻される名前は接頭辞付きの形式です。§既知の問題を参照してください。- 隣接スライドの空間的な変化。 ペア間で移動量 ≥ 5cm または回転 ≥ 15° を確保すること。そうでなければ、モーフは目に見える補間を何も行いません。
- レンダラーの実際の挙動。 モーフは PowerPoint 365 / Keynote / WPS で描画されます。LibreOffice や多くの Web ビューアーでは単純なフェードとして描画されます(実行時の機能)。これはスキルの欠陥ではなく、
[RENDERER-BUG]です。
逆方向の引き継ぎ — pptx ベース(または関連スキル)に戻るべき場合
クロススライドのモーションを使わないデッキ(取締役会資料、営業資料、全社会議、研修)では、pptx v2 ベースにとどまってください。モーフを使わない資金調達のナラティブ構成には officecli-pitch-deck にとどまってください。このスキルを使うのは、ユーザーが明示的に「モーフ」「滑らかなトランジション」「連続したアニメーション」を求めており、かつ 2 枚以上の連続するスライドが変形する視覚要素を共有している場合のみです。単発の入場アニメーションを指す「アニメーション付きデッキ」は、モーフではなく pptx v2 §アニメーションの対象です。
シェルと実行の規律
シェルのクォート、段階的実行、$FILE の規約 → pptx v2 §Shell & Execution Discipline を参照してください。ルールはそのまま同じです。
Morph 固有の追加事項:
- シェルの値に含まれる
!!は単一引用符で囲む。 Bash / zsh の履歴展開は、引用符で囲まれていない!!fooを解釈してしまいます。必ず--prop 'name=!!scene-ring'(単一引用符)を使ってください。Python のsubprocess.run([...])のリストでは引用符は不要で、"name=!!scene-ring"を通常の文字列として渡します。 - プロップのテキストに含まれる
$は単一引用符で囲む(価格トークン)。--prop text='$9/mo'や--prop text='$199/yr'のように記述し、--prop text="$9/mo"は絶対に使わないでください(zsh/bash が$9を空の変数として解釈し、テキストが.や余分なピリオドとして表示されてしまいます)。${VAR}、$USER、\n、\r、\tも、二重引用符で囲んだプロップの中では同様です。下記の Gate 2 Morph 追補では、この漏れの兆候を grep で確認します。 - シェルの値に含まれる
#は安全ですが、それでも引用符で囲んでください。#がコメントの開始になるのは、シェルの単語の先頭にある場合だけです。--prop name=#s1-titleでも動作しますが、--prop 'name=#s1-title'と書く習慣があれば、推測に頼らずに済みます。 - 複数の形状を含むスライドには、バッチのヒアドキュメントが最も確実な方法です。
<<'EOF' | officecli batch $FILEはシェルの展開をすべて無効にするため、JSON の本文に含まれる$、!!、#、'も安全に扱えます。 --jsonのレスポンスは、ペイロードを.data.results[]でラップします。queryとgetはどちらも.data.results[]の配列を返します。単一ノードのformatは.data.results[0].format.Xにあり、そのノードの子要素は.data.results[0].children[]にあります(各子要素の format は.data.results[0].children[].format.Xにあります)。必ず.data.results[0]を経由してください。.data.children[]や.data.formatを直接指定すると、エラーなしに null が返されます。- 変数: すべてのビルドスクリプトの先頭に
FILE="deck.pptx"を記述してください。以下の例はすべて$FILEを使用します。 - ゲートのシェルパターン — まず COUNT を取得し、その後 if/else。
grep … && echo LEAK || echo OKとは書かないでください。grep が終了コード 1(一致 0 件)で終了すると、||の分岐が標準出力が空の状態で実行され、「OK」が紛らわしく表示される(または前のパイプから「LEAK」が出力される)ことがあります。標準的な形式はCOUNT=$(cmd | wc -l); if [ "$COUNT" -gt 0 ]; then echo "LEAK: …"; else echo "OK"; fiです。
このスキルが担当する 2 つの基本要素
- Scene Actors(シーンアクター)= 隣接するスライド間で同一の名前が付けられ、Morph が補間できる、永続的な
!!名の形状(装飾またはコンテンツ)。!!scene-*/!!actor-*の形状はすべてシーンアクターです。 - Choreography(コレオグラフィー)=アクターがどのように変化するかの計画。どのアクターがどこへ移動し、誰が入場し、誰が退場するか、どのスライドのペアで行うかを定めます。コードを書く前に、§Morph Pair Planning の表に記述します。
このスキルは、ユーザーがモーションのある Morph を求めており、かつ 2 枚以上の連続するスライドで変形する視覚要素を共有している場合に使用します。対象の閲覧環境に関する注意:Morph には PowerPoint 365 / Keynote / WPS が必要です。ユーザーが LibreOffice のみを使用している場合は、まず警告してください(§Renderer honesty を参照)。
スピーカーノートのルール。 すべてのコンテンツスライド(表紙と締めくくり以外)には、必ず officecli add "$FILE" /slide[N] --type notes --prop text='…' でスピーカーノートを付けなければなりません。ノートがない場合は出荷できません。これは pptx v2 §Hard rules(H7)を継承しています。Morph のデッキは視覚的に簡素になりがちなので、ナレーションはノートに記載します。
Morph とは(基本的な仕組み)
PowerPoint の Morph トランジションは、同一の形状名で対応付けられた形状のプロパティを隣接するスライド間で補間することにより、滑らかなモーションを生成します。
Slide 1: shape name="!!scene-ring" x=5cm width=8cm fill=E94560 opacity=0.3
Slide 2: shape name="!!scene-ring" x=20cm width=12cm fill=E94560 opacity=0.6
↓ transition=morph on slide 2
Result: Ring smoothly moves, grows, and fades darker over ~1 second
Morph は、スライド N+1 に transition=morph が設定されている場合にのみ動作します。作成時に officecli add / --type slide --prop transition=morph で適用するか、後から officecli set "/slide[N]" --prop transition=morph で設定してください。このプロップを省略したスライド 2 以降は、マスターに定義されているトランジション(通常はなし)にフォールバックし、モーションは何のエラーもなく失われます。
3 つの接頭辞による命名体系(例外なし):
| Prefix | Role | Lifecycle | Example |
|---|---|---|---|
!!scene-* | 背景・装飾。デッキ全体にわたって存在し続ける | 一度設定し、位置・サイズを調整して動きを出す。ゴーストにすることはほとんどない | !!scene-ring, !!scene-bg-band, !!scene-grid |
!!actor-* | コンテンツ・前景。セクション全体にわたって変化する | スライドNで導入し、スライドN+1、N+2…で変更し、退場するスライドで**x=36cmへゴースト化**する | !!actor-feature-box, !!actor-metric, !!actor-headline |
#sN-* | スライドごとのコンテンツ(タイトル、箇条書き、キャプション) | スライドNで新規追加し、スライドN+1で**x=36cmへゴースト化**する | #s1-title, #s2-kpi, #s3-caption |
厳守ルール: !!scene-* と !!actor-* の名前が衝突することは絶対にあってはなりません(例: 同じデッキ内に !!scene-card と !!actor-card を置くと、モーフエンジンが混同します)。名前を区別してください。例: !!scene-card-bg と !!actor-card-content。
グラフもモーフのペアリング対象にできます。 officecli add … --type chart は --prop name=!!… を受け付けます(名前は読み戻せます)。隣接するスライドで同じ !! 名を持つグラフは、シェイプ名によるモーフのペアリングに参加し、グラフのフレームは位置・サイズが補間されます。ただし、モーフはグラフフレーム内のプロットされたデータを補間できない点に注意してください。棒が伸びる・線が伸びるといった表現で棒自体をアニメーションさせる必要がある場合は、(a) グラフをそのままフェードインさせる、または (b) 値に合わせて大きさを設定したN個の !!actor-bar-K 矩形を手作業で作成し、それらをモーフさせる、のいずれかを選んでください。各矩形は隣接するスライド間で同じ !!actor-bar-K 名を保持し、幅・高さ・塗りつぶしが変化します。
ゴーストの蓄積は気づかれにくい。 一度 !! 接頭辞のシェイプがどこかのスライドに現れると、明示的に x=36cm へ移動されない限り、以降のすべてのモーフスライドで表示され続けます。final-check ヘルパーは、可視領域に残った !! シェイプを検出しません。検出できるのは Gate 5b のスクリーンショット監査のみです。コーディングを始める前に、ペア表で各アクターの退場スライドをすべて計画してください。
空間的なバリエーションのルール。 隣接するスライドは、明確に異なる構図でなければなりません。少なくとも3つのモーフ対象シェイプについて、移動量 ≥ 5cm、または回転 ≥ 15°、またはサイズ変化 ≥ 30% のいずれかを満たす必要があります。これがないと、モーフは目に見える補間を行わず、トランジションはフェードに崩れてしまいます(サイレント失敗)。
同時タイミングの制約。 1つのモーフペア内のすべての !! シェイプは同時にアニメーションします。シェイプAをシェイプBより遅らせたい場合は、中間のキーフレームスライドを挿入してください。シェイプごとの遅延設定は存在しません。
ペア・登場・退場:1つのルールによる3つの動作。 同じ仕組み(シェイプ名の一致)によって、3つの結果が生じます。
| 動作 | 元スライド A | 先スライド B | !! を持つのは? |
|---|---|---|---|
| ペアのモーフ(補間) | !!foo を持つ | !!foo を持つ | 両スライド、同一の名前 |
| 登場(フェード / モーフイン) | —(対応するものがない) | !!foo を持つ | 先スライドのみ(新規シェイプ) |
| ゴーストによる退場(スライドアウト) | 可視位置 x に !!foo を持つ | x=36cm に !!foo を持つ | 両方。同名で、B は画面外 |
新しく入ってくるものではなく、退場するコンテンツに !! 接頭辞を付けて x=36cm へゴースト化します。 !!actor-* シェイプは、忘れられると暗黙のうちに「消える」ことになります。スライドBでその名前が欠けていると、対応のない退場(単純なフェード)として扱われます。退場アニメーションが右端からはっきりスライドアウトするように、必ず明示的に x=36cm へゴースト化してください。実行可能な例を1つ示します。
# Slide 2: actor is visible at x=5cm — Slide 3: same name, ghosted off-canvas → visible slide-off motion
officecli add "$FILE" "/slide[3]" --type shape --prop 'name=!!actor-metric' \
--prop text="42%" --prop x=36cm --prop y=8cm --prop width=6cm --prop height=3cm
コンテンツ(#sN-*)はスライドごとに新規追加します。 テキストは毎スライド変わるため、Morph はタイトルや本文に意味のあるペアリングを行えず、クロスフェードさせます。だからこそ #sN-* は各スライドで異なる名前を付けられており(意図的にペアリングされない)、スライドN+1でゴースト化しなければなりません。連続性を担うのはシーンのアクター(!!)であり、メッセージを担うのはコンテンツ(#)です。
Morph ペアの計画(コード作成前・必須)
Morph ペアを計画する前に、デッキの対象読者・目的・ナラティブが不明確な場合は、reference/decision-rules.md のプランニングプロンプトを実行して、まず brief.md を出力してください。ナラティブの軸がないモーフのアークは「動きのあるスライド」に崩れてしまい、「動きのあるストーリー」にはなりません。
officecli add を書く前に、すべてのトランジションを brief.md 内の表で計画してください。ビルドの途中で図形の名前を変更することが、ゴーストが蓄積するバグの最大の原因です。
| ペア | スライド A(開始) | スライド B(終了) | 登場するアクター | スライド B のゴースト |
|---|---|---|---|---|
| 1→2 | !!scene-ring を中央に 5cm で配置、#s1-title を表示 | リングが x=20cm に移動し、8→12cm に拡大。#s2-subtitle を表示 | !!scene-ring が変化 | #s1-title → x=36cm |
| 2→3 | !!actor-feature-box を大きく表示(幅 14cm) | フィーチャーボックスを小さく(6cm)表示し、!!actor-metric が登場 | !!scene-ring、!!actor-feature-box、!!actor-metric | #s2-subtitle → x=36cm |
| 3→4 | コンテンツセクション A | セクション B の区切りスライド | — | !!actor-feature-box + !!actor-metric → x=36cm(セクション退場)、#s3-* → x=36cm |
計画のルール:
- すべての
!!名を先に決めてください。モーフで対応付ける図形は、両方のスライドでまったく同じ名前を使う必要があります。 - すべての
!!図形を!!scene-*か!!actor-*に分類してください。シーン図形は残り続けますが、アクターには計画された退場スライドが必要です。 - セクション遷移の境界: 新しいトピックセクションに移るときは、新セクションの最初のスライドで、前のセクションのすべての
!!actor-*をゴースト化してください。残るのは!!scene-*(デッキ全体の装飾)だけです。 - 表が完成するまでビルドを開始しないでください。ビルド途中で計画が変わった場合は、表を引き直し、影響を受けるスライドを再検証してください。
Morph のレシピ(4 パターン)
4 つのパターンで、morph デッキの約 95% をカバーできます。以降のすべてのブロックで $FILE="deck.pptx" を使用します。各ブロックは独立しており、20 行以内です。
(a) 単一要素のモーフ — サイズ / 位置
見た目の結果。 スライド 1 の中央にあるヒーロータイトル(48pt、y=8cm)を、スライド 2 で 32pt に縮小し、左上隅(x=1.5cm、y=1cm)へ移動させます。スライド 2 の新しいコンテンツを中央で目立たせます。図形は 1 つだけで、アクターは不要な、シンプルな動きです。
FILE="deck.pptx"
officecli create "$FILE"; officecli open "$FILE"
# Slide 1 — hero
officecli add "$FILE" / --type slide --prop layout=blank --prop background=1E2761
officecli add "$FILE" /slide[1] --type shape --prop 'name=!!actor-headline' \
--prop text="The one idea" --prop x=4cm --prop y=8cm --prop width=26cm --prop height=3cm \
--prop font=Georgia --prop size=48 --prop bold=true --prop color=FFFFFF --prop align=center --prop fill=none
# Slide 2 — headline shrinks + moves; new body takes stage
officecli add "$FILE" / --type slide --prop layout=blank --prop background=1E2761 --prop transition=morph
officecli add "$FILE" /slide[2] --type shape --prop 'name=!!actor-headline' \
--prop text="The one idea" --prop x=1.5cm --prop y=1cm --prop width=12cm --prop height=1.5cm \
--prop font=Georgia --prop size=24 --prop bold=true --prop color=FFFFFF --prop align=left --prop fill=none
officecli add "$FILE" /slide[2] --type shape --prop 'name=#s2-body' \
--prop text="Here is the supporting evidence." --prop x=1.5cm --prop y=5cm --prop width=30cm --prop height=2cm \
--prop font=Calibri --prop size=20 --prop color=CADCFC --prop fill=none
officecli close "$FILE"; officecli validate "$FILE"
(b) 複数要素の協調モーフ — アクター / コレオグラフィー
見た目の結果。 3 つのシーンアクター(!!scene-ring、!!scene-dot、!!scene-band)を 3 枚のスライドにわたって再配置し、カメラのパンのような動きにします。スライドごとの新しいタイトルは、#sN-* のゴーストパターンでフェードイン/フェードアウトします。ナラティブに連続した視覚的な背景があるときに使用してください。
# Slide 1 — anchor composition (already built via recipe a; here we add actors)
officecli add "$FILE" /slide[1] --type shape --prop 'name=!!scene-ring' --prop preset=ellipse \
--prop fill=E94560 --prop opacity=0.3 --prop x=5cm --prop y=3cm --prop width=8cm --prop height=8cm
officecli add "$FILE" /slide[1] --type shape --prop 'name=!!scene-dot' --prop preset=ellipse \
--prop fill=0F3460 --prop x=28cm --prop y=15cm --prop width=1cm --prop height=1cm
# Slide 2 — morph: ring moves + grows, dot slides left (spatial variety ≥ 5cm on both)
officecli set "$FILE" "/slide[2]" --prop transition=morph
officecli add "$FILE" /slide[2] --type shape --prop 'name=!!scene-ring' --prop preset=ellipse \
--prop fill=E94560 --prop opacity=0.6 --prop x=20cm --prop y=2cm --prop width=12cm --prop height=12cm
officecli add "$FILE" /slide[2] --type shape --prop 'name=!!scene-dot' --prop preset=ellipse \
--prop fill=0F3460 --prop x=3cm --prop y=16cm --prop width=1.5cm --prop height=1.5cm
# Ghost slide-1 content (name path still resolves after morph — see Known Issues)
officecli set "$FILE" "/slide[2]/shape[@name=#s1-title]" --prop x=36cm 2>/dev/null || true
# Verify morph pair: identical names on slides 1 & 2
officecli get "$FILE" /slide[1] --depth 1 --json | jq -r '.data.results[0].children[]?.format.name // empty'
officecli get "$FILE" /slide[2] --depth 1 --json | jq -r '.data.results[0].children[]?.format.name // empty'
# Compare — `!!scene-ring` and `!!scene-dot` MUST appear on both, byte-identical.
# Note: morph stores names with a `!!` prefix; compare the prefixed forms.
(c) 連続する複数スライドのモーフ(ストーリーアーク)— ヘルパーを使用
見た目の結果。 5 枚のスライドで 1 つの連続したストーリーを語るアークです。ナラティブが進むにつれて、同じ 2 つのシーンアクターがキャンバス上をゆっくり移動します。コンテンツ(#sN-*)はスライドごとに更新され、次のスライドでゴースト化されます。これを手作業で作ると約 60 個のコマンドが必要になるため、reference/morph-helpers.py を使ってビルドスクリプトを短く保ち、自動検証を行ってください。
#!/usr/bin/env python3
# Invoke the provided helper library for clone + ghost + verify
import subprocess, sys, os
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
HELPERS = os.path.join(SCRIPT_DIR, "reference", "morph-helpers.py")
FILE = "deck.pptx"
def helper(*args):
subprocess.run([sys.executable, HELPERS, *[str(a) for a in args]], check=True)
# ... assume slide 1 is built with 2 scene actors (!!scene-ring, !!scene-dot) + #s1-title
# Helper builds slide 2–5 with: clone from previous + apply transition=morph + ghost previous #sN- content
# `clone` prints the cloned slide's shape list — read it to pick which shape indices carry the
# previous slide's #s(n-1)- content, then pass those explicit indices to `ghost`.
for n in range(2, 6):
helper("clone", FILE, n - 1, n) # clone + set transition=morph + list shapes (note the #s(n-1)- indices)
helper("ghost", FILE, n, 1, 2) # ghost the #s(n-1)- content shapes by index (here shapes 1 & 2)
# …then add THIS slide's #sN- content via officecli add as normal…
helper("final-check", FILE) # structural pass; DOES NOT catch !! lingering in visible area
ヘルパーのシグネチャとソース: reference/morph-helpers.py(clone、ghost、verify、final-check)。シェル版は reference/morph-helpers.sh です。プラットフォームに応じてどちらか一方を選び、混在させないでください。
ヘルパーと生の officecli の使い分け。 2〜3 枚のスライドのデッキでは、生のコマンド(レシピ a、b)の方が分かりやすいです。5 枚以上で clone/ghost/verify を繰り返すデッキでは、ヘルパーを使うとコマンド数を約 40% 削減でき、検証も組み込まれます。どのスライドも、納品前に必ず officecli validate で確認してください。
(d) モーフとフェードのハイブリッド — モーフスライドでの登場
見た目の結果。 !!scene-ring が連続的に移動する一方で、新しいスライド単位のカード #s2-card が同時にフェードインするモーフのペアです。モーフ適用の背景が視線を引きつけていて、新しい前景コンテンツには、生の出現よりも穏やかな登場が必要な場合に使用します。
# Slide 2 already has transition=morph and !!scene-ring. Add a new card with fade-entrance.
officecli add "$FILE" /slide[2] --type shape --prop 'name=#s2-card' --prop preset=roundRect \
--prop fill=F5F7FA --prop line=none --prop x=2cm --prop y=12cm --prop width=10cm --prop height=5cm
# Apply simultaneous-with-morph fade entrance to the new card.
# 'fade-entrance-300-with' = fade in, 300ms, trigger=withPrevious (plays with the morph transition).
officecli set "$FILE" "/slide[2]/shape[@name=#s2-card]" --prop animation=fade-entrance-300-with
officecli get "$FILE" "/slide[2]/shape[@name=#s2-card]" --json | jq '.data.results[0].format.animation' # readback sanity — drops the trigger suffix, reads back as "fade-entrance-300"
この方法が機能する理由。 モーフが対象とするのは !!scene-* の図形のみです(スライド 1 に対応するペアがあるため)。新しい #s2-card にはスライド 1 に対応するものがないため、モーフでは既定でフェードになります。fade-entrance-300-with は、そのフェードを明示的かつ時間指定付きにします。アニメーションは pptx v2 の下限に従ってください。すなわち 600 ms 以下とし、バウンド、スウィベル、端からの飛び込みは使用しないでください(正式なプリセット一覧は officecli help pptx animation を参照)。
コリオグラフィー — アニメーションの種類とずらしたタイミング
morph が複数の図形をどのようにアニメーションさせるかで、観客に見える動きが決まります。各ペアには適切な仕組みを選んでください:
| アニメーションの種類 | 実現方法(スライド A から スライド B への場合) |
|---|---|
| 単純な移動 | 両スライドで同じ !! 名、同じサイズ、異なる x/y — morph が位置を補間します |
| スケール変換 | 同じ名前、異なる width/height — morph がサイズを補間します(中心位置も再配置されます) |
| 移動 + スケール | x、y、width、height を同時に変更 — morph がすべての次元をまとめて処理します |
| 色 / 不透明度の変化 | 同じ名前、異なる fill または opacity — morph が塗りつぶしをクロスフェードします |
| 回転 | 同じ名前、異なる rotation(度)— morph が最短の弧に沿って回転します |
| フォントサイズの変更 | テキスト図形で同じ名前、異なる size(pt)— PowerPoint 365 では補間されます。Keynote / WPS / LibreOffice では信頼性が低く(クロスフェードに劣化することがあります)。移植性の高い動きにするには、size の変更と対応する width/height の差分または x/y の変位を組み合わせてください。サイズ補間が効かない場合でも、空間的な変化によって動きが見えるようになります |
| 出現(フェードイン) | 図形が スライド B にのみ存在する(A に対応する図形がない)— morph がフェードインさせます |
| 消失(フェードアウト) | 図形が スライド A にのみ存在する(B に対応する図形がない)— morph がフェードアウトさせます |
複数図形のタイミング制約。 1 つの morph ペアにあるすべての !! 図形は同時にアニメーションします。CLI には図形ごとの遅延や持続時間の設定はありません(ヘルプでも確認済み: スライドに morph.duration / morph.delay はありません)。図形 A を図形 B より先に動かすには、中間スライドを挟んでトランジションを 2 つのペアに分割してください:
Slide 2 → Slide 3: !!actor-A moves (!!actor-B stays put)
Slide 3 → Slide 4: !!actor-B moves (!!actor-A stays put or ghosts)
スライド 3 は明示的な中間キーフレームです。図形の animation= プロパティでタイミングを指定して擬似的にずらすことは試みないでください。Morph は図形ごとのアニメーションより先に実行されます。
変化の多様性に関する目安(ベストプラクティス — 表現の自由度)。 morph を「動き」として読ませるには、主要なペアの図形で {x, y, width, height, rotation, fill, opacity} のうち少なくとも 3 つを変更し、変位 ≥ 5cm、または回転 ≥ 15°、または サイズの変化 ≥ 30% のいずれかを満たしてください。1 つの図形で 3 つのプロパティを変えるのも有効な表現パターンです(主役の要素に焦点を当てる場合)。
デリバリーゲート 5b-morph-2 はより厳格です。 このゲートは、ペア全体で {x, y, width, height, rotation, font-size} のうち 1 つ以上が変化する、異なる !! 接頭辞の図形が 3 つ以上あることを必ず検証します。これは「本当の morph か、見せかけの morph か」を確かめる整合性チェックです。目安は創作上の意図を示し、デリバリーはゲートが判定します。背景として固定されている装飾(固定ヘッダーの帯、フッターバー、ロゴのバッジ)は 3 図形の基準に含めません。これらは動かない前提のものなので、動きは他の名前付き図形 3 つから生じさせる必要があります。判断に迷う場合は、より厳格なゲートを満たすようにしてください。
デッキ全体のリズム。 すべてのトランジションを morph にすると、映画的ではなく落ち着きがなく見えます。morph の見せ場をデッキの長さに合わせて配置してください:
- 8〜10 スライド(密度が高い): morph の見せ場は 3〜5 回。動きはまとめて配置しても構いません。
- 12〜18 スライド(儀式的): morph は合計 3〜5 回とし、4〜6 スライドごとに配置します。セクションの区切りで
transition=morphを使い、アニメーションが途切れない揺れではなく章の区切りとして読まれるようにしてください。 - 18 スライド以上(幕構成): 3 つの幕に分け、幕と幕の間に 1 回の長いセクション区切り用 morph(5〜10 秒の意図的な動きと短い静止を含む)を置き、各幕の中に 2〜3 回の控えめな morph を入れます。スライドごとに
!!actor-*を頻繁に入れ替えるよりも、!!scene-*による連続性を重視してください。
シーンアクターの空間ルール
シーンアクターおよびキャンバス上を移動するアクターは、モーフィング中も予測可能なゾーンに留まらなければなりません(MUST)。そうしないと、コンテンツと交差して雑然とした印象になります。
安全ゾーン(シーンアクターの静止位置およびモーフィングの経路に優先して使用):
Top-right corner: x ≥ 24cm, y ≤ 6cm
Bottom-right: x ≥ 24cm, y ≥ 12cm
Bottom-left: x ≤ 2cm, y ≥ 12cm
Off-canvas (ghost): x ≥ 33.87cm (canvas right edge; use x=36cm for explicit ghost)
コンテンツのコア領域にはアクターを静止させないでください: x = 2~28cm, y = 3~16cm。モーフィング中にアクターがコアを通過するのは問題ありません(それが動きだからです)。ただし、スライドの最後にそこで高い不透明度を保ったまま留まらせないでください。アクター自体がコンテンツ(スライドのメッセージを担う !!actor-*)である場合は例外です。
シーンアクターを配置する前に、既存のシェイプの境界を確認してください:
officecli get "$FILE" "/slide[$N]" --depth 1 --json | \
jq -r '.data.results[0].children[]? | "\(.format.name // .path) x=\(.format.x) y=\(.format.y) w=\(.format.width) h=\(.format.height)"'
アクターの目標位置が、どの #sN-* コンテンツシェイプのバウンディングボックス(x から x + width、y から y + height)とも重ならないことを確認してください。重なる場合は、アクターの opacity を 0.15 以下に下げるか、安全ゾーンに移動してください。
スタイルライブラリの参照ワークフロー
reference/styles/ には 52 個のビジュアルスタイルディレクトリ(dark / light / warm / vivid / bw / mixed のムード)があります。これらはデザインのインスピレーションであり、テンプレートではありません。ライブラリは必要に応じて参照するものとして使い、コンテンツをそのまま流し込む用途には使わないでください。
コピーではなく参照する理由。 52 個の build.sh ファイルはいずれも完全なスタイルデモですが、その座標は各デモのコンテンツ長に合わせて手作業で調整されたものです。そのままデッキにコピーすると、コンテンツが異なるため重なりや位置ずれが生じます(INDEX.md L5-11 で指摘済み)。ライブラリの価値はデザインロジックにあります。つまり、ムードに応じたパレットの選び方、象徴的なシェイプ、演出のパターンです。そのロジックを、自分のグリッド計算に適用してください。
4 ステップの参照手順:
- INDEX を閲覧する。
reference/styles/INDEX.mdは 52 個すべてのスタイルをパレットのカテゴリとムード別にまとめています(例:dark--premium-navy= 権威的・洗練、warm--earth-organic= オーガニック・落ち着き)。クイック参照表には各スタイルの主要な 16 進数のトリオ(bg / fg / accent)も載っています。ユーザーがブランドカラーを指定している場合は、16 進数の列をスキャンして、各style.mdを開かずに最も近いものを見つけてください。トピックのムードに合う、またはユーザー指定の 16 進数に合うスタイルを 1 つ選んでください。 - 設計思想を読む。
reference/styles/<style-id>/style.mdを開き、デザインの意図(書体の組み合わせ、色の考え方、象徴的な要素)を確認してください。 - 手法を確認する。
reference/styles/<style-id>/build.shは、手法の参考(象徴的なシェイプ、パレットの 16 進数コード、演出のアイデア)としてのみ開いてください。座標はINDEX.mdL5-11 に従って既知の不具合があるため、コピーしないでください。 - 自分のキャンバスに適用する。 pptx v2 のグリッド計算と視覚的な下限を使ってデッキを構築し、借用するのはパレットと象徴的な表現だけにしてください。
参照先: → see reference/styles/<style-id>/ ― style の build.sh から座標をインラインでコピーしてはいけません。
配布ゲート(pptx v2 とモーフィングの追加事項を継承)
ゲート 1〜5a:pptx v2 からの完全な移植。 → pptx v2 の §配布ゲート を参照してください。スキーマ(C-P-2 のチャート spPr のホワイトリスト化)、トークンの grep($…$ / {{…}} / \$\t\n / () / [])、ハイパーリンクの rPr(C-P-1)、スライド順の確認、暗背景上の暗い文字のコントラスト(ゲート 5a)。pptx のゲート 1〜5a がそれぞれ OK メッセージを出力するまで、完了を宣言しないでください。 モーフィングのデッキにも、通常の pptx と同じトークン・スキーマ・順序のリスクがあります。
ゲート 2 モーフィングの追補 ― zsh に食われる価格・指標トークン
pptx v2 のゲート 2 は、$…$、{{…}}、\$\t\n のリテラル、空の () / [] を対象としています。モーフィングのデッキでは、さらに別種の漏れが発生します。価格・指標のトークン($9/mo、$29/month、$199/yr)を、ダブルクォートで囲んだ --prop text="…" に書いた場合です。シェルは $9 を空の変数として展開してしまい、CLI は /mo や余分なピリオドを保存してしまいます。pptx のゲート 2 に加えて、次のチェックを実行してください。
# Gate 2 morph — price / metric token leaks + stray-period placeholders
# Pattern hits: bare prices ($9, $29, $9.99), /unit suffix ($9/mo, $199/yr), ${VAR}, \n/\r/\t, lone period
LEAKS=$(officecli view "$FILE" text | grep -nE '\$[0-9]+(\.[0-9]+)?(/(mo|month|yr|year|day|wk|week|hr|hour))?|\$\{[A-Z_]+\}|\\[nrt]|^\.$' || true)
if [ -z "$LEAKS" ]; then echo "Gate 2 morph OK"; else echo "LEAK: $LEAKS"; fi
対象:$9 $9.99 $29/month $199/yr $1/day ${VAR} \n/\r/\t のリテラル、および余分な . のプレースホルダー。修正方法:プロパティをシングルクォートで囲んでください(--prop text='$9/mo')。
Gate 5b — HTMLプレビューによる視覚監査(必須)— morph 向けに拡張
officecli view "$FILE" html を実行し、返された HTML パスを Read してください。すべてのスライドについて、pptx v2 Gate 5b の質問(重なり / 暗背景上の暗色 / 区切り線の重なり / 順序の妥当性 / 矢印の欠落)に加え、以下の morph 固有の 4 つのチェックに回答します。
重要:前方一致セレクターについて。 officecli query がサポートする演算子は =、!=、~=、>=、<=、>、< のみで、前方一致の ^= 演算子はありません。shape[name^=!!actor-] のようなセレクターは invalid_selector エラーを返します。「前方一致」でフィルタリングする場合は、以下に示すように get --depth 1 のループと jq startswith() を使用してください。
-
5b-morph-1 — 退場後の
!!actor-*が表示領域に漏れていないか。 退場しているべき!!actor-*のそれぞれについて、x ≥ 33.87cm(キャンバス右端)であることを確認します。ループとフィルタ(セレクター非依存):NSLIDES=$(officecli query "$FILE" slide --json | jq '.data.results | length') for N in $(seq 1 $NSLIDES); do officecli get "$FILE" "/slide[$N]" --depth 1 --json | \ jq -r --arg n "$N" '.data.results[0].children[]? | select(.format.name? // "" | startswith("!!actor-")) | select((.format.x // "0cm" | rtrimstr("cm") | tonumber) < 33.87) | "slide \($n) leak: \(.format.name) stuck at x=\(.format.x)"' done何らかの行が出力された場合、そのアクターは表示されたままになっています。
final-checkではこれを検出できず、ループと HTML の Read によってのみ検出できます。 -
5b-morph-2 — 隣接するスライドの空間構成が同一(動きなし)。 厳守ルール:すべての morph ペアの間で、
!!接頭辞を持つ 3 つ以上の異なるシェイプがそれぞれ {x, y, width, height, rotation, font-size} のうち 1 つ以上で 1 pt 以上異なる必要があります。検証ループ(両スライドをダンプし、同名シェイプを比較して、差分のあるシェイプ数を数えます):for K in 1 2 3 4; do A=$(officecli get "$FILE" "/slide[$K]" --depth 1 --json | \ jq -r '.data.results[0].children[]? | select(.format.name? // "" | startswith("!!")) | "\(.format.name)|\(.format.x)|\(.format.y)|\(.format.width)|\(.format.height)|\(.format.rotation // 0)"') B=$(officecli get "$FILE" "/slide[$((K+1))]" --depth 1 --json | \ jq -r '.data.results[0].children[]? | select(.format.name? // "" | startswith("!!")) | "\(.format.name)|\(.format.x)|\(.format.y)|\(.format.width)|\(.format.height)|\(.format.rotation // 0)"') VARIES=$(diff <(echo "$A") <(echo "$B") | grep -c '^[<>]') if [ "$VARIES" -lt 6 ]; then echo "pair $K→$((K+1)) FLAT: only $VARIES diff-lines (need ≥ 6 = 3 shapes × 2 sides)"; fi done -
5b-morph-3 — morph ペアの名前不一致。 隣接するスライドは、
!!接頭辞を持つ名前を少なくとも 2 つ完全一致で共有しなければなりません。証明(子要素は.data.results[0].children[]にあります。単なる.data.children[]は null を返します):for N in 1 2 3 4 5; do echo "--- slide $N ---" officecli get "$FILE" "/slide[$N]" --depth 1 --json | \ jq -r '.data.results[0].children[]? | select(.format.name? // "" | startswith("!!")) | .format.name' done連続するブロックを目視で比較してください。N と N+1 の間で共有される
!!名が morph ペアです。重なりがゼロの場合、そのペアは単純なフェードになります。 -
5b-morph-4 —
#sN-*が N+1 スライドに残留している(ゴーストの漏れ)。 スライド N の内容は、次のスライドでゴースト化(x=36cm)されていなければなりません。N≥2 ごとにループとフィルタを実行します:NSLIDES=$(officecli query "$FILE" slide --json | jq '.data.results | length') for N in $(seq 2 $NSLIDES); do PREV=$((N-1)) officecli get "$FILE" "/slide[$N]" --depth 1 --json | \ jq -r --arg n "$N" --arg p "$PREV" '.data.results[0].children[]? | select(.format.name? // "" | startswith("#s\($p)-")) | select((.format.x // "0cm" | rtrimstr("cm") | tonumber) < 33.87) | "slide \($n) leak: \(.format.name) stuck at x=\(.format.x)"' done何らかの行が出力された場合、
#s(N-1)-*のシェイプがスライド N で表示されたままになっています。ゴースト化してください。
5b-morph-1〜4 のいずれかのループが行を出力した場合、納品を却下してください。 4 つのループすべての標準出力を 1 つのストリームにまとめ、COUNT パターンで検証します:LEAK_COUNT=$(...4 つのループすべて... | wc -l); if [ "$LEAK_COUNT" -gt 0 ]; then echo "REJECT: $LEAK_COUNT morph leaks"; else echo "Gate 5b-morph OK"; fi。
レンダラーの正直な説明
Morph が表示されるもの: PowerPoint 365(Windows/Mac)、Keynote、WPS、PowerPoint Online。
Morph が表示されないもの: LibreOffice Impress(静的に表示され、場合によってはフェードとして表示される)、Google スライドのウェブビューア(補間が失われる)、ほとんどの HTML / SVG ビューア、officecli view html(構造のみ。morph はランタイムの機能です)。これは スキルの欠陥ではなく [RENDERER-BUG] です。ユーザーには次のように明確に伝えてください:「morph のモーションを確認するには PowerPoint 365 / Keynote / WPS で開いてください。その他のビューアでは静的表示またはプレーンなフェードとして表示されます。」
どのレンダラーの静的スクリーンショットも morph のモーションを検証することはできません(モーションはランタイムにのみ存在します)。ペアの正しさの証明には上記の Gate 5b のクエリを使用し、モーションの品質の証明にはライブビューアを使用してください。
ゴーストの運用とアクターのライフサイクル
すべての !!actor-* と #sN-* シェイプは、「退場」スライドだけでなく、すべてのスライドにわたって管理しなければなりません。
スライドごとのゴースト化ルール
複数スライドの morph デッキを構築する際は:
- スライド N:
!!actor-ringを導入する(x=0cm で表示) - スライド N+1:新しい内容を追加する。完了前に
!!actor-ringをx=36cmにゴースト化する。 - スライド N+2:さらに内容を追加する。
!!actor-ringを再度x=36cmにゴースト化する。(任意ではありません。すでに画面外にあったとしても、各スライドは新しいキャンバスだからです。) - スライド N+3:
!!actor-ringを再び表示すべき場合は、x=0cm またはその新しい位置に戻す。
理由: 各スライドのシェイプリストは独立しています。スライド N でシェイプをキャンバス外に移動しても、スライド N+1 には引き継がれません。再度ゴースト化し忘れると、スライド N+1 で元の位置に再び現れます。
ワークフローのパターン(Bash)
# After adding new content shapes to slide $SLIDE:
for ACTOR in "!!actor-ring" "!!actor-dot" "!!actor-accent-bar"; do
officecli set "$FILE" "/slide[$SLIDE]/shape[@name=$ACTOR]" --prop x=36cm || true
done
または、ビルドループの中で:
for SLIDE_NUM in 3 4 5 6 7 8 9 10 11; do
# Add content specific to this slide
officecli add "$FILE" "/slide[$SLIDE_NUM]" --type shape ...
# IMMEDIATELY ghost all old actors (M-2 prevention)
officecli set "$FILE" "/slide[$SLIDE_NUM]/shape[@name=!!actor-ring]" --prop x=36cm || true
officecli set "$FILE" "/slide[$SLIDE_NUM]/shape[@name=!!actor-dot]" --prop x=36cm || true
done
検出:ゴースト数ゲート
morph-helpers.py final-check は x ≥ 34cm にあるすべての図形を数えます。数が 50 を超えると、次を出力します:
REJECT: Found 135 accumulated ghosts — likely M-2 ghost accumulation.
Run: officecli query deck.pptx 'shape[x>=34cm]' --json | jq '.data.results | length'
Expected ≤ 50 (roughly 4–5 active actors × 10–12 slides).
対処: ビルドログを確認し、各スライドで表示されるべきでないすべてのアクターが再ゴースト化されていることを確認します。final-check を再実行します。それでも 50 を超える場合は、morph-helpers.py clean-accumulation deck.pptx を使用します(リファレンスセクションを参照)。
Morph でよくある落とし穴(設計とワークフローの罠)
基本の pptx の落とし穴(シェルのクォート、zsh の [N] グロビング、16 進数の # プレフィックス、プロパティテキスト内の \n)については、pptx v2 の §Common Pitfalls を参照してください。以下は Morph 固有の罠です:
| 落とし穴 | 正しいアプローチ |
|---|---|
同じデッキ内に !!scene-card と !!actor-card がある | 名前はプレフィックスをまたいで一意である必要があります。名前を変更します: !!scene-card-bg と !!actor-card-content |
| 一部のスライドが完了した後にビルドの途中で図形名を変更する | ゴースト蓄積のバグが発生する可能性があります。作業を止め、§Morph Pair Planning の表を描き直して、影響を受けるスライドを再実行します |
出口を計画せずに !!actor-* をコンテンツのコアに配置する | すべての !!actor-* にはゴーストスライドが必要です。コーディングの前にペア表で計画してください |
ゴースト蓄積(M-2): 後のスライドで !!actor-* の再ゴースト化を忘れる | 重要: 新しいコンテンツをスライド N+1 に追加するときは、スライド N から表示されるべきでないすべての !!actor-* を x=36cm に再度移動する必要があります。一度ゴースト化すれば画面外に留まると想定しないでください。各スライドは独立しています。ビルドパターン: 各新規スライドについて: コンテンツ図形を追加 → 次に、アクティブな各 !!actor-* を x=36cm に設定するループ。morph-helpers.py final-check は、ゴースト数が 50 を超えると拒否します。 |
スライドで transition=morph を設定し忘れる | 無音のフェードになります。Gate 5b-morph-2(モーションなし)が検出します。set /slide[N] --prop transition=morph で修正します |
Morph スライドで @name= パスが壊れると想定する | 壊れません。transition=morph の後も @name= は解決されます(M-1)。変わるのは 読み取り時の 名前に !! プレフィックスが付くことだけです |
| 隣接するスライドが視覚的に同一である | Morph が補間するものがなく、単純なフェードに崩れます。§Scene-actor spatial rule を適用し、3 つ以上の図形を 5cm 以上 / 15° 以上移動させます |
| 1 つのペアの 2 つの図形を図形ごとのタイミングで時間差をつけようとする | サポートされていません。ペアを中間キーフレームスライドを挟んだ 2 つのトランジションに分割してください |
| LibreOffice またはブラウザで Morph のモーションをテストする | スキルの不具合ではなく [RENDERER-BUG] です。PowerPoint 365 / Keynote / WPS でテストしてください |
!! 図形を退場時にゴースト化せずに削除する | 削除すると Morph のペアリングが壊れ、図形がアニメーションなしで消えます。必ず x=36cm にゴースト化してください |
--prop text="$9/mo" のように二重引用符で書く | シェルが $9 を空の変数として扱い、テキストが /mo や余分な . として保存されます。一重引用符を使用してください: --prop text='$9/mo'。Gate 2 の Morph 追補がこの漏れを検出します |
--prop text='line1<a:br/>line2' の中で <a:br/> をリテラルとして使う | 改行ではなく 7 文字のリテラルとして保存されます。行ごとに officecli add "/slide[N]/shape[@id=K]" --type paragraph を使用してください(M-6) |
shape[name^=!!actor-] セレクターを使う | officecli query には ^= 演算子がなく、invalid_selector が返されます。代わりに get /slide[N] --depth 1 --json | jq '.data.results[0].children[]? | select(.format.name | startswith("!!actor-"))' を使用してください。 |
既知の問題と注意点
基本的な pptx のバグ C-P-1..7(ハイパーリンクの rPr、チャートの ChartShapeProperties 警告、アニメーションの duration 読み取り、アニメーションの削除、コネクタの列挙値、コネクタの @name=、チャート色のレンダラー正規化)は、すべて該当します。回避策は pptx v2 の §Known Issues C-P-1..7 を参照してください。
Morph 固有の問題(M-1..5):
| # | 症状 | 回避策 |
|---|---|---|
| M-1 | officecli set '/slide[N]' --prop transition=morph の実行後、そのスライド上のすべての図形名の先頭に !! が自動付加されます(#s1-title → !!#s1-title)。読み取り時の名前は接頭辞付きの形式になります。セレクタのフィルタに関する注意: 自動接頭辞付与後は、!!#sN-caption が !!actor-* と共存します。そのため jq で「シーンのアクター」を startswith("!!") でフィルタすると、自動接頭辞付きのコンテンツが誤って一致します。必ず startswith("!!actor-") または startswith("!!scene-") でフィルタし、単なる startswith("!!") は使用しないでください。 | @name= のパスセレクタは引き続き解決されます。/slide[N]/shape[@name=#s1-title] は図形を返します(一致は接尾辞/接頭辞を許容します)。したがってパスの書き換えは不要です。jq フィルタで接頭辞付きの名前を使う場合は、先頭の !! を考慮してください。 |
| M-2 🚨 | ゴーストの蓄積 — スライド 3 で導入された !!actor-* は、すべてのページで明示的にゴースト化しない限り、スライド 4、5、6 にも表示されたままになります。 final-check ヘルパーはこれを検出し、ゴーストの数が 50 を超えると拒否します。 | 必須のページごとのルール: スライドに新しいコンテンツを追加したら、直ちに前のスライドにあるアクティブな !!actor-* をすべて x=36cm に設定してください(現在の文脈で表示すべきものは、明示的に表示位置に戻してください)。例: officecli set /slide[4]/shape[@name=!!actor-ring] --prop x=36cm。最後にまとめて実行するのではなく、スライドを追加するたびに毎回実行してください。以下の §Ghost Discipline & Actor Lifecycle を参照してください。 |
| M-3 | セクション切り替えの境界 — 新しいトピックセクションの最初のスライドでは、前のセクションの !!actor-* 図形が目に見えて残ってしまいます。コマンドはエラーになりません。見た目の乱れだけが発生します。 | 各セクション開始スライドで、前のセクションのすべての !!actor-* を明示的に x=36cm へゴースト化してください。シーン図形(!!scene-*)はそのままにします。 |
| M-4 | エージェントが morph.duration= / transition.delay= を独立したプロパティとして発明することがあります。これらは UNSUPPORTED として拒否されます。 | transition プロパティで組み合わせの省略形を使用してください: transition=morph-slow / -fast、または transition=morph-<DUR_MS>(例: transition=morph-1500)。どちらも読み取り時にラウンドトリップします(transitionSpeed=slow、transitionDuration=1500)。省略形で指定できない範囲(生の XML の細かい制御)のみ、<p:transition> に対する raw-set にフォールバックしてください。下記の M-4 の例ブロックを参照してください。 |
| M-5 | [RENDERER-BUG] LibreOffice / Google Slides の Web ビューアでは、morph スライドが単純なフェードとして描画されます(補間なし)。 | PowerPoint 365 / Keynote / WPS でテストしてください。スキルの欠陥ではないため、追跡する必要はありません。 |
| M-6 | --prop text='line1<a:br/>line2' の中に書かれた <a:br/> は、改行として解釈されず、7 文字のリテラル文字列として保存されます。聴衆には line1<a:br/>line2 がそのまま表示されます。 | 複数行の箇条書きやキャプションでは、1 行ごとに段落を追加してください: officecli add "/slide[N]/shape[@id=K]" --type paragraph --prop text='line1' を実行し、続けて text='line2' で繰り返します。実際の改行を使うワークフローについては、pptx v2 の §Shell escape を参照してください。 |
M-4 の例 — すべての morph トランジションを遅くする、raw-set によるフォールバック(transition=morph-slow を優先してください。この方法は省略形を超える制御が必要な場合のみ使用してください)。morph スライドでは //p:transition が mc:Choice と mc:Fallback の両方に一致し、2 element(s) affected となることに注意してください:
# Per-slide: add spd="slow" to every transition element on slide N (2 XML hits per morph slide)
for N in 2 3 4; do
officecli raw-set "$FILE" "/slide[$N]" --xpath "//p:transition" --action setattr --xml 'spd=slow'
done
officecli validate "$FILE"
読み取り確認: officecli query "$FILE" slide --json | jq '.data.results[].format | select(.transition=="morph") | .transitionSpeed' を実行すると、影響を受けた各スライドで "slow" が出力されます。
成果物と納品
すべての morph デッキは、それぞれ独立したファイルとして次の 3 つの成果物を提供します。
<topic>.pptx— デッキ本体。保存済みでofficecli validateにも問題がないこと(Delivery Gate 1 OK)。build.shまたはbuild.py— 再実行可能なスクリプト(シェルネイティブなビルドには bash、morph-helpers.pyを使う複数スライド構成には Python)。新しいofficecli create呼び出しからデッキを再生成できる必要があります。brief.md— 独立したファイルであり、他のどのファイルにも埋め込まないこと。 次の内容を含みます。- セクション 1:トピック / 対象読者 / 目的 / ナラティブ / スタイルの方向性(
reference/styles/INDEX.mdから名前付きのスタイルを 1 つ選択) - セクション 2:スライドごとのアウトライン(ページタイプ + スライドごとの一文の主張)
- セクション 3:§Morph Pair Planning の表(Pair / Slide A / Slide B / Actors / Ghosts)。レビュー担当者がアニメーションの振り付けを監査するための設計記録です。
- セクション 1:トピック / 対象読者 / 目的 / ナラティブ / スタイルの方向性(
ユーザーへの納品前リマインダー(そのまま使える文言):
- 「デッキはモーフトランジション付きで完成しています。動きを確認するには PowerPoint 365 / Keynote / WPS で開いてください。LibreOffice や Web ビューアーでは静止画として表示されます。」
- 「ビルドスクリプトの実行中、
.pptxは何度も書き換えられることがあります。進捗をプレビューしたい場合はofficecli watch "$FILE"を使い、AionUi でライブプレビューを開いてください。ビルド中に「システムのアプリで開く」をクリックしないでください。ファイルロックが発生します。」
作成後の調整
標準的な調整の一覧は pptx v2 の §Common Pitfalls / swap / move / remove / set を参照してください。morph 特有の注意点:morph のペアになっているスライドの順序を swap または move で変更したあとは、共有される !! 名の隣接関係を必ず再確認してください。 影響を受けるペアに対して上記の Gate 5b-morph-3 クエリを実行してください。入れ替えによってペアが崩れた場合は、シェイプ名を変更するか、トランジションの振り付けをやり直してください。
納品前の最終確認。 Delivery Gate 全体(1 から 5b-morph-1..4 まで)を実行し、.pptx を PowerPoint 365 / Keynote / WPS で開き、スライド間の morph を 1 回すべて再生して動きが見えることを確認してください。いずれかの Gate が REJECT を出力した場合は、修正して再実行してください。既知の未解決 Gate がある状態で納品してはいけません。
参考資料
reference/decision-rules.md— ピラミッド原則、SCQA、ページタイプの一覧、brief.mdのスキーマ。コマンドを書く前にナラティブの構成を決めるため、§Morph Pair Planning の作業中に読んでください。reference/pptx-design.md— 残りの設計メモ(Scene Actors の仕組み、ページタイプの表、振り付けのパターン)。キャンバス・フォント・配色は pptx v2 にあり、このファイルは morph 固有の内容のみを扱います。reference/morph-helpers.py— クローン・ゴースト・検証・最終チェックのためのクロスプラットフォーム(Mac / Windows / Linux)対応 Python ヘルパー。ライブラリとしてインポートするか、CLI 引数で呼び出せます。5 スライド以上の構成には推奨です。reference/morph-helpers.sh— Bash 版の同等ツール。プロジェクトごとにどちらか一方を選び、混在させないでください。reference/styles/INDEX.md— 52 種類のスタイルのビジュアルライブラリ。パレット(dark / light / warm / vivid / bw / mixed)と雰囲気で分類されています。検索手順は上の §Style library lookup workflow を参照してください。skills/officecli-pptx/SKILL.md— pptx v2 の基本ルール(ビジュアルの最低基準、グリッド、標準パレット、チャートの選び方、コネクタの基準、Delivery Gate 1–5a、Known Issues C-P-1..7、シェルのエスケープ 3 層)。