GSAP, le timing et la musique

dans la ou les catégorie(s) : code et avec pour étiquette(s) :

À partir d’une petite boucle de batterie, voici comment travailler sur une pulsation avec GSAP.
Les timelines de GSAP utilisent comme unité de temps la seconde, la musique se base sur le BPM, battements par minute.

  • À 60 bpm, un temps par seconde, 0s 1s 2s 3s donne la pulsation ;
  • À 120 bpm (le tempo de la Marseillaise) 2 temps par seconde, 0s 0.5s 1s 1.5s donne la pulsation ;
  • À 88 bpm, c’est plus complexe, 0s 0.6818s 1.3636s 2.04545s (60/88*t)

GSAP a une fonction pour accélérer ou décélérer les timelines !

tl.timeScale(2); // double la vitesse
tl.timeScale(0.5); // divise par 2 la vitesse

L’astuce est de compter le nombre de temps dans l’extrait musical et de faire un timeScale(nombre de temps/durée de l’extrait).

Voici ma boucle de 8 temps.
http://www.orangefreesounds.com/funk-drum-loop/, elle dure 5,333333 secondes.

En écriture musicale de boite à rythmes sur https://drumbit.app/, j’obtiens ceci pour les 4 derniers temps (une petite variation d’ouverture de hit‐hat):


beats.json à importer

La base SVG

Je vais utiliser 3 cercles, un rouge pour la grosse caisse (BD), un orange pour la caisse claire (SD) et un dernier jaune pour l’ouverture de la charleston.

  <svg width="800px" height="800px">
    <circle id="ho" cx="400" cy="400" r="50" fill="yellow"/>
    <circle id="sd" cx="500" cy="400" r="50" fill="#f60"/>
    <circle id="bd" cx="300" cy="400" r="50" fill="red"/>
  </svg>

Pour le son, je copie/colle pour créer une répétition.
Version 1 fois


Version 4 fois

GSAP est chargé via <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js"></script>

Le reste est en commentaire sur le code.

var audio = document.querySelector("audio");
var duration = 5.333333; // durée des 8 temps en seconde;
var beat = 8;
 
var tl = new TimelineMax({repeat:4}); 
tl.pause(); // antidémarrage 
tl.set("circle", { transformOrigin: "center center", opacity: 0 }); // réglage important pour le scale
 
/* la grosse caisse */
tl.to("#bd", 0.1, { scale: 4, opacity: 0.5 }, 0); // zoom rapide à 0 = 1er temps
tl.to("#bd", 0.9, { scale: 1, opacity: 0.0 }, 0.1); // dézoom à 0.1 temps pendant 0.9 temps
tl.to("#bd", 0.1, { scale: 4, opacity: 0.5 }, 2); // 2 = 3e temps
tl.to("#bd", 0.1, { scale: 1, opacity: 0.0 }, 2.1);
tl.to("#bd", 0.1, { scale: 4, opacity: 0.5 }, 2.5); // 2.5 = contretemps du 3e temps
tl.to("#bd", 0.1, { scale: 1, opacity: 0.0 }, 2.6);
 
/* (…) */
 
tl.to("#sd", 0.1, { scale: 4, opacity: 0.5 }, 1); // 1 = 2e temps
tl.to("#sd", 0.1, { scale: 1, opacity: 0.0 }, 1.1);
 
/* (…) */
 
tl.to("#ho", 0.4, { scale: 8, opacity: 0.5 }, 6.5); // 6.5 = contretemps du 3e temps de la 2e mesure à 4 temps
tl.to("#ho", 0.1, { scale: 0, opacity: 0 }, 6.9);
 
/* l'astuce */
tl.timeScale(beat / duration);
 
 
audio.addEventListener("play", function() {
  tl.play(0); // lecture quand on clique sur play
});
 
audio.addEventListener("pause", function() {
  tl.pause();
});

Version Codepen

See the Pen GSAP & BPM by Benoît Wimart (@benoitwimart) on CodePen.0

Interaction SVG, chemin et temps

dans la ou les catégorie(s) : code

Sur cet exemple, je vais effacer un tracé vectoriel selon le temps qui s’écoule.
La première étape consiste à dessiner le tracé sous Illustrator ou autres et l’exporter en SVG.

Une fois le SVG préparé, on l’ouvre avec un éditeur (VS Code), on ajoute un id sur la balise path et enfin un peu de CSS.

See the Pen svg, chemin et temps 01 by Benoît Wimart (@benoitwimart) on CodePen.0

À cette étape, il faut mesurer la taille du chemin… pas besoin de calcul savant, on va jouer avec la taille des pointillés. J’ajoute stroke-dasharray:0px sur mon id et avec l’inspecteur je modifie la valeur avec les flèches et la touche maj.

