Animating Changes in Image Size
October 31, 2001
by Will Turnage
Dear Multimedia Handyman,
I would like a bitmap image to make a "smooth" change in size from 640 to 800. I have tried it with keyframes on frame 1 and 50; it's everything but smooth. Please tell me the secret!
All the best,
Nic
Dear Nic,
If you want to make an image transition work really smoothly, then sometimes the best approach is to use Lingo programming instead of keyframes in the Score. The biggest reason is that Lingo allows you to control the degree of smoothness in your animation without requiring you to add or delete keyframes.
To create your own behavior that will make an image grow, the first step is to initialize a few variables that will determine the appearance of the image.
on beginSprite me
pZoomSteps = 200
pLargeRect = rect (0, 0, 400, 300)
pSmallRect = rect (0, 0, 200, 150)
end
When your sprite begins, it initializes three variables. The first variable, pZoomSteps, will determine the number of intervals in the animation. The more intervals you have, the smoother the animation will be, but also the longer it will take. You should experiment with different values in the intervals to find the right balance for your project. The next two variables are the two different sized rects for your image.
Once you've initialized your variables, then you need to have another handler that will start the animation. This handler can be called from another button on screen, by a frame script, or even just by clicking on the image.
on startGrow me
pZoomCounter = 0
timeout ("growImage").new (40, #growImage, me)
end
When the startGrow handler gets called, it sets a counter to 0, and then it creates a new timeout object. This timeout object is called growImage, and from now on it will execute the growImage handler every 40 milliseconds (or 25 times a second). The growImage handler looks like this:
on growImage me
pZoomCounter = pZoomCounter + 1
tempRect = (pLargeRect - pSmallRect)
tempPercent = float(pZoomCounter) / float (pZoomSteps)
tempRect = (tempRect * tempPercent) + pSmallRect
sprite (me.spriteNum).rect = tempRect
if pZoomCounter >= pZoomSteps then
timeout ("growImage").forget ()
end if
end
The growImage handler starts by incrementing pZoomCounter by 1. It calculates the difference between your small and large rects and stores them in a local variable. Next it uses the pZoomCounter variable and the pZoomSteps variable to calculate the percentage of zoom to apply at the current time. It then takes this percentage and multiplies it by the difference in the large and small rects you calculated earlier. Finally, it takes this value and adds it to the smaller rect, giving you a new rect that is used to resize the sprite the behavior is attached to. Finally, check to see if your counter is equal or greater to the number of steps, and if so cancel the timeout object so the growImage handler won't be called again.
If you want to run this process in reverse, then the handlers are mostly the same. The biggest difference is that instead of starting your counter at 0 and working up to pZoomSteps, this time you'll start with your counter equal to pZoomSteps and work downwards to 0. Then, your handlers will look like this
on startShrink me
pZoomCounter = pZoomSteps
timeout ("shrinkImage").new (40, #shrinkImage, me)
end
on shrinkImage me
pZoomCounter = pZoomCounter - 1
tempRect = (pLargeRect - pSmallRect)
tempPercent = float (pZoomCounter) / float (pZoomSteps)
tempRect = (tempRect * tempPercent) + pSmallRect
sprite (me.spriteNum).rect = tempRect
if pZoomCounter <= 0 then
timeout ("shrinkImage").forget ()
end if
end
The final outcome:
A sample Director 8 movie is available for download in Windows or Macintosh format.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.