Annuaire › Code ouvert
Code publié par son auteur, en lecture seule. « Copier dans mon espace » crée un nouveau site à vous (non publié) que vous pouvez modifier librement.
js/horloge.js · 6.9 Ko
/* ============================================================
horloge.js - le cadran et les aiguilles
============================================================
Idée clé : on se place AU CENTRE du cadran avec translate(),
et on dessine chaque aiguille "pointée vers le haut" ; il suffit
ensuite de TOURNER le repère avec rotate() pour la placer.
RAPPEL : rotate() travaille en RADIANS par défaut.
un tour complet = TWO_PI (≈ 6,283) ; un demi-tour = PI.
Avec une aiguille dessinée vers le haut (y négatif), l'angle 0
correspond à "12 h" et l'angle augmente dans le sens des
aiguilles d'une montre. Pratique !
============================================================ */
/* ------------------------------------------------------------
lireHeure(heureSimulee)
But : obtenir l'heure à afficher.
- Si heureSimulee est un nombre (curseur de la page), on le
convertit en heures / minutes / secondes.
- Sinon on utilise les fonctions p5 hour(), minute(), second()
qui lisent l'heure LOCALE de l'appareil.
Paramètre : heureSimulee = nombre (ex. 14.5) ou null
Retour : {h, m, s, decimal} avec decimal = heure en nombre
décimal (14 h 30 -> 14.5)
------------------------------------------------------------ */
function lireHeure(heureSimulee) {
if (heureSimulee !== null) {
const h = floor(heureSimulee); // partie entière = heures
const reste = (heureSimulee - h) * 60; // la partie décimale, en minutes
const m = floor(reste);
const s = floor((reste - m) * 60);
return { h: h, m: m, s: s, decimal: heureSimulee };
}
const h = hour(); // 0 à 23
const m = minute(); // 0 à 59
const s = second(); // 0 à 59
return { h: h, m: m, s: s, decimal: h + m / 60 + s / 3600 };
}
/* ------------------------------------------------------------
formaterDeuxChiffres(n)
But : écrire 5 sous la forme "05" (pour afficher 09:05:03).
p5 offre nf(n, 2) qui fait exactement cela.
------------------------------------------------------------ */
function formaterDeuxChiffres(n) {
return nf(n, 2);
}
/* ------------------------------------------------------------
dessinerGraduations(r, encre)
But : dessiner les 60 petits traits du cadran (un plus long
toutes les 5 graduations = les heures).
Paramètres : r = rayon du cadran, encre = couleur des traits
------------------------------------------------------------ */
function dessinerGraduations(r, encre) {
stroke(encre);
for (let i = 0; i < 60; i++) {
push();
rotate(i * TWO_PI / 60); // 60 positions autour du cercle
const grand = (i % 5 === 0); // % = reste de la division : vrai toutes les 5 graduations
strokeWeight(grand ? r * 0.03 : r * 0.012);
const longueur = grand ? r * 0.1 : r * 0.045;
line(0, -r * 0.93, 0, -r * 0.93 + longueur); // trait vertical près du bord haut
pop();
}
}
/* ------------------------------------------------------------
dessinerChiffres(r, encre)
But : écrire les chiffres 1 à 12 autour du cadran.
Pour placer un chiffre sur le cercle, on utilise la
trigonométrie : x = sin(angle) * rayon ; y = -cos(angle) * rayon
(le signe "-" car y est orienté vers le bas).
------------------------------------------------------------ */
function dessinerChiffres(r, encre) {
noStroke();
fill(encre);
textAlign(CENTER, CENTER); // le texte est centré sur le point donné
textSize(r * 0.15);
for (let i = 1; i <= 12; i++) {
const angle = i * TWO_PI / 12;
text(i, sin(angle) * r * 0.74, -cos(angle) * r * 0.74);
}
}
/* ------------------------------------------------------------
dessinerAiguille(angle, longueur, epaisseur, couleur)
But : dessiner UNE aiguille tournée de "angle" radians.
Paramètres :
angle : 0 = vers le haut (12 h)
longueur : en pixels
epaisseur : épaisseur du trait
couleur : couleur du trait
push()/pop() isolent la rotation : elle ne touche pas aux
autres aiguilles.
------------------------------------------------------------ */
function dessinerAiguille(angle, longueur, epaisseur, couleur) {
push();
rotate(angle);
stroke(couleur);
strokeWeight(epaisseur);
strokeCap(ROUND); // extrémités arrondies
line(0, longueur * 0.12, 0, -longueur); // petite "queue" derrière le centre
pop();
}
/* ------------------------------------------------------------
dessinerHorloge(t, cx, cy, r, nuit)
But : dessiner le cadran complet avec les trois aiguilles.
Paramètres :
t : l'heure ({h, m, s}) renvoyée par lireHeure()
cx, cy : centre du cadran dans le canevas
r : rayon du cadran
nuit : 0 (plein jour) à 1 (nuit) ; le cadran devient sombre la nuit
------------------------------------------------------------ */
function dessinerHorloge(t, cx, cy, r, nuit) {
// Couleurs du cadran : claires le jour, sombres la nuit (mélange selon "nuit").
const fondCadran = lerpColor(color(255, 250, 240, 225), color(18, 28, 58, 225), nuit);
const encre = lerpColor(color(30, 40, 60), color(240, 240, 230), nuit);
push(); // sauvegarde l'état de dessin
translate(cx, cy); // (0, 0) = centre du cadran à partir d'ici
// Disque du cadran
stroke(encre);
strokeWeight(r * 0.035);
fill(fondCadran);
circle(0, 0, r * 2); // circle(x, y, DIAMÈTRE)
dessinerGraduations(r, encre);
dessinerChiffres(r, encre);
// Petit texte « ANTALAHA » et heure numérique
noStroke();
fill(encre);
textAlign(CENTER, CENTER);
textSize(r * 0.075);
text('ANTALAHA', 0, -r * 0.38);
textSize(r * 0.13);
text(formaterDeuxChiffres(t.h) + ':' + formaterDeuxChiffres(t.m), 0, r * 0.42);
// --- Calcul des angles ---
// map(valeur, minAvant, maxAvant, minAprès, maxAprès) :
// ici on convertit une durée en angle (0 à TWO_PI = un tour complet).
// Aiguille des secondes : 60 s = un tour.
const angleSecondes = map(t.s, 0, 60, 0, TWO_PI);
// Aiguille des minutes : 60 min = un tour ; les secondes la font avancer en douceur.
const angleMinutes = map(t.m + t.s / 60, 0, 60, 0, TWO_PI);
// Aiguille des heures : 12 h = un tour (on utilise % 12 : 15 h -> 3 h) ;
// les minutes la font avancer en douceur aussi.
const angleHeures = map((t.h % 12) + t.m / 60, 0, 12, 0, TWO_PI);
// L'ordre compte : la trotteuse est dessinée en dernier pour être au-dessus.
dessinerAiguille(angleHeures, r * LONGUEUR_AIGUILLE_HEURE, r * 0.07, encre);
dessinerAiguille(angleMinutes, r * LONGUEUR_AIGUILLE_MINUTE, r * 0.045, encre);
dessinerAiguille(angleSecondes, r * LONGUEUR_AIGUILLE_SECONDE, r * 0.02, color(COULEUR_TROTTEUSE));
// Pastille centrale
noStroke();
fill(COULEUR_TROTTEUSE);
circle(0, 0, r * 0.09);
pop(); // on revient à l'état sauvegardé (origine en haut à gauche)
}