Zoom interactif en Lingo (D6) 

 

 

 

Seul moyen d'exploiter une image de grande dimension, carte ou tableau d'art sur la scène de Director, le zoom interactif est devenu un grand classique des Cédés sur la peinture. Le CrapoWeb vous propose de suivre la réalisation de cet exercice qui ne requiert qu'un peu de Lingo et aussi... un peu d'arithmétique.

Pour explorer la carte, déplacez le petit rectangle jaune :

 

Afin de bien préparer les acteurs requis par cette animation, il convient de s'interroger sur son principe : Les déplacements du petit rectangle jaune sur la petite carte induisent des déplacements proportionnels de la grande carte. Si l'on nomme "ratio" le rapport des deux cartes, on peut aisément imaginer que la grande carte est à chaque déplacement, positionnée suivant la formule :

nouvellePositionDeLaGrandeCarte = positionInitialeDeLaGrandeCarte + déplacement * ratio

A l'usage néanmoins, on risque fort de s'apercevoir que l'unité de pixel utilisée pour mesurer les déplacements rend vaine toute tentative de conserver une quelconque précision décimale au rapport. S'il on veut donc obtenir une relative précision, IL FAUT DÈS LA CRÉATION DES ACTEURS veiller à ce que ce rapport (dimension de la grande carte/dimension de la petite) reste entier.

C'est ce que nous avons fait, en conférant à la carte miniature des dimensions spécifiques 33 X 32...

 

 

...qui l'accordait à la grande carte. Ici un fichier vectoriel au format Flash 2 de 999 X 960.

 

 

Le rapport des deux largeurs 999/33 comme aussi des deux hauteurs 960/32 est un entier et cette condition était indispensable à la bonne marche de notre projet.

 

Construction du scénario

Les deux cartes sont importées dans la distribution et placées sur la scène de Director piste 1 et 3. On donne à la grande carte une position aisément identifiable; par exemple on aligne son coin supérieur droit sur le bord droit de la scène. Le rectangle jaune est un acteur forme au fond transparent que l'on dispose piste 5. Pour que ce rectangle ne sorte pas des limites de la carte, on utilise une nouvelle fois l'acteur forme (contour rouge sur notre dessin mais sans aucun contour et donc invisible en réalité) piste 4. Le coin supérieur gauche - point de référence - du rectangle jaune piste 5 sera contenu à l'intérieur du sprite 4 à l'aide de la propriété constraint.

 

 

 

On immobilise la tête de lecture sur un tableau quelconque et on contraint les déplacements du rectangle jaune.

on exitFrame
  if not the constraint of sprite 5 then set the constraint of sprite 5 to 4
  go the frame
end

 

 

Nous souhaitons maintenant déplacer la carte en même temps que l'utilisateur déplacera le rectangle jaune avec sa souris. On sélectionne le sprite correspondant sur le scénario (piste 5) et on clique sur l'icône losange pour appeler l'éditeur de comportement. Au rectangle jaune nous associons les lignes Lingo suivantes  :

 

on mouseEnter me
    cursor [11,12]
end

--- 11 et 12 étant les numéros de deux acteurs noir/blanc qui servent ici respectivement de curseur personnalisé et de masque de curseur.

on mouseLeave
     cursor 0
end mouseLeave

--- Quand la souris s'éloigne, on restitue au curseur sa forme normale en lui affectant la valeur 0

 

Le script de mouseDown

Voyons maintenant le script de mouseDown, c'est-à-dire le script qui sera exécuté lors du cliquer-glisser sur le rectangle : Nous devons obtenir  : 1) le déplacement du rectangle jaune suivant les mouvements de la souris, 2) le déplacement proportionnel de la grande carte; et ce tout le temps que la souris est enfoncée.

1) Le premier problème est un classique : nous ne pouvons pas simplement aligner le point de référence du sprite à déplacer sur la position de la souris car l'utilisateur est susceptible de placer son pointeur diversement au dessus le rectangle. Le sprite doit être déplacé en même temps que la souris mais garder ses distances (initiales). On mesure donc en tout premier lieu l'écart entre le sprite et le pointeur (decalageH et decalageV) au début du cliquer-glisser. C'est seulement après, tenant compte de cet écart, que l'on déplace répétitivement le rectangle :

