Introduction : Ce tutoriel n'a pas la prétention d'être la seule technique, ou la meilleure technique pour réaliser un dessin animé interactif.
Pour comprendre les concepts de ce tutoriel, il faut retourner au tout début dans la préhistoire et affiner dans les nombreux écrits Celtes ( Ce n'est pas parce qu'avec les langues d'aujourd'hui, ils sont incompréhensibles qu'ils n'existent pas).
Les dessins animés des grottes préhistoriques ariégeoises, nous donnent plusieurs techniques ayant toutes en commun le langage multidirectionnel jusqu'aux dessins animés symboliques.
Le tutoriel explique comment utiliser une de ces techniques matériels.
Ici, il n'y a pas d'algèbre, pas d’algorithme, pas de recherche d'absolue. Ici, il n'y a que de la logique, la même logique qui a fait reprendre les anciennes traditions au siècle des lumières en déclarant qu'il ne fallait pas utiliser de dictionnaire, mais utiliser des encyclopédies (logique multidirectionnelle).
Première approche :
Comme l'image sur l'écran est fixe, nous remplaçons le mouvement de la tête, ou du corps, dans les grottes, par un changement de l'image dans le temps.
Bien qu'avec le HTML5 et CSS3, cela ne soit plus obligatoire, nous allons créer en les balisant deux grandes zones de travail. L'une nommé head, l'autre nommée body.
Dans le head nous plaçons les actions en javascript et les dessins en css
Dans le body nous appelons à l'affichage les informations se trouvant dans le head
La forme de départ du dessin animé interactif ici est donc :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Titre du dessin animé interactif</title>
<script>
je déclare les variables
j'écris ici les actions
</script>
<style>
je dessine les formes
</style>
</head>
<body>
Je précharge mes sons pour pouvoir les mixer dans les actions
j'appel les forme et j'indique leurs placements dans le documents
</body>
</html>
Une fois la structure de la page html5 connue, nous écrivons un scénario.
De ce scénario, nous identifions qu'elles sont les formes à dessiner et quelles sont les actions à créer.
Imaginons que pour l'exemple, je veux une fleur qui penche la tête.
Scénario = une fleur qui penche la tête
action en 4 temps
dessin fleur
appel fleur et préchargement des sons à mixer
Nous commençons par les dessins sans oublier que nous sommes en logique multidirectionnelle, plusieurs causes peuvent avoir le même effet, et la même cause peut avoir des effets différents selon l'environnement.
Le dessin, c'est du css.
J'utilise les bordures d'un rectangle que je courbe ou un cercle que je courbe aussi.
En exemple pour une fleur basique j'associe trois formes.
.petales1 {
position: absolute;
border: 1.5px solid black;
display:block;
width:16px;
height:40px;
background-color: red;
-webkit-border-radius: 50px 50px 50px 50px / 20px 20px 90px 90px;
border-radius: 50% 50% 50% 50% / 20% 20% 90% 90%;
}
Le point quelque chose permet de donner un nom à la forme géométrique qui se trouve entre les parenthèses qui suivent
le width permet d'indiquer la largeur de la forme géométrique
le height permet d'indiquer la hauteur de la forme géométrique
le background-color permet d'indiquer la couleur à l'intérieur de la forme géométrique
le reste permet de jouer sur l'aspect de la forme géométrique finale.
.tige1{
position:absolute;
width: 40px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:4px;
border-top-right-radius:4px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
Je ne reprends pas ce que je viens de décrire juste au dessus sur le point, et ...
ici je dessine un carré puisque la hauteur égale la largeur,
mais cela importe peu, car ce qui m'interesse c'est son coté droit.
comme je ne demande pas l'affichage de l'intérieur et
que je dis à l'aide de " border: 0px;" qu'aucun bord n'est affiché, le carré n'existe pas.
ensuite, je dis quelle coté de bordure afficher, ici le droit border-right.
dans la même ligne nous avons son épaisseur et sa couleur
Avec le reste je joue à créer la courbure qui me convient.
.feuille1 {
position: absolute;
border: 1.5px solid black;
display:block;
width:32px;
height:10px;
background-color: green;
-webkit-border-radius: 50px 50px 50px 50px / 20px 20px 90px 90px;
border-radius: 50% 50% 50% 50% / 20% 20% 90% 90%;
}
La feuille n'est qu'un cercle déformé à ma convenance de couleur verte
Pour donner un angle à une forme, il suffit d'utiliser transform: rotate
Pour avoir une rotation de -21°, nous ajoutons dans le style du head
.tourne21m {
float: left;
-ms-transform: rotate(-21deg); /* IE 9 */
-webkit-transform: rotate(-21deg); /* Safari */
transform: rotate(-21deg);
}
Dans le scénario, nous avons décidé de créer 4 images
Les variations de formes peuvent être de trois natures
1- La variation peut être répétitive, en exemple une fleur balancé par le vent
c'est une simple boucle que nous verons plus tard car c'est dans la gestion des actions
voir au début dans la structure de page html5
2- la variation peut-être un déplacement dans la page
mais la gestion des positions dans la page se fait dans le body
voir au début dans la structure de page html5, nous le verrons plus tard
3- la forme est différente et nous devons la dessiner
Pour courber la fleur petales1 n'a pas besoin d'être redessiné, il suffit de lui faire faire une rotation dans le positionnement
Pour courber la fleur feuille1 n'a pas besoin d'être redessiné, il suffit de changer la rotation dans le positionnement
Pour courber la fleur tige1 a besoin d'une nouvelle coubure pour chaque nouvelle image.
nous allons donc créer 3 nouvelles formes nommées tige2 tige3 tige4
.tige4{
position:absolute;
width: 20px;
height: 20px;
border: 0px;
border-right: 2.5px solid green;
border-top: 2.5px solid green;
border-top-left-radius:4px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tourne90m {
float: left;
-ms-transform: rotate(-90deg); /* IE 9 */
-webkit-transform: rotate(-90deg); /* Safari */
transform: rotate(-90deg);
}
.tourne21 {
float: left;
-ms-transform: rotate(21deg); /* IE 9 */
-webkit-transform: rotate(21deg); /* Safari */
transform: rotate(21deg);
}
.indique{
cursor:pointer;
}
.cachemoi {
display: none;
}
.sortdutrou {
display: inline;
}
.petales1 {
position: absolute;
border: 1.5px solid black;
display:block;
width:16px;
height:40px;
background-color: red;
-webkit-border-radius: 50px 50px 50px 50px / 20px 20px 90px 90px;
border-radius: 50% 50% 50% 50% / 20% 20% 90% 90%;
}
.tige1{
position:absolute;
width: 40px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:4px;
border-top-right-radius:4px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tige2{
position:absolute;
width: 40px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:40px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tige3{
position:absolute;
width: 20px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:40px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tige4{
position:absolute;
width: 20px;
height: 20px;
border: 0px;
border-right: 2.5px solid green;
border-top: 2.5px solid green;
border-top-left-radius:4px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.feuille1 {
position: absolute;
border: 1.5px solid black;
display:block;
width:32px;
height:10px;
background-color: green;
-webkit-border-radius: 50px 50px 50px 50px / 20px 20px 90px 90px;
border-radius: 50% 50% 50% 50% / 20% 20% 90% 90%;
}
.tourne21m {
float: left;
-ms-transform: rotate(-21deg); /* IE 9 */
-webkit-transform: rotate(-21deg); /* Safari */
transform: rotate(-21deg);
}
.tourne90m {
float: left;
-ms-transform: rotate(-90deg); /* IE 9 */
-webkit-transform: rotate(-90deg); /* Safari */
transform: rotate(-90deg);
}
.tourne21 {
float: left;
-ms-transform: rotate(21deg); /* IE 9 */
-webkit-transform: rotate(21deg); /* Safari */
transform: rotate(21deg);
}
.tourne30m {
float: left;
-ms-transform: rotate(-30deg); /* IE 9 */
-webkit-transform: rotate(-30deg); /* Safari */
transform: rotate(-30deg);
}
.tourne60m {
float: left;
-ms-transform: rotate(-60deg); /* IE 9 */
-webkit-transform: rotate(-60deg); /* Safari */
transform: rotate(-60deg);
}
.indique{
cursor:pointer;
}
.cachemoi {
display: none;
}
.sortdutrou {
display: inline;
}
switch (persistanceretinienne) {
case 0:
lancerChange1();
JoueLeSon2();
break;
case 1:
lancerChange2();
JoueLeSon1();
break;
case 2:
lancerChange3();
break;
case 3:
lancerChange4();
break;
case 4:
lancerChange5();
mua1 = mua1 + 1;
if(mua1>3){
mua1 =0;
}
JoueLeSon(mua1);
break;
case 5:
lancerChange6();
break;
case 6:
lancerChange7();
break;
case 7:
lancerChange8();
break;
case 8:
lancerChange8();
break;
}
}
<div id="fleur1" ....> contenue du reprère </div>
document.getElementById('fleur1').className = 'sortdutrou';
var mua1 = 0;
mua1 = mua1 + 1;
mua1 += 1;
mua1++;
On pourrait croire à de l'arithmétique ici, mais il n'en est rien.
En fait nous avons un tableau de noms contenant les termes 0, 1 , 2, 3 .., et à chaque fois que nous faisons une des actions précédentes, nous donnons à mua1 le contenue suivant du tableau.
Il n'y pas pas d'opération mathématique ici, c'est de l'adressage.
Nous aurions pu faire la même chose en remplaçant 1 par albert, 2 par lune ...
C'est une simple liste de courses mises dans la mémoire de l'ordinateur, un positionnement et le + n'additionne pas, le + change la position dans la liste de courses
Nous pouvons lancer plusieurs actions en même temps en les regroupant dans ce qui se nomme une fonction.
une fonction est de la forme
function lancerChange1(){
document.getElementById('fleur3').className = 'cachemoi';
document.getElementById('fleur2').className = 'cachemoi';
document.getElementById('fleur1').className = 'sortdutrou';
}
pour revenir à notre liste de courses, selon la position dans la liste nous allons afficher ou masquer les formes en appelant telle ou telle fonction
Pour identifier ou nous sommes dans la liste de courses, nous utilisons le bidule nommé switch
Le switch s'utilise comme ça :
switch (persistanceretinienne) {
case 0:
lancerChange1();
JoueLeSon2();
break;
case 1:
lancerChange2();
JoueLeSon1();
break;
case 2:
lancerChange3();
break;
case 3:
lancerChange4();
break;
case 4:
lancerChange5();
mua1 = mua1 + 1;
if(mua1>3){
mua1 =0;
}
JoueLeSon(mua1);
break;
}
Explications
les placements sont dans le body, ils permettent d'indiquer ou sont les formes,ou lancer les fonctions, et précharger les documents audio (ou vidéo dans le cas de vidéo interactive pas utilisé dans ce tutoriel).
Dessinons notre premier, dessin et expliquons le
<div id="fleur1">
<div class="petales1" style="margin-left:142px ; margin-top:105px;">
</div>
<div class="feuille1 tourne21m" style="margin-left:150px ; margin-top:147px;">
</div>
<div class="tige1" style="margin-left:110px ; margin-top:145px;">
</div>
</div>
Nous indiquons en premier le repère de la première image entre des balise div, et nous dessinons nos trois forme à l'intérieur en les plaçant à l'aide de la distance par rapport au bord gauche "margin-left" et par rapport au haut "margin-top"
Pour le démarrage du dessin animé, nous allons laisser qu'une seule image visible.
Et nous allons masquer les formes des autres images à l'aide d'un paramètre css que j'ai décidé d'appeler cachemoi.
Ce qui donne pour le body
<body>
<div id="fleur1">
<div class="petales1" style="margin-left:142px ; margin-top:105px;">
</div>
<div class="feuille1 tourne21m" style="margin-left:150px ; margin-top:147px;">
</div>
<div class="tige1" style="margin-left:110px ; margin-top:145px;">
</div>
</div>
<div id="fleur4" class="cachemoi">
<div class="petales1 tourne90m" style="margin-left:82px ; margin-top:125px;">
</div>
<div class="feuille1 tourne21" style="margin-left:123px ; margin-top:150px;">
</div>
<div class="tige4" style="margin-left:110px ; margin-top:145px;">
</div>
</div>
</body>
Quand j'ai identifié les lois physiques de l'acoustique début d'année 2010 et que j'ai créé le format audio abadie.jo adapté à ces lois, je n'ai pas rencontré de problème pour mixer, car j'étais sous linux qui utilise des fork. Je pouvais lancer facilement plusieurs applications lisant le même fichier audio.
Rapidement quelques jours plus tard, je me suis apperçu que sur les autres systèmes d'exploitations la lecture du même fichier audio induisait de nombreux problèmes. Après de nombreux tests et analyses, j'ai mis au point une solution acceptable qui passe partout. C'est cette solution que j'utilise aussi en css.
Pour pouvoir lire plusieurs fois le même fichier audio en même temps, je crée plusieurs copies du fichier en leur accordant un nom différent.
Je crée une variable qui s'incrémente au travers d'un switch qui lance à chaque fois une copie différente du même fichier audio.
Cette technique m'a été des plus utile dans PianoBaul HTML5 pour pouvoir avoir la répétition des touches clavier
Nous pouvons même dire que depuis plus d'un ans je crée des dessins animés interactif car dans PianoBaul je fais bouger les cordes et parfois d'autres formes.
Sans plus d'explications passons au code
function JoueLeSon(mua1){
if(mua1==0){
var multia1 = document.getElementById("1awav");
multia1.play();
}
else if(mua1==1){
var multia2 = document.getElementById("1bwav");
multia2.play();
}
else if(mua1==2){
var multia3 = document.getElementById("1cwav");
multia3.play();
}
else if(mua1==3){
var multia4 = document.getElementById("1dwav");
multia4.play();
}
}
La variable se nomme mua1, c'est elle qui change chaque fois qu'une demande audio est faite.
JoueLeSon est la fonction qui appelle la lecture sonore
A l'appel du changement d'image, nous lançons l'appel du fichier audio accompagné de la variable qui change, ce qui donne
lancerChange3();
mua1 = mua1 + 1;
if(mua1>3){
mua1 =0;
}
JoueLeSon(mua1);
La gestion du temps totale du dessin animé est faite avec
function lancertout()
{
nbimg = setInterval(seance, vitesseDuVent);
setTimeout(durermax, persistanceretinienne * 41000);
change(persistanceretinienne)
}
Avec la valeur de vitesseDuVent qui représente la durée d'affichage de chaque image
Pour pouvoir changer la valeur de vitesseDuVent, il faut en premier arrêter la fonction ce qui donne
function diminuLeVent(){
clearInterval(nbimg);
vitesseDuVent = vitesseDuVent + 300;
nbboucle = 70;
lancertout();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Titre du dessin animé interactif</title>
<script>
var persistanceretinienne = 3;
var nbimg = null;
var nbboucle = 70;
var mua1 = 0;
var vitesseDuVent = 300;
function acelereLeVent(){
if(vitesseDuVent>50){
vitesseDuVent = vitesseDuVent -40;
}
}
function diminuLeVent(){
clearInterval(nbimg);
vitesseDuVent = vitesseDuVent + 300;
nbboucle = 70;
lancertout();
}
function lancerChange1(){
document.getElementById('fleur4').className = 'cachemoi';
document.getElementById('fleur3').className = 'cachemoi';
document.getElementById('fleur2').className = 'cachemoi';
document.getElementById('fleur1').className = 'sortdutrou';
}
function lancerChange2(){
document.getElementById('fleur4').className = 'cachemoi';
document.getElementById('fleur3').className = 'cachemoi';
document.getElementById('fleur2').className = 'sortdutrou';
document.getElementById('fleur1').className = 'cachemoi';
}
function lancerChange3(){
document.getElementById('fleur4').className = 'cachemoi';
document.getElementById('fleur3').className = 'sortdutrou';
document.getElementById('fleur2').className = 'cachemoi';
document.getElementById('fleur1').className = 'cachemoi';
}
function lancerChange4(){
document.getElementById('fleur4').className = 'sortdutrou';
document.getElementById('fleur3').className = 'cachemoi';
document.getElementById('fleur2').className = 'cachemoi';
document.getElementById('fleur1').className = 'cachemoi';
}
function change(persistanceretinienne)
{
switch (persistanceretinienne) {
case 0:
lancerChange1();
JoueLeSon2();
break;
case 1:
lancerChange2();
JoueLeSon1();
break;
case 2:
lancerChange3();
mua1 = mua1 + 1;
if(mua1>3){
mua1 =0;
}
JoueLeSon(mua1);
break;
case 3:
lancerChange4();
break;
}
}
function durermax()
{
clearInterval(nbimg);
/* lancerChange4(); */
}
function seance()
{
change(persistanceretinienne);
persistanceretinienne--;
if ((nbboucle>1)&&(persistanceretinienne<0))
{
/* persistanceretinienne = 8;*/
persistanceretinienne = 3;
nbboucle = nbboucle-1;
}
}
function lancertout()
{
nbimg = setInterval(seance, vitesseDuVent);
setTimeout(durermax, persistanceretinienne * 41000);
change(persistanceretinienne)
}
function JoueLeSon(mua1){
if(mua1==0){
var multia1 = document.getElementById("1awav");
multia1.play();
}
else if(mua1==1){
var multia2 = document.getElementById("1bwav");
multia2.play();
}
else if(mua1==2){
var multia3 = document.getElementById("1cwav");
multia3.play();
}
else if(mua1==3){
var multia4 = document.getElementById("1dwav");
multia4.play();
}
}
function JoueLeSon1(){
var multib1 = document.getElementById("2awav");
multib1.play();
}
function JoueLeSon2(){
var multic1 = document.getElementById("3awav");
multic1.play();
}
</script>
<style>
.petales1 {
position: absolute;
border: 1.5px solid black;
display:block;
width:16px;
height:40px;
background-color: red;
-webkit-border-radius: 50px 50px 50px 50px / 20px 20px 90px 90px;
border-radius: 50% 50% 50% 50% / 20% 20% 90% 90%;
}
.tige1{
position:absolute;
width: 40px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:4px;
border-top-right-radius:4px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tige2{
position:absolute;
width: 40px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:40px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tige3{
position:absolute;
width: 20px;
height: 40px;
border: 0px;
border-right: 2.5px solid green;
border-top-left-radius:40px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.tige4{
position:absolute;
width: 20px;
height: 20px;
border: 0px;
border-right: 2.5px solid green;
border-top: 2.5px solid green;
border-top-left-radius:4px;
border-top-right-radius:40px;
border-bottom-right-radius:40px;
border-bottom-left-radius:40px;
}
.feuille1 {
position: absolute;
border: 1.5px solid black;
display:block;
width:32px;
height:10px;
background-color: green;
-webkit-border-radius: 50px 50px 50px 50px / 20px 20px 90px 90px;
border-radius: 50% 50% 50% 50% / 20% 20% 90% 90%;
}
.tourne21m {
float: left;
-ms-transform: rotate(-21deg); /* IE 9 */
-webkit-transform: rotate(-21deg); /* Safari */
transform: rotate(-21deg);
}
.tourne90m {
float: left;
-ms-transform: rotate(-90deg); /* IE 9 */
-webkit-transform: rotate(-90deg); /* Safari */
transform: rotate(-90deg);
}
.tourne21 {
float: left;
-ms-transform: rotate(21deg); /* IE 9 */
-webkit-transform: rotate(21deg); /* Safari */
transform: rotate(21deg);
}
.tourne30m {
float: left;
-ms-transform: rotate(-30deg); /* IE 9 */
-webkit-transform: rotate(-30deg); /* Safari */
transform: rotate(-30deg);
}
.tourne60m {
float: left;
-ms-transform: rotate(-60deg); /* IE 9 */
-webkit-transform: rotate(-60deg); /* Safari */
transform: rotate(-60deg);
}
.indique{
cursor:pointer;
}
.cachemoi {
display: none;
}
.sortdutrou {
display: inline;
}
</style>
</head>
<body onload="javascript:lancertout();">
<div><audio id="1awav" preload>
<source src="https://www.letime.net/alpha/a.wav">
<source src="https://www.letime.net/alpha/galop.mp3">
</audio></div>
<div><audio id="1bwav" preload>
<source src="https://www.letime.net/alpha/b.wav">
</audio></div>
<div><audio id="1cwav" preload>
<source src="https://www.letime.net/alpha/c.wav">
</audio></div>
<div><audio id="1dwav" preload>
<source src="https://www.letime.net/alpha/d.wav">
</audio></div>
<div><audio id="2awav" preload>
<source src="https://www.letime.net/alpha/galop1.wav">
<source src="https://www.letime.net/alpha/galop1.mp3">
</audio></div>
<div><audio id="3awav" preload>
<source src="https://www.letime.net/alpha/galop2.wav">
<source src="https://www.letime.net/alpha/galop2.mp3">
</audio></div>
<div id="fleur1">
<div class="petales1 indique" onMouseDown="acelereLeVent();" style="margin-left:142px ; margin-top:105px;">
</div>
<div class="feuille1 tourne21m indique" onMouseDown="diminuLeVent();" style="margin-left:150px ; margin-top:147px;">
</div>
<div class="tige1" style="margin-left:110px ; margin-top:145px;">
</div>
</div>
<div id="fleur3" class="cachemoi">
<!---->
<div class="petales1 tourne60m indique" onMouseDown="acelereLeVent();" style="margin-left:115px ; margin-top:115px;">
</div>
<!---->
<div class="feuille1 tourne21m indique" onMouseDown="diminuLeVent();" style="margin-left:150px ; margin-top:147px;">
</div>
<!---->
<div class="tige3" style="margin-left:130px ; margin-top:145px;">
</div>
</div>
<div id="fleur2" class="cachemoi" >
<div class="petales1 tourne30m" onMouseDown="acelereLeVent();" style="margin-left:104px ; margin-top:108px;">
</div>
<div class="feuille1 tourne21m" style="margin-left:130px ; margin-top:147px;">
</div>
<div class="tige2" style="margin-left:90px ; margin-top:145px;">
</div>
</div>
<div id="fleur4" class="cachemoi">
<div class="petales1 tourne90m indique" onMouseDown="acelereLeVent();" style="margin-left:82px ; margin-top:125px;">
</div>
<div class="feuille1 tourne21" style="margin-left:123px ; margin-top:150px;">
</div>
<div class="tige4" style="margin-left:110px ; margin-top:145px;">
</div>
</div>
</body>
</html>