尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Devtober 2026 : un mot par jour, une création en code
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
Un mot par jour pendant tout octobre, une création en code inspirée du mot. Le résultat est en ligne sur damienmarill.github.io/devtober. La règle du Devtober demande un dossier par jour avec un README. Ici, tout le mois est une seule application Angular : chaque jour est un composant Angular dans son propre dossier, chargé à la demande quand on ouvre sa page. On garde donc l'esprit de la règle (un dossier + un README par jour), mais tout est navigable depuis un même site.查看完整 README ↗
Un mot par jour pendant tout octobre, une création en code inspirée du mot. Le résultat est en ligne sur damienmarill.github.io/devtober.
La règle du Devtober demande un dossier par jour avec un README. Ici, tout le mois est une seule application Angular : chaque jour est un composant Angular dans son propre dossier, chargé à la demande quand on ouvre sa page. On garde donc l'esprit de la règle (un dossier + un README par jour), mais tout est navigable depuis un même site.
/day-XX-mot, où la création occupe tout l'écran sous la barre de navigation.Dans days/, un dossier par jour :
days/
day-01-pulse/
day-01-pulse.ts ← le composant du jour (canvas, SVG, WebGL… au choix)
README.md ← ce que fait le code et le lien avec le mot
preview.gif ← (optionnel) l'aperçu à poster avec #devtober
preview.png ← (optionnel) la miniature de la carte sur l'accueil
registry.ts ← liste des jours publiés, branchée sur le routing
Le reste du repo, c'est le cadre commun :
src/app/
home/ ← page d'accueil : grille des 31 jours
layout/ ← barre de navigation, fil d'Ariane, modale README
days.ts ← mots, dates et statut de chaque jour
libs/ui/ ← composants spartan-ng (helm) utilisés par le cadre
scripts/new-day.mjs ← crée le dossier d'un jour
.claude/skills/ ← skill Claude Code qui rédige le README d'un jour
| # | Mot | # | Mot | # | Mot | ||
|---|---|---|---|---|---|---|---|
| 01 | Pulse | 12 | Lost | 23 | Spark | ||
| 02 | Loop | 13 | Tangle | 24 | Hidden | ||
| 03 | Bloom | 14 | Bounce | 25 | Melt | ||
| 04 | Drift | 15 | Shadow | 26 | Machine | ||
| 05 | Chaos | 16 | Tide | 27 | Haunted | ||
| 06 | Tiny | 17 | Orbit | 28 | Grow | ||
| 07 | Swarm | 18 | Glitch | 29 | Infinite | ||
| 08 | Maze | 19 | Echo | 30 | Collapse | ||
| 09 | Gravity | 20 | Fragile | 31 | Wake | ||
| 10 | Fold | 21 | Signal | ||||
| 11 | Ripple | 22 | Mirror |
npm run new-day -- 3 # ou sans argument pour le jour d'aujourd'hui
Le script crée days/day-03-bloom/ avec un composant de départ et un squelette de README, puis l'ajoute à days/registry.ts (avec un réglage de capture par défaut). Le jour passe en « Publié » sur l'accueil et devient accessible sur /day-03-bloom.
Le composant reçoit toute la zone sous la barre de navigation (size-full). À toi de jouer.
Une fois le code écrit, demande à Claude Code « documente le jour 3 ». Le skill day-readme lit le code du dossier et rédige le README : l'idée, comment c'est codé, le lien avec le mot. Les liens relatifs vers les fichiers fonctionnent à la fois sur GitHub et dans la modale du site.
npm run gif -- 3 # preview.gif (README), preview.mp4 (posts), preview-embed.gif (liens partagés) et preview.png (accueil)
npm run gif -- 3 --preview # 3 s seulement, pour vérifier le clic et le cadrage (preview-test.gif, non versionné)
npm run gif -- 3 --light # GIF plus léger (~9 Mo au lieu de ~13 pour 30 s)
npm run gif -- 3 --embed-only # refait seulement preview-embed.gif, depuis le MP4 existant (sans refilmer)
npm run gif -- 3 --no-thumbnail # tout sauf la miniature PNG
npm run thumbnail -- 3 # refait seulement la miniature PNG (--at 12 : photo 12 s après le clic)
Le script construit l'app, ouvre la page /capture/day-03-bloom dans Chrome (Playwright), la filme, puis convertit la vidéo avec ffmpeg. Cette page est hors de la barre de navigation : elle affiche le jour dans un carré, avec en bas un bandeau (numéro et mot à gauche, logo Marill.dev à droite). Ouverte dans un navigateur, elle montre le même carré, pratique pour régler le clic.
Chaque jour a un réglage capture dans days/registry.ts (créé par new-day) :
capture: { click: { x: 307, y: 534 }, seconds: 30, settle: 3000 },
click : où cliquer, en pixels dans le carré de 720 × 720, pour lancer l'animation. null si on ne clique pas.key (optionnel) : une touche à presser pour lancer l'animation (nom Playwright : 't', 'Space', 'Enter'…), seule ou après le clic. Sans click ni key, le jour démarre tout seul : on filme dès que la page est chargée.seconds : la durée filmée, à partir du clic ou de la touche.settle : l'attente (ms) avant de cliquer ou d'appuyer, le temps que le jour finisse de charger (1500 par défaut).thumbnailFocus (optionnel) : le cadrage vertical de la miniature 16/9 dans la scène carrée, de 0 (le haut) à 1 (le bas), 0,5 par défaut.thumbnailAt (optionnel) : l'instant de la miniature, en secondes après le clic ou la touche (le tiers de seconds par défaut). À régler sur le moment où la scène est la plus parlante.Pour trouver les coordonnées d'un bouton, ouvre /capture/day-03-bloom en mode « appareil » 720 × 720 dans les outils de développement, ou mesure-le avec Playwright (locator(...).boundingBox()). Le registre est compilé dans l'app : après l'avoir modifié, relance sans --skip-build.
Il faut Google Chrome et ffmpeg installés.
GIF ou MP4 ? Pour 30 s d'animation, le GIF pèse ~13 Mo (400 px, 256 couleurs, 12 images/s) alors que le MP4 (720 px, pleine qualité) en pèse ~4 : c'est le format à envoyer sur X, LinkedIn ou Instagram. Le GIF sert à l'aperçu du README, où une vidéo ne s'affiche pas. Un GIF est lourd par nature sur ces scènes (fonds en dégradé, lueurs qui changent à chaque image) : avec moins de 128 couleurs, les dégradés se découpent en aplats. Pour l'alléger sans les abîmer, --light ; sinon --fps 10, --width 360 ou --colors 128. --dither bayer lisse les dégradés mais double le poids. Le script débruite la vidéo avant la palette, ce qui allège le GIF sans changer son aspect.
Si l'image reste figée pendant les dernières secondes (la musique s'est coupée, un réseau lent…), le script le signale : une capture ratée ne se voit sinon qu'à l'œil. Relance simplement la commande. npm run gif sans argument donne la liste des options.
Chaque carte d'un jour publié sur l'accueil affiche son preview.png, pour qu'on voie d'un coup d'œil les univers différents. scripts/thumbnail.mjs la génère : il joue le jour sur /capture/<jour> comme le script de GIF, attend l'instant thumbnailAt, puis photographie une bande 16/9 de la scène (sans le bandeau du bas, déjà redit par la carte), au format des cartes. npm run gif l'appelle à la fin : une seule commande produit tous les aperçus. --preview et --embed-only n'y touchent pas ; npm run thumbnail -- 3 la refait seule, sans refilmer (--focus 0.3 pour monter le cadrage).
Le PNG reste dans le dossier du jour ; angular.json le sert sous thumbnails/<jour>/preview.png. Sans PNG, la carte s'affiche sans image. Le socle commun aux deux scripts (build, serveur, Chrome, clic) est dans scripts/lib/capture-env.mjs.
Quand on partage le lien d'un jour (/day-03-bloom/), les réseaux affichent son preview-embed.gif. npm run build:pages écrit pour chaque jour une page HTML statique avec ses balises de partage (Open Graph, X) : le titre, la description (le premier paragraphe du README) et l'image. C'est nécessaire parce que les robots des réseaux n'exécutent pas le JavaScript d'Angular : sans ça, tous les liens afficheraient le même aperçu. Le script est scripts/social-pages.mjs. Un jour sans preview-embed.gif a ses balises de titre et de description, mais pas d'image. L'accueil a des balises génériques, sans image.
Cette image est à part du preview.gif du README, pour une raison de poids : X, LinkedIn et Slack ignorent une image de plus de 5 Mo (8 Mo pour Facebook et Discord), et un GIF de 30 s en fait ~13. npm run gif prend donc la fenêtre la plus animée du clip (12 s par défaut, 360 px) et la raccourcit jusqu'à passer sous 4,5 Mo. X et LinkedIn n'affichent que sa première image, qui montre ainsi l'action et non le début calme du clip ; Facebook et Discord jouent l'animation. Le carré n'est pas recadré : la carte X est de type summary, qui accepte le 1:1.
Les réseaux mettent les aperçus en cache : après un déploiement, ils peuvent montrer l'ancien jusqu'à ce qu'on force la relecture (Facebook Sharing Debugger, LinkedIn Post Inspector).
npm install
npm start # http://localhost:4200
npm run build:pages # build de prod tel que déployé sur GitHub Pages
Node 22.22.3+ ou 24 (voir .nvmrc).
npx ng g @spartan-ng/cli:ui <nom>.#0E0A35, accent périwinkle, titres en Bricolage Grotesque, texte en Lato. Les variables sont dans src/styles.css.Les créations de chaque jour sont libres : elles n'ont pas à utiliser spartan ni le thème.
Chaque push sur main lance le build et le déploiement sur GitHub Pages via .github/workflows/deploy.yml. Le build utilise --base-href /devtober/ et copie index.html en 404.html pour que les liens directs vers un jour fonctionnent.