Cours 13¶
Zdog¶

Zdog est une petite librairie JavaScript pour créer des illustrations pseudo-3D “flat” (sans perspective) et animées, à partir de formes simples (cercles, rectangles, cylindres, etc.).
Sa particularité est que les objets existent en 3D, mais sont rendus comme des formes 2D plates, ce qui donne un look illustratif plutôt qu’un rendu 3D réaliste.
Zdog n’est pas une vraie librairie 3D comme threejs, mais plutôt un petit moteur pseudo-3D très simplifié.
Installation¶
<html>
<head>
<script type="importmap">
{
"imports": {
"zzz": "https://esm.sh/zdog"
}
}
</script>
<script type="module" src="./src/js/zdog.js"></script>
</head>
<body>
<canvas class="zdog-canvas"></canvas>
</body>
</html>
.zdog-canvas {
width: 90vw;
height: 90vh;
}
import Zdog from "zzz";
const illo = new Zdog.Illustration({
element: ".zdog-canvas",
resize: true, // canvas responsive
});
new Zdog.Ellipse({
addTo: illo,
diameter: 100,
stroke: 40,
color: "#E49",
});
illo.updateRenderGraph(); // 👈 Dessine dans le canvas
Interactivité¶
import Zdog from "zzz";
const illo = new Zdog.Illustration({
// ...
dragRotate: true, // 👈
});
// 👇 Nécessaire pour l'interactivité
function animate() {
illo.updateRenderGraph();
requestAnimationFrame(animate);
}
animate();
Bloquer un axe¶
import Zdog from "zzz";
const illo = new Zdog.Illustration({
// ...
dragRotate: true,
onDragMove: function() {
this.rotate.x = 0;
},
});
Animation¶
import Zdog from "zzz";
const illo = new Zdog.Illustration({
// ...
});
function animate() {
illo.rotate.y += 0.03; // 👈 360° = 2π
illo.rotate.x += 0.03; // 👈 360° = 2π
illo.updateRenderGraph();
requestAnimationFrame(animate);
}
animate();
Formes¶

Les formes zdog (Rect, RoundedRect, Ellipse, Polygon, Shape, Hemisphere, Cone, Cylinder, Box) sont pour la plupart assez simples à mettre en place. Il suffit de consulter la documentation à cet effet.
AnimeJS¶
Yep ! Ça se fait. Et assez facilement même.
Avec AnimeJS, on peut animer des variables. Ces mêmes variables seront utilisées pour changer les transformations Zdog.
import Zdog from "zzz";
import { animate, utils } from 'animejs';
let illo = new Zdog.Illustration({
element: ".zdog-canvas",
resize: true
});
let box = new Zdog.Box({
addTo: illo,
// ...
});
const rotationAnimation = { x: 0, y: 0, z: 0 };
const getRandomRotation = () => utils.random(0, Math.PI * 2, 2);
animate(rotationAnimation, {
x: getRandomRotation,
y: getRandomRotation,
z: getRandomRotation,
duration: 2000,
loop: true,
ease: "outElastic",
onUpdate: () => {
box.rotate.x = rotationAnimation.x;
box.rotate.y = rotationAnimation.y;
box.rotate.z = rotationAnimation.z;
},
onLoop: (self) => {
self.refresh();
}
});
function animateZDOG() {
illo.updateRenderGraph();
requestAnimationFrame(animateZDOG);
}
animateZDOG();
Tone.js¶

