iart-ai/ecommerce-video-skills

Générez des vidéos e-commerce / produit — démos produit, promos de vente et diaporamas photo — directement à partir de vos captures d'écran, prix et dossiers d'images.

Qu'est-ce que ecommerce-video-skills ?

Ce skill est conçu pour créer des démonstrations vidéo animées de produits à partir de captures d'écran ou de maquettes statiques, sans aucun enregistrement d'écran. Il est idéal pour les démos d'applications SaaS, les annonces de fonctionnalités, les parcours d'intégration ou les diaporamas promotionnels, en transformant des images fixes en animations fluides avec cadre de navigateur, curseur animé, effets de clic, zoom sur les zones clés et annotations. Fonctionnant avec Remotion, le skill génère des vidéos MP4 déterministes où chaque image est une fonction pure du numéro d'image, garantissant une reproductibilité parfaite. L'utilisateur fournit des captures d'écran (idéalement en 2× pour un zoom net), des prix et des dossiers d'images, et le skill produit une vidéo finale prête à être déployée sur des plateformes comme YouTube ou les réseaux sociaux.

Compatible avec~Claude Code~Codex CLI✓Cursor
npx skills add iart-ai/ecommerce-video-skills

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Vidéo de démo produit

Transformez des captures d'écran ou des maquettes de produit statiques en une démonstration animée et soignée — sans enregistreur d'écran, sans curseur réel tremblant, sans décalage de version d'interface. Encadrez chaque écran, faites glisser un curseur synthétique vers le pixel exact, ondulez le clic, puis zoomez sur la partie importante et légendez la fonctionnalité. Puisque l'entrée est statique et que le mouvement est codé, chaque valeur est déterministe et se re-rend à l'identique lorsque la capture d'écran change.

Quand l'utiliser

  • Démo d'application / SaaS, annonce de fonctionnalité, parcours d'intégration (15–90s).
  • Montrer un parcours de clics dans une interface dont vous n'avez que des captures d'écran ou maquettes.
  • Mettre en évidence une zone focale d'un tableau de bord dense (zoom sur une région + annotation).

Pourquoi les captures d'écran sont meilleures que les enregistrements

Enregistrement d'écranPiloté par capture d'écran (ce skill)
Le curseur réel dérive, dépasse, trembleLe curseur suit un chemin fluide vers une cible exacte
Réenregistrer toute la prise pour corriger une étapeÉchanger un PNG, re-rendre le même code
L'interface change en cours de prise, la souris chercheChaque écran est un asset propre et final
Difficile de zoomer sans pixellisationExporter les captures à 2× (DPR 2) → zooms nets

Capturez les entrées à deux fois la taille d'affichage (retina / deviceScaleFactor: 2) pour qu'un zoom 2× reste net. Voir references/screenshot-demo.md pour un script de capture Playwright.

La boucle de démo

Chaque démo suit la même séquence, répétée par fonctionnalité. Maintenez assez longtemps pour lire, déplacez-vous avec intention, posez le clic, révélez le résultat.

TempsBudgetRôle
Stabilisation sur l'écran0,5–1sLaisser le spectateur s'orienter avant tout mouvement
Le curseur se déplace vers la cible0,4–0,8sMouvement fluide (ease-in-out), pas linéaire
Onde de clic + changement d'état0,2–0,3sRetour tactile ; l'écran réagit sur la même image
Zoom sur la zone focale1–2s pour entrer, maintenir 2–4s2× est le point idéal — assez de détail, garde le contexte
Légender la fonctionnalitémaintenir avec le zoomUne phrase d'avantage, ex. "Export en un clic"

Déplacez la caméra ou le curseur, rarement les deux à la fois — deux mouvements simultanés divisent l'attention.

Encadrer la capture d'écran

Une capture d'écran brute ressemble à un rapport de bug ; une capture encadrée ressemble à un produit. Enveloppez chaque écran dans un navigateur ou un cadre de périphérique sur un fond de marque.

// Cadre de navigateur — insérez une capture, obtenez une fenêtre crédible
const BrowserFrame = ({ url, children }) => (
  <div style={{ borderRadius: 12, overflow: "hidden", background: "#1e1e22",
                boxShadow: "0 40px 80px rgba(0,0,0,.35)" }}>
    <div style={{ height: 40, display: "flex", alignItems: "center", gap: 8, padding: "0 14px" }}>
      {["#ff5f57", "#febc2e", "#28c840"].map((c) => (
        <span key={c} style={{ width: 12, height: 12, borderRadius: "50%", background: c }} />
      ))}
      <div style={{ marginLeft: 12, flex: 1, height: 24, borderRadius: 6, background: "#2b2b30",
                    color: "#9aa", fontSize: 13, display: "flex", alignItems: "center", padding: "0 10px" }}>
        {url}
      </div>
    </div>
    <div style={{ background: "#fff" }}>{children}</div>
  </div>
);

