> For the complete documentation index, see [llms.txt](https://docs.responsiveads.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.responsiveads.com/creating-ads/designing-your-ad-in-the-fluid-ad-creator/animation-timeline/using-sprite-sheets-and-animation-in-responsiveads.md).

# Using Sprite Sheets & Animation in ResponsiveAds

This page shows three reliable ways to deliver lightweight, transparent animations in HTML5 ads built with ResponsiveAds:

* **Animated WebP** (fastest path for simple loops)
* **Sprite sheets in Google Web Designer (GWD)** (visual authoring with a built‑in component)
* **Sprite sheets from TexturePacker** (professional packing + JSON metadata for custom/GSAP workflows)

> If your animation has transparency and must fit strict initial‑load limits (e.g., ≤150 KB), sprite sheets or animated WebP are typically the best choices.

***

### Picking the right approach

**Choose Animated WebP when…**

* You have a short, looping animation; one asset is easier to manage.
* You don’t need per‑frame interactivity.
* You’re fine providing a PNG fall‑back for older browsers.

**Choose Sprite Sheets (GWD or TexturePacker) when…**

* You want transparent overlays with tight file size control (trim + quantize).
* You need deterministic frame stepping, looping, or syncing with other timeline events.
* You may reuse frames across variants or export @2× assets.

***

### Prerequisites (for all workflows)

1. **Export a PNG sequence with alpha** from your motion tool (e.g., After Effects). Use sequential names: `walk_0001.png`, `walk_0002.png`, …
2. **Trim empty transparency** from each frame to reduce file size.
3. **Match target ad dimensions**, or plan to scale down.
4. Keep the animation concise (≤ 24 fps; short loops) to stay within initial‑load limits.

***

### Option A — Animated WebP (Ezgif)

**Best for:** fastest path to a single animated asset with transparency.

1. Convert your MOV with alpha **or** upload your **PNG sequence** to an online converter (e.g., Ezgif → Video to WebP / Animated WebP Maker).
2. Set frame delay and loop count; enable transparency.
3. **Optimize**: adjust quality/compression; consider reducing dimensions or dropping redundant frames.
4. Export your `.webp` and add a static PNG/GIF fall‑back for older browsers.

**Embed example**

```html
<picture>
  <source srcset="animation.webp" type="image/webp" />
  <img src="fallback.png" width="300" height="250" alt="Ad Animation" />
</picture>
```

**Tips**

* Aim for **≤150 KB initial load**. If over, reduce dimensions, frame count, or quality.
* Test transparency and looping in Chrome, Firefox, Safari, and Edge.
* Verify performance under network throttling (e.g., Fast 3G in DevTools).

***

### Option B — Sprite Sheets in Google Web Designer (GWD)

**Best for:** no‑code/low‑code authoring with a native Sprite Sheet component.

1. **Build the sprite sheet** from your PNG sequence (any packer or exporter). Keep total sheet size at or below **2048×2048** when possible.
2. In **GWD → Components → Sprite Sheet**, drag the component to the stage.
3. In **Properties**:
   * **Source**: your sprite sheet image (PNG‑32 with alpha).
   * **Frame Width / Height**: dimensions of a single cell.
   * **Number of Frames** and **Duration (ms)**.
   * **Loops**: `0` for infinite.
   * **Autoplay** if desired.
4. Preview to confirm alignment, then **Publish** (HTML5/AMPHTML as required).

**Optimization checklist**

* Use PNG compression (TinyPNG/ImageOptim) while preserving alpha.
* Split long animations into multiple sheets or lower resolution/frame count.
* Keep total initial load under your ad platform’s limit (commonly **≤150 KB**).

***

### Option C — TexturePacker → Sprite Sheets (Pro Workflow)

**Best for:** maximal packing efficiency, JSON metadata, custom code/GSAP control.

1. **Import PNG sequence** into TexturePacker.
2. Recommended settings for web ads:
   * **Trim Sprites**: remove excess transparency.
   * **Allow Rotation**: off (simplifies CSS/JS indexing).
   * **Max Size**: 1024–2048 px (pick the smallest that fits).
   * **Padding**: 1–2 px to prevent edge bleeding.
   * **Texture Format**: PNG‑32 (alpha preserved).
   * **Scale**: 0.5–0.75× if needed to hit size targets.
   * **Reduce Colors / PNGQuant / Zopfli** for smaller output.
3. **Export**: `animation.png` (sheet) + `animation.json` (metadata). Optionally export a second **@2×** sheet for retina.
4. **Integrate**:

**A) Quick CSS background‑position animation**

```html
<div id="sprite" style="width:120px;height:120px;background:url('animation.png') 0 0 no-repeat;"></div>
<script>
  const frames = 24, frameW = 120; let i = 0;
  setInterval(() => {
    i = (i + 1) % frames;
    document.getElementById('sprite').style.backgroundPosition = `${-i * frameW}px 0`;
  }, 1000 / 12); // 12 fps
</script>
```

**B) GSAP steps‑based animation**

```html
<div id="sprite" style="width:120px;height:120px;background:url('animation.png') 0 0 no-repeat;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script>
  const frames = 24, w = 120;
  gsap.to('#sprite', {
    backgroundPosition: `${-w * frames}px 0`,
    ease: `steps(${frames})`,
    duration: 1,
    repeat: -1
  });
</script>
```

**Pro tips**

* Keep frame rate ≤ 24 fps; shorter loops pack smaller.
* Reuse the same sheet across multiple ad sizes/variants where possible.
* For trimmed sprites, read the JSON’s per‑frame offsets when positioning.

***