J’obtiens le chiffre magique de ‘4891px’, j’ajoute la même valeur en offset et le tracé disparait.

  #jens{
    stroke:#f60;
    stroke-width: 6px;
    stroke-linejoin: round;
    stroke-linecap: round;
    stroke-dashoffset: 4891px; /* 0 trait*/
    stroke-dasharray:  4891px; 
  }

Un codepen avec la moitié du tracé :

See the Pen svg, chemin et temps 02 by Benoît Wimart (@benoitwimart) on CodePen.0

Un peu de JavaScript

var d = new Date().getSeconds(); // le nombre de secondes 16:42:18 -> 18
var jens = document.querySelector('#jens'); // le chemin 
jens.style.strokeDashoffset = d * (4891/60) + "px"; // calcul et changement du style

Avec ce code, à chaque ouverture de la page, le chemin s’efface selon le nombre de secondes écoulées depuis la dernière minute.

See the Pen svg, chemin et temps 03 by Benoît Wimart (@benoitwimart) on CodePen.0

Version animée (requestAnimationFrame lance ou relance la fonction en visant les 60 fps)

See the Pen svg, chemin et temps 04 by Benoît Wimart (@benoitwimart) on CodePen.0

entrainement JavaScript (partie 2)

dans la ou les catégorie(s) : code

Voici une petite illustration d’un sélecteur multiple associé à une concaténation et une transformation CSS.

See the Pen 50 paragraphes by Benoît Wimart (@benoitwimart) on CodePen.0

Autre exemple, avec en prérequis :

  • les animations CSS
  • Les chaines de caractères sont comme des tableaux de signes "abc"[0]; // "a"; "abc"[1]; // "b"

Le code va emballer chaque lettre dans une <span> avec sur l’attribut style un délai d’animation ; le reste est en CSS.

See the Pen span automatique by Benoît Wimart (@benoitwimart) on CodePen.0

Entrainement :

  • changer le CSS et le JS (pour mieux comprendre le code)
  • faire une boucle pour mettre dans des span et appliquer le code du premier exemple sur celles‐ci.

Le faux gras

Le faux gras est un problème courant sur le web (attention, je ne parle pas de faux foie‐gras) ; il se manifeste quand vous utilisez une police sans « version bold » dans un style gras. Le navigateur ajoute alors un contour sur le caractère et le résultat n’est plus correct, on perd en lisibilité, les « trous » se bouchent et le texte est gonflé.

La faute à ?

Il n’y a pas de coupable, juste une logique d’ordinateur qui va compenser l’absence du fichier correcte par un effet. La bonne graisse n’est pas sur votre ordinateur ou n’est pas chargée en @font-face (via Google Fonts, autres ou à la main), le navigateur prend alors la graisse existante et « se débrouille ».
Le problème n’est pas nouveau, s’applique aussi au print et existe aussi en version faux italique (oblique)

Voici un exemple de faux gras (passez la souris sur le texte pour voir la version corrigée).
Je charge une typo avec Google et cette feuille de styles :

