返回 ppt-master
pptx-transitions.md
根目录 / skills / ppt-master / scripts / docs / pptx-transitions.md
1 # PPTX Transition Core
2
3 The shared transition core owns page-transition vocabulary, slide-advance
4 semantics, OOXML mutation, MCE preservation, package timing enablement, and
5 read-back validation for every PPTX route.
6
7 ## 1. Ownership
8
9 | Concern | Owner |
10 |---|---|
11 | Page transition registry | scripts/pptx_transitions.py |
12 | In-slide object animation | scripts/pptx_animations.py |
13 | Generated PPTX adapter | svg_to_pptx/pptx_package/builder.py |
14 | Template Fill adapter | template_fill_pptx/transitions.py |
15 | Native Enhance adapter | native_enhance_pptx_core.py |
16 | Public workflow | references/animations.md |
17
18 **Hard rule**: adapters resolve route policy, then call the shared core. They
19 must not build, replace, or patch a transition with route-local XML or regex.
20
21 ---
22
23 ## 2. Domain Model
24
25 | Layer | Meaning | OOXML |
26 |---|---|---|
27 | Enter | How the current slide appears from the preceding slide | Native effect, Effect Options, and duration |
28 | Advance | How the current slide leaves for the next slide | advClick and advTm |
29
30 Enter policy:
31
32 | Policy | Behavior |
33 |---|---|
34 | preserve | Keep the source visual transition, including unknown extensions |
35 | replace | Write the requested supported effect |
36 | none | Write no visual effect |
37
38 Advance mode:
39
40 | Mode | Behavior |
41 |---|---|
42 | preserve | Keep source advClick and advTm |
43 | click | Click advance only |
44 | after | Timed advance only |
45 | both | Click or timed advance, whichever occurs first |
46 | narration | Timed advance from audio duration plus padding; click disabled |
47
48 **Hard rule**: enter=none may coexist with a timed advance. The valid result is
49 a timing-only p:transition with no visual-effect child.
50
51 ---
52
53 ## 3. Compatibility Contract
54
55 The native registry covers the complete current PowerPoint transition gallery:
56 12 Subtle effects, 29 Exciting effects, and 7 Dynamic Content effects. New
57 selection, sidecars, plans, conversion traces, help, and writers use only these
58 48 native keys.
59
60 Eight established low-level names remain valid at input boundaries. They
61 normalize to one native effect plus native `effect_options`; they are not a
62 second transition registry:
63
64 | Compatibility input | Native request |
65 |---|---|
66 | `strips` | `wipe` with `direction: right` |
67 | `circle` | `shape` with `shape: circle` |
68 | `diamond` | `shape` with `shape: diamond` |
69 | `plus` | `shape` with `shape: plus` |
70 | `newsflash` | `flash` |
71 | `pull` | `uncover` |
72 | `wedge` | `clock` with `style: wedge` |
73 | `wheel` | `clock` with `style: clockwise` |
74
75 Standard PresentationML effects use a direct `p:transition` carrier:
76
77 | Effect | Required primary child and attributes |
78 |---|---|
79 | fade | p:fade |
80 | push | p:push dir=r |
81 | wipe | p:wipe dir=r |
82 | split | p:split |
83 | cut | p:cut |
84 | random_bars | p:randomBar dir=vert |
85 | shape | p:circle |
86 | uncover | p:pull dir=r |
87 | cover | p:cover dir=r |
88 | dissolve | p:dissolve |
89 | checkerboard | p:checker |
90 | blinds | p:blinds dir=vert |
91 | clock | p:wheel spokes=1 |
92 | random | p:random |
93 | box | p:zoom |
94 | comb | p:comb |
95
96 Office 2010 effects use a `p14` Choice with a `p:fade` Fallback:
97
98 | Effect | Required primary child and attributes |
99 |---|---|
100 | reveal | p14:reveal dir=r |
101 | flash | p14:flash |
102 | ripple | p14:ripple |
103 | honeycomb | p14:honeycomb |
104 | glitter | p14:glitter |
105 | vortex | p14:vortex dir=r |
106 | shred | p14:shred dir=out |
107 | switch | p14:switch dir=r |
108 | flip | p14:flip dir=r |
109 | gallery | p14:gallery dir=r |
110 | cube | p14:prism dir=r |
111 | doors | p14:doors dir=vert |
112 | zoom | p14:warp dir=in |
113 | pan | p14:pan dir=r |
114 | ferris_wheel | p14:ferris dir=r |
115 | conveyor | p14:conveyor dir=r |
116 | rotate | p14:prism dir=r isContent=1 |
117 | window | p14:window |
118 | orbit | p14:prism dir=r isContent=1 isInverted=1 |
119 | fly_through | p14:flythrough |
120
121 Office 2012 effects use a `p15` Choice with a `p:fade` Fallback:
122
123 | Effect | Required primary child and attributes |
124 |---|---|
125 | fall_over | p15:prstTrans prst=fallOver invX=1 |
126 | drape | p15:prstTrans prst=drape invX=1 |
127 | curtains | p15:prstTrans prst=curtains |
128 | wind | p15:prstTrans prst=wind |
129 | prestige | p15:prstTrans prst=prestige |
130 | fracture | p15:prstTrans prst=fracture |
131 | crush | p15:prstTrans prst=crush |
132 | peel_off | p15:prstTrans prst=peelOff invX=1 |
133 | page_curl | p15:prstTrans prst=pageCurlSingle invX=1 |
134 | airplane | p15:prstTrans prst=airplane |
135 | origami | p15:prstTrans prst=origami |
136
137 `morph` uses `p159:morph option=byObject` in an Office 2015 Choice with a
138 `p:fade` Fallback. `none` is the explicit no-visual-effect input and therefore
139 is not a registry entry.
140
141 ### 3.1 Native Effect Options
142
143 Use `effect_options` only with an explicit native `effect`. Omitted options use
144 the PowerPoint-authored `default` reported by `--describe-transition`:
145
146 | Effect | Supported options |
147 |---|---|
148 | `morph` | `morph_by`: `object`, `word`, `character` |
149 | `fade` | `style`: `smoothly`, `through_black` |
150 | `push`, `wipe`, `vortex`, `cube`, `pan`, `rotate`, `orbit` | `direction`: `left`, `right`, `up`, `down` |
151 | `split` | `orientation`: `horizontal`, `vertical`; `direction`: `out`, `in` |
152 | `reveal` | `direction`: `right`, `left`; `through_black`: boolean |
153 | `cut` | `through_black`: boolean |
154 | `random_bars`, `blinds`, `doors` | `orientation`: `vertical`, `horizontal` |
155 | `checkerboard` | `direction`: `across`, `down` |
156 | `comb`, `window` | `orientation`: `horizontal`, `vertical` |
157 | `shape` | `shape`: `circle`, `diamond`, `plus` |
158 | `uncover`, `cover` | `direction`: `left`, `right`, `up`, `down`, `up_left`, `up_right`, `down_left`, `down_right` |
159 | `fall_over`, `drape`, `wind`, `peel_off`, `airplane`, `origami` | `direction`: `right`, `left` |
160 | `page_curl` | `direction`: `right`, `left`; `pages`: `single`, `double` |
161 | `clock` | `style`: `clockwise`, `counterclockwise`, `wedge` |
162 | `ripple` | `origin`: `center`, `up_left`, `up_right`, `down_left`, `down_right` |
163 | `glitter` | `shape`: `diamond`, `hexagon`; `direction`: `right`, `left`, `up`, `down` |
164 | `shred` | `pattern`: `strips`, `rectangle`; `direction`: `out`, `in` |
165 | `switch`, `flip`, `gallery`, `ferris_wheel`, `conveyor` | `direction`: `right`, `left` |
166 | `box`, `zoom` | `direction`: `out`, `in` |
167 | `fly_through` | `direction`: `in`, `out`; `bounce`: boolean |
168 | All other native effects | No Effect Options |
169
170 Example:
171
172 ~~~json
173 {
174 "transition": {
175 "effect": "page_curl",
176 "effect_options": {
177 "direction": "left",
178 "pages": "double"
179 },
180 "duration": 0.6
181 }
182 }
183 ~~~
184
185 Inspect the exact contract, including compatibility desugaring:
186
187 ~~~bash
188 python3 skills/ppt-master/scripts/pptx_animations.py --describe-transition page_curl
189 python3 skills/ppt-master/scripts/pptx_animations.py --describe-transition diamond
190 ~~~
191
192 Read-back reports the canonical native effect, its complete effective options,
193 the raw OOXML child, and raw attributes. This makes option loss a validation
194 failure rather than a silent downgrade.
195
196 **Hard rule — no downgrade**:
197
198 - Never rename or remove an established effect.
199 - Never omit its established direction or split attributes.
200 - Reject an unknown requested effect; never substitute fade.
201 - Preserve an unknown source effect when the route selects preserve.
202 - An extension counts as successful only when the primary Choice contains the
203 requested effect. A fallback alone is not success.
204
205 ### 3.2 Deterministic Morph Identity
206
207 The generated route may add an explicit `slides.<destination>.morph` block to
208 bind direct-root SVG groups across adjacent slides. The sidecar stable key is
209 lowered to the same top-level `p:cNvPr@name="!!<key>"` on both final
210 Slide-local objects. This does not create an Animation Pane row and does not
211 change either object's numeric shape id.
212
213 The full plan is resolved before any SVG conversion so a source group named by
214 the following slide remains a stable top-level target. Names are written only
215 after flat/structured/preserve processing has finished; structured slide-shape
216 roster expectations are then refreshed. Package read-back requires:
217
218 - the declared source to be the immediately preceding public slide;
219 - exactly one `!!<key>` object on each side;
220 - the same OOXML object container type on both sides;
221 - Morph by object on the destination; and
222 - no structural target, same-slide name collision, group/key conflict, or
223 undeclared shared `!!` name on a Morph edge.
224
225 Morph without an explicit pair block retains PowerPoint's automatic matching
226 behavior. Explicit pairing is generated-route authoring; direct-PPTX routes
227 continue to preserve existing object names and transition XML.
228
229 ---
230
231 ## 4. Route Mapping
232
233 | Route | Default enter | Default advance | Compatibility note |
234 |---|---|---|---|
235 | Generated PPTX CLI | fade, 0.4s | click | auto-advance maps to both |
236 | Recorded narration | Preserve resolved enter | narration | none remains visually none |
237 | Template Fill | preserve source | preserve source | explicit effects replace; legacy advance_after maps to both |
238 | Native Enhance | Confirmed global/per-slide plan effect | Confirmed timing module | With audio off, an enabled global transition or explicit global `none` applies to all pages; with audio on, the scope flag controls non-narrated pages |
239
240 Template Fill changes source transitions only when its CLI or per-slide plan
241 selects a replacement, removal, or timed advance. Native Enhance uses its
242 confirmed plan. The public `create_pptx_with_native_svg` Python API retains its
243 legacy 0.5s default; the generated-deck CLI explicitly passes 0.4s.
244
245 ---
246
247 ## 5. OOXML Rules
248
249 **Slide child order**:
250
251 ~~~text
252 p:cSld
253 p:clrMapOvr
254 p:transition or transition mc:AlternateContent
255 p:timing
256 p:extLst
257 ~~~
258
259 One slide may contain at most one logical transition carrier:
260
261 - one direct p:transition; or
262 - one root-level mc:AlternateContent whose Choice/Fallback branches contain
263 p:transition.
264
265 Mutation rules:
266
267 | Operation | Direct transition | AlternateContent |
268 |---|---|---|
269 | preserve | Leave unchanged | Leave wrapper and branches unchanged |
270 | advance-only | Patch direct attributes | Patch Choice and Fallback identically |
271 | replace | Replace the direct carrier | Remove the whole wrapper, then write one carrier |
272 | none | Remove visual carrier; retain timing-only carrier when needed | Remove the whole wrapper; retain timing-only carrier when needed |
273
274 **MCE prefix rule**: Requires and Ignorable values contain textual prefix
275 names. Serialization must retain bindings for those exact names. Renaming an
276 effect prefix without updating these attributes corrupts compatibility.
277
278 **Package timing rule**: when a route writes advTm, set
279 ppt/presProps.xml p:presentationPr/p:showPr useTimings=1. Do not write showPr
280 into ppt/presentation.xml.
281
282 ---
283
284 ## 6. Validation and Read-Back
285
286 Reject:
287
288 - unknown effect names;
289 - options without an explicit native effect;
290 - unknown option fields or values for the selected effect;
291 - non-finite values, including NaN and Infinity;
292 - duration less than or equal to zero;
293 - negative advance or narration padding;
294 - booleans passed as numeric API values;
295 - multiple logical transition carriers;
296 - unresolved MCE Requires or Ignorable prefixes.
297 - invalid forced-Morph adjacency, identity uniqueness, object type, or
298 destination effect.
299
300 Read-back must report the canonical native effect and complete effective
301 options, while keeping the primary Choice child separate from the fallback. It
302 must also report raw effect attributes, carrier type, duration, click mode, and
303 automatic advance time. Package validation must run after writing, not only
304 before mutation.
305
306 Use inline smoke commands and gitignored projects/_smoke_* artifacts. Do not
307 add a tests directory or test_*.py files.
308
308 lines MARKDOWN