on mouseDown me

   set decalageH to (the locH of sprite the spritenum of me) - the mouseH
   set decalageV to (the locV of sprite the spritenum of me) - the mouseV

   repeat while the stilldown

        set the loc of sprite the spritenum of me to point( the mouseH + decalageH, the mouseV + decalageV )

   end repeat

end

 

2) On doit désormais veiller à obtenir un déplacement proportionnel de la grande carte. Déplacer celle-ci exige que l'on ajoute ou que l'on soustraie des pixels à sa position initiale. Le nombre de pixels à retirer ou ajouter est bien-sûr fonction du déplacement subi par le rectangle jaune. L'importance de ce déplacement peut être connue à tout moment par la formule :

DeplacementDuRectangleJaune = PositionInitialeDuRectangleJaune - PositionActuelleDuRectangleJaune.

La grande carte doit être déplacée proportionnellement. Proportionnellement : c'est-à-dire que lorsque le rectangle jaune parcours la totalité de la largeur de la carte miniature, la grande carte doit connaître un déplacement exactement inverse qui lui fait parcourir la surface de visualisation de part en part. La formule qui détermine les déplacements de la grande carte (ajout ou retrait de pixels à sa position initiale) est bien comme nous l'avons écrit :

DeplacementDeLaGrandeCarte = DeplacementDuRectangleJaune * RATIO

...où ratio représente le rapport des dimensions des deux cartes.

Pour compléter notre script nous avons donc besoin de connaître plusieurs valeurs : les positions initiales de la grande carte, du petit rectangle jaune et le rapport des dimensions des deux cartes. Afin que ces valeurs constantes ne soient calculées qu'une fois et disponibles tout le temps nous créons un script d'animation qui les détermine au début de l'animation. On appelle la commande script du menu fenêtre de Director et l'on saisit le gestionnaire suivant :

global positionInitialeDelaGrandeCarte, positionInitialeDuPetitRectangle, ratioH, ratioV

on startMovie
   set positionInitialeDelaGrandeCarte to the loc of sprite 1
   set positionInitialeDuPetitRectangle to the loc of sprite 5

   set ratioH to (the width of sprite 1) / the width of sprite 3
   set ratioV to (the height of sprite 1) / the height of sprite 3
end

 

Notre animation disposera désormais de variables globales (visibilité permanente) contenant les infos nécessaires. Pour accéder à la position horizontale de la carte, on extraira de la variable liste positionInitialeDelaGrandeCarte la première valeur :
exemple getAt( positionInitialeDelaGrandeCarte, 1 ).
Nous retournons dès lors modifier le comportement attaché au rectangle jaune. Notre script nous le savons, doit à chaque instant mesurer le déplacement subi par le rectangle jaune et faire subir à la grande carte un déplacement proportionné. Parce que ces opérations sont effectuées au sein d'un boucle repeat on forcera le rafraîchissement permanent de la scène à l'aide de la commande updateStage.

 

on mouseDown me

   global positionInitialeDelaGrandeCarte, positionInitialeDuPetitRectangle, ratioH, ratioV

   set decalageH to (the locH of sprite the spritenum of me) - the mouseH
   set decalageV to (the locV of sprite the spritenum of me) - the mouseV

   repeat while the stilldown

        set the loc of sprite the spritenum of me to point( the mouseH + decalageh, the mouseV + decalagev )

set deplacementh to getAt ( positionInitialeDuPetitRectangle, 1) - the locH of sprite the spritenum of me
set deplacementv to getAt (
positionInitialeDuPetitRectangle, 2) - the locV of sprite the spritenum of me

set the loc of sprite 1 to point ( getAt( positionInitialeDelaGrandeCarte, 1 ) + deplacementH * ratioH, getAt ( positionInitialeDelaGrandeCarte, 2 ) + deplacementV * ratioV )

updateStage

   end repeat

end

 

 Si c'est un bitmap de grande taille que l'on expose ainsi, un processeur puissant est requis.

Les utilisateurs de Director 7 ou ultérieur étudieront avec profit le fonctionnement de la fonction map()