Skip to content
Image Generation
Skill

/3dicon

Turn a prompt or a still image into a looping animated icon with real transparency — GPT Image / Nano Banana for the art, Seedance via OpenRouter for the motion, exact-unpremultiply matting for the alpha, animated WebP out. Use when asked to animate an app icon, make a 3D icon

BOOST
From plugin
3dicon
5601 skill
Install
$ npx -y skills add samyost1/3dicon --skill 3dicon --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/3dicon

Context preview

The summary Claude sees to decide when to auto-load this skill.

Turn a prompt or a still image into a looping animated icon with real transparency — GPT Image / Nano Banana for the art, Seedance via OpenRouter for the motion, exact-unpremultiply matting for the alpha, animated WebP out. Use when asked to animate an app icon, make a 3D icon

SKILL.md

3dicon.SKILL.md
name: 3dicon
description: Turn a prompt or a still image into a looping animated icon with real transparency — GPT Image / Nano Banana for the art, Seedance via OpenRouter for the motion, exact-unpremultiply matting for the alpha, animated WebP out. Use when asked to animate an app icon, make a 3D icon loop, produce a transparent animated asset, or add motion to flat icon art.

3dicon

Generate a still, animate it into a seamless loop, key the background out properly, and encode it as an animated WebP with true soft alpha — the format `expo-image`, Chrome and Safari all render natively, with no Lottie conversion and no new native dependency.

Before anything

1. `pip install -r requirements.txt` (or `uv pip install -r requirements.txt`). 2. `cp .env.example .env` and fill in the keys for the backend you want. 3. `ffmpeg` must be on PATH.

Check the keys are present *before* running — `animate` costs money, and a run that dies halfway has already spent it.

Always stop after the still

One still, then ask. Never generate several takes to choose from, and never run through to the animation without the user seeing the art first.

1. Generate exactly ONE still. 2. **Show it to the user** and ask plainly whether they are happy with the static design before anything else happens. 3. Only on a yes, animate it.

Why this is a hard rule, not a nicety: the still is 13 cents and the full run is 48 cents and four minutes, and every later stage inherits the still's object, colour and weight. Animating art the user has not approved means paying twice. `run` therefore stops after the still on purpose.

If they are not happy, adjust the prompt and generate one replacement — not a grid of options. Variants exist behind `--variants` but are off by default and should stay that way unless the user asks to compare.

How to report back

Keep the chat almost empty. The user is looking at an image, not reading a report — everything they need is either in the picture or in one line under it.

**After the still**, say only this, then stop and wait:

> **Still ready.** > *(show the image)* > Happy with it, or change something?

Do not explain the prompt, list what you did, or describe the image back to them. They can see it.

**Then propose the motion and stop again.** Do not animate on the strength of the still being approved — the motion is the second decision and it is the one that costs four minutes. Propose exactly one:

> **Motion** — *(one plain sentence: what actually happens, in physical terms)* > `event` · `lively` · `--emit` > > Agree, or describe the motion you want?

One sentence and the flags. No reasoning, no alternatives, no explanation of what the flags mean.

**If they describe their own motion, translate it.** They will use ordinary words; your job is to turn those into the flags and one physical sentence, not to pass their phrasing through. Work out:

  • *what does this object do when left alone?* → `--strategy`
  • *how much should the object itself move?* → `--energy`
  • *would the action throw something off?* → `--emit`
  • *what literally happens to the material?* → `--motion`

Then show the translated proposal in the same format and confirm before running. If what they asked for is not supported — a camera move, something entering the frame, the object travelling away — say so in one line and offer the nearest thing that is.

`animate --dry-run` composes the full prompt and spends nothing. Use it if you need to check what the flags expand to; do not paste the result into the chat.

**After the animation**, one line of numbers and the file:

> **Done** — `flame.webp` · 857 KB · 122f @ 24fps > *(show the contact sheet)*

**If `verify` fails**, one line on what failed and one on what you propose:

> **Motion too weak** — step 0.9, needs 1.0. > Retry as `event` with `--emit`?

**Never** paste raw CLI output, stage-by-stage progress, the composed motion prompt, or a summary of the pipeline. If a stage succeeds, its output is the file — say the filename and move on. Save the detail for when something breaks and the user has to choose what to do next.

The pipeline

python -m iconloop --out out still   --prompt "a 3D stopwatch, sage green and cream, soft matte plastic"
python -m iconloop --out out animate --motion "the stopwatch rocks gently while its hand sweeps clockwise"
python -m iconloop --out out matte
python -m iconloop --out out encode  --sweep
python -m iconloop --out out encode  --size 288 --name timer
python -m iconloop --out out verify

`run` is just `still` plus the reminder to stop and ask. The stages are separate because each one is a place to look before spending the next thing.

Choosing the motion

Before animating, answer one question: **what does this object do when left alone?** The answer picks the strategy, and picking it wrong is the main cause of a dull or generic result.

| answer | strategy | what you get | |---|---|---| | It moves by itself — flows, burns, breathes, ticks | `native` | continuous motion from its own physics | | Nothing. It is inert until used | `event` | it performs its function once, then rests | | Nothing, but part of it is loose, hinged or light | `part` | the body anchors, one small piece moves | | Nothing, and it has no moving parts at all | `surface` | light or material travels across a fixed form |

Most objects people ask for are **inert**. Asking an inert object to move naturally is what produces a turntable spin or an aimless bob — it has no natural motion, so the model supplies a generic one. Reach for `event` first unless the thing genuinely moves on its own.

Add `--emit` when the action would realistically throw something off — a fragment, a droplet, a spark, a glint. For an inert object that emission is often the entire reason the animation reads at icon size.

`event` and `part` also permit the object to be **temporarily altered** — something removed, opened, split, filled — as long as it returns to its

Read more
Ships with3dicon

One prompt in, a looping animated 3D icon out (with real transparency) an animated WebP you can drop straight into your app UI.

Get the whole plugin
Stats
560
Stars
48
Forks
Active
Maintenance
Python
Language
MIT
License
23d ago
Last commit
23d ago
Created
1h ago
Added

Repo: samyost1/3dicon