# How PowerPoint Animations and Transitions Work in OfficeCLI: A Developer's Guide

> Developers explore how OfficeCLI handles PowerPoint animations and transitions. Learn about its dual-layer architecture and OOXML element processing for OfficeAI.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: internals
- Published: 2026-07-13

---

**OfficeCLI treats PowerPoint animations and transitions as first-class OOXML elements, emitting them as `<p:timing>` and `<p:transition>` blocks through a dual-layer architecture that separates semantic modeling from raw XML passthrough.**

The **iOfficeAI/OfficeCLI** repository provides a command-line interface for manipulating Office documents, including deep support for PowerPoint animations and transitions. Understanding how this tool handles OOXML generation helps developers automate presentation workflows while preserving complex visual effects.

## The Animation Architecture

OfficeCLI builds animations by creating per-shape animation indexes and converting high-level CLI commands into structured OOXML. The system validates properties, handles triggers, and maintains ordered timing chains that PowerPoint can execute natively.

### Building the Animation Index

The core emission logic lives in [`src/officecli/Handlers/Pptx/PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PptxBatchEmitter.cs) (lines 41-71). Here, the emitter constructs a per-shape animation index and writes `<p:timing>` nodes that define when and how shapes appear or move.

This batch processing approach ensures that multiple animations added via the command line are serialized into the correct OOXML sequence before the final `.pptx` package is written.

### Setting Shape Animations

Animation assignment occurs in [`src/officecli/Handlers/Pptx/PowerPointHandler.Set.Shape.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.Set.Shape.cs) through the `SetShapeAnimationByPath` method (lines 26-66). This method:

- Extracts the target shape or chart from the document path
- Enumerates existing animation "child time nodes" via `EnumerateShapeAnimationCTns`
- Replaces existing animations or appends new ones based on the command context

The implementation enforces **read-only facets** including `presetId`, `easein`, `easeout`, and `motionPath` to maintain OOXML schema compliance (lines 72-84). These constraints prevent invalid state combinations that would corrupt the presentation.

## Slide Transitions in OfficeCLI

While animations affect individual shapes, transitions control how slides advance. OfficeCLI handles these separately from animations, using a specialized emission strategy for slide-level effects.

### Semantic vs. Raw Emission

The architecture distinguishes between **semantic emission** (building a high-level model) and **raw passthrough** (preserving exotic XML). In [`src/officecli/Handlers/Pptx/PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PptxBatchEmitter.cs) (lines 540-108), the emitter strips user-provided transition properties from the standard semantic path, then appends a raw `<p:transition>` slice or "exotic" transitions (such as morph) directly after the slide element.

This dual-layer design ensures that common transitions remain fully editable while advanced PowerPoint constructs round-trip without data loss.

### Transition Helper Implementation

The [`src/officecli/Handlers/Pptx/PowerPointHandler.Helpers.Transition.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.Helpers.Transition.cs) file (lines 18-55) provides helper methods that create or locate existing `<p:transition>` elements. These utilities safely handle unknown or alternate-content transitions, ensuring the CLI can process presentations containing custom or newer transition types not explicitly modeled in the SDK.

## Controlling Animations via the CLI

Users interact with the animation system through the command line, supplying parameters either as compact strings or granular property flags.

### Compound vs. Element Syntax

OfficeCLI supports two syntax styles for animation properties, documented in [`examples/ppt/animations.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/examples/ppt/animations.md) (lines 14-22):

- **Compound shortcut**: `--prop animation=fade-entrance-800`
- **Element form**: `--type animation` with individual `--prop` flags for `effect`, `class`, `trigger`, `duration`, `delay`, `repeat`, and `autoReverse`

The system returns these properties individually on `get` operations, making the model **fully round-trippable** except for certain template-exit effects (lines 24-31).

### Timing Chains and Triggers

Animations execute based on trigger relationships defined in [`examples/ppt/animations.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/examples/ppt/animations.md) (lines 61-70). Each animation's `trigger` property determines its relationship to predecessors:

- `onClick` – Requires manual advancement
- `afterPrevious` – Executes automatically when the prior animation completes
- `withPrevious` – Executes simultaneously with the prior animation

This trigger system enables self-playing sequences built entirely through CLI commands.

### Motion Path Animations

