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