Tone.js est une librairie JavaScript pour créer et manipuler du son dans le navigateur. Elle permet de générer des sons avec des synthétiseurs, de jouer des fichiers audio, d'appliquer des effets sonores et de créer des séquences musicales.
Installation¶
<html>
<head>
<script type="importmap">
{
"imports": {
"tone.js": "https://esm.sh/tone@15.1.22",
}
}
</script>
<script type="module" src="./src/js/tonejs.js"></script>
</head>
<body>
<button>♬</button>
</body>
</html>
import * as Tone from "tone.js";
document.querySelector("button").addEventListener("click", async () => {
await Tone.start();
const synth = new Tone.Synth().toDestination();
synth.triggerAttackRelease("C4", "8n");
});
Quelques notions importantes
Notation anglo-saxonne :
C D E F G A B (Do Ré Mi Fa Sol La Si)
Ex: C4, le 4 représente l'octave
Notation rythmique :
1n: ronde2n: blanche (demi-note)4n: noire (quart de note)8n: croche (huitième de note)16n: double-croche (seizième de note)
Instruments¶
import * as Tone from "tone.js";
document.querySelector("button").addEventListener("click", async () => {
await Tone.start();
const synth = new Tone.Synth().toDestination();
synth.triggerAttackRelease("C4", "8n");
const fmSynth = new Tone.FMSynth().toDestination();
fmSynth.triggerAttackRelease("C3", "4n");
const drum = new Tone.MembraneSynth().toDestination();
drum.triggerAttackRelease("C2", "4n");
// ...
});
Liste des instruments et leurs paramètres.
Polyphonie / accords¶
import * as Tone from "tone.js";
document.querySelector("button").addEventListener("click", async () => {
await Tone.start();
const synth = new Tone.PolySynth(Tone.Synth).toDestination();
synth.triggerAttackRelease(["C4", "E4", "G4"], "4n");
});
Suite¶
import * as Tone from "tone.js";
const synth = new Tone.Synth().toDestination();
document.querySelector("button").addEventListener("click", async () => {
await Tone.start();
const now = Tone.now();
synth.triggerAttackRelease("C4", "8n", now + 0.0);
synth.triggerAttackRelease("D4", "8n", now + 0.25);
synth.triggerAttackRelease("E4", "8n", now + 0.5);
synth.triggerAttackRelease("F4", "8n", now + 0.75);
synth.triggerAttackRelease("G4", "8n", now + 1.0);
synth.triggerAttackRelease("A4", "8n", now + 1.25);
synth.triggerAttackRelease("B4", "8n", now + 1.5);
synth.triggerAttackRelease("c5", "2n", now + 1.75);
});
Fichiers¶
import * as Tone from "tone.js";
const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();
document.querySelector("button").addEventListener("click", async () => {
await Tone.start();
Tone.loaded().then(() => {
player.start();
});
});
Base de données de fichiers audio gratuits.
Effets¶
import * as Tone from "tone.js";
document.querySelector("button").addEventListener("click", async () => {
const now = Tone.now();
// Synth -> Delay -> Reverb -> 🔈
const reverb = new Tone.Reverb(2).toDestination();
const delay = new Tone.FeedbackDelay("8n", 0.5).connect(reverb);
const synthWithReverb = new Tone.Synth().connect(delay);
synthWithReverb.triggerAttackRelease("A4", "2n", now + 5);
});
Liste des effets et leurs paramètres.
.toDestination()
Imaginez le .toDestination() comme si on disait que c'était branché dans le haut-parleur 🔈.
Typed.js¶

Typed.js est une librairie JavaScript qui simule la frappe de texte au clavier. Elle affiche du texte lettre par lettre, comme si quelqu'un le tapait en temps réel, avec des options pour contrôler la vitesse, les pauses et les boucles.
Installation¶
npm i typed.js
<html>
<head>
<script type="importmap">
{
"imports": {
"typed.js": "./node_modules/typed.js/dist/typed.module.js",
}
}
</script>
<script type="module" src="./src/js/typedjs.js"></script>
</head>
<body>
<p>
<span id="typedjs-elem"></span>
</p>
</body>
</html>
import Typed from 'typed.js';
new Typed("#typedjs-elem", {
strings: [
"Typed.js est une <strong>librairie</strong> JavaScript.",
"Elle <em>simule la frappe</em> de phrases, comme si quelqu’un les tapait au clavier."
],
typeSpeed: 50,
loop: true
});
Snippet du jour¶
npm i tone-visualizer
<!DOCTYPE html>
<html lang="fr">
<head>
<script src="https://cdn.jsdelivr.net/npm/p5@2.1.1/lib/p5.js"></script>
<script type="importmap">
{
"imports": {
"tone.js": "https://esm.sh/tone@15.1.22",
"tone-visualizer": "./node_modules/tone-visualizer/dist/visualizer.esm.js"
}
}
</script>
<script type="module" src="./src/js/script.js"></script>
</head>
<body>
<div class="visualizer"></div>
</body>
</html>
import * as Tone from "tone.js";
import { ToneVisualizer } from "tone-visualizer";
document.body.addEventListener("click", async () => {
await Tone.start();
const fmSynth = new Tone.FMSynth().toDestination();
const viz = new ToneVisualizer('.visualizer', fmSynth, {Tone});
fmSynth.triggerAttackRelease("C3", "4n");
});
Exercices¶

Exercice - Tone.js
La cinquième

Exercice - Zdog
Éclipse
TP2¶

TP
HUD