JavaScript : valeur aléatoire d'une propriété CSS

HTML5, CSS3, Javascript, support des mobiles... Que penser de votre site ? Vous manquez d'informations pour la construction d'un site qui puisse s'afficher correctement partout ? C'est un problème simple, un peu complexe ? Venez ici !
Nicosmos
Iguane
Messages : 633
Inscription : 20 août 2005, 14:17

JavaScript : valeur aléatoire d'une propriété CSS

Message par Nicosmos »

Hello !
Je crois que ça fait des années que je n'ai rien posté ici. :)

Je ne suis pas très bon en JavaScript. Je débute même. Je prévois de commencer par la théorie un jour, mais pour le moment, pas le temps, et j'ai des petites choses à faire avec malgré tout. Voilà mon problème. J'ai un titre dont chaque lettre est isolée dans un span avec un id différent (solution temporaire, j'y reviendrais après). Je veux légèrement déplacer chaque lettre sur les deux axes en sélectionnant aléatoirement entre trois valeurs (neuf positions par lettre, donc) appliquées à une propriété CSS transform.

Pour le moment, j'ai ça dans l'HTML :

Code : Tout sélectionner

<h1>
  <a href='#' onclick='melange();'>
      <span id='c01'>p</span><!--
   --><span id='c02'>r</span><!--
   --><span id='c03'>o</span><!--
   --><span id='c04'>b</span><!--
   --><span id='c05'>a</span><!--
   --><span id='c06'>b</span><!--
   --><span id='c07'>l</span><!--
   --><span id='c08'>e</span><!--
   --><span id='c09'>m</span><!--
   --><span id='c10'>e</span><!--
   --><span id='c11'>n</span><!--
   --><span id='c12'>t</span>
  </a>
 </h1>
Et ceci dans le JS :

Code : Tout sélectionner

// agitateur de titre
// le code le plus redondant de l'univers

var valeurs = new Array("-5","0","5");

function alea() {
 position = valeurs[Math.floor(Math.random()*valeurs.length)];
}

function melange() {
 var lettre01 = document.getElementById('c01');
 var lettre02 = document.getElementById('c02');
 var lettre03 = document.getElementById('c03');
 var lettre04 = document.getElementById('c04');
 var lettre05 = document.getElementById('c05');
 var lettre06 = document.getElementById('c06');
 var lettre07 = document.getElementById('c07');
 var lettre08 = document.getElementById('c08');
 var lettre09 = document.getElementById('c09');
 var lettre10 = document.getElementById('c10');
 var lettre11 = document.getElementById('c11');
 var lettre12 = document.getElementById('c12');
 
 alea(); lettre01.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre01.style.transform = lettre01.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre02.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre02.style.transform = lettre02.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre03.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre03.style.transform = lettre03.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre04.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre04.style.transform = lettre04.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre05.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre05.style.transform = lettre05.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre06.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre06.style.transform = lettre06.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre07.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre07.style.transform = lettre07.style.transform + "translateY(" + position + "px)";
 
 alea(); lettre08.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre08.style.transform = lettre08.style.transform + "translateY(" + position + "px)";
  
 alea(); lettre09.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre09.style.transform = lettre09.style.transform + "translateY(" + position + "px)";
  
 alea(); lettre10.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre10.style.transform = lettre10.style.transform + "translateY(" + position + "px)";
  
 alea(); lettre11.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre11.style.transform = lettre11.style.transform + "translateY(" + position + "px)";
  
 alea(); lettre12.style.transform =                            "translateX(" + position + "px)";
 alea(); lettre12.style.transform = lettre12.style.transform + "translateY(" + position + "px)";
}
Ça marche plutôt bien. Cependant :
  • transform ne fonctionne que sur les navigateurs ayant dépréfixé cette propriété. C'est-à-dire Mozilla et Microsoft. Il faudrait aussi que je fasse des (-webkit/-o/-ms/-moz)-transform pour que ça marche chez tout le monde. Or, mon code est déjà ultra redondant.
  • Précisément : c'est ultra redondant. Je pense que je pourrais systématiser ça en écrivant une seule fois ce que je veux faire, puis appliquer ça à chaque lettre (en sachant que les valeurs aléatoires doivent être différente pour chaque axe de chaque caractère), mais je ne sais pas du tout comment faire.
  • La soupe de balises dans l'html est temporaire. J'aimerais utiliser lettering.js ou équivalent pour générer les span dynamiquement (ou invisiblement). lettering.js applique des class et non des id aux span, mais je n'arrive pas à les sélectionner après. getElementsByClass() ne semble pas fonctionner comme getElementById(). Idéalement en fait, j'aimerais même simplement sélectionner chaque enfant (un h1 a > span ou h1 a > * en CSS) et leur appliquer la transformation. Là encore, je ne vois pas comment faire.
SOS ! :D
Merci beaucoup,
Bon week-end,
Nicolas.
calimo
Animal mythique
Messages : 14118
Inscription : 26 déc. 2003, 11:51

Re: JavaScript : valeur aléatoire d'une propriété CSS

Message par calimo »

Salut,

Tu as besoin de 2 choses : premièrement les fonctions (pour factoriser ton code, tu appelles une "fonction" générique que tu peux appliquer à n'importe quoi, comme tu as fait pour la fonction alea()), et deuxièmement, les boucles (pour répéter quelque chose avec juste une toute petite différence à chaque fois.)


Pour commencer avec les fonctions, voici un exemple :

Code : Tout sélectionner

var applyTransformation = function(objectATransformer) {
    objectATransformer.style.transform =                            "translateX(" + position + "px)";
    objectATransformer.style.transform = objectATransformer.style.transform + "translateY(" + position + "px)";
}
Avec ça, tu vas pouvoir appliquer la transformation sur tous tes objets en écrivanmt simplement

Code : Tout sélectionner

applyTransformation(lettre01)
applyTransformation(lettre02)
...
plutôt que d'avoir 2 lignes compliqueés à chaque fois. Ensuite si tu veux rajouter du code (par exemple avec les préfixes), tu n'as qu'un seul endroit à adapter (le corps de la fonction).


Ensuite, tu peux utiliser les boucles. Voici un exemple :

Code : Tout sélectionner

for (i=0; i<12; i++) {
    var lettreCourante = document.getElementById('c' + i);
    applyTransformation(lettreCourante)
}
Cela va s'appliquer à toutes tes lettres de 1 à 12.


En gros, ta fonction "melange" fait quelque chose comme 8 lignes et sera beaucoup plus facile à modifier à l'avenir.

Pour lettering.js je ne connais pas du tout, donc je préfère ne rien dire ;-)


PS : code non vérifié, il contient probablement quelques erreurs :wink:
Nicosmos
Iguane
Messages : 633
Inscription : 20 août 2005, 14:17

Re: JavaScript : valeur aléatoire d'une propriété CSS

Message par Nicosmos »

Merci beaucoup. :)
  • J'ai mis la fonction, c'est super pratique !
  • Trouvé style.cssText qui permet d'éditer les CSS plus facilement qu'avec plusieurs style.transform, et surtout autorise d'appliquer des propriétés préfixées !
  • Compris comment marchait getElementsByClass() (il faut mettre des [0], [1], [2] après pour sélectionner quel élément on vise).
  • Installé lettering.js qui s'occupe tout seul de découper le titre en span. Fini la soupe de balises.

