Files
wehub-resource-sync 8ef9db2513
Deploy to GitHub Pages / deploy (push) Has been cancelled
Deploy to GitHub Pages / build (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:56:49 +08:00

8.2 KiB

PPTX Animation Core

The shared animation core owns the entrance-effect vocabulary, trigger semantics, OOXML timing writer, semantic read-back, and package validation for PowerPoint OOXML. Per-element animation remains opt-in: generated PPTX export defaults to none, exactly as before this validation upgrade.

1. Ownership

Concern Owner
Effect registry, timing writer, and read-back scripts/pptx_animations.py
Sidecar parsing and SVG target discovery svg_to_pptx/animation_config.py
SVG group-to-shape mapping svg_to_pptx/drawingml/converter.py
Generated PPTX resolution and validation svg_to_pptx/pptx_package/builder.py
Narration timing merge svg_to_pptx/pptx_package/narration.py
Public authoring contract references/animations.md
Customization workflow workflows/customize-animations.md

Hard rule: only the generated SVG-to-PPTX route writes object entrance animations. Direct-PPTX routes preserve source animations and run structural package validation; they do not resolve or author animation effects.


2. Domain Model

One resolved animation-pane row contains these fields:

Field Meaning
Target Positive PowerPoint shape id written to p:spTgt@spid
Effect One exact registry tuple: filter, presetID, and presetSubtype
Trigger on-click, with-previous, or after-previous
Duration Finite positive schedule duration; filter effects serialize it as behavior duration
Delay Finite non-negative offset used by after-previous
Order Positive integer sidecar order; ties retain stable SVG order

Modes resolve before XML writing:

Mode Resolution
auto Deterministic semantic mapping from the SVG group id
mixed Deterministic legacy cycle
random Stable seeded choice from the legacy pool
none No entrance sequence

The same effective input produces the same random choices. When enabled, --conversion-trace records each resolved row and effect, so a generated deck can be audited without replaying the resolver.


3. Compatibility Contract

The registry preserves these established 22 tuples exactly:

Key p:animEffect@filter presetID presetSubtype
appear none 1 0
fade fade 10 0
fly slide(fromBottom) 2 4
cut slide(fromLeft) 42 8
zoom image 23 0
wipe wipe(left) 22 1
split barn(inVertical) 16 21
blinds blinds(horizontal) 3 10
checkerboard checkerboard(across) 5 6
dissolve dissolve 9 0
random_bars randombar(horizontal) 14 10
peek wipe(down) 12 4
wheel wheel(4) 21 0
box box(in) 4 0
circle circle(in) 6 0
diamond diamond(in) 8 0
plus plus(in) 13 0
strips strips(downRight) 18 12
wedge wedge 20 0
stretch stretch(across) 17 0
expand stretch(across) 50 0
swivel wheel(1) 19 0

cut is a legacy public key. Compatibility promises the tuple above; it does not infer a different semantic name from external preset-id tables.

Hard rule — no downgrade:

  • Keep the 22 established tuples byte-for-byte equivalent in meaning.
  • Reject an unknown effect, mode, or trigger; never substitute another value.
  • Reject booleans and non-finite, out-of-range, or invalidly ordered values.
  • Reject a missing slide, missing group, or structural-layer target.
  • Keep the generated-route default at none; validation does not opt a deck in.

4. Target Resolution

Generated object animation targets top-level SVG content groups. Explicit SVG semantics are authoritative; the group-id chrome heuristic is only a fallback for marker-free legacy SVGs.

Target state Behavior
Ordinary content group Animatable
Legacy chrome-like id Skipped unless explicitly named in animations.json
Explicit sidecar group override May override only the legacy chrome-name heuristic
data-pptx-layer or explicit static role/placeholder Structural and never animatable

An explicit sidecar entry cannot turn a Master/Layout/Slide structural layer or an explicitly marked static page-frame role/placeholder into an animation target. This boundary preserves PPTX structure even when a legacy id resembles content.


5. OOXML Rules

The writer emits one root-level p:timing after p:transition and before p:extLst. Its animation tree contains a tmRoot, one mainSeq, unique p:cTn@id values, and p:spTgt references to shapes on the same slide.

Trigger mapping:

Public trigger Entrance p:cTn@nodeType
on-click clickEffect
with-previous withEffect
after-previous afterEffect

The writer does not emit p:bldP for grouped content or pictures. Microsoft defines p:bldP@spid for a text-bearing p:sp; using it for p:grpSp or p:pic creates an invalid build reference. Package validation still accepts a valid source p:bldP that targets a text-bearing shape.

Direct-PPTX preserve mode also tolerates an unchanged legacy p:bldP that targets an existing group/picture. Earlier PPT Master exports wrote this form; the direct routes fingerprint and preserve it instead of blocking those decks. New generated output never writes it, and generated-package validation remains strict.

appear is the visibility-flip exception: its p:set behavior is always 1ms. The configured positive duration remains the row's scheduling span used when computing the next after-previous offset; read-back verifies the 1ms behavior and the resulting timeline offset separately.


6. Validation and Read-Back

Generated export reads every slide back before packaging and compares each requested row with the serialized result:

  • row count and row order;
  • trigger and shape target;
  • resolved effect key, filter, presetID, and presetSubtype;
  • serialized behavior duration and computed timeline offset (appear uses the 1ms exception above).

After packaging, validation scans every slide part for root timing placement, duplicate or malformed p:cTn ids, missing p:spTgt shapes, invalid build targets, and unsupported generated effect tuples. A mismatch fails export before the requested output file replaces an existing deck.

Narration injection parses and merges the slide DOM. It adds audio timing under the existing tmRoot child list, allocates fresh time-node ids, and preserves the object entrance sequence. It does not replace an existing p:timing tree. The merge accepts only a direct p:sld/p:timing source tree; a timing tree wrapped in mc:AlternateContent or another non-root container fails safely instead of being rewritten or duplicated.

Direct-PPTX routes run the structural package validator with generated-effect enforcement disabled. This permits preservation of source/extension effects and legacy group build rows while still rejecting corrupt timing IDs or missing targets. Template fill and native enhancement fingerprint the source object-animation tree before and after their allowed edits; any semantic change fails. These routes have no object-animation write ownership.


7. Compatibility Scope

The compatibility contract covers PowerPoint OOXML and PowerPoint read-back. Other presentation applications may interpret timing trees or filter values differently; the exporter does not make an unconditional Keynote guarantee.

Official references:

See pptx-transitions.md for the symmetric page-motion core, MCE handling, and slide-advance contract.