Black Lodge – Sommaire

Ce document a été réalisé par Emmanuel Papillon : http://production.batbad.com/

Le site décrit dans cette charte est : http://lynch.batbad.com/

 

Concept et Visuel

·       Concept

·       Format

·       Texte

·       Popups

·       Liens

·       CSS

·       Panoramiques - scrolling

Charte Technique

·       Popups

·       Aléatoire

·       Dialogue

·       Liens différés

Charte d'Animations/Sons

·       Charte générale

·       Animations et sons de séquences

·       Animations et sons "de fond"

·       Animations et sons d'évènements

Annexe - La Red Room


black lodge – charte : concept & visuel

1)Concept

Exploration de l’univers de David Lynch, utilisant les images de ses films, à la façon d’un jeu d’aventure "pointer et cliquer". Fusionner les univers de David Lynch appartenant à la même cohérence de ton et d’ambiance, la même logique psychotique.

Cette exploration est contemplative, avec quelques embranchements choisis par l’utilisateur. L’intérêt de la visite n’est pas l’interaction au sens du choix du déroulement des évènements, mais plutôt l’appréciation relativement passive des visuels créés par le réalisateur (les personnages de David Lynch étant toujours plus victimes des évènements qu'acteurs) : les sujets, les cadres, les ambiances, la beauté de la photo sont l'intérêt du site. C'est un site d'immersion.

Le site est structuré en étoile : on entre dans un des univers de David Lynch, qui mène toujours à terme (après de rares détours sur une autre entrée) sur la Chambre Rouge ("Red Room"). Après avoir erré dans la Chambre Rouge (qui est aussi la "Black Lodge" donnant son nom au site), le visiteur est ensuite renvoyé dans un autre univers. Tout peut alors recommencer, par la même entrée ou non.

Les nombreux évènements aléatoires, (rencontres, dialogues, animations et embranchements) apportent de la vie à cet univers, même dans les mêmes lieux et situations. Le site aspire ainsi à apparaître comme un véritable monde virtuel - ce qui est très apprécié des fans du réalisateur.

Des dialogues ou situations du site n'apparaissant pas dans les films, ils sont tirés d'éléments de scripts ou ont tout simplement été inventés. Ils apportent de la richesse au projet, et "cimentent" les zones vides. On est là dans le domaine de la "fan fiction", qui est aussi très apprécié des fans.

L'ambiguïté de l'identité du visiteur est aussi intéressante, puisqu'il (ou elle) change régulièrement en passant d'un monde à l'autre, s'insérant dans la logique schizophrène des films de Lynch que l'on a choisi d'inclure (l'exemple le plus frappant est "Lost Highway" : on peut se demander à plusieurs moments du site si l'on ne se fait pas habiter par Fred Madison).

L'aspect aléatoire de certaines scènes et leur mise en boucle avec des détails changés est aussi cohérent avec cette logique schizophrène : Lynch s'est souvent amusé (comme à la fin de "Twin Peaks", dans "Lost Highway" ou dans "Mulholland Drive") à intervertir des dialogues ou des personnages dans des scènes similaires et répétées. Ce qui pouvait apparaître alors comme une faiblesse du site (reprendre les mêmes décors au gré du hasard) devient alors une illustration d'une constante de l'univers de David Lynch.

(RETOUR A L'INDEX)

2)Format

Le site est compatible avec toute résolution comprise entre 800x600 et 1600x1200. On a deux principaux formats possibles :

 

·       Soit le format de type cinémascope, bande d'image de 307 pixels de haut étirée sur toute la largeur de l'écran avec une largeur maximale des éléments d'image mis bout à bout de 760 pixels (pour compatibilité en 800x600).

·       Soit le format de type 4/3 (comme pour "Eraserhead" ou la "Black Lodge" proprement dite), qui est étiré en largeur et en hauteur (hauteur maximale du contenu de 423 pixels de haut sans barre de scrolling, largeur de 760 pixels).

 

Pour étirer ces images photo-réalistes tirées des DVD de David Lynch, on utilise de façon intensive le papier peint HTML. Dans certains cas, cependant, on n'utilise pas de papier peint : certains panoramiques en largeur, "collant" bout à bout les plans de balayages horizontaux de la caméra (pour présenter une pièce, par exemple) sont tout simplement une grande image, composées de plusieurs fichiers images en mosaïque, le tout faisant sans papier peint au moins 1600 pixels de large (résolution maximale envisagée).

(RETOUR A L'INDEX)

3)Texte

En dehors du Noyau et de la popup d'aide du début - autrement dit, dans tout ce qui est "voyage virtuel", le site ne comporte aucun texte au format texte. Les textes, au format d'image ou de fichier Flash, ne peuvent en effet apparaître que sous deux formes possibles :

 

·       Les sous-titres : accompagnant effectivement du son ou non (si oui, il peut être intéressant de les afficher à l'aide de Flash), ce sont la plupart du temps des dialogues. Les dialogues jouent une part importante dans l'atmosphère du site, ils rendent les personnages rencontrés (et le visiteur lui-même, son identité restant un mystère) plus vivants et interactifs. La plupart des dialogues ont des éléments aléatoires, ils font vivre et évoluer les personnages, et jouent sur des répétitions entre différents scènes, ou au contraire, sur différentes variantes dans une même scène. Les sous-titres sont toujours écrits avec la même police, "Eras Medium ITC" de taille "32 px", avec le lissage Photoshop "précis". Dans les scènes en cinémascope, ils sont affichés dans une bande centrée de 60 pixels de haut sous la bande d'image. En 4/3, ils sont dans une image de 48 pixels de haut alignée en bas de page : le bas des lettres non rondes est à 25 pixels du bord. Les phrases coupées ne le sont par des pointillés que dans la Black Lodge.

·       Les commentaires, fonctionnant comme titre de la composition visuelle présente à l'écran. On les utilise dans les popups et dans les pages de transition, passage d'une ambiance à l'autre, avec transfert automatique vers une autre page (transfert non interactif). Ils imitent l'écriture (et le style, mystérieux ou surréaliste) que David Lynch utilise sur ses toiles abstraites. Ils sont animés au format GIF, rédigés à la main en trois exemplaires similaires, scannés, nettoyés (avec Corel, Intensité en +5, Négatif, puis Intensité en +5), superposés sous Photoshop. Pour l'animation, avec trois exemplaires A, B et C, on superpose A et B, puis B et C, puis A et C, avec une latence d'un dixième de seconde.

(RETOUR A L'INDEX)

4)Popups

Les popups sont des zooms : ils sont là pour satisfaire la curiosité de l’utilisateur pour un objet, renforcent le côté "réel" et la crédibilité de la visite virtuelle de l’univers de David Lynch, et vont avec le plaisir contemplatif du projet. De plus, les fans du réalisateur reconnaissent et apprécient la plupart de ces détails, puisque certains sont "cultes", David Lynch aimant beaucoup les gros plans sur objets. Ce sont donc des éléments importants.

Les popups dépendent de la page qui les a ouvertes, et se ferment donc automatiquement quand le visiteur quitte cette page. Elles n'ont pas de barre de scrolling, et n'ont aucun menu, barre de statut, etc. Elles ont un fond de 1600x1200 pixels délimitant la zone de l'image avec des pointillés. En dehors des rares cas où elles causent des évènements déterminant la suite de la visite (apparition de BOB, par exemple), elles comportent toutes un titre, un commentaire manuscrit et animé.

(RETOUR A L'INDEX)

5)Liens

Le code de lien est toujours du même type :

 

<a href="adresse.html" onMouseOver="window.status=''; return true" onMouseOut="window.status=''; return true" onFocus="this.blur()"><img SRC="image.jpg" border=0 height=XXX width=XXX></a>

 

Pour les liens avec zone de cliquage, on adapte le code à la balise "<area>". On fait en sorte de ne pas afficher l'adresse dans la barre de statut ("window.status"), et surtout de masquer le contour de zone cliquée (affiché dans Internet Explorer) grâce au code "this.blur()". Le tirage aléatoire se fait avec un code du type :

 

onClick="this.href=HASARD(); return true"

 

On le met entre les balises onMouseOver et onMouseOut. Si le lien ne doit pas mener à une autre page (popup ou déclenchement d'évènement), l'adresse pointée est "javascript:void(0)", et la fonction lancée ne change pas la propriété "href" (pas de "this.href=", pas de valeur retournée). On remplace également le "return true" par un "return false", ce qui annule la fonction de recherche de nouvelle page par le navigateur (plus propre).

(RETOUR A L'INDEX)

6)CSS

Les CSS ne sont utilisées ici que pour colorer les barres de scrolling (le site ne comportant de toute façon pas d'élément au format texte en dehors du noyau), pour les navigateurs qui l'autorisent. Le site étant avant tout graphique, avec beaucoup d'importance dans les ambiances et les atmosphères, une barre de scrolling non neutre pouvait en effet casser les tons de la page.

Le code est simple, du type (ici, pour une barre en noir et blanc) :

 

BODY {

    SCROLLBAR-ARROW-COLOR: #000000;

    SCROLLBAR-3DLIGHT-COLOR: #808080;

    SCROLLBAR-HIGHLIGHT-COLOR: #BFBFBF;

    SCROLLBAR-FACE-COLOR: #FFFFFF;

    SCROLLBAR-SHADOW-COLOR: #808080;

    SCROLLBAR-DARKSHADOW-COLOR: #404040;

    SCROLLBAR-TRACK-COLOR: #000000;

}

 

Ceci est stocké dans un fichier nommé "nom_zone_barre.css", qui est référencé par les pages l'appliquant entre la balise </script> et </head> :

 

<link REL=stylesheet HREF="nom_zone_barre.css" TYPE="text/css">

 

Bien entendu, les popups ne l'appliquent pas. Si dans une zone une seule page ne s'accorde pas avec les tons de la barre générale, on définit la barre appropriée à la page dans un fichier "exception_barre.css". Si plusieurs pages ne s'accordent pas avec la barre générale, on crée un fichier par groupe d'exception.

(RETOUR A L'INDEX)

7)Panoramiques - Scrolling

Dans certaines pages dépassant la taille de l'écran (panoramiques horizontaux ou verticaux), on peut vouloir caler la fenêtre vers le bas ou le bord droit de la page. Comme le navigateur ne peut le faire simplement, on utilise un code Javascript avec "self.scrollTo". Le code doit être inséré après la lecture des dimensions de la page. Voici le code typique d'un panoramique horizontal de 1600 pixels de large :

 

<table BORDER=0 CELLSPACING=0 CELLPADDING=0 HEIGHT="3%" >

  <tr>

    <td><img SRC="espaceur.gif" height=1 width=1600></td>

  </tr>

</table>

<script LANGUAGE="JavaScript">

<!--

  self.scrollTo(1600,0);

//-->

</script>

 

Le tableau de 3% de haut est nécessaire pour un format de page en cinémascope avec panoramique : comme on a une barre de scrolling horizontale, les dimensions de la fenêtre sont réduites en bas. On met donc la composition principale dans un tableau de 94% de haut (contenu centré), qui suit la "cale" de 3% de haut. Cela laisse un vide en bas, sinon le navigateur n'a pas la place de tout mettre dans la fenêtre et ajoute une barre de scrolling verticale inutile.

(RETOUR A L'INDEX)


black lodge – charte Technique

1)Popups

On fait une fonction par popup, avec des variables et des noms de fonction ayant la même nomenclature dans tous les cas. On écrit aussi une fonction ferme_POPUP (ou ferme_POPUPS s’il y en a plusieurs dans une même page) pour fermer toutes les popups ouvertes par une page à la fermeture de cette même page. Cette fonction est appelée par un onUnload dans la balise <body>. On ferme aussi toujours une popup avant ouverture de la même popup pour éviter deux occurrences du même zoom.

 

 var fenetre_nom_zoom=null;

 

  function nom_zoom_POPUP()

  {

    if ((fenetre_nom_zoom!=null)&&(!fenetre_nom_zoom.closed)) fenetre_nom_zoom.close();

    fenetre_nom_zoom=window.open('nom_zoom.html', 'nom_zoom', 'width=XXX, height=XXX, channelmode=0, directories=0, fullscreen=0, location=0, menubar=0, resizable=0, scrollbars=0, status=0, toolbar=0, left=XX, top=XX');

 

    return true;

  }

 

  function ferme_POPUP()

  {

    if ((fenetre_nom_zoom!=null)&&(!fenetre_nom_zoom.closed)) fenetre_nom_zoom.close();

 

    return true;

  }

 

S’il y a des animations dans la page où s’ouvre la popup, il faut ajouter une fonction de rechargement de substituts (images de l’animation). Beaucoup de navigateurs (IE en particulier) considèrent en effet à l’ouverture de la popup que la page en cours a été quittée, et dés-allouent les images pré-chargées. On place cette fonction préservant l’animation (que l’on adapte si plusieurs animations sont dans la page) après la fonction CHECK :

 

  function nom_anim_RELOAD()

  {

    initialise_tableau(tableau_nom_anim,nb_img,"nom_img_","jpg",false);

 

    return true;

  }

 

La fonction est exécutée par un onFocus, avec une condition (test si une popup a été ouverte) pour ne pas que la fonction ne soit lancée trop tôt (l’arrivée initiale sur la page, notamment, est une cause de onFocus). Dans le cas de plusieurs popups, il faut tester si au moins l’une d’elle a été ouverte.

 

onFocus="if (fenetre_nom_zoom!=null) {nom_anim_RELOAD()}"

 

Le code du lien est généralement le même. Le "return false" dans l’évènement onClick invalide normalement le lien HTML, mais en sécurité, on met tout de même l’adresse à "javascript:void(0)" :

 

<a href="javascript:void(0)" onMouseOver="window.status=''; return true" onClick="nom_zoom_POPUP(); return false" onMouseOut="window.status=''; return true" onFocus="this.blur()">

(RETOUR A L'INDEX)

2)Aléatoire

L’aléatoire joue un grand rôle dans ce site, c’est ce qui permet de rendre intéressantes les visites répétées : même dans les mêmes zones, il y a toujours quelque chose de différent à voir, des détails, des embranchements, des dialogues. Il y a deux grands types d'éléments aléatoires :

a. Les éléments faisant partie intégrante de la page

Ce sont généralement des images, ou des zones de lien. On ne les tire pas au hasard après le chargement de l'HTML, mais pendant ce chargement, en utilisant des insertions de code javascript. Un exemple typique est une image dans une cellule de tableau, avec un code du style :

 

<td><script LANGUAGE="JavaScript">

    <!--

    if (Math.random()<0.5)

    {

      document.write('<img SRC="image_A.jpg" height=XXX width=XXX>');

    }

    else

    {

      document.write('<img SRC="image_B.jpg" height=XXX width=XXX>');

    }

    //-->

    </script></td>

 

Pour les cas plus compliqués, se souvenir de l'instruction "document.writeln('')" qui insère un saut de ligne à la fin de la chaîne de caractère passée en paramètre.

b. Les éléments tirés après chargement

Ce sont des animations, des dialogues, des sons, des évènements : tout ce qui peut arriver après que les éléments initiaux de la page se soient chargés. La fonction d’aléatoire est commune aux différents éléments tirés au hasard. Elle se nomme "initialise_aleatoire()", et est située vers la fin du code, juste avant la fonction "initialisation()", s’il y en a une (si c'est le cas, c'est elle qui classiquement appelle "initialise_aleatoire()", sinon, c'est suite à un onLoad).

La fonction elle-même a une forme qui dépend de la page, et doit donc être traitée au cas par cas. Le tirage de l’aléatoire fait toujours appel à "Math.random()", qui tire un nombre entre 0 et 1 (0 est inclus mais pas 1), et peut être utilisé comme un pourcentage. Si le chargement des tableaux dépend de l’aléatoire, la fonction initialise_tableau() est appelée dans cette fonction.

(RETOUR A L'INDEX)

3)Dialogues

L’importance des dialogues dans le site est très grande (cf. la charte graphique et conceptuelle plus haut), et leur dimension aléatoire également. Techniquement, ce sont en fait des animations de séquences (cf. plus bas), et ils sont codés à peu près comme tels : les principales différences sont la latence entre deux images (c’est à dire deux lignes de dialogue) qui est bien plus longue, le fait que cette latence peut varier en fonction de la longueur de la réplique, et l’aspect aléatoire des dialogues. On distingue ici les deux cas, aléatoire ou non aléatoire.

a. Dialogues non aléatoires

Le tableau contenant les dialogues est initialisé par la même fonction type que les animations classiques (voir plus bas). Ce chargement est effectué après un onLoad pour diminuer le temps de chargement apparent. La latence est soit fixe (comme dans le code ci-dessous), soit variable selon la réplique (utile si les dialogues mêlent répliques longues et répliques courtes). Dans ce dernier cas, latence_txt est défini comme étant un tableau de nb_txt éléments (latence_txt=new Array(XXXX,XXXX,XXXX);).

Les dialogues sont numérotés de (0) à (nb_txt-1). Contrairement aux animations de séquences, l’image d’index (0) n’est jamais l’image affichée initialement au chargement de la page : c’est l’image vide_txt qui remplit ce rôle. Typiquement la déclaration des variables est comme suit :

 

// ELEMENTS DU DIALOGUE NON ALEATOIRE

 

 vide_txt=new Image();

 vide_txt.src="vide.jpg";

 

 var nb_txt=X;

 var latence_txt=XXXX;

 tableau_txt=new Array();

 

// FONCTIONS DU DIALOGUE : initialisation, CHECK, SUBST, LAUNCH

 

Selon les cas, on peut vouloir mettre ou non un vide entre chaque réplique. On déclare la durée de ce vide ainsi : "var latence_vide=XXXX;", sous la déclaration de la latence de dialogue classique.

Les fonctions de gestion du dialogue sont à peu près les mêmes que pour une animation de séquence. Par défaut, elles sont situées juste avant la fonction "initialisation()" s'il y en a, sinon, avant le </script>. Ici la latence est fixe, si elle est variable, elle est gérée par un tableau "latence_txt=new Array(XX,XX);"), et il faut mettre à la place de "latence_txt", "latence_txt[etape]".

 

// FONCTIONS DU DIALOGUE : CHECK, SUBST, LAUNCH

 

  function dialogue_CHECK()

  {

    if (tableau_txt.length==0) return false;

 

    for (i=0;i<=nb_txt-1;i++)

    {

      if (!tableau_txt[i].complete) return false;

    }

 

    return true;

  }

 

Sans vide entre chaque réplique on définit les fonction SUBST et LAUNCH ainsi :

 

  function dialogue_SUBST(etape)

  {

    document.DIALOGUE.src=tableau_txt[etape].src;

 

    if (etape<nb_txt-1) setTimeout('dialogue_SUBST(' + (etape+1) + ')',latence_txt);

    else setTimeout('document.DIALOGUE.src=vide_txt.src',latence_txt);

 

    return true;

  }

 

  function dialogue_LAUNCH()

  {

    if (dialogue_CHECK()) dialogue_SUBST(0);

    else setTimeout('dialogue_LAUNCH()',500);

 

    return true;

  }

 

Sinon, ces fonctions sont modifiées ainsi (on dit que le dialogue est "lent") :

 

  function dialogue_lent_SUBST(etape)

  {

    document.DIALOGUE.src=tableau_txt[etape].src;

    setTimeout('document.DIALOGUE.src=vide_txt.src',latence_txt);

 

    if (etape<nb_txt-1) setTimeout('dialogue_lent_SUBST(' + (etape+1) + ')',latence_txt+latence_vide);

 

    return true;

  }

 

  function dialogue_LAUNCH()

  {

    if (dialogue_CHECK()) dialogue_lent_SUBST(0);

    else setTimeout('dialogue_LAUNCH()',500);

 

    return true;

  }

 

Enfin, on lance le dialogue après une latence suivant le onLoad. Comme l'initialisation se fait au onLoad, on obtient ce type de code :

 

onLoad="initialisation(); setTimeout('dialogue_LAUNCH()',XXXX)"

 

b. Dialogues aléatoires

La nomenclature des dialogues aléatoires se fait à l'aide de lettres : si on a par exemple trois dialogues JPG possibles avec le nom "dialogue", on les appelle "dialogue_AX.jpg", "dialogue_BX.jpg" et "dialogue_CX.jpg" (où X est l'indexage des répliques). Chaque dialogue peut avoir une longueur différente, "nb_txt" devient donc un tableau indexé par "choix_ss_tt" :

 

// ELEMENTS DU DIALOGUE ALEATOIRE

 

 vide_txt=new Image();

 vide_txt.src="vide.jpg";

 

 var choix_ss_tt;

 nb_txt=new Array(X,X,X,X);

 var latence_txt=XXXX;

 tableau_txt=new Array();

 

// FONCTIONS DU DIALOGUE : initialisation, CHECK, SUBST, LAUNCH

 

La variable "choix_ss_tt" est tirée dans la fonction "initialise_aleatoire()", placée vers la fin du code, juste avant la fonction générale "initialisation()" :

 

  function initialise_aleatoire()

  {

    hasard=Math.random();

    if (hasard==0) hasard=1;

    choix_ss_tt=Math.ceil(hasard*nb_txt.length);

 

    initialise_tableau(tableau_txt,nb_txt[choix_ss_tt-1],"nom_dial_" + String.fromCharCode(choix_ss_tt+64),"ext",true);

 

    return true;

  }

 

On applique ensuite les mêmes codes que ceux pour les dialogues non aléatoires, en remplaçant simplement deux fois, une dans la fonction CHECK et une dans la fonction SUBST, "nb_txt" par "nb_txt[choix_ss_tt-1]".

Pour le cas particulier d'un dialogue aléatoire avec une latence variable selon la réplique, on gère "latence_txt" comme une matrice :

 

 latence_txt=new Array;

 latence_txt[0]=new Array(XXXX,XXXX,XXXX,XXXX);

 latence_txt[1]=new Array(XXXX,XXXX,XXXX,XXXX,XXXX);

 

On passe donc de "latence_txt" pour un dialogue non aléatoire à latence fixe, à "latence_txt[etape]" pour un dialogue non aléatoire ayant une latence non fixe, et dans le cas qui nous occupe, à "latence_txt[choix_ss_tt-1][etape]".

(RETOUR A L'INDEX)

4)Liens différés

Dans de nombreuses situations, un lien ne doit pas être cliquable avant qu’une certaine séquence ou un certain évènement se soit produit. C’est aussi vrai pour le tirage aléatoire d’un lien. De façon type, on code le lien comme suit (click_OK est initialisé à false lors de sa création, la variable est déclarée sous les variables d’animation, s’il y en a) :

 

<a href="javascript:void(0)" onMouseOver="window.status=''; return true" onClick="if (click_OK) {this.href='adresse.html'} else {return false}" onMouseOut="window.status=''; return true" onFocus="this.blur()">

(RETOUR A L'INDEX)


black lodge – charte d’animations/sons

1)Charte générale

La plupart des animations, compte tenu des graphismes de type photographique et/ou de l’interaction de l’utilisateur avec celles-ci (par exemple suite à un rollover), ne seraient pas possibles avec le format GIF (qui n’offre pas assez de couleurs, fait des fichiers trop lourds, etc.)

La solution du site est donc celle des animations avec des JPEG compressés au maximum (avec le meilleur compromis entre finesse des graphismes et poids total), pré-chargés puis substitués l’un après l’autre par un code Javascript utilisant des instructions setTimeout (pour régler la fréquence), le tout validé par un onLoad et un test de pré-chargement pour les animations autres que celles "de fond".

Dans des animations fluides de type "film" (par opposition au type "diapo"), la fréquence est à peu près fixe (avec possibilités d’accélérations). Si elles ne sont pas dans une séquence (qui est une animation non interactive), elles ne sont pas gérées par le son (Flash) lui-même (c’est l’inverse, le Javascript lançant le Flash).

Le son est donc géré par un fichier Flash, de format précis pour chacun des trois grands cas énumérés ci-dessous. En dehors de ceux-ci, on fait au cas par cas. Comme les images de séquence ou d’évènement, on teste le chargement des fichiers Flash (de séquence ou d’évènement) avant exécution. Voici les grandes lignes communes :

a. Codes et caractéristiques communs aux animations

Pour les animations fluides, le chargement se fait avec indexage de (0) à (nb_img-1). Si l’animation a une première image au chargement initial de la page qui ne fera pas partie du reste de l’animation (un état initial), on lui donne tout de même l’indexage (0) pour accélérer son chargement, l’animation étant donc activée à partir de l’indexage (1). Les fichiers ont donc un nom type :

 

<img SRC="nom_0.jpg" NAME="NOM" width=XXX height=XXX>

 

Les JPEG indexés (avec un numéro) sont toujours chargés avec la même fonction. Si besoin est, elle peut présenter des variantes, mais sa forme générale reste la même. Elle sert également au chargement des sous-titres (GIF comme JPEG). Elle est lancée directement dans le <head> pour les animations de fond cycliques, sinon, pour les séquences et les animations d’évènement, on les charge après un onLoad. Une fonction "initialisation()", appelée dès exécution du onLoad, lance les initialisations des tableaux de l’animation. On utilise "allouer" pour les rechargements (popups).

 

  function initialise_tableau(tableau,img_nb,nom_img,extension,allouer)

  {

    for (i=0;i<=img_nb-1;i++)

    {

      if (allouer) tableau[i]=new Image();

      tableau[i].src=nom_img + i + "." + extension;

    }

 

    return true;

  }

 

Les fonctions de test (systématiques pour les animations autres que les animations "de fond" qui équivalent à des GIF animés) sont au cas par cas, du nom de l’animation. Elles peuvent tester plusieurs tableaux si l’animation comporte plusieurs tranches, et comporter un fichier Flash. Ci-dessous une fonction type avec test sur un seul tableau et un fichier Flash :

 

  function nom_anim_CHECK()

  {

    if (tableau_nom_anim.length==0) return false;

 

    for (i=0;i<=nb_img-1;i++)

    {

      if (!tableau_nom_anim[i].complete) return false;

    }

 

    if (document.nom_swf.PercentLoaded()!=100) return false;

 

    return true;

  }

 

Tous les types d’animations ont des constantes claires déclarées en début de page pour définir immédiatement le nombre d’images de l’animation, la latence entre deux images, si besoin est, l’état (dans le cas d’une animation interactive, par exemple tiroir_ouvert), etc.

b. Codes et caractéristiques communs aux sons Flash

Les fichiers Flash servent surtout à gérer du son au format MP3. Ils peuvent aussi servir à la synchronisation entre le son et les évènements Javascript par fscommand. Ils sont inclus directement dans la page, sauf dans le cas de séquences lourdes (pour répartir le téléchargement).

Comme ils n’ont pas de graphisme, ils n’ont pas de calque d’objet, ont une couleur de fond généralement identique à celle de la page, et une surface minimale (idéalement, hauteur ou largeur de 1px). Le menu est interdit (menu=false), et la qualité est la plus faible (quality=low), puisque la "qualité" est définie comme étant la qualité graphique au détriment de la synchronisation et que l’on n’a pas de graphisme, juste du son et des évènements.

Ils font 5i/s. Sauf exception : son compressé en MP3, 16Kbits/s mono, Optimale.

Les sons eux-même peuvent être ou non maintenus synchronisés avec les évènements. Tout dépend du contexte : si le son est très bref et à côté de l'évènement dans le scénario (comme une ampoule qui grille, par exemple), il faut définir le son dans Flash comme "évènement". Si, au contraire, on a un son long (un dialogue, une musique) pendant lequel les évènements arrivent au milieu de la bande-son, mais à des moments précis, il faut définir le son en stream ("en continu" en Français).

Il faut aussi tenir compte du fait que deux fichiers Flash avec des sons "en continu" jouant en même temps peuvent vraiment ralentir le plugin.

(RETOUR A L'INDEX)

2)Animations et sons de séquences

Animation qui copie une animation ou séquence cinématographique. Contemplatives, non interactives, souvent accompagnées de son, elle sont capitales pour l’ambiance. Ce sont des vignettes artistiques. Ce sont elles qui rendent convaincante, vivante, réelle, la simulation de l’univers de Lynch et rapprochent le site du support initial du cinéma ou de l’animation (stop motion).

a. Animations de séquences

La fonction CHECK est lancée par la fonction LAUNCH qui lance l’animation après test. Cette fonction LAUNCH est lancée par le onLoad. Ci-dessous, la séquence proprement dite est lancée par le biais d’un fichier Flash (situation typique) :

 

  function nom_anim_LAUNCH()

  {

    if (nom_anim_CHECK()) document.nom_swf.Play();

    else setTimeout('nom_anim_LAUNCH()',500);

 

    return true;

  }

 

On a donc : onLoad  ---->  LAUNCH  –-(si CHECK)-->  lire Flash ou lancer SUBST

Le fichier Flash lui-même lance ensuite la fonction SUBST (par fscommand), qui démarre l’animation (la fonction SUBST s’appelant elle-même jusqu’à la fin).

S’il n’y a pas de son, on lance directement la fonction SUBST après le test de chargement. La fonction SUBST est personnalisée pour chaque séquence, compte tenu des nombreuses spécificités possibles. Elle utilise des variables globales : le nom de l’image du document à substituer, le tableau des substituts, nb_img et la latence. Souvent, une ligne "else" est ajoutée après le test "if (etape<nb_img-1)" pour effectuer une action finale (changement de page, validation d’un lien)...

 

  function nom_anim_SUBST(etape)

  {

    document.nom_doc.src=tableau_nom_anim[etape].src;

 

    if (etape<nb_img-1) setTimeout('nom_anim_SUBST(' + (etape+1) + ')',latence);

 

    return true;

  }

 

Les variables globales de la séquence doivent être définies comme suit :

 

// ELEMENTS DE LA SEQUENCE "NOM"

 

 var nb_img=X;

 var latence=XX;

 tableau_nom_anim=new Array();

 

// FONCTIONS : initialisation, CHECK, SUBST, LAUNCH

 

b. Sons de séquences

Un son de séquence n’est pas forcément un son qui passe pendant une séquence, c’est la bande son (musique, bruitage ou les deux) d’une animation assez longue, non interactive, et de type cinématographique. Le son n’est absolument pas cyclique, il est acteur de ce qui se passe sur l’écran et initiateur des animations (contrairement aux animations interactives où c’est l’inverse, subordonnant le son à l’action).

Il peut y avoir des exceptions à cela avec une forme d’interactivité (le fait de déclencher la séquence, le plus souvent), mais les conséquences de l’animation sont systématiquement irréversibles (le plus souvent, transfert vers une autre page).

Ce type de fichier Flash est toujours testé avant exécution (cf. plus haut), son format est toujours le même. Il est la plupart du temps chargé directement (sauf répartition de téléchargement). Paramètres : play=false, loop=false, activer fscommand. Le format interne est toujours comme suit :

 

·       une image vide

·       le son en stream ("en continu" en Français) ou en évènement (cf. charte générale)

·       sur un calque "Commande", des appels fscommand avec paramètre ("command")

·       en fin d’animation, si besoin est, un getURL (ou équivalent)

(RETOUR A L'INDEX)

3)Animations et sons "de fond"

Animations cycliques sans début ou fin (équivalentes à un GIF), ou sons d’ambiance en boucle. Ces animations et sons font partie du décors, leur moment de démarrage n’est pas très important. Le but est réellement d’émuler un GIF avec les avantages du JPEG (taille, couleurs, son), et avec la souplesse du Javascript pour certains effets (latence non constante entre les images, effets d’accélération, paramètres aléatoires, boucle en ping-pong, contrôle)...

a. Animations fluides JPEG cycliques

La principale différence technique des animations de fond par rapport aux autres est qu’il n'est pas nécessaire que tous les éléments de la page soient chargés pour qu'elles démarrent. On a les fonctions habituelles (CHECK, SUBST, LAUNCH), mais le chargement des substituts se fait directement dans les balises Javascript du header. Le lancement de la fonction LAUNCH se fait normalement, après un onLoad, ou dans la fonction "initialisation()" s'il y en a une. Dans l'ensemble, ce sont des séquences mises en boucle.

 

// ELEMENTS DE L'ANIMATION DE FOND "NOM"

 

 var nb_img=X;

 var latence=XX;

 tableau_nom_anim=new Array();

 

// FONCTIONS : initialisation, CHECK, SUBST, LAUNCH

 

La fonction d'initialisation bien sûr, mais aussi les fonctions CHECK et LAUNCH, sont identiques aux fonctions de séquence. La seule différence concerne l'initialisation des substituts, faite directement.

Typiquement, pour la fonction SUBST, on a une mise en boucle :

 

  function nom_anim_SUBST(etape)

  {

    document.nom_doc.src=tableau_nom_anim[etape].src;

 

    etape++;

    etape=etape%nb_img;

 

    setTimeout('nom_anim_SUBST(' + etape + ')',latence);

 

    return true;

  }

 

ATTENTION : pour certains types d'animations (stroboscopes, scènes avec popups), il peut être préférable de provoquer les substitutions d'image par un onLoad (avec setTimeout) dans le tag IMG de l'image. En effet, Internet Explorer a la mauvaise habitude d'oublier les images préchargées, et faire l'opération dans un onLoad empêche les saccades de l'animation dues à un rechargement inutile.

b. Sons d’ambiance

Les sons d’ambiance sont tout bonnement des effets sonores ou des musiques en boucle. Dans le même esprit qu’un GIF animé, ils démarrent donc quand ils le peuvent, et n’ont pas vraiment de début ou de fin, même s’ils peuvent ponctuellement commencer par une transition (une introduction, ou une transition du silence à la boucle).

(RETOUR A L'INDEX)

4)Animations et sons d’évènements

Les animations d’évènement sont totalement interactives : cela veut dire que l’utilisateur n’est pas seulement capable de démarrer l’animation, mais aussi d’influencer son déroulement. Typiquement se sont des rollovers qui s’animent de façon fluide et qui réagissent selon le mouvement de la souris (dans le cas d’une porte : elle s’ouvre quand on passe dessus et se ferme quand on part, mais cela sans point d’arrêt, potentiellement en plein milieu de la suite d’images).

a. Animations d’évènements

Le principe de l’animation est que son évolution est gérée par la fonction SUBST si une de ses itération est encore en cours (ou en attente de l’être par setTimeout, on dit alors que l’animation est "mobile"), ou, sinon, elle est lancée par l’évènement onMouseOver ou onMouseOut, lui-même déclenchant la fonction SUBST.

Si une itération de SUBST est en court, elle adapte donc l’animation en fonction du mouvement de l’utilisateur. Cette information (souris étant dans la zone concernée ou non) est stockée dans une variable globale. Eventuellement, la fonction peut tenir compte d’autres paramètres (si une zone a été ou non cliquée, par exemple).

Initialement, tout est démarré par onMouseOver ou onMouseOut. Bien sûr, les images de l’animation doivent être entièrement (et directement) chargées avant exécution (le reste de la page n’a pas à être chargé puisque déclencher l’animation ne fait pas quitter la page, et l’animation peut être rejouée plus tard).

On teste le chargement avec la fonction CHECK standard, avec juste une différence de nomenclature commune à toutes les animations d’évènements :

 

  function NOM_ANIM_check()

  {

    if (tableau_nom_anim.length==0) return false;

 

    for (i=0;i<=NOM_ANIM_nb_img-1;i++)

    {

      if (!tableau_nom_anim[i].complete) return false;

    }

 

    if (document.nom_swf.PercentLoaded()!=100) return false;

 

    return true;

  }

 

En effet, comme leur code est plus "acteur", interactif, on met "NOM_ANIM" en majuscules et le complément en minuscules dans tous les noms de fonction. Cela rend la lecture du code plus lisible, surtout avec plusieurs types d’animations présents.

Les variables de l’animation sont plus nombreuses que pour les autres types, l’animation étant dynamique. Elles portent toutes le nom de l’animation en préfixe puisque l’animation est centrée autour d’un objet de la page précis, avec lequel on peut interagir (on est donc plus proche de la programmation objet). Comme les autres cas, les variables sont déclarées en début de page, ici sous cette forme (respecter le saut de ligne pour séparer les constantes des variables dynamiques) :

 

// ELEMENTS DE L'ANIMATION D’EVENEMENT "NOM"

 

 var NOM_ANIM_nb_img=X;

 var NOM_ANIM_latence=XX;

 tableau_nom_anim=new Array();

 

 var NOM_ANIM_etape=0;

 var NOM_ANIM_over=false;

 var NOM_ANIM_mobile=false;

 

// FONCTIONS : initialisation, CHECK, SUBST

 

La fonction SUBST est donc initialement lancée par l’évènement onMouseOver ou onMouseOut, dont la forme est très importante. On peut la modifier pour ajouter des conditions ou générer certains effets. Classiquement on a :

 

onMouseOver="window.status=''; NOM_ANIM_over=true; if (NOM_ANIM_check()&&(!NOM_ANIM_mobile)) {NOM_ANIM_subst()} return true"

 

Le code pour onMouseOut est à peu près le même (seul NOM_ANIM_over change) :

 

onMouseOut="window.status=''; NOM_ANIM_over=false; if (NOM_ANIM_check()&&(!NOM_ANIM_mobile)) {NOM_ANIM_subst()} return true"

 

Dans la plupart des cas, on a un onClick entre les deux. Classiquement, il s’agit d’un lien qui n’est validé que si on est à la dernière étape de l’animation (dans le cas type d’une porte qui s’ouvre, par exemple, le lien n’est validé que si la porte est entièrement ouverte). L’adresse par défaut (paramètre href), comme toujours dans ce type de cas, est "javascript:void(0)". En onClick, on a le code :

 

onClick="if (NOM_ANIM_etape==NOM_ANIM_nb_img-1) {this.href='adresse.html'} else {return false}"

 

Enfin, la fonction SUBST. La version classique ci-dessous fait aller l’animation dans un sens ou l’autre dès que l’utilisateur entre ou sort de la zone cliquable. Sa structure peut facilement s’adapter à différents effets : choix de faire jouer l’animation jusqu’au bout avant de revenir dans l’autre sens, latence différente selon que l’on va dans un sens ou l’autre, etc.

Le code présenté ici n’intègre pas de commande de fichier son (par Flash). Si on décide de mettre du son avec l’animation, il faut ajouter une ligne "document.nom_swf.Play();" après un test sur le numéro de l’étape de l’animation, lui même intégré dans le test général sur le sens de l’animation (classiquement, on joue le son à l’étape (0) ou (NOM_ANIM_nb_img-1)).

Le chargement du fichier Flash, comme on l’a vu plus haut, est testé dans la fonction CHECK. On verra dans le sous-chapitre suivant quels sont les paramètres de ces fichiers Flash de son d’évènement.

 

  function NOM_ANIM_subst()

  {

    if (NOM_ANIM_over)

    {

      if (NOM_ANIM_etape<NOM_ANIM_nb_img-1)

      {

        NOM_ANIM_etape++;

        document.nom_doc.src=tableau_nom_anim[NOM_ANIM_etape].src;

        NOM_ANIM_mobile=true;

        setTimeout('NOM_ANIM_subst()',NOM_ANIM_latence);

      }

      else NOM_ANIM_mobile=false;

    }

    else

    {

      if (NOM_ANIM_etape>0)

      {

        NOM_ANIM_etape--;

        document.nom_doc.src=tableau_nom_anim[NOM_ANIM_etape].src;

        NOM_ANIM_mobile=true;

        setTimeout('NOM_ANIM_subst()',NOM_ANIM_latence);

      }

      else NOM_ANIM_mobile=false;

    }

 

    return true;

  }

 

b. Sons d’évènements

C’est le type de son le plus simple, il correspond tout à fait à la définition des sons "Evènement" de Flash. C’est un son court, comme une porte qui claque, une ampoule qui grésille, etc. qui peut être réutilisé plusieurs fois par interaction de l’utilisateur avec l’animation associée.

Le fichier est chargé directement et incorporé dans la page avec les options : play=false, loop=false, pas de fscommand. Son format est très, très simple et toujours le même :

 

·       une image vide

·       le son en évènement (le scénario va au bout du son)

 

... et c’est tout. Ces fichiers sont utilisés comme une touche de piano : on appuie, on a le son, on relâche. On appuie, on a de nouveau le son, etc. Eventuellement, on peut regrouper différents sons d’évènements dans un seul fichier, et adapter le concept à plusieurs objets/sons dans un même fichier plutôt que plusieurs fichiers ayant chacun un son.

(RETOUR A L'INDEX)


Annexe – La Red Room

1)Dialogues

Contrairement au reste du site, les dialogues sont à peu près tous gérés par Flash (en particulier les dialogues dans les popups). Les dialogues de la Black Lodge sont en effet plus longs, et la procédure par Javascript devient du coup trop lourde en temps de chargement, et surtout trop laborieuse.

2)Popups

On utilise la barre CSS par défaut dans les popups de la Black Lodge.

3)Aléatoire

On conserve des données sur les éléments déjà affichés dans une frame de commande, commune à toute la Black Lodge. L'aléatoire est entièrement géré dans la page de cette frame.

(RETOUR A L'INDEX)