Les Masques
Nous avons sans doute observé que l'édition de masque dans After Effects était
plutôt limitée et qu'un masque par exemple ne pouvait pas être contrôlé par expression.
En revanche dans le scripting, toutes les données relatives à la forme d'un masque (ses points et les tangentes aux points)
sont des tableaux de données accessibles, dont le contenu peut être animé au cours du temps. On pourrait par exemple donner
individuellement une trajectoire aux points d'ancrage du masque ou encore lier leur mouvement à une composante audio.
La propriété de Masque est en réalité un groupe de propriété (ce "PropertyGroup" est appelé property("Masks") ou Masks). Ce groupe contiendra l'ensemble des masques
appliqués au calque ("Masque 1", "Masque 2", etc).
Il faudra donc être vigilent pour accéder à ses propriétés afin de pouvoir les manipuler.
Supposons que nous ayons une composition contenant un seul solide auquel on aimerait ajouter un masque. On aura au préalable récupéré notre objet calque
dans une variable "mySolid" avec une instruction de ce type par exemple :
mySolid = app.project.activeItem.layer(1);
On rappelle ici pour se fixer les idées que les objets s'imbriquent les uns dans les autres et qu'il faut respecter leur hiérarchie.
Dans l'instruction précédente "app" désigne l'application (After Effects), "project" représente notre projet, "activeItem" est l'élément actif du projet
(ici on suppose qu'il s'agit de notre composition) et enfin "layer(1)" désigne le premier calque de l'élément actif.
Nous ajoutons un masque à un calque par l'intermédiaire de la méthode addProperty().
L'instruction suivante va ajouter au calque une propriété de masque et la stocker dans la variable "myMask" :
myMask = mySolid.property("Masks").addProperty("Mask");
que nous pouvons également écrire sous la forme :
myMask = mySolid.Masks.addProperty("Mask");
Nous pouvons accéder à un masque en précisant sa position (i.e. son index) parmi son groupe de propriété.
Remarque : nous pouvons à tout moment dans l'élaboration d'un script nous aider des fonctions d'affichage
telle que la fonction "alert()" pour contrôler que notre syntaxe est correcte et vérifier à quel endroit nous nous situons.
alert("Mon premier masque s'appelle " + mySolid.Masks.property(1).name);
Pour l'instant comme nous n'avons rien précisé quand à sa forme, le masque a la forme du solide.
Nous allons donc "descendre d'un niveau" et accéder à la propriété Forme d'un masque ( maskShape ) pour lui en attribuer une.
Note : soyons prudents car les erreurs sont fréquentes lorsqu'il s'agit de propriétés imbriquées les unes
dans les autres au sein d'un "PropertyGroup", c'est pourquoi il est préférable de récupérer dans des variables les propriétés
que l'on parcourt et réaliser cela en plusieurs étapes, plutôt que de chercher à tout prix à minimiser le nombre
d'instructions en écrivant par exemple 3 fois le terme "property()" dans une même ligne de code.
L'instruction suivante définit la variable "myMaskShape" comme étant la propriété Forme du masque de notre masque.
myMaskShape = myMask.property("maskShape");
Remarque : nous pouvons aussi accéder à cette propriété en précisant simplement sa position.
La "Forme du masque" étant la première propriété d'un masque, nous aurions pu écrire de façon équivalente :
myMaskShape = myMask.property(1);
Nous créons maintenant un objet Shape qui servira de forme pour le masque, ce sera sa valeur (value).
Cet objet "Shape" possède 4 attributs : "closed", "vertices", "inTangents" et "outTangents".
L'attribut closed spécifie si la courbe est fermée ou non.
L'attribut vertices désigne l'ensemble des points d'ancrage de la forme. Il s'agit d'un tableau dont chaque élément est une paire de valeur
(un couple), représentant l'abscisse et l'ordonnée d'un point de la forme.
Les attributs inTangents et outTangents sont également des tableaux dont les éléments sont des paires de valeur,
chacune représentant la valeur de la tangente, i.e. un vecteur, se rapprochant ("inTangents") ou s'éloignant d'un point ("outTangents").
Notons que par défaut ces deux attributs sont nuls,
et que dans le cas d'un masque rotoBézier ( avec l'instruction myMask.rotoBezier = true; après avoir créé sa forme),
ces attributs n'auront plus à être spécifiés car ils seront automatiquement calculés.
Une fois que notre forme est créée, on l'affecte à la Forme du masque par la méthode setValue().
Supposons que l'on veuille créer un masque rectangulaire de taille 200*100, centré par rappport à la composition de taille 320*240,
nous pouvons écrire quelque chose comme cela (à la suite des instructions précédentes bien entendu):
myShape = myMaskShape.value;
myShape.vertices = [[60,70],[60,170],[260,170],[260,70]];
myShape.closed = true;
myMaskShape.setValue(myShape);
Si nous souhaitons avoir un masque avec des courbes (des arrondis),
il faut préciser la valeur des tangentes. On aurait pu écrire cela par exemple :
myShape = myMaskShape.value;
myShape.vertices = [[20,120],[160,220],[300,120],[160,20]];
myShape.inTangents = [[0,-100],[-120,0],[0,100],[120,0]];
myShape.outTangents = [[0,100],[120,0],[0,-100],[-120,0]];
myShape.closed = true;
myMaskShape.setValue(myShape);
Nous pouvons aussi paramétrer le mode de masque. Cet attribut de masque est noté maskMode et sa valeur est un type énuméré :
MaskMode.ADD, MaskMode.SUBTRACT ou encore MaskMode.INTERSECT (on consultera le guide pour les autres modes de masque possibles). On écrirait par exemple
myMask.maskMode = MaskMode.SUBTRACT; .
On pourra également inverser un masque en utilisant l'attribut inverted. Il faudra fixer la valeur
de cet attribut à "true" pour activer l'inversion ( myMask.inverted = true; ).
Pour finir cette partie, notons qu'il est possible d'animer la position des points ainsi que la valeur de leurs tangentes.
Pour réaliser cela, il faut utiliser la méthode setValueAtTime() au sein d'une boucle, avec une instruction du type :
myMaskShape.setValueAtTime(i,myShape);
et mettre à jour la forme du masque entre les différentes itérations.
En utilisant cette méthode nous pouvons essayer de relier le mouvement des sommets à une composante audio.
Le scripting ne permet pas de convertir des données audio en images clés, mais en supposant que nous ayons fait
au préalable cette manipulation, on peut à l'aide d'une boucle parcourant toutes les images de la composition, récupérer les valeurs de l'audio et les stocker dans un tableau.
Il ne nous reste plus qu'à exprimer la valeur des points et de leurs tangentes en fonction de ces données.
Le script qui a réalisé cette animation n'est pas donné ici car il est relativement long, mais retenons simplement qu'il est possible d'animer un masque en fonction d'une composante audio comme ici
ou d'une autre propriété de la composition (les points de piste d'un suivi de mouvement par exemple).
|