/* latin */
@font-face {
  font-family: 'Fredoka One';
  font-style: normal;
  font-weight: 400;
  src: local('Fredoka One'), local('FredokaOne-Regular'), url(https://fonts.gstatic.com/s/fredokaone/v6/k3kUo8kEI-tA1RRcTZGmTlHGCaen8wf-.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

La graisse (font‐weight) de 400 correspond à normal (contre 700 pour Bold).


Récapitulation des chiffres :
100 Thin (Hairline)
200 Extra Light (Ultra Light)
300 Light
400 Normal
500 Medium
600 Semi Bold (Demi Bold)
700 Bold
800 Extra Bold (Ultra Bold)
900 Black (Heavy)

J’utilise un h1, qui sera par défaut en gras.

<h1>faux-gras</h1>

See the Pen faux gras by Benoît Wimart (@benoitwimart) on CodePen.0

L’art du bon @font-face

Attention à vos @font-face, voici la bonne manière de définir une famille de graisses :

@font-face {
  font-family: 'Fredoka';
  font-style: normal;
  font-weight: 400;
  src:; /* le ou les fichiers du Fredoka regular */
}
@font-face {
  font-family: 'Fredoka'; /* le même nom */
  font-style: normal;
  font-weight: 700; /* ici c'est 700 */
  src: /* le ou les fichiers du Fredoka Bold */ ;
}

Voici une manière déconseillée :

@font-face {
  font-family: 'Fredoka';
  font-style: normal;
  font-weight: 400;
  src:; /* le ou les fichiers du Fredoka regular */
}
@font-face {
  font-family: 'Fredoka Bold'; /* le nom avec la graisse  */
  font-style: normal;
  font-weight: 700; 
  src: /* le ou les fichiers du Fredoka Bold */ ;
}

Qui donnera ce genre d’écriture :

body{
  font-family: 'Fredoka';
}
h1{
  font-family: 'Fredoka Bold'; /* sinon : faux gras */
}

code, bug et web

dans la ou les catégorie(s) : code

Pratiquer le code apporte de la joie et des problèmes. Réussir une mise en page, finaliser un projet peut être comparable à terminer un puzzle, imbriquer des pièces de Tetris, empiler des cartes ou optimiser le chargement d’un camion de déménagement. Hélas, parfois il manque une pièce au puzzle ou le dernier carton ne rentre pas.

Pour la pièce manquante, avec beaucoup de frustration et si près du but il faudra chercher ou faire avec… et pour le carton, sortir quelques éléments, prendre du recul, recommencer ou prévoir un trajet de plus. Aborder un problème de code est très similaire.

En programmation, les langages évoluent et s’adaptent aux nouveaux besoins. Certains changements solutionnent des problèmes et certaines envies en créent de nouveaux. Vouloir une position « fixe(d) » sur une page peut devenir complexe et résoudre cette mise en page engendre parfois d’autres problèmes.

Je suis graphiste

#Métaphore
Si vous découvrez Illustrator et que votre seule compétence est l’outil rectangle ; vous pouvez déjà faire un logo et peut‐être même un excellent logo. Personne ne va vérifier votre niveau d’Illustrator.

Pour les mises en page web, pour commencer il faut savoir s’imposer des limites techniques et toujours opter pour la simplicité.
Je classe les problèmes en deux catégories les bugs mineurs et les autres.
Un bug mineur est un problème d’affichage qui ne perturbe pas le fonctionnement du site et qui ne se voit pas forcement ; un bug présent sur un seul navigateur qui rend la mise en page différente, un peu moins bien, mais « supportable ».
Pour les autres bugs primordiaux…

Ça ne marche pas

L’inspecteur (Chrome ou Firefox) est l’outil le plus efficace, vérifiez l’imbrication du HTML et la bonne écriture du CSS.
Un onglet réseau permet de vérifier le bon chargement des éléments, un rapide coup d’œil peut mieux expliquer le problème.
Un code mal écrit partiellement peut casser le reste de la page, une solution automatique consiste à utiliser le validateur W3C et voir si des balises sont bien ouvertes et fermées.
Si les problèmes persistent, un peu de rangement de code (Beautify, Formater) s’impose.

Ça ne marche toujours pas

Trois voies possibles, résoudre le problème en solo, avec un ami ou avec Internet.
Pour ces trois choix, isoler le problème, refaire une simulation minimum du problème s’impose.

#Métaphore
Si vous écrivez un roman et que vous demandez à des personnes inconnues de corriger vos 300 pages, vous devriez avoir peu de candidats. Par contre, si vous avez un doute sur une règle d’écriture sur une phrase, une expression ou un mot, les amoureux de la langue seront volontaires pour vous éclairer. Les langages de programmation suivent ces mêmes règles, favorisant la pédagogie et sachant différencier une aide, d’un travail.

Bien poser sa question est un exercice difficile et parfois amène la réponse, beaucoup de forums contiennent des « self reply » postés quelques minutes après la question.

Un exemple de code problématique peut être poster sur CodePen ou jsbin en utilsant un service comme DummyImage pour les images.

La Faune et la fonte #cnap

Bien utiliser @font-face n’est pas toujours simple, voici un exemple avec le caractère Faune.
Le Faune est « Un caractère typographique créé par Alice Savoie » pour « Une commande du Centre national des arts plastiques ».
Un excellent site explique le projet à cette adresse : http://www.cnap.graphismeenfrance.fr/faune/.

Néanmoins, à l’heure actuelle le site étant en « http », si votre site est en « https », la méthode de la feuille de style liée (comme sur Google Font), ne marchera pas sur les navigateurs modernes.

<link rel='stylesheet' href='http://www.cnap.graphismeenfrance.fr/faune/styles/faune-fontes.css'><!-- pas en https -->

La solution consiste à télécharger la fonte (en .zip sur le site).

Renommer le dossier Webfonts (en bleu sur l’image) en « fonts ».
Copier ce dossier « fonts » dans le même dossier que votre feuille de styles.
Ajouter ce code au début de votre feuille de styles :

@font-face {
  font-family: Faune;
  src: url(fonts/eot/Faune-Display_Thin.eot);
  src: url(fonts/eot/Faune-Display_Thin.eot?#iefix) format("embedded-opentype"),
       url(fonts/woff2/Faune-Display_Thin.woff2) format("woff2"),
       url(fonts/woff/Faune-Display_Thin.woff) format("woff"),
       url(fonts/ttf/Faune-Display_Thin.ttf) format("truetype"),
       url(fonts/svg/Faune-Display_Thin.svg#Faune-Display_Thin) format("svg");
  font-weight: 100;
  font-style: normal
}
 
@font-face {
  font-family: Faune;
  src: url(fonts/eot/Faune-Text_Bold.eot);
  src: url(fonts/eot/Faune-Text_Bold.eot?#iefix) format("embedded-opentype"),
       url(fonts/woff2/Faune-Text_Bold.woff2) format("woff2"),
       url(fonts/woff/Faune-Text_Bold.woff) format("woff"),
       url(fonts/ttf/Faune-Text_Bold.ttf) format("truetype"),
       url(fonts/svg/Faune-Text_Bold.svg#Faune-Bold) format("svg");
  font-weight: 700;
  font-style: normal
}
 
@font-face {
  font-family: Faune;
  src: url(fonts/eot/Faune-Text_Italic.eot);
  src: url(fonts/eot/Faune-Text_Italic.eot?#iefix) format("embedded-opentype"),
       url(fonts/woff2/Faune-Text_Italic.woff2) format("woff2"),
       url(fonts/woff/Faune-Text_Italic.woff) format("woff"),
       url(fonts/ttf/Faune-Text_Italic.ttf) format("truetype"),
       url(fonts/svg/Faune-Text_Italic.svg#Faune-Text_Italic) format("svg");
  font-weight: 400;
  font-style: italic
}
 
@font-face {
  font-family: Faune;
  src: url(fonts/eot/Faune-Display_Black.eot);
  src: url(fonts/eot/Faune-Display_Black.eot?#iefix) format("embedded-opentype"),
       url(fonts/woff2/Faune-Display_Black.woff2) format("woff2"),
       url(fonts/woff/Faune-Display_Black.woff) format("woff"),
       url(fonts/ttf/Faune-Display_Black.ttf) format("truetype"),
       url(fonts/svg/Faune-Display_Black.svg#Faune-Display_Black) format("svg");
  font-weight: 900;
  font-style: normal
}
 
@font-face {
  font-family: Faune;
  src: url(fonts/eot/Faune-Display_Bold_Italic.eot);
  src: url(fonts/eot/Faune-Display_Bold_Italic.eot?#iefix) format("embedded-opentype"),
       url(fonts/woff2/Faune-Display_Bold_Italic.woff2) format("woff2"),
       url(fonts/woff/Faune-Display_Bold_Italic.woff) format("woff"),
       url(fonts/ttf/Faune-Display_Bold_Italic.ttf) format("truetype"),
       url(fonts/svg/Faune-Display_Bold_Italic.svg#Faune-Display_Bold_Italic) format("svg");
  font-weight: 700;
  font-style: italic
}
 
@font-face {
  font-family: Faune;
  src: url(fonts/eot/Faune-Text_Regular.eot);
  src: url(fonts/eot/Faune-Text_Regular.eot?#iefix) format("embedded-opentype"),
       url(fonts/woff2/Faune-Text_Regular.woff2) format("woff2"),
       url(fonts/woff/Faune-Text_Regular.woff) format("woff"),
       url(fonts/ttf/Faune-Text_Regular.ttf) format("truetype"),
       url(fonts/svg/Faune-Text_Regular.svg#Faune-Text_Regular) format("svg");
  font-weight: 400;
  font-style: normal
}

Explications

Chaque @font-face donne le nom « Faune » au caractère, chaque src correspond aux fichiers sources pour les différents navigateurs (internet Explorer, Safari, Chrome, Firefox…). Le font-weight et le font-style définissent la graisse et le style des fichiers sources, cela permet d’avoir le vrai italique et la bonne graisse automatiquement.

Si vous avez réussi ce code, la font-family pourra être appliqué en CSS :

font-family: 'Faune', sans-serif;
Attention ! Si la fonte est déjà sur votre ordinateur, un test sur celui‐ci ne prouve pas un CSS correctement écrit, pensez à désactiver la police temporairement. Vérifiez deux fois que les fichiers sont dans les bons dossiers ! Testez sur une autre machine !

Bap s01e01 et s01e02

dans la ou les catégorie(s) : code

épisode 2

Pour profiter de cette période de vacances, je vous propose de découvrir comment coder en Javascript pour faire de la musique.
Mon choix s’est porté sur la librairie Bap, relativement complète et inspirée du MPC, elle semble moins populaire que P5JS, mais à quelques avantages.

Pour cette première approche, je ne charge pas de son (sample) et n’utilise pas d’effect. Par la suite, nous verrons comment faire avec de vrais sons et interagir avec la boucle ou créer des phrases rythmiques selon des données (variables).

See the Pen BAP JS s01e01 by Benoît Wimart (@benoitwimart) on CodePen.0

épisode 2

See the Pen BAP JS s01e02 by Benoît Wimart (@benoitwimart) on CodePen.0

source image