home *** CD-ROM | disk | FTP | other *** search
/ com!online 2002 May / comcd0502.iso / homepage / special / javascript / 01_01 / Java / fireworks / animate2.js next >
Encoding:
JavaScript  |  2000-05-25  |  16.7 KB  |  574 lines

  1. /*******************************************************************
  2. *
  3. * File    : animate.js
  4. *
  5. * Created : 2000/05/16
  6. *
  7. * Author  : Roy Whittle  (Roy@Whittle.com) www.Roy.Whittle.com
  8. *
  9. * Purpose : To create animated rollovers
  10. *
  11. * History
  12. * Date         Version        Description
  13. *
  14. * 2000-05-16    2.0        I have been doing JavaScript for over 8 months
  15. *                    and have decided to start this project from
  16. *                    scratch using what I have learned.
  17. *                    Knowing now what is required for animated rollovers
  18. *                    I have re-done the state transition diagram to
  19. *                    come up with a more efficient design.
  20. ***********************************************************************/
  21. /*** Create some global variables ***/
  22. var AnimationRunning = false; /*** Global state of animation ***/
  23. var FrameInterval    = 30;   /*** Time between frames in milliseconds   ***/
  24.  
  25. var AniImage = new Array();
  26. var AniFrame = new Array();
  27.  
  28. var BaseHref="images/";
  29. var Sep     = "/";
  30. var Timer   = null;
  31.  
  32. /***********************************************************
  33. * Function   : ImageError
  34. *
  35. * Parameters : 
  36. *              
  37. * Description : If the image being loaded does not exist then
  38. *               this function will report an error giving the
  39. *               full URL of the image we are trying to load.
  40. *              
  41. ***********************************************************/
  42. function ImageError()
  43. {
  44.     alert("animate.js has detected an error\nImage not found\n" + this.src);
  45. }
  46. /***********************************************************
  47. * Function   : CreateAnimationFrames
  48. *
  49. * Parameters : aniName - the name of the animation.
  50. *              n       - number of frames in animation
  51. *              ext     - the type of image (".GIF", ".JPG")
  52. *              
  53. * Description : Creates an object that can hold the current
  54. *               images for the animation.
  55. *               There must be 1 ".ext" file for every frame
  56. *               of animation  and they must reside in a 
  57. *               the directory "images/name/x.ext". 
  58. *               E.g.
  59. *                 "images/email/0.gif"
  60. *                 "images/email/1.gif"
  61. *                 ....
  62. *                 "images/email/x.gif" //where x=(n-1);
  63. ***********************************************************/
  64. function CreateAnimationFrames(aniName, n, ext)
  65. {
  66.     this.num_frames = n;
  67.     for(var i=0 ; i<n ; i++)
  68.     {
  69.         this[i]=new Image();
  70.         this[i].src = BaseHref + aniName + Sep + i + ext;
  71.  
  72.         this[i].onerror=ImageError;
  73.     }
  74. }
  75. /***********************************************************
  76. * Function   : CreateAnimatedImage
  77. *
  78. * Parameters : imgNname - the name of the image.
  79. *              aniName  - the name of the animation effect
  80. *                         to use with this image
  81. *              
  82. * Description : Creates an object that can hold the current
  83. *               state of the animation for a particular image
  84. * NOTE: imgName must match an image defined in the document
  85. *      BODY (e.g. <IMG SRC="xxx.ext" NAME="imgName">)
  86. ***********************************************************/
  87. function CreateAnimatedImage(imgName, aniName)
  88. {
  89.     if(document.images)
  90.     {
  91.         this.img_name   = imgName;
  92.         this.ani_name   = aniName;
  93.         this.next_on    = null;
  94.         this.next_off   = null;
  95.         this.index      = 0;
  96.         this.target_frame= 0;
  97.         this.state      = "CLOSED";
  98.         this.img        = null;
  99.     }
  100.     
  101. }
  102. /***********************************************************
  103. * Function   : AnimatedImage
  104. *
  105. * Parameters : imgName - the name of the image.
  106. *              aniName - the name of the animation effect
  107. *                     to use with this image
  108. *              
  109. * Description : Creates an object to hold the current state of
  110. *            the animation and stores it in the AniImage array.
  111. ***********************************************************/
  112. function AnimatedImage(imgName, aniName)
  113. {
  114.     AniImage[ imgName ] = new CreateAnimatedImage( imgName, aniName);
  115.  
  116.     if(AniFrame[aniName]==null)
  117.         alert("animate.js has detected a possible error\n       --------------------------------\n"
  118.             + "Error    : AnimationFrames \"" + aniName + "\" not defined\n"
  119.             + "Function    : AnimatedImage(\"" + imgName + "\",\"" + aniName + "\")");
  120.  
  121. }
  122. /***********************************************************
  123. * Function   : AnimationFrames
  124. *
  125. * Parameters : aniName - the name of the animation effect
  126. *              n    - number of frames in animation
  127. *              ext  - the type of image (".GIF", ".JPG")
  128. *              
  129. * Description : Creates an object to hold all the frames
  130. *               for an animation and stores it in the AniFrames array.
  131. ***********************************************************/
  132. function AnimationFrames(aniName, n, ext)
  133. {
  134.     /*** Only download this animation if we don't already have it ***/
  135.     if(AniFrame[aniName] == null)
  136.         AniFrame[ aniName ]= new CreateAnimationFrames(aniName, n, ext);
  137.     else
  138. //        alert(aniName + " already defined");
  139.         ;
  140. }
  141. /***********************************************************
  142. * Function   : AnimatedGif AnimatedJpg
  143. *
  144. * Parameters : name - the name of the image.
  145. *              n    - number of frames in animation
  146. *              
  147. * Description : These are a couple of helper functions to
  148. *               help create simple animations.
  149. *
  150. ***********************************************************/
  151. function AnimatedGif(name, n)
  152. {
  153.     AnimationFrames(name, n, ".gif");
  154.     AnimatedImage( name, name);
  155. }
  156. function AnimatedJpg(name, n)
  157. {
  158.     AnimationFrames(name, n, ".jpg");
  159.     AnimatedImage( name, name);
  160. }
  161.  
  162. /*****************************************************************
  163. * Function    : getImage
  164. *
  165. * Parameters : n - the name of the image to find
  166. *           d - the (window/layer) document
  167. *
  168. * Description : In ie - just get the doucument.image.
  169. *            In NS, if there are layers we recursively
  170. *            search them for the image.
  171. *
  172. *****************************************************************/
  173. function getImage(n, d) 
  174. {
  175.     var img = d.images[n];
  176.     if(!img && d.layers)  
  177.         for(var i=0 ; !img && i<d.layers.length ; i++) 
  178.             img=getImage(n,d.layers[i].document); 
  179.     return img;
  180. }
  181.  
  182. /*****************************************************************
  183. * Function    : startAnimation
  184. *
  185. * Description : Set a timeout which will call the animate routine
  186. *               and start the animation running
  187. *****************************************************************/
  188. function startAnimation()
  189. {
  190.     if(!AnimationRunning)
  191.         Animate();
  192. }
  193. /*****************************************************************
  194. *
  195. * Function   : turn_on
  196. *
  197. * Parameters : ingName - string containing the name of the
  198. *                        image to start animating.
  199. *           aniName - optional, animation to use to open.
  200. *
  201. * Description: Checks that the imgName is in a valid state to
  202. *              start "OPENING". If it is it sets the state to
  203. *              "OPENING" and calls startAnimation.             
  204. *
  205. *****************************************************************/
  206. function turn_on(imgName, aniName)
  207. {
  208.     if(!ErrorCheck("turn_on", imgName, aniName))
  209.     {
  210.         var b=AniImage[ imgName ];
  211.  
  212.         if(b.state == "CLOSED" )
  213.         {
  214.             b.state = "OPENING";
  215.             if(aniName)
  216.                 b.ani_name=aniName;
  217.             startAnimation();
  218.         }
  219.         else if ( b.state == "OPEN_CLOSE"
  220.             ||  b.state == "CLOSING" 
  221.             ||  b.state == "CLOSE_OPEN") 
  222.         {
  223.             if(!aniName || b.ani_name==aniName)
  224.                 b.state = "OPENING";
  225.             else
  226.             {
  227.                 b.next_on=aniName;
  228.                 b.state = "CLOSE_OPEN";
  229.             }
  230.         }
  231.         /*** Special effect, can only happen in forced situations ***/
  232.         /*** Hopefully this is described in the manual ***/
  233.         else if( b.state == "OPENING"
  234.             || b.state == "OPEN")
  235.         {
  236.             if(aniName && b.ani_name != aniName)
  237.             {
  238.                 b.ani_name=aniName;
  239.                 b.index=0;
  240.                 b.state="OPENING";
  241.                 startAnimation();
  242.             }
  243.         }
  244.     }
  245. }
  246. /*****************************************************************
  247. *
  248. * Function   : turn_off
  249. *
  250. * Parameters : imgName - string containing the name of the
  251. *                        image to start reverse animating.
  252. *
  253. * Description: Checks that the imgName is in a valid state to
  254. *              start "CLOSING". If it is it sets the state to
  255. *              "CLOSING" and calls startAnimation.             
  256. *
  257. *****************************************************************/
  258. function turn_off(imgName, aniName)
  259. {
  260.     if(!ErrorCheck("turn_off", imgName, aniName))
  261.     {
  262.         var b=AniImage[ imgName ];
  263.  
  264.         if( b.state == "OPEN")        
  265.         {
  266.             if(aniName)
  267.             {
  268.                 b.ani_name=aniName;
  269.                 b.index=AniFrame[aniName].num_frames-1;
  270.             }
  271.             b.state = "CLOSING";
  272.             startAnimation();
  273.         }
  274.         else if(b.state == "CLOSE_OPEN")
  275.         {
  276.             b.next_off=null;
  277.             b.state="CLOSING"
  278.         }
  279.         else if( b.state == "OPENING" )
  280.         {
  281.             b.next_off = aniName;
  282.             b.state = "OPEN_CLOSE";
  283.         }
  284.     }
  285. }
  286. /*******************************************************************
  287. *
  288. * Function    : Animate
  289. *
  290. * Description : Each animation object has a state.
  291. *               The states normally go as follows
  292. *                   CLOSED->OPENING->OPEN
  293. *                   OPEN->CLOSING->CLOSED.
  294. *               When a turn_on() event is received, an image in the
  295. *               CLOSED state is switched to the OPENING state until OPEN
  296. *               is reached. When the turn_off() event is received an image
  297. *               in the OPEN state is switched to the CLOSING state until
  298. *               the CLOSED state is reached. 
  299. *
  300. *               The special cases are what happens when we get turn_off() when
  301. *               in the middle of opening. In this case the path is :-
  302. *               CLOSED->OPENING->OPEN_CLOSE->CLOSING->CLOSED.
  303. *               in this way the image will fully "open" before it starts 
  304. *               closing. This can be changed by always setting the state
  305. *               to "CLOSING" when the turn_off() event is received.
  306. *
  307. *               If the button is "CLOSING" and the turn_on() event is
  308. *               received and the new open animation is null or the same
  309. *               then the state is set back to "OPENING and the
  310. *               button will start opening again immediately.
  311. *                 Otherwise the state is set to CLOSE_OPEN so the image
  312. *               will get to the CLOSED state and start opening with the
  313. *               new animation.
  314. *
  315. *******************************************************************/
  316. function Animate()
  317. {    
  318.     AnimationRunning = false; /*** Are there more frames that need displaying? ***/
  319.  
  320.     for(var i in AniImage)
  321.     {
  322.         var b=AniImage[i];
  323.         var a=AniFrame[b.ani_name];
  324.  
  325.         if(b.state == "OPENING")
  326.         {
  327.             /*** Increment the frame index - display the next frame ***/
  328.             /*** when fully open, set state to "OPEN"               ***/
  329.             if(++b.index < a.num_frames)
  330.             {
  331.                 b.img.src=a[b.index].src;
  332.                 AnimationRunning = true;
  333.             }
  334.             else
  335.             {
  336.                 b.index=a.num_frames-1;
  337.                 b.state = "OPEN";
  338.             }
  339.         }
  340.         else if(b.state == "OPEN_CLOSE")
  341.         {
  342.             /*** Increment the frame index - display the next frame ***/
  343.             /*** when fully open, set state to "CLOSING"            ***/
  344.             if(++b.index < a.num_frames)
  345.             {
  346.                 b.img.src=a[b.index].src;
  347.             }
  348.             else
  349.             {
  350.                 if(b.next_off)
  351.                 {
  352.                     b.ani_name=b.next_off;
  353.                     a=AniFrame[b.ani_name];
  354.                     b.next_off=null;
  355.                 }
  356.                 b.index=a.num_frames-1;
  357.                 b.state = "CLOSING";
  358.             }
  359.             AnimationRunning = true;
  360.         }
  361.         else if(b.state == "CLOSING")
  362.         {
  363.             /*** Decrement the frame index - display the next frame ***/
  364.             /*** when fully closed, set state to "CLOSED"           ***/
  365.             if(--b.index >= 0)
  366.             {
  367.                 b.img.src=a[b.index].src;
  368.                 AnimationRunning = true;
  369.             }
  370.             else
  371.             {
  372.                 b.index=0;
  373.                 b.state = "CLOSED";
  374.             }
  375.         }
  376.         else if(b.state == "CLOSE_OPEN")
  377.         {
  378.             /*** Decrement the frame index - display the next frame ***/
  379.             /*** when fully closed, set state to "OPENING"           ***/
  380.             if(--b.index >= 0)
  381.             {
  382.                 b.img.src=a[b.index].src;
  383.             }
  384.             else
  385.             {
  386.                 b.index=0;
  387.                 b.ani_name=b.next_on;
  388.                 b.state = "OPENING";
  389.             }
  390.             AnimationRunning = true;
  391.         }
  392.         else if(b.state == "ROTATE_UP")
  393.         {
  394.             /*** Increment the frame index - display the next frame ***/
  395.             /*** when target reached, set state to "CLOSED"        ***/
  396.             if(b.index != b.target_frame)
  397.             {
  398.                 if(++b.index == a.num_frames)
  399.                     b.index = 0;
  400.                 b.img.src=a[b.index].src;
  401.                 AnimationRunning = true;
  402.             }
  403.             else
  404.                 b.state = "CLOSED";
  405.         }
  406.         else if(b.state == "ROTATE_DOWN")
  407.         {
  408.             /*** Decrement the frame index - display the next frame ***/
  409.             /*** when target reached, set state to "CLOSED"        ***/
  410.             if(b.index != b.target_frame)
  411.             {
  412.                 if(--b.index < 0)
  413.                     b.index = a.num_frames-1;
  414.                 b.img.src=a[b.index].src;
  415.                 AnimationRunning = true;
  416.             }
  417.             else
  418.                 b.state = "CLOSED";
  419.         }
  420.     }
  421.     /*** Check to see if we need to animate any more frames. ***/
  422.     if(AnimationRunning)
  423.     {
  424.         if(!Timer)
  425.             Timer=setInterval("Animate()",FrameInterval);
  426.     }
  427.     else
  428.     {
  429.         clearInterval(Timer);
  430.         Timer=null;
  431.     }
  432. }
  433.  
  434.  
  435.  
  436. /***********************************************************
  437. * Function   : ErrorCheck
  438. *
  439. * Parameters : funcName - the name of the function that called this one
  440. *              imgName  - The name of the image being animated
  441. *              aniName  - (optional) the animation being used.
  442. *              
  443. * Description : This function checks that all the required
  444. *               objects that make up an animated onMouseOver
  445. *               have been defined. It will report any errors
  446. *               detected. This function will also search for
  447. *            the corresponding document image by calling getImage().
  448. *              
  449. ***********************************************************/
  450. function ErrorCheck(funcName, imgName, aniName)
  451. {
  452.     var err_str="";
  453.  
  454.     if(AniImage[imgName]==null)
  455.         err_str += "Error    : AnimatedImage \"" + imgName + "\" not defined\n";
  456.     else
  457.     {
  458.         var b=AniImage[imgName];
  459.         if(b.img == null)
  460.             b.img=getImage(imgName, document);
  461.  
  462.         if(b.img==null)
  463.             err_str += "Error    : Document <IMG NAME=\"" + imgName + "\"> not defined\n";
  464.  
  465.         /*** Check the AnimationFrames(b.ani_name, n, ext) has been defined ***/
  466.         if(AniFrame[b.ani_name]==null)
  467.             err_str += "Error    : AnimationFrames \"" + b.ani_name + "\" not defined\n";
  468.  
  469.     }
  470.  
  471.     if(aniName)
  472.         /*** Check the AnimationFrames(aniName, n, ext) has been defined ***/
  473.         if(AniFrame[aniName]==null)
  474.             err_str += "Error    : AnimationFrames \"" + aniName + "\" not defined\n";
  475.  
  476.     if(err_str)
  477.     {
  478.         var extra = aniName ? ("\",\"" + aniName + "\")") : ("\")");
  479.         alert("animate.js has detected an error\n       --------------------------------\n"
  480.             + err_str
  481.             + "Function    : " + funcName + "(\"" + imgName + extra);
  482.     
  483.         return true;
  484.     }
  485.  
  486.     return false;
  487. }
  488. /*****************************************************************
  489. *
  490. * Function   : animate_to
  491. *
  492. * Parameters : imgName - string containing the name of the
  493. *                        image to start animating.
  494. *              frameNo - the target frame
  495. *
  496. * Description: Determines the shortest animation path to the
  497. *           target frame. sets the state and calls startAnimation.             
  498. *
  499. *****************************************************************/
  500. function animate_to(frameNo, imgName)
  501. {
  502.     if(!ErrorCheck("animate_to", imgName) )
  503.     {
  504.         var b = AniImage[ imgName  ];
  505.         var a = AniFrame[ b.ani_name];
  506.         var s = frameNo - b.index;
  507.  
  508.         b.target_frame = frameNo;
  509.  
  510.         if(Math.abs(s) > (a.num_frames/2))
  511.         {
  512.             if(s < 0)
  513.                 b.state = "ROTATE_UP";
  514.             else
  515.                 b.state = "ROTATE_DOWN";
  516.         }
  517.         else
  518.         {
  519.             if(s > 0)
  520.                 b.state = "ROTATE_UP";
  521.             else
  522.                 b.state = "ROTATE_DOWN";
  523.         }
  524.         startAnimation();
  525.     }
  526. }
  527. /*****************************************************************
  528. *
  529. * Function   : animate_upto
  530. *
  531. * Parameters : imgName - string containing the name of the
  532. *                        image to start animating.
  533. *              frameNo - the target frame
  534. *
  535. * Description: Sets the state to ROTATE_UP calls startAnimation.             
  536. *
  537. *****************************************************************/
  538. function animate_upto(frameNo, imgName)
  539. {
  540.     if(!ErrorCheck("animate_upto", imgName) )
  541.     {
  542.         var b=AniImage[ imgName ];
  543.  
  544.         b.target_frame = frameNo;
  545.         b.state       = "ROTATE_UP";
  546.  
  547.         startAnimation();
  548.     }
  549. }
  550. /*****************************************************************
  551. *
  552. * Function   : animate_downto
  553. *
  554. * Parameters : imgName - string containing the name of the
  555. *                        image to start animating.
  556. *              frameNo - the target frame
  557. *
  558. * Description: Sets the state to ROTATE_DOWN calls startAnimation.             
  559. *
  560. *****************************************************************/
  561. function animate_downto(frameNo, imgName)
  562. {
  563.     if(!ErrorCheck("animate_downto", imgName) )
  564.     {
  565.         var b=AniImage[ imgName ];
  566.  
  567.         b.target_frame = frameNo;
  568.         b.state       = "ROTATE_DOWN";
  569.         startAnimation();
  570.     }
  571. }
  572.  
  573.  
  574.