DHTML Lab: CrossBrowser Visibility Transitions; Transition 0 (BoxIn)
CrossBrowser Visibility Transitions



Try the first example in the left column. The BoxIn transition, you notice, is a gradual clipping of all four sides, making the element shrink into its own center. The Wrong WayOur first inclination is to include the following statements in doTransNS(): switch (transNo) { case 0: incrementW = halfW/visits; incrementH = halfH/visits; whichEl.transFunct = zero; break; } transTimer=setInterval("whichEl.transFunct()",intval); Here, we have divided the width of half of the element by the number of visits (function calls). This gives us the pixel increment by which to clip the left and the right edges of the element on each function call. We do the same for the height, and then call the function. function zero() { this.clip.left += incrementW; this.clip.right = incrementW; this.clip.top += incrementH; this.clip.bottom = incrementH; if (elBad.clip.height <= 0 && elBad.clip.width <= 0) { clearInterval(transTimer); this.hideIt(); } } In function zero(), we clip the four sides by the appropriate pixel increments. If both the clip width and the clip height become 0 or less, the transition is complete, so we clear the repeated function calls with clearInterval() and restore the element to its original size and hide it with hideIt(). This code results in the second example in the left column. If you are using Navigator 4, try it. What is the difference from the first example? The box does not reduce in size equally on all sides, as it does in Explorer. This is due to Navigator rounding numbers to integers, to use as pixel increments. Let's make up for this behavior, by embellishing the code to account for (almost) every pixel! The LongWinded Correct WayFirst we get a temporary horizontal increment (incW) by dividing halfW by visits, as above. We then check to see if incW is greater than 1 pixel. If it is, we take the full integer part of it (left of the decimal point), and assign it to incrementW using parseInt(). If incW is less than 1, we assign 0 to incrementW. case 0: incW = halfW/visits; incrementW = (incW >= 1) ? parseInt(incW) : 0; xtraPixW = Math.round((incW  incrementW) * visits); incH = halfH/visits; incrementH = (incH >= 1) ? parseInt(incH) : 0; xtraPixH = Math.round((incH  incrementH) * visits); whichEl.transFunct = zero; break; Next, we obtain the noninteger part of incW (right of the decimal point), by subtracting the integer part (incrementW) from it (incW  incrementW). If we multiply this fraction result by the number of visits ((incW  incrementW) * visits), we get the total number of pixels that will be stray and lost if we continue our routine as in the "wrong way" above. This number is then rounded to the closest integer using the We perform the same calculations for the element height before calling the zero() function. zero()The complete zero() function looks like this: function zero() { if (xtraPixW > 0) { if (xtraPixW <= visits) { if (alternateW) { this.clip.left++; this.clip.right; xtraPixW; } alternateW = !alternateW; } else { this.clip.left++; this.clip.right; xtraPixW; } } this.clip.left += incrementW; this.clip.right = incrementW; if (xtraPixH > 0) { if (xtraPixH <= visits) { if (alternateH) { this.clip.top++; this.clip.bottom; xtraPixH; } alternateH = !alternateH; } else { this.clip.top++; this.clip.bottom; xtraPixH; } } this.clip.top += incrementH; this.clip.bottom = incrementH; visits; if (this.clip.height <= 0 && this.clip.width <= 0) { clearInterval(transTimer); this.hideIt(); } } The major problem in developing zero() is the use of the extra pixels. xtrapixW and xtraPixH will always be less than the visits, by definition. We need a smoother transition closer to the end of the transition, when the element is smaller. The way to achieve this is:
The above logic leads us to this routine for horizontal clipping: if (xtraPixW > 0) { if (xtraPixW <= visits) { if (alternateW) { this.clip.left++; this.clip.right; xtraPixW; } alternateW = !alternateW; } else { this.clip.left++; this.clip.right; xtraPixW; } } this.clip.left += incrementW; this.clip.right = incrementW; If we have extra pixels to account for The value of alternateW is then toggled, regardless of whether it was originally true or false. This ensures that an extra pixel will be used every second visit, that is, when alternateW is true. If the extra pixels are not less than the visits, then zero() clips the left and right sides by one, and decrements xtraPixW. Finally, the left and right sides are clipped using incrementW. The height is clipped in the same way: if (xtraPixH > 0) { if (xtraPixH <= visits) { if (alternateH) { this.clip.top++; this.clip.bottom; xtraPixH; } alternateH = !alternateH; } else { this.clip.top++; this.clip.bottom; xtraPixH; } } this.clip.top += incrementH; this.clip.bottom = incrementH; On every visit to zero(), once the sides have been clipped, visits is decremented, and the size of the element is checked to determine whether the function calls should continue or be cancelled. visits; if (this.clip.height <= 0 && this.clip.width <= 0) { clearInterval(transTimer); this.hideIt(); } We now have a much smoother clipping routine that ends the boxin transition in the center of the element. Next, we'll reverse the effect for the boxout transition. 
Produced by Peter Belesis and
All Rights Reserved. Legal Notices.Created: Apr. 28, 1998
Revised: Apr. 28, 1998
URL: http://www.webreference.com/dhtml/column19/transBoxIn.html