When `class=motion` is specified, the `path` property accepts either preset values or custom SVG-like coordinates. As noted in [`examples/ppt/animations.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/examples/ppt/animations.md) (lines 54-56), custom paths use a `d=` attribute containing coordinates normalized to slide dimensions, stored as `motionPath` in the underlying OOXML.

## Code Examples

Add a simple entrance animation to a specific shape:

```bash
officecli add deck.pptx /slide[2]/shape[3] --type animation \
  --prop effect=fade --prop class=entrance --prop duration=800

```

Apply a custom motion path using SVG-like coordinates:

```bash
officecli add deck.pptx /slide[5]/shape[8] --type animation \
  --prop class=motion --prop path=custom \
  --prop d='M 0 0 L 0.3 -0.1 L 0.6 0.1 E' --prop duration=1500

```

Set a slide transition with speed control:

```bash
officecli set deck.pptx /slide[1] --prop transition=fade \
  --prop transitionSpeed=slow

```

Chain a self-playing animation sequence using triggers:

```bash
officecli add deck.pptx /slide[6]/shape[2] --type animation \
  --prop effect=fade --prop class=entrance --prop trigger=onClick --prop duration=500
officecli add deck.pptx /slide[6]/shape[3] --type animation \
  --prop effect=fly --prop class=entrance --prop trigger=afterPrevious --prop duration=600
officecli add deck.pptx /slide[6]/shape[4] --type animation \
  --prop effect=zoom --prop class=entrance --prop trigger=withPrevious --prop duration=600

```

## Summary

- **OfficeCLI** emits PowerPoint animations as `<p:timing>` elements and transitions as `<p:transition>` elements according to the iOfficeAI/OfficeCLI source code.
- The **dual-layer architecture** separates semantic emission (editing common properties) from raw passthrough (preserving exotic XML), ensuring lossless round-tripping.
- **Animation indexing** occurs in [`PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PptxBatchEmitter.cs), while **shape animation assignment** is handled by `SetShapeAnimationByPath` in [`PowerPointHandler.Set.Shape.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.Set.Shape.cs).
- **Triggers** (`onClick`, `afterPrevious`, `withPrevious`) control timing chains, enabling complex sequences without manual intervention.
- **Motion paths** support custom SVG-like coordinates normalized to slide dimensions when `class=motion` is specified.

## Frequently Asked Questions

### How does OfficeCLI handle complex motion path animations?

When `class=motion` is specified, OfficeCLI stores the path data as `motionPath` in the OOXML according to [`examples/ppt/animations.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/examples/ppt/animations.md). Custom paths use an SVG-like `d` attribute with coordinates normalized to the slide size. The [`PowerPointHandler.Set.Shape.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.Set.Shape.cs) file treats `motionPath` as a read-only facet (lines 72-84), ensuring the path data validates against the OOXML schema before emission.

### Can I chain multiple animations to play automatically?

Yes. Set the `trigger` property to `afterPrevious` or `withPrevious` when adding animations via the CLI. As documented in [`examples/ppt/animations.md`](https://github.com/iOfficeAI/OfficeCLI/blob/main/examples/ppt/animations.md) (lines 61-70), `afterPrevious` starts the animation when the preceding one finishes, while `withPrevious` plays them simultaneously. This creates self-playing sequences without requiring user clicks between effects.

### What is the difference between semantic emission and raw passthrough in OfficeCLI?

**Semantic emission** builds a high-level model of shapes, animations, and transitions that the SDK can fully parse and modify. **Raw passthrough** appends XML slices directly to the output stream without parsing, used in [`PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PptxBatchEmitter.cs) (lines 540-108) for exotic transitions that the SDK cannot yet model (such as morph). This dual approach ensures common features remain editable while advanced constructs survive round-trips.

### Which source files govern animation indexing in OfficeCLI?

The primary animation indexing logic resides in [`src/officecli/Handlers/Pptx/PptxBatchEmitter.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PptxBatchEmitter.cs) (lines 41-71), where the emitter builds per-shape animation trees. The validation and assignment logic lives in [`src/officecli/Handlers/Pptx/PowerPointHandler.Set.Shape.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.Set.Shape.cs), specifically within the `SetShapeAnimationByPath` method (lines 26-66) and its enumeration of existing "child time nodes" via `EnumerateShapeAnimationCTns`.