Arborescence du dépôt récit défilant¶
L'essentiel en 3 points
- Un fichier CSS et un fichier JS par chapitre, dans des dossiers
chapitres/. Chaque fichier appartient à la personne responsable du chapitre. - Quelques fichiers communs (
index.html,commun.css,main.js,data.json) : à toute l'équipe. On se prévient avant d'y toucher. Dansdata.json, seules les clés communes sont fixes : lecontenude chaque chapitre appartient à son responsable, qui le change librement. - Toute la structure, avec un fichier par chapitre, même vide, se crée une seule fois, ensemble, sur
main, au début. Ensuite, chacun travaille dans ses fichiers, sur sa branche.
Pourquoi un fichier par chapitre?¶
- Moins de conflits : un conflit arrive quand deux personnes modifient les mêmes lignes du même fichier. Si chacun travaille surtout dans ses propres fichiers, ça arrive rarement.
- Votre travail est visible : votre matrice de responsabilités correspond à des fichiers précis. L'historique Git de
ch-03.jsmontre qui l'a écrit. - À la défense, on ouvre vos fichiers, et vous les expliquez.
L'arborescence¶
Exemple pour 6 chapitres. Le README.md et le dossier documentation/ existent déjà depuis la remise du cahier de charges : on ajoute le reste autour.
.vscode/settings.json ← commun : désactive Copilot (voir plus bas)
README.md ← déjà là : équipe, thème, lien Figma, crédits
documentation/ ← déjà là : la planification
CAHIER-DE-CHARGES.md
storyboard.pdf ← v1, à garder tel quel
storyboard-v2.pdf
JOURNAL-prenom.md ← un journal par personne
JOURNAL-prenom.md
brainstorm/ ← les photos, si brainstorm sur papier
index.html ← commun
css/
style.css ← commun : importe tous les autres
commun.css ← commun : couleurs, typographie, mise en page
chapitres/
ch-01.css ← le responsable du chapitre 1
ch-02.css
...
ch-06.css
js/
main.js ← commun : fetch, construction des chapitres
chapitres/
ch-01.js ← le responsable du chapitre 1
ch-02.js
...
ch-06.js
data/
data.json ← commun : clés communes fixes, contenu libre
assets/images/
Désactiver Copilot dans votre projet
Créez le fichier .vscode/settings.json à la racine de votre dépôt, et commitez-le :
{
"github.copilot.enable": { "*": false }
}
Les complétions de Copilot sont alors désactivées dans ce projet seulement. Vos autres projets ne changent pas. N'utilisez pas non plus le chat de Copilot.
Le HTML¶
Une seule page. Les chapitres sont construits par le JavaScript, à partir de data.json.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Notre récit</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<main id="recit"></main>
<!-- type="module" : main.js peut importer les fichiers des chapitres -->
<script type="module" src="js/main.js"></script>
</body>
</html>
Le CSS : un fichier qui importe tous les autres¶
style.css ne contient que des @import, dans l'ordre : le commun, puis chaque chapitre.
/* Le CSS commun, puis un fichier par chapitre */
@import url("commun.css");
@import url("chapitres/ch-01.css");
@import url("chapitres/ch-02.css");
@import url("chapitres/ch-03.css");
/* ... un @import par chapitre */
Dans le fichier d'un chapitre, ciblez toujours sa section, avec l'id du chapitre dans data.json. Ainsi, vos règles ne touchent jamais les chapitres des autres :
/* Chapitre 3 : responsable, Prénom */
#la-foret h2 {
color: #2E5E3A;
}
Les données : data.json¶
Un objet par chapitre, dans l'ordre du récit. Chaque objet a deux parties :
{
"id": "la-foret",
"numero": 3,
"titre": "Dans la forêt",
"responsable": "Zoé",
"texte": ["Premier paragraphe...", "Deuxième paragraphe..."],
"contenu": {
"sprite": "assets/images/chaperon-marche.webp",
"images": 8,
"alt": "Le Petit Chaperon rouge marche dans la forêt"
}
}
Les clés communes : fixes¶
id, numero, titre, responsable et texte : main.js s'en sert pour construire chaque section. Elles sont les mêmes pour toutes les équipes et tous les chapitres, et elles ne changent pas en cours de route.
contenu : libre, au responsable du chapitre¶
Tout ce qui est propre à votre chapitre va dans contenu : vos images, vos calques et leur vitesse, le nombre d'images de votre spritesheet, des répliques, le lieu pour votre API... Vous inventez les clés dont vous avez besoin, et vous les changez quand vous voulez : seul le module de votre chapitre (ch-03.js) lit son contenu. Votre coéquipier ne peut pas planter à cause de vos changements.
Vous ne savez pas encore ce qu'il vous faut? C'est normal. Commencez avec "contenu": {}, et ajoutez des clés à mesure que vous découvrez ce dont votre chapitre a besoin.
Qui change quoi¶
| Vous changez... | Ce que vous faites |
|---|---|
Le contenu de votre chapitre |
Rien de spécial : c'est votre espace. Votre createMedia et votre animate lisent les nouvelles clés. |
| Une clé commune (en ajouter une, en renommer une) | Comme pour main.js : vous en parlez avant à votre coéquipier. Une personne modifie tous les chapitres d'un coup, et main.js s'il le faut, puis commit (Données : ajoute la clé sousTitre), push, et chacun met sa branche à jour avec main. |
Votre cahier de charges, section 5
Le format décrit à la section 5 de votre cahier est votre version de départ : il va évoluer, c'est prévu. À la fin du projet, mettez la section 5 à jour : vos clés communes, et un exemple de contenu pour un de vos chapitres.
Le JavaScript : des modules¶
Un module, c'est un fichier JavaScript qui garde ses variables et ses fonctions pour lui. Il partage seulement ce qu'il exporte (export), et un autre fichier s'en sert en l'important (import). Résultat : deux chapitres peuvent avoir une fonction qui porte le même nom sans se nuire.
Vous n'avez pas à maîtriser les modules en détail : utilisez le code ci-dessous tel quel, et complétez-le.
Le fichier d'un chapitre¶
Chaque chapitre exporte deux fonctions, toujours les mêmes. main.js les appelle et leur donne l'objet du chapitre dans data.json (chapter).
// js/chapitres/ch-03.js
// Chapitre 3 : responsable, Prénom
// Appelée par main.js pendant la construction de la section.
// Retourne le HTML du média de ce chapitre.
export function createMedia(chapter) {
// Vos données : chapter.contenu (ex. chapter.contenu.sprite)
return `<div class="foret"></div>`;
}
// Appelée par main.js, une fois tout le HTML dans la page.
// section : l'élément <section> de ce chapitre.
export function animate(section, chapter) {
// Vos animations ici : IntersectionObserver, GSAP...
// Cherchez vos éléments DANS la section :
// section.querySelector(".foret")
}
- Pas encore de média?
return "";. - Pas d'animation en JavaScript (tout est en CSS)? Laissez
animatevide. - Mais les deux fonctions doivent exister :
main.jsles appelle pour chaque chapitre.
Vous pouvez écrire d'autres fonctions dans ce fichier : seules createMedia et animate sont exportées, les autres restent privées au chapitre.
main.js : importer tous les chapitres¶
// js/main.js
// Un module par chapitre, dans l'ordre du récit
import * as ch01 from "./chapitres/ch-01.js";
import * as ch02 from "./chapitres/ch-02.js";
import * as ch03 from "./chapitres/ch-03.js";
// ... un import par chapitre
const chapterModules = [ch01, ch02, ch03];
// Une section par chapitre : le texte (commun à tous),
// puis le média, créé par le module du chapitre
function createChapter(chapter, chapterModule) {
// ... les paragraphes (voir « Du JSON aux chapitres », étape 3)
return `
<section class="chapitre" id="${chapter.id}">
<h2>${chapter.titre}</h2>
${paragraphs}
${chapterModule.createMedia(chapter)}
</section>
`;
}
async function init() {
// 1. Charger les chapitres (voir « Du JSON aux chapitres »)
const chapters = await loadChapters();
// 2. Le HTML de chaque chapitre, avec le module du même rang
const recit = document.querySelector("#recit");
recit.innerHTML = chapters
.map((chapter, index) => createChapter(chapter, chapterModules[index]))
.join("");
// 3. Puis, chaque chapitre anime sa propre section
chapters.forEach((chapter, index) => {
const section = document.getElementById(chapter.id);
chapterModules[index].animate(section, chapter);
});
}
init();
L'ordre du tableau chapterModules doit suivre l'ordre des chapitres dans data.json : le 3e objet du JSON va avec le 3e module.
Live Server obligatoire
Les modules, comme fetch(), ne fonctionnent pas si vous ouvrez index.html en double-cliquant (adresse file:///...). Ouvrez toujours la page avec Live Server.
GSAP et Vue, chargés par CDN
Une librairie chargée avec une balise <script> classique (GSAP, Vue) reste disponible partout, y compris dans vos modules : gsap.to(...) fonctionne dans ch-03.js sans import. Placez ces balises avant celle de main.js.
Qui touche à quoi¶
| Fichier | À qui | Règle |
|---|---|---|
css/chapitres/ch-03.css, js/chapitres/ch-03.js |
Le responsable du chapitre 3 | Sur sa branche, librement |
data.json, le contenu d'un chapitre |
Le responsable du chapitre | Librement : seul son module le lit |
data.json, les clés communes |
Toute l'équipe | On s'entend avant, et une personne modifie tous les chapitres d'un coup (voir plus haut) |
index.html, commun.css, main.js, style.css |
Toute l'équipe | On se prévient avant d'y toucher, et on fusionne vite |
Créer la structure, au début¶
Une seule fois, ensemble, sur un seul poste, sur main : tous les fichiers, avec un fichier CSS et un fichier JS par chapitre, même vides, et tous les @import et les import déjà écrits. Puis commit (Commun : ajoute la structure de départ) et push. Ensuite, chacun crée sa branche.
Même principe pour le squelette de data.json : un objet par chapitre, avec les clés communes et un "contenu": {} vide. Et pour les fichiers : si chacun ajoutait ses objets, ses fichiers et ses import plus tard, vous modifieriez tous les deux les mêmes lignes de style.css et de main.js, et le conflit serait garanti.