Par contre je n'ai pas réussi à mettre en place la boucle, je chercherais plus en détails comment ça fonctionne dans le futur. :?

Au final j'ai :

Code : Tout sélectionner

 <script src='js/lettering.js'></script>
 <script src='js/agitateur.js'></script>
(...)
 <h1 onclick='melange();'>
  <span>probablement</span>
  <span>.net</span>
 </h1>

Code : Tout sélectionner

// fichier : agitateur.js

// sécateur de titre
$(document).ready(function() {
 $('h1 span:first-child').lettering();
});

// agitateur de titre
var valeurs = new Array("-5","0","5");

function alea() {
 position  = valeurs[Math.floor(Math.random()*valeurs.length)];
 position2 = valeurs[Math.floor(Math.random()*valeurs.length)];
}

function agiter(lettre) {
 alea();
 lettre.style.cssText +=      "-o-transform: translateX(" + position + "px) translateY(" + position2 + "px);";
 lettre.style.cssText +=    "-moz-transform: translateX(" + position + "px) translateY(" + position2 + "px);";
 lettre.style.cssText += "-webkit-transform: translateX(" + position + "px) translateY(" + position2 + "px);";
 lettre.style.cssText +=     "-ms-transform: translateX(" + position + "px) translateY(" + position2 + "px);";
 lettre.style.cssText +=         "transform: translateX(" + position + "px) translateY(" + position2 + "px);";
}
    
function melange() {
 var lettre01 = document.getElementsByClassName('char1') [0]; agiter(lettre01);
 var lettre02 = document.getElementsByClassName('char2') [0]; agiter(lettre02);
 var lettre03 = document.getElementsByClassName('char3') [0]; agiter(lettre03);
 var lettre04 = document.getElementsByClassName('char4') [0]; agiter(lettre04);
 var lettre05 = document.getElementsByClassName('char5') [0]; agiter(lettre05);
 var lettre06 = document.getElementsByClassName('char6') [0]; agiter(lettre06);
 var lettre07 = document.getElementsByClassName('char7') [0]; agiter(lettre07);
 var lettre08 = document.getElementsByClassName('char8') [0]; agiter(lettre08);
 var lettre09 = document.getElementsByClassName('char9') [0]; agiter(lettre09);
 var lettre10 = document.getElementsByClassName('char10')[0]; agiter(lettre10);
 var lettre11 = document.getElementsByClassName('char11')[0]; agiter(lettre11);
 var lettre12 = document.getElementsByClassName('char12')[0]; agiter(lettre12);
}
C'est déjà mieux, encore perfectible, mais j'ai résolu mes problèmes principaux. :)
Bonne journée !
calimo
Animal mythique
Messages : 14118
Inscription : 26 déc. 2003, 11:51

Re: JavaScript : valeur aléatoire d'une propriété CSS

Message par calimo »

Une chose que je n'ai pas mentionnée.
Tout ceci peut être largement simplifié avec une bibliothèque comme jQuery.
Si tu maîtrises un petit peu l'anglais (essentiellement l'anglais technique / web), il existe un livre intitulé "jQuery in action". Il est assez populaire et tu as des chances de le trouver dans une bibliothèque pas trop loin de chez toi (en première ou seconde édition). C'est une très bonne introduction à ce quasi remplacement de javascript (en simplifié), qui ne nécessite pas franchement de bases en programmation. Et si tu penses que ça va te prendre trop de temps, détrompes-toi : tu vas très rapidement en gagner :wink:
Répondre

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 6 invités