Animations and Effects for VisualWorks
Return to home page
Comments Loading...
2007-05-04

The litmus test for any UI technology these days is - can it do better than a web browser? That's one of my base lines for Widgetry and the work that I've started doing with Cincom Smalltalk - VisualWorks in particular.

One thing that I've gotten very used to in the web world is fading stuff in and out, moving things with smooth acceleration/deceleration and fading from one colour to another.

This sort of animation is something the Apple guys have been enjoying for a long time now with their NSAnimation framework in Cocoa. It's about time we had the same sort of thing for Smalltalk.

I've just published Animations and Animations-Tests to public store. This package provides the same sorts of animation APIs you get in Cocoa, Mootools, Scriptaculous, Flash MX, etc. Although the VisualWorks GDI doesn't provide alpha transparency, libraries like Cairo and SDL do. The Animations package is not specifically tied to any one UI - so you can use it in Wrapper and Widgetry equally.

Each Animation can be run with different kinds of transitions, such as Linear, Quadratic, Sinenoidal, Circular, Bouncing, etc. Eased Tweening is based off of Robert Penners algorithms, http://www.robertpenner.com/easing/.

Animations are easy to set up and combine together to run in sequential order or run in parallel.

[:progress | Transcript cr; show: progress printString] asAnimation
 	duration: 2000;
 	fps: 50;
 	play.
 

Animations can be run in the active process or put in to a background process and controlled with #start and #stop, eg:

| myAnimation |
myAnimation := [:progress | ] asAnimation.
myAnimation start.
(Delay forMilliseconds: 25) wait.
myAnimation stop.
 

Animations can be combined sequentially using , or Animations.AnimationSequence, eg:

([:progress | Transcript cr; show: 'a: ', progress printString] asAnimation, [:progress | Transcript cr; show: 'b: ', progress printString] asAnimation) play

And Animations can be run in parallel using an Animations.AnimationSet, eg:

Animations.AnimationSet new
 	add: [:progress | Transcript cr; show: 'a: ', progress printString] asAnimation;
 	add: [:progress | Transcript cr; show: 'b: ', progress printString] asAnimation;
 	play.
 
 

Combinations of Sets and Sequences can be used arbitrarily.

Animations can also be reversed to 'undo' their effect. Calling #reverse gives you a copy of the animation that will run in reverse, eg:

[:progress | Transcript cr; show: 'a: ', progress printString] asAnimation reverse play

And finally, just to make a more interesting example, we can animate the background color of a window and resize it at the same time with something like the following:

| animation window |
window := Window currentWindow.
window damageRepairPolicy: UI.DoubleBufferingWindowDisplayPolicy new.
animation := [:progress | 
	[window moveTo: 50@50 resize: ((progress @ progress) * (320@200) + (320@200)) truncated.
	window background: (ColorValue white blendWith: ColorValue blue weight: progress / 2).
	window display] uiEventNow] asAnimation.
(animation, animation reverse, animation) play