| 1 | Le fond | |
| 2 | Les boutons | |
| 3 | Le source des animations | |
| 4 | L'emballement final | |
Voici les différents fichiers ou patrons qui m'ont servi à monter la version des chorégraphies de C. Simò sous forme d'animations flash.
Le fond est composé avec MetaPost, comme il y a des éléments variables j'utilise un patron fond.pat (les éléments qui varient sont identifiés sous la forme %%élément%%), le fichier résultant porte le nom fond.mp.
% clés : num titre
prologues := 1;
verbatimtex
%&latex
\documentclass[10pt]{article}
\usepackage[latin1]{inputenc}
\usepackage{t1enc}
\usepackage{times}
\begin{document}
etex
beginfig(1);
fill (0,0)--(600,0)--(600,400)--(0,400)--cycle
withcolor (72/255,86/255,146/255);
labeloffset := 0;
label(btex \textbf{Syracuse} etex xscaled 12 yscaled 5,(300,372))
withcolor(92/255,106/255,166/255);
label.rt(btex \it\textbf{Les chorégraphies} etex scaled 3,(10,380))
withcolor white;
label.lft(btex
\textsf{%%titre%%}
etex xscaled 1.85 yscaled 1.5,(590,355))
withcolor 0.8white;
label.lft(btex
\textsf{%%num%%}
etex xscaled 2.5 yscaled 1.8,(590,373))
withcolor (235/255,235/255,165/255);
endfig;
end
Une fois ce fichier chargé et compilé, je dispose d'un fichier fond.1 que je transforme en pdf en m'aidant d'un fichier pilote fond.ps.
<</PageSize [600 400]>> setpagedevice
/TeXBase1Encoding [
% 0x00 (encoded characters from Adobe Standard not in Windows 3.1)
/.notdef /dotaccent /fi /fl
/fraction /hungarumlaut /Lslash /lslash
/ogonek /ring /.notdef
/breve /minus /.notdef
% These are the only two remaining unencoded characters, so may as
% well include them.
/Zcaron /zcaron
% 0x10
/caron /dotlessi
% (unusual TeX characters available in, e.g., Lucida Bright)
/dotlessj /ff /ffi /ffl
/.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef
% very contentious; it's so painful not having quoteleft and quoteright
% at 96 and 145 that we move the things normally found there down to here.
/grave /quotesingle
% 0x20 (ASCII begins)
/space /exclam /quotedbl /numbersign
/dollar /percent /ampersand /quoteright
/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
% 0x30
/zero /one /two /three /four /five /six /seven
/eight /nine /colon /semicolon /less /equal /greater /question
% 0x40
/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
% 0x50
/P /Q /R /S /T /U /V /W
/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
% 0x60
/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
% 0x70
/p /q /r /s /t /u /v /w
/x /y /z /braceleft /bar /braceright /asciitilde
/.notdef % rubout; ASCII ends
% 0x80
/Euro /.notdef /quotesinglbase /florin
/quotedblbase /ellipsis /dagger /daggerdbl
/circumflex /perthousand /Scaron /guilsinglleft
/OE /.notdef /.notdef /.notdef
% 0x90
/.notdef /.notdef /.notdef /quotedblleft
/quotedblright /bullet /endash /emdash
/tilde /trademark /scaron /guilsinglright
/oe /.notdef /.notdef /Ydieresis
% 0xA0
/.notdef % nobreakspace
/exclamdown /cent /sterling
/currency /yen /brokenbar /section
/dieresis /copyright /ordfeminine /guillemotleft
/logicalnot
/hyphen % Y&Y (also at 45); Windows' softhyphen
/registered
/macron
% 0xD0
/degree /plusminus /twosuperior /threesuperior
/acute /mu /paragraph /periodcentered
/cedilla /onesuperior /ordmasculine /guillemotright
/onequarter /onehalf /threequarters /questiondown
% 0xC0
/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
/Egrave /Eacute /Ecircumflex /Edieresis
/Igrave /Iacute /Icircumflex /Idieresis
% 0xD0
/Eth /Ntilde /Ograve /Oacute
/Ocircumflex /Otilde /Odieresis /multiply
/Oslash /Ugrave /Uacute /Ucircumflex
/Udieresis /Yacute /Thorn /germandbls
% 0xE0
/agrave /aacute /acircumflex /atilde
/adieresis /aring /ae /ccedilla
/egrave /eacute /ecircumflex /edieresis
/igrave /iacute /icircumflex /idieresis
% 0xF0
/eth /ntilde /ograve /oacute
/ocircumflex /otilde /odieresis /divide
/oslash /ugrave /uacute /ucircumflex
/udieresis /yacute /thorn /ydieresis
] def
% Activer l'encodage ISO latin1 au moment de la conversion
/ISOEncode {
dup length dict begin
{1 index /FID ne {def} {pop pop} ifelse} forall
/Encoding TeXBase1Encoding def
currentdict
end
/Temporary exch definefont
} bind def
% Récupération dans le systemdict de la procédure setfont
/syssetfont {
systemdict /setfont get exec
} def
% Création dans le userdict d'une procédure setfont adaptée
/setfont {ISOEncode syssetfont} def
% Documentation du PDF
[ /Author (Jean-Michel Sarlat) /DOCINFO pdfmark
[ /Title (fond d'animation flash) /DOCINFO pdfmark
[ /Subject (Les chorégraphies) /DOCINFO pdfmark
[ /Creator (Metapost + ps2pdf + pdf2swf) /DOCINFO pdfmark
% Insertion du code généré par MetaPost (prologues != 0)
(fond.1) run
Il ne reste plus qu'à transformer en clip d'animation à l'aide de pdf2swf.
Les trois boutons + rapide, + lent et trace o/n sont aussi écrits avec MetaPost en s'appuyant sur une procédure bouton définie dans btn.mp.
vardef bouton(expr txt) =
picture $;
path $$;
pair BLLC,BULC,BURC,BLRC;
numeric RRAY,wray;
wray = 4pt;
RRAY = 1-1/sqrt(2);
$ = thelabel(txt,(0,0)); % acquisition du texte à encadrer sous forme d'image
BLLC = (0,0) ; BULC = (0,14);
BURC = (50,14); BLRC = (50,0);
% construction du bord de la boîte
$$ = (BLLC + (0,wray)) -- (BULC - (0,wray)) .. (BULC + RRAY*(wray,-wray)) ..
(BULC + (wray,0)) -- (BURC - (wray,0)) .. (BURC - RRAY*(wray,wray)) ..
(BURC - (0,wray)) -- (BLRC + (0,wray)) .. (BLRC + RRAY*(-wray,wray)) ..
(BLRC - (wray,0)) -- (BLLC + (wray,0)) .. (BLLC + RRAY*(wray,wray)) .. cycle;
fill $$ withcolor (1,1,0.7);
draw $ shifted (25,7);
draw $$ withcolor (0,0,.3) withpen pencircle scaled 1;
enddef;
prologues := 1;
input btn.mp;
verbatimtex
\font\sfb=cmssbx10 at 10pt
etex
beginfig(1);
bouton(btex $+$\sfb rapide etex);
endfig;
end
prologues := 1;
input btn.mp;
verbatimtex
\font\sfb=cmssbx10 at 10pt
etex
beginfig(1);
bouton(btex $+$\sfb lent etex);
endfig;
end
prologues := 1;
input btn.mp;
verbatimtex
\font\sfb=cmssbx10 at 10pt
etex
beginfig(1);
bouton(btex \sfb Trace o/n etex);
endfig;
end
Il leur est associé un fichier PostScript pour préparer la conversion en PDF.
<</PageSize [50 14]>> setpagedevice % Insertion du code généré par MetaPost (prologues != 0) (btnrapide.1) run
<</PageSize [50 14]>> setpagedevice % Insertion du code généré par MetaPost (prologues != 0) (btnlent.1) run
<</PageSize [50 14]>> setpagedevice % Insertion du code généré par MetaPost (prologues != 0) (btntrace.1) run
Les compilations sont, en fait, exécutées à l'aide d'un petit script. Ghostscript est, quand à lui, configuré pour trouver le fichier cmbx10.pfb.
mpost btntrace.mp ps2pdf14 btntrace.ps pdf2swf btntrace.pdf mpost btnlent.mp ps2pdf14 btnlent.ps pdf2swf btnlent.pdf mpost btnrapide.mp ps2pdf14 btnrapide.ps pdf2swf btnrapide.pdf rm -f *.1 *.log *.mpx btn*.pdf
Il est construit à partir d'un patron: trajectoire.pat transformé en trajectoire.sc.
# clés : nom orbite b d e nb t
.flash name="%%nom%%.swf" bbox=600x400 version=6
# Le fond de l'image
.swf fondmp "fond.swf"
# .box fond width=600 height=400 line=0 fill=fondmp
.put fondmp 0 0
# Les corps
.circle c0 r=3 color=red fill=red
.circle c1 r=3 color=blue fill=blue
.put c0 245 10 .put c1 257 10
# Le cadre de la trajectoire
.box cadre width=578 height=333 line=2 color=#886644 fill=#BBBBBB
.put cadre 11 56
.swf btntrace "btntrace.swf"
.put btntrace 535 382
.swf btnrapide "btnrapide.swf"
.put btnrapide 15 382
.swf btnlent "btnlent.swf"
.put btnlent 70 382
.sprite s0
.put c0 -3 -3
.end
.sprite s1
.put c1 -3 -3
.end
.put s0 -10 0
.put s1 -10 0
.action:
_global.orbite = %%orbite%%;
_global.b = %%b%%;
_global.d = %%d%%;
_global.e = %%e%%;
_global.nb = %%nb%%;
_global.t = %%t%%;
_global.pas = 20;
_global.trace = 1;
function posX(i,t) {
return orbite[(t + i * b) % d][0];
}
function posY(i,t) {
return orbite[(t + i * b) % d][1];
}
_root.createEmptyMovieClip("orbiteDesNCorps",1);
orbiteDesNCorps.lineStyle(1,0xAA8866,100);
orbiteDesNCorps.moveTo(orbite[0][0],orbite[0][1]);
for(var i=1; i < orbite.length; i++) {
orbiteDesNCorps.lineTo(orbite[i][0],orbite[i][1]);
}
btnrapide.onPress = function () {
if (pas > 5) {
pas /= 1.5;
}
clearInterval(tmp);
btnrapide._alpha = 60;
tmp = setInterval(deplaceCorps,pas);
};
btnrapide.onRelease = btnrapide.onReleaseOutside = function () {
btnrapide._alpha = 100;
};
btnlent.onPress = function () {
pas *= 1.5 ;
clearInterval(tmp);
btnlent._alpha = 60;
tmp = setInterval(deplaceCorps,pas);
};
btnlent.onRelease = btnlent.onReleaseOutside = function () {
btnlent._alpha = 100;
};
btntrace.onPress = function () {
var couleurs = new Color(orbiteDesNCorps);
var trans = couleurs.getTransform();
if (trace == 1) {
trans.aa = 0;
couleurs.setTransform(trans);
} else {
trans.aa = 100;
couleurs.setTransform(trans);
}
trace = 1 - trace;
btntrace._alpha = 50;
};
btntrace.onRelease = btntrace.onReleaseOutside = function () {
btntrace._alpha = 100;
};
var corps = new Array();
corps[0] = _root.attachMovie('s0','corps0',2);
for(var i=1; i < nb; i++) {
corps[i] = _root.attachMovie('s1','corps'+i,i+2);
}
function deplaceCorps() {
t += e;
t = t % d;
for(var i = 0; i < nb; i++) {
corps[i]._x = posX(i,t);
corps[i]._y = posY(i,t);
}
updateAfterEvent();
}
_global.tmp = setInterval(deplaceCorps,pas);
.end
.end
C'est un script perl qui acquiert les données, construit les patrons et actionne les compilations.
#!/usr/bin/perl
my $N = $ARGV[0];
open(LST,"simo/liste.txt"); my @liste = <LST>; chop(@liste); close(LST);
foreach (@liste) {
if ($_ =~ /^$N:/) {
($null,$fichier,$a,$b,$c,$d,$e,$f,$k,$titre) = split(/:/,$_);
$fichier =~ s/\s+$//;
$titre =~ s/^\s+//;
}
}
exit(0) if $fichier eq "";
print "Taitement de $fichier ($N)\n";
print " -> construction des patrons...\n";
$orbite = `./orb2tab.pl simo/$fichier`;
$orbitemp = `./orb2path.pl simo/$fichier`;
$orbitemp =~ s/§/\n/g;
%C = (
orbite => $orbite,
orbitemp => $orbitemp,
nom => sprintf("simo%02d",$N),
a => $a,
b => $b,
c => $c,
d => $d,
e => $e,
f => $f,
t => 1,
nb => sprintf("%d", $d/$b),
num => $N,
titre => $titre
);
open(MP,">fond.mp");
print MP &Patron("fond.pat",\%C);
close(MP);
open(MP,">image.mp");
print MP &Patron("image.pat",\%C);
close(MP);
open(SC,">trajectoire.sc");
print SC &Patron("trajectoire.pat",\%C);
close(SC);
open(HTM,">$C{nom}.html");
print HTM &Patron("popup.pat",\%C);
close(HTM);
open(HTM,">$C{nom}w.html");
print HTM &Patron("popupw.pat",\%C);
close(HTM);
print " -> compilations vers swf...\n";
print `. compilations1`;
print " -> compilations vers png...\n";
print `. compilations2`;
if (-e "image.png") {
print `mv image.png $C{nom}.png`;
}
if (-e "image.mp") {
print `mv image.mp $C{nom}.mp`;
}
sub Patron {
my ($nom_patron,$remplissage) = @_;
my $texte;
local $/;
local *F;
open (F,"< $nom_patron\0") || return;
$texte = <F>;
close(F);
$texte =~ s{ %%(.*?)%% }
{ exists( $remplissage->{$1} )
? $remplissage->{$1}
: ""
}gsex;
return $texte;
}
#!/usr/bin/perl
$n = 0; # Compteur
$xmax = $ymax = -1000; # maximums en abscisse et ordonnée
$xmin = $ymin = 1000; # minimums en abscisse et ordonnée
# === Acquisition des points de la trajectoire
open(F,"$ARGV[0]"); @liste = <F>; close(F); chop(@liste);
foreach (@liste) {
if ($_ ne "") {
$n++;
($null,$x,$y) = split(/\s+/,$_);
$xmax = $x if $x > $xmax;
$xmin = $x if $x < $xmin;
$ymax = $y if $y > $ymax;
$ymin = $y if $y < $ymin;
push(@X,$x); push(@Y,$y);
}
}
$fx = ($xmax - $xmin) / 558.0;
$fy = ($ymax - $ymin) / 310.0;
$f = $fx > $fy ? $fx : $fy ;
$mx = ($xmin + $xmax) / 2;
$my = ($ymin + $ymax) / 2;
$n = 0 ;
print STDOUT "[";
while(@X) {
$n++;
$x = shift @X;
$x = sprintf("%.3f",($x - $mx) / $f + 300);
$y = shift @Y;
$y = sprintf("%.3f",($my - $y) / $f + 223);
if ($n == 1) {
print STDOUT "[$x,$y]";
} else {
print STDOUT ",[$x,$y]";
}
}
print STDOUT "]";
#!/usr/bin/perl
$n = 0; # Compteur
$xmax = $ymax = -1000; # maximums en abscisse et ordonnée
$xmin = $ymin = 1000; # minimums en abscisse et ordonnée
# === Acquisition des points de la trajectoire
open(F,"$ARGV[0]"); @liste = <F>; close(F); chop(@liste);
foreach (@liste) {
if ($_ ne "") {
$n++;
($null,$x,$y) = split(/\s+/,$_);
$xmax = $x if $x > $xmax;
$xmin = $x if $x < $xmin;
$ymax = $y if $y > $ymax;
$ymin = $y if $y < $ymin;
push(@X,$x); push(@Y,$y);
}
}
$fx = ($xmax - $xmin) / 300;
$fy = ($ymax - $ymin) / 300;
$f = $fx > $fy ? $fx : $fy ;
$mx = ($xmin + $xmax) / 2;
$my = ($ymin + $ymax) / 2;
$n = 0 ;
while(@X) {
$n++;
$sep = ($n % 5) == 1 ? "§" : "";
$x = shift @X;
$x = sprintf("%.3f",($x - $mx) / $f + 160);
$y = shift @Y;
$y = sprintf("%.3f",($y - $my) / $f + 160);
if ($n == 1) {
print STDOUT "($x,$y)";
} else {
print STDOUT "$sep..($x,$y)";
}
}
mpost fond.mp ps2pdf14 fond.ps pdf2swf fond.pdf swfc trajectoire.sc rm -f fond.1 fond.mpx fond.log fond.swf