EuroAnim

From Wiki
Jump to navigation Jump to search

< Sample documents

Since the PDF specification allows JavaScript embedded in Documents, we can create simple animation in JavaScript. The Metafun Handbook has an example. This is slightly modified to demonstrate how the new european currency symbol is created.

Let us start with some general declarations:

\setupoutput[pdftex]
\setupcolors[state=start]
\setupinteraction[state=start,openaction=]
%\setupinteraction[state=start,openaction=ResetForm]

\setuppapersize[A4,landscape][A4,landscape]

The JavaScript implementation varies among different Acrobat Reader version, so you might need some other initialization then above. I am not going to explain all the metapost stuff here, for a description see my article in the MAPS. I start with some global variables:

\startbuffer[a]
path unitcircle; unitcircle:=fullcircle scaled 2;

path inner, outer; % the big circle: inner and outer part
path hbar;         % horizontal bar
path a[];          % aux paths for intersections
path clippath;     % path for clipping 
pair topbarleft, bottombarleft; 
pair o[];          % official points :-)
pair c[];          % clip points
path bb;           % max. bounding box of the picture
picture cp;        %currentpicture for clipping
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% calculate points

u :=1cm;
radius:=5.5u;
topbarlength := 10u;
thickness:=1u;



% for the size of the picture, first draw everything, remember the
% size and use it.
def calculate_bb =
 draw_circle;
 draw_tophbar;
 draw_bottomhbar;
 bb:=boundingbox currentpicture;
 cp:= currentpicture;
 currentpicture := nullpicture;
enddef ; 

def setbb =
    setbounds currentpicture to bb;
enddef;

% these are the ``official'' points
o1 = (0 ,-radius-.5thickness);    
o2 = dir  40 * (radius-.5thickness);
o3 = dir -40 * (radius-.5thickness);

% the very strange angle at the ends of the two vertical bars and the
% upper right edge of the C 
alpha := angle (o2-o1);

a1 := o1 -- o2;      % the right slant
a2 := origin -- o3;  % the lower 40deg. angle


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% the bars
hbar := unitsquare xscaled topbarlength yscaled thickness
               slanted (1/tand (alpha));

% top bar lrcorner:
c3 := ((-infinity,0.5u) -- (infinity , 0.5u)) intersectionpoint a1; 

topbarleft    := (xpart c3 - topbarlength , 0.5u);
bottombarleft := (xpart c3 - topbarlength ,-1.5u);

def draw_circle =
   pickup pencircle scaled thickness;
   draw unitcircle scaled radius;
enddef;

def draw_tophbar =
  pickup pencircle scaled 1pt;
  fill hbar shifted topbarleft;
enddef;

def draw_bottomhbar =
  pickup pencircle scaled 1pt;
  fill hbar shifted bottombarleft;
enddef;

calculate_bb;

% clip the right part
c2 := a1  intersectionpoint a2;
c4 := o2 + dir alpha *2u;
c6 := (xpart  o3, ypart lrcorner cp);

outer := unitcircle scaled (radius+.5thickness);
c1 := (o1--c4) intersectionpoint outer;


clippath := llcorner cp -- c6 -- o3 -- c2 -- c1 -- 
          (xpart c1,ypart urcorner cp) -- ulcorner cp -- cycle ;

def draw_dot expr p = 
  draw p withpen pencircle scaled 3pt ; 
enddef ; 

def stand_out = 
  drawoptions(withcolor .625red) ; 
enddef ;

def draw_clippath =
   pickup pencircle scaled 2pt;
   draw clippath;
enddef;

def clipright =
  clip currentpicture to clippath;
enddef;

def draw_lines =
  draw a1 dashed evenly withcolor .7white withpen pencircle scaled 1pt;
  draw origin -- o2 dashed evenly withcolor .7white 
        withpen pencircle scaled 1pt;
  draw origin -- o1 dashed evenly withcolor .7white 
        withpen pencircle scaled 1pt;
  draw a2  dashed evenly withcolor .7white withpen pencircle scaled 1pt;
enddef;
\stopbuffer

I now define the animation steps:

\startbuffer[1]
stand_out; draw_circle; draw_lines; setbb;
\stopbuffer

\startbuffer[2]
draw_circle; stand_out; draw_tophbar; draw_lines; setbb;
\stopbuffer

\startbuffer[3]
draw_circle; draw_tophbar; stand_out; draw_bottomhbar; draw_lines; setbb;
\stopbuffer

\startbuffer[4]
draw_circle; draw_tophbar; draw_bottomhbar; stand_out; draw_clippath;
draw_lines; setbb;
\stopbuffer

\startbuffer[5]
draw_circle; draw_tophbar; draw_bottomhbar; clipright; setbb;
\stopbuffer

The whole animation is done in \definefieldstack.

\definesymbol[step 1][{\processMPbuffer[a,1]}]
\definesymbol[step 2][{\processMPbuffer[a,2]}]
\definesymbol[step 3][{\processMPbuffer[a,3]}]
\definesymbol[step 4][{\processMPbuffer[a,4]}]
\definesymbol[step 5][{\processMPbuffer[a,5]}]

\definefieldstack 
   [euroconstruction] 
   [step 1,step 2,step 3,step 4,step 5] 
   [frame=on,offset=3pt,framecolor=darkyellow,rulethickness=1pt]


\starttext
\placefigure [here][fig:steps] 
      {Just click \goto {here} [JS(Walk_Field{euroconstruction})] 
      to walk through the construction! \goto{(restart)}[JS(Set_Field{euroconstruction,1})]}    
        {\fieldstack[euroconstruction]}

\stoptext

That's it. You can also download the source and the resulting pdf at http://dl.contextgarden.net/examples/euro-anim/ .