### Option D — SVG Sprite Container + Timeline Trigger

**Best for:** authoring fades/overlays/impacts on a visual timeline while the **sprite playback** is controlled by code and starts **when the timeline plays**.

#### Overview

* The animated character/object lives inside an **SVG element**.
* A parent **sprite container** holds a single `<image>` that points to a packed **sprite sheet** (PNG with alpha) hosted in your **publish bucket**.
* The timeline manages opacity/position effects; a **start trigger** fires to begin integer frame‑stepping of the sheet. Optional pause/complete triggers stop/reset playback.

#### Build steps

1. **Prepare the sprite sheet** using Option B or C and upload it to a public path in your publish bucket.
2. **Create the SVG holder** sized to one frame. Place the full sheet as an `<image>` and reveal a single frame with a clipPath. Move the sheet by one frame width each tick.

```html
<svg id="spriteSvg" width="120" height="120" viewBox="0 0 120 120" role="img" aria-label="Sprite animation">
  <defs>
    <clipPath id="frameWindow"><rect width="120" height="120"/></clipPath>
  </defs>
  <g clip-path="url(#frameWindow)">
    <!-- Replace with your publish-bucket URL -->
    <image id="spriteSheet" href="https://cdn.yourdomain.com/ads/sprite.png"
           x="0" y="0" width="2880" height="120"/>
  </g>
</svg>
```

> Example: `width="2880"` implies **24 frames × 120px** (single‑row sheet).

3. **Playback controller** — listen for timeline events and step the sheet by whole frames.

```html
<script>
  (function(){
    const sheet = document.getElementById('spriteSheet');
    const FRAME_W = 120, FRAMES = 24, FPS = 12;
    let i = 0, timer = null;

    function step(){ i = (i + 1) % FRAMES; sheet.setAttribute('x', String(-i * FRAME_W)); }
    function play(){ if (!timer) timer = setInterval(step, 1000 / FPS); }
    function pause(){ if (timer) { clearInterval(timer); timer = null; } }
    function reset(){ i = 0; sheet.setAttribute('x', '0'); }

    // Timeline integration — dispatch these custom events from your timeline actions
    window.addEventListener('ra:timeline:start', play);
    window.addEventListener('ra:timeline:pause', pause);
    window.addEventListener('ra:timeline:complete', () => { pause(); reset(); });

    // Optional visibility‑based start
    const io = new IntersectionObserver(e=>{ if(e[0].isIntersecting) play(); }, {threshold: 0.5});
    io.observe(document.getElementById('spriteSvg'));
  })();
</script>
```

4. **Timeline triggers**

   * At **0 ms**: dispatch `ra:timeline:start`.
   * At a pause point: dispatch `ra:timeline:pause`.
   * At the end (after fade‑out): dispatch `ra:timeline:complete`.

   Example code for timeline actions:

   ```js
   // Start
   window.dispatchEvent(new Event('ra:timeline:start'))
   // Pause
   window.dispatchEvent(new Event('ra:timeline:pause'))
   // Complete
   window.dispatchEvent(new Event('ra:timeline:complete'))
   ```

#### Notes & gotchas

* For **multi‑row** sheets, compute `col = i % cols`, `row = Math.floor(i / cols)` and set both `x` and `y`.
* Add **1–2 px padding** between frames to prevent edge bleeding; snap to integer positions.
* You can replace `setInterval` with **GSAP** animating the `<image>` `x` property using `ease: steps(FRAMES)`.
* Keep animation logic isolated; the timeline continues to control fades/motion separately from sprite stepping.

***

### Testing & Compliance Checklist

* **Initial load**: ≤150 KB (GDN typical) — verify bundle + assets.
* **Transparency**: confirm in all target browsers.
* **Network**: test under Fast 3G to simulate real ad loads.
* **Fallbacks**: static backup image for non‑animated/unsupported cases.
* **Mobile**: check touch performance and layout.

***

### Troubleshooting

**Sprite offset/misalignment**

* Ensure each frame is the same width/height grid if using a simple sheet.
* If using trimmed frames + JSON, apply the per‑frame origin/offset when drawing.

**Edge bleeding/ghost lines**

* Add 1–2 px padding between cells.
* Snap background positions to whole pixels.

**File size too large**

* Reduce dimensions, quantize colors, drop redundant frames, lower fps.
* Split long loops into several shorter sheets or use WebP where appropriate.

**Stuttery playback**

* Use `steps(N)` easing (GSAP) or integer frame stepping.
* Avoid CSS transitions with fractional positions for frame indices.

***

### FAQ

**Do I need both WebP and a sprite sheet?**\
No. Pick one per creative. Use WebP for simplicity; sprite sheets for control/reuse.

**What about retina?**\
Export @2× sheets and scale CSS/JS positions accordingly, or serve based on DPR.

**Will this work in AMPHTML?**\
Yes—with constraints. Prefer GWD export for AMP creatives, and mind inline script limits.

**How do I count frames?**\
In TexturePacker/GWD you set the frame count explicitly; with WebP the timing is encoded in the asset.

***

### Deliverables to Engineering

* **Animated WebP**: `animation.webp` (+ `fallback.png`), width × height, loop rules, target KB.
* **GWD Sprite Sheet**: packed PNG sheet, frame dimensions, frame count, duration, loop policy, published bundle.
* **TexturePacker Sprite Sheet**: PNG + JSON, intended fps, any offsets, example integration (CSS/GSAP).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.responsiveads.com/creating-ads/designing-your-ad-in-the-fluid-ad-creator/animation-timeline/using-sprite-sheets-and-animation-in-responsiveads.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