Mettez une vraie URL dans la barre d'adresse (authenticité), ajoutez une ombre douce et un fond dégradé. Pour le mobile, passez à un cadre de téléphone avec une encoche et des coins arrondis. Gardez le style de cadre dans un seul objet de thème pour que chaque écran corresponde.

Curseur animé + onde de clic (le mouvement clé)

Pilotez la position à partir de l'image actuelle, jamais à partir d'une transition CSS ou d'une horloge murale — un rendu vidéo a besoin que chaque image soit une fonction pure du numéro d'image, sinon le curseur se désynchronise et scintille.

import { useCurrentFrame, interpolate, spring, useVideoConfig } from "remotion";

// Trajet fluide de `from` à `to` entre startFrame et startFrame+dur
const useCursor = (from, to, startFrame, dur) => {
  const frame = useCurrentFrame();
  const t = interpolate(frame, [startFrame, startFrame + dur], [0, 1],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: (x) => x * x * (3 - 2 * x) }); // smoothstep
  return { x: from.x + (to.x - from.x) * t, y: from.y + (to.y - from.y) * t };
};

export const Cursor = ({ from, to, startFrame, dur, clickAt }) => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();
  const { x, y } = useCursor(from, to, startFrame, dur);

  // L'onde s'étend une fois, à l'image du clic
  const since = frame - clickAt;
  const showRipple = since >= 0 && since < 18;
  const r = spring({ frame: since, fps, config: { damping: 18 }, durationInFrames: 18 });

  return (
    <>
      {showRipple && (
        <div style={{ position: "absolute", left: x, top: y, transform: "translate(-50%,-50%)",
          width: 12 + r * 60, height: 12 + r * 60, borderRadius: "50%",
          border: "2px solid rgba(80,140,255,.9)", opacity: 1 - r }} />
      )}
      <svg width="28" height="28" viewBox="0 0 28 28"
           style={{ position: "absolute", left: x, top: y, filter: "drop-shadow(0 2px 3px rgba(0,0,0,.4))" }}>
        <path d="M3 2 L3 21 L9 15 L13 24 L16 23 L12 14 L20 14 Z" fill="#fff" stroke="#222" strokeWidth="1.4" />
      </svg>
    </>
  );
};

Le curseur utilise smoothstep pour accélérer depuis l'arrêt et décélérer vers la cible (un curseur linéaire semble robotique). Déclenchez l'onde et le changement d'état de l'écran sur la même image clickAt pour que la cause et l'effet coïncident. Voir references/screenshot-demo.md pour la composition complète connectant plusieurs clics sur plusieurs écrans.

Zoom sur une région (Ken Burns pour interface)

Pour zoomer sur un élément focal, mettez à l'échelle l'écran et définissez transform-origin au centre de cet élément, afin que le zoom converge vers lui plutôt que vers le centre du cadre.

const ZoomToRegion = ({ target, scale = 2, startFrame, dur, children }) => {
  const frame = useCurrentFrame();
  const s = interpolate(frame, [startFrame, startFrame + dur], [1, scale],
    { extrapolateLeft: "clamp", extrapolateRight: "clamp", easing: (x) => 1 - Math.pow(1 - x, 3) }); // easeOutCubic
  return (
    <div style={{ transform: `scale(${s})`, transformOrigin: `${target.x}px ${target.y}px`,
                  willChange: "transform" }}>
      {children}
    </div>
  );
};

Limitez le zoom à environ 2× (au-dessus de 3×, le contexte est perdu et désoriente). Maintenez l'état zoomé 2–4s — assez pour lire le détail — puis redescendez en douceur avant de passer à l'écran suivant. Associez le zoom avec une annotation, jamais brut.

Annotations et légendes de fonctionnalités

Annotez le point d'inflexion, puis effacez-le. Une annotation est une étiquette + un connecteur (flèche, cercle ou soulignement) qui pointe vers l'élément focal.

  • Mettez en évidence l'élément avec un anneau doux ou un environnement atténué (box-shadow: 0 0 0 9999px rgba(0,0,0,.45) crée un trou de projecteur).
  • Légendez un avantage par temps — une courte phrase nominale ("Analytiques en temps réel"), pas une phrase. Entrez sur le zoom, sortez avant l'étape suivante.
  • Gardez les légendes dans le tiers inférieur et dans la zone de sécurité de titre pour qu'elles survivent aux recadrages en 9:16.

Voir references/annotation-and-transitions.md pour les masques de projecteur, les connecteurs fléchés et une piste de légende typée.

Transitions d'écran à écran

Entre les étapes, déplacez les écrans avec un langage cohérent. Choisissez-en un et tenez-vous-y :

TransitionSensationUtilisation
Pousser / glisserMouvement vers l'avant "étape suivante"Parcours linéaires
Zoom croiséÉlan, comme une applicationPlonger dans une vue détaillée
Fondu croiséCalme, neutreChangement de contexte (paramètres → tableau de bord)
Coupe sur un élément partagéTransparentMême carte persistante entre les écrans

Maintenez l'écran sortant jusqu'à ce que son clic se résolve, puis transitionnez — ne coupez jamais en plein mouvement. Voir references/annotation-and-transitions.md.

Liste de vérification de sortie

  • Entrées capturées à 2× (DPR 2) ; les zooms restent nets à 2×.
  • Chaque valeur de curseur/zoom est une fonction pure de useCurrentFrame() — pas de transitions CSS pour l'état animé.
  • Le curseur se déplace sur un chemin fluide (smoothstep) ; l'onde et le changement d'état se déclenchent sur la même image de clic.
  • Chaque écran est encadré (navigateur/périphérique) avec une vraie URL et un thème cohérent.
  • Un mouvement à la fois (caméra ou curseur) ; zoom ≤ 2×, maintenu 2–4s.
  • Une légende d'avantage par temps, dans le tiers inférieur de sécurité de titre ; les transitions utilisent un langage cohérent.

Livrer et vérifier (images rendues → MP4)

Aide packagée (scripts/) : assemblez vos images avec scripts/contact-sheet.sh sheet.png f-hook.png f-mid.png f-end.png, puis vérifiez l'encodage avec scripts/probe-mp4.sh out.mp4 [LxH] [fps]. Voir scripts/README.md.

C'est un niveau lourd : le livrable est un MP4, pas une page en direct. La démo ingère les assets de l'utilisateur — captures d'écran/maquettes, logo optionnel — donc la vérification concerne principalement l'image correcte s'est-elle chargée et positionnée dans le cadre.

Contrat de sortie :

  • Un projet Remotion avec la composition enregistrée (<Composition> + schema zod + defaultProps) ; chaque valeur de curseur/zoom/transition est une fonction pure de useCurrentFrame() (pas de transitions CSS, minuteries, Date.now()).
  • Captures d'écran chargées via staticFile(), sécurisées avec delayRender/continueRender pour que le PNG 2× (et toute police web) soit présent avant le rendu de l'image — sinon l'écran apparaît vide en cours de démo.
  • Livrable = le out/*.mp4 rendu plus le projet (re-rendre lorsque la capture d'écran change).

Boucle de vérification — rendre les images → inspecter → encoder. Des PNG bon marché d'abord, vidéo seulement lorsqu'ils sont corrects.

# Images à trame exacte AVEC LES PROPS QUE VOUS ALLEZ LIVRER (chemins réels de captures), pas defaultProps
npx remotion still ProductDemo out/f-settle.png --frame=15  --props=demo.json   # écran encadré, avant mouvement
npx remotion still ProductDemo out/f-click.png  --frame=90  --props=demo.json   # curseur sur cible + onde
npx remotion still ProductDemo out/f-zoom.png   --frame=150 --props=demo.json   # zoom sur zone focale + légende
# image finale = durationInFrames - 1 (npx remotion compositions le lit)

Inspectez chaque PNG pour la fidélité (capture d'écran correcte chargée ; curseur sur le pixel exact ; onde de clic et changement d'état sur la même image ; texte de légende correct) ET les artefacts (image vide/non chargée, écran hors cadre, zoom pixellisé ou dépassant le cadre, légende hors du tiers inférieur de sécurité de titre, mauvais format/letterboxing).

# Uniquement après que les images sont propres :
npx remotion render ProductDemo out/demo.mp4 --props=demo.json
npx remotion render ProductDemo out/demo.gif --props=demo.json --codec=gif   # Preuve premier écran du README

Traitement par lots (un modèle, plusieurs produits) : lorsque vous personnalisez la démo pour chaque produit, vérifiez les props d'UN produit représentatif via des images avant de rendre le catalogue par lots — détectez un bug d'image blanche ou hors cadre une fois, pas N fois.

Avant de terminer :

  1. Les images se rendent proprement au temps de stabilisation / clic / fin — pas d'erreurs, les captures sont effectivement chargées (pas vides).
  2. Le curseur atterrit sur la cible exacte ; onde + changement d'état sur la même image ; texte de légende correct et dans le tiers inférieur de sécurité de titre.
  3. Tout mouvement est piloté par trames — pas de transitions CSS / minuteries / Date.now() / Math.random().
  4. Les props livrées (chemins réels de captures) se rendent correctement, pas seulement defaultProps.
  5. MP4 complet encodé et lisible ; (optionnel) GIF rendu pour le README.

Fichiers de référence

  • references/screenshot-demo.md — une démo Remotion complète et exécutable : capture de captures d'écran à 2× avec Playwright, les composants de cadre navigateur/téléphone, une composition multi-étapes qui fait parcourir un curseur sur plusieurs écrans avec ondes de clic, et une commande de rendu.
  • references/annotation-and-transitions.md — masques

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills associés