Changes between Version 1 and Version 2 of animations
- Timestamp:
- 11/22/2010 11:17:53 AM (13 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
animations
v1 v2 1 == [[Image:Icons_silk_comment.png]]Introduction ==2 3 In its current development state, the Morphic implementation of Squeak does not support a extensible mechanism to allow visually appealing transitions whenever a morph's state changes, e.g., positon, rotation, color. 1 == Introduction == 2 3 ''In its current development state, the Morphic implementation of Squeak does not support a extensible mechanism to allow visually appealing transitions whenever a morph's state changes, e.g., positon, rotation, color.'' 4 4 5 5 This project provides such an extension to Morphic with the following key-features: 6 6 7 * respect timeliness no matter how high the cpu load is8 * support any property of a morph that as an accessor like <code>#position:</code> 9 * allow graphic transitions even without the need to change the state of a morph10 11 == [[Image:Icons_silk_disk.png]]How to Install ==12 13 <div style="float:right;"> 14 {| style="color:#404040; background-color:#dedede;border-style:dotted;" cellpadding="10" cellspacing="0" border="0" 15 | 16 ; Environment 17 : [[Image:Icons_squeak_16.png|Recommended Squeak Version]] 4.1, 4.2 Alpha 18 : [[Image:Icons_silk_application_home.png|Recommended VM Version]] 4.0.2 (Win), ? (Mac) 19 ; Sources 20 : [[Image:Icons_silk_database.png|Repository]] [http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/SwaUtilities/ SwaUtilities] 21 : [[Image:Icons_silk_package.png|Needed Packages from the Repository]] Animations 22 : [[Image:Icons_silk_bullet_go.png|Dependents]] - 23 ; Misc 24 : [[Image:Icons_silk_world.png|Website]] [http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/SwaUtilities.html SwaUtilities@SqueakSource] 25 | }26 </div> 27 28 Just load the '' Animations'' package into your Squeak image.7 * respect timeliness no matter how high the cpu load is 8 * support any property of a morph that as an accessor like `#position:` 9 * allow graphic transitions even without the need to change the state of a morph 10 11 == How to Install == 12 13 {{{ 14 #!div style="float:right;" 15 ||'''Environment'''|| || 16 || [[Image(media/icons/custom:squeak_16.png, title="Recommended Squeak Version", nolink, right)]] || 4.1, 4.2 Alpha || 17 || [[Image(media/icons/silk:application_home.png, title="Recommended Squeak VM Version", nolink, right)]] || 4.0.2 (Win), ? (Mac) || 18 || [[Image(media/icons/silk:cog.png, title="Recommended Cog VM Version", nolink, right)]] || ''supported?'' || 19 ||'''Sources'''|| || 20 || [[Image(media/icons/silk:script_gear.png, title="Metacello Configuration", nolink, right)]] || [http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/MetacelloRepository/YourConfiguration YourConfiguration] || 21 || [[Image(media/icons/silk:database.png, title="Repository", nolink, right)]] || [http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/SwaUtilities/ SwaUtilities] || 22 || [[Image(media/icons/silk:package.png, title="Needed Packages from the Repository", nolink, right)]] || ''`Animations`'' || 23 || [[Image(media/icons/silk:bullet_go.png, title="Dependents", nolink, right)]] || ''`---`'' || 24 ||'''Misc'''|| || 25 || [[Image(media/icons/silk:world.png, title="Website", nolink, right)]] || [http://www.hpi.uni-potsdam.de/hirschfeld/squeaksource/SwaUtilities.html SwaUtilities@SqueakSource] || 26 }}} 27 28 Just load the ''`Animations`'' package into your Squeak image. 29 29 30 30 '''Warning:''' Once installed, unloading will probably cause your image to stop rendering, which means it will hang. That's because of same very important messages like <code>WorldState>>doOneCycleFor:</code> that were overridden and could get lost on unloading. … … 37 37 <div style="clear:both;"></div> 38 38 39 = = [[Image:Icons_silk_book_open.png]] How to Use ==40 41 == = Simple Example ===39 = How to Use = 40 41 == Simple Example == 42 42 43 43 Open a workspace and create a new morph: 44 44 45 <pre> 45 {{{ 46 46 | myMorph | 47 47 myMorph := Morph new topLeft: 100@100; extent: 400@400; openInWorld. 48 </pre> 48 }}} 49 49 50 50 Now let this morph disappear. Try the close all unnecessary morphs for performance reasons: 51 51 52 <pre> 52 {{{ 53 53 myMorph fadeOut. 54 </pre> 54 }}} 55 55 56 56 It's gone! Now get it back: 57 57 58 <pre> 58 {{{ 59 59 myMorph fadeIn. 60 </pre> 60 }}} 61 61 62 62 This animation is about 200 milliseconds. If your Squeak image is quite busy it will be not that smooth. 63 63 64 == = Basic Animation Concept ===64 == Basic Animation Concept == 65 65 66 66 In principle, an animation is a timer that has a duration and can run several times to produce loops. 67 67 68 <pre> 68 {{{ 69 69 AnimAnimation new 70 70 duration: 500; "milliseconds" 71 71 start. 72 </pre> 73 74 You may inspect this animation and look at <code>#currentTime</code> but nothing will change. There are no extra processes involved to keep the animation running. You need to call <code>#updateCurrentTime:</code>with an increasing time value frequently to achieve this.72 }}} 73 74 You may inspect this animation and look at ''`#currentTime`'' but nothing will change. There are no extra processes involved to keep the animation running. You need to call ''`#updateCurrentTime:`'' with an increasing time value frequently to achieve this. 75 75 76 76 Animations were designed to be used in the Squeak UI process. Therefore, the best reference time to be used is: 77 77 78 <pre> 78 {{{ 79 79 WorldState lastCycleTime. 80 </pre> 80 }}} 81 81 82 82 One possibility (there is a better one) could be to use morph's stepping or a custom process: 83 83 84 <pre> 84 {{{ 85 85 "Using morph stepping." 86 86 MyMorph>>stepTime … … 95 95 (Delay forMilliseconds: 16) wait. "Avoid high load. Get 60 cycles per second." 96 96 ] fork. 97 </pre> 98 99 Having this, the animation <code>AnimAnimation</code> handles just simple time interpretation. You can control the animation with <code>#start</code>, <code>#stop</code>, <code>#pause</code>, <code>#resume</code>. Here are some other examples:100 101 <pre> 97 }}} 98 99 Having this, the animation ''`AnimAnimation`'' handles just simple time interpretation. You can control the animation with ''`#start`'', ''`#stop`'', ''`#pause`'', ''`#resume`''. Here are some other examples: 100 101 {{{ 102 102 AnimAnimation 103 103 duration: 500; "Always needed!" … … 111 111 start: #keepWhenFinished. "Memory management. Not needed for infinite animations. 112 112 Not used in base class." 113 </pre> 113 }}} 114 114 115 115 You can perform an action after the animation is finished using a block: 116 116 117 <pre> 117 {{{ 118 118 AnimAnimation 119 119 duration: 500; 120 120 finishBlock: [Transcript cr; show: 'Animation finished!']; 121 121 start. 122 </pre> 123 124 == = Variant Animations ===125 126 Variant animations add value interpolation behaviour to animations. There is a start and an end value. During one animation loop <code>#currentValue</code>changes in this range including the start and the end value itself.127 128 <pre> 122 }}} 123 124 == Variant Animations == 125 126 Variant animations add value interpolation behaviour to animations. There is a start and an end value. During one animation loop ''`#currentValue`'' changes in this range including the start and the end value itself. 127 128 {{{ 129 129 AnimVariantAnimation new 130 130 duration: 500; … … 132 132 endValue: 10; 133 133 start. 134 </pre> 135 136 Having <code>#updateCurrentTime:</code> called frequently somehow, <code>#updateCurrentValue</code>can be called frequently too to trigger a callback that allows variant animations to change their internal state or perform other operations:137 138 <pre> 134 }}} 135 136 Having ''`#updateCurrentTime:`'' called frequently somehow, ''`#updateCurrentValue`'' can be called frequently too to trigger a callback that allows variant animations to change their internal state or perform other operations: 137 138 {{{ 139 139 MyVariantAnimation>>updateCurrentValue: newValue 140 140 Transcript cr; show: newValue asString. 141 </pre> 141 }}} 142 142 143 143 The value interpolation uses an easing curve that maps a value between 0.0 and 1.0 to another value between 0.0 and 1.0 or maybe more. This can be used to modify the normal linear interpolation and get some more pleasing effects. Overshooting is possible but 1.0 should map to 1.0 because the loop ends there. Here is an example for a custom easing curve: 144 144 145 <pre> 145 {{{ 146 146 MyEasingCurve>>valueForProgress: aFloat 147 147 ^ aFloat * aFloat … … 153 153 easingCurve: MyEasingCurve new; 154 154 start. 155 </pre> 155 }}} 156 156 157 157 Variant animations make use of the <code>#direction</code> attribute which means the value goes from <code>#endValue</code> to <code>#startValue</code> if backwards. An offset can be specified to allow relative value changes: 158 158 159 <pre> 159 {{{ 160 160 AnimVariantAnimation new 161 161 duration: 500; … … 164 164 offsetBlock: [ActiveHand position]; "or just #offset:" 165 165 start. 166 </pre> 167 168 == = Property Animations ===169 170 Property animations are variant animations that are bound to an object and a property. The <code>#updateCurrentValue:</code>callback will try to send a keyword message to the object with one argument using the property name:171 172 <pre> 166 }}} 167 168 == Property Animations == 169 170 Property animations are variant animations that are bound to an object and a property. The ''`#updateCurrentValue:`'' callback will try to send a keyword message to the object with one argument using the property name: 171 172 {{{ 173 173 AnimPropertyAnimation new 174 174 duration: 500; … … 178 178 endValue: 100@100; 179 179 start. 180 </pre> 181 182 == = Let them run! - How to register Animations ===183 184 Animations are meant to be used in the Squeak UI process. There is a reference time called <code>WorldState class>>lastCycleTime</code> and some animations can use the world's main loop to keep themselves running. This is achieved by '''registering''' the animation in the <code>AnimAnimationRegistry</code>:185 186 <pre> 180 }}} 181 182 == Let them run! - How to register Animations == 183 184 Animations are meant to be used in the Squeak UI process. There is a reference time called ''`WorldState class>>lastCycleTime`'' and some animations can use the world's main loop to keep themselves running. This is achieved by '''registering''' the animation in the ''`AnimAnimationRegistry`'': 185 186 {{{ 187 187 AnimPropertyAnimation new 188 188 duration: 500; … … 193 193 start: #deleteWhenFinished; "Automatic registry clean-up. No need to unregister." 194 194 register. "Add to animation registry." 195 </pre> 196 197 Only <code>AnimPropertyAnimation</code> and <code>AnimGraphicsAnimation</code>can be registered.195 }}} 196 197 Only ''`AnimPropertyAnimation`'' and ''`AnimGraphicsAnimation`'' can be registered. 198 198 199 199 If you want to keep animations after they finished, you need to unregister them manually, e.g., if it has stopped: 200 201 <pre> 200 {{{ 202 201 myAnimation isStopped 203 202 ifTrue: [myAnimation unregister]. 204 </pre> 205 206 === = Using Processes ====207 208 The animation registry is thread-safe which means that <code>#register</code> and <code>#unregister</code>operations are secured and can be called from within any process. However, that process should have a higher priority than the Squeak UI process. Otherwise it could be problematic to acquire the mutex because every world cycle needs it too.209 210 == = Graphics Animations ===203 }}} 204 205 === Using Processes === 206 207 The animation registry is thread-safe which means that ''`#register`'' and ''`#unregister`'' operations are secured and can be called from within any process. However, that process should have a higher priority than the Squeak UI process. Otherwise it could be problematic to acquire the mutex because every world cycle needs it too. 208 209 == Graphics Animations == 211 210 212 211 Graphics animations are variant animations that modify the visual appearance of a morph and all its submorphs doing simple color mappings. ''Graphic animations need to be registered.'' 213 212 214 <pre> 213 {{{ 215 214 AnimAlphaBlendAnimation new 216 215 morph: myMorph; … … 220 219 start; 221 220 register. "Always needed for graphics animations!" 222 </pre> 223 224 There is no need to reimplement <code>#updateCurrentValue:</code> but <code>#transformedCanvas:</code> which returns a custom <code>AnimColorMappingCanvas</code>to be used during the drawing routine of morphs:225 226 <pre> 221 }}} 222 223 There is no need to reimplement ''`#updateCurrentValue:`'' but ''`#transformedCanvas:`'' which returns a custom ''`AnimColorMappingCanvas`'' to be used during the drawing routine of morphs: 224 225 {{{ 227 226 MyAlphaBlendingAnimation>>transformedCanvas: aCanvas 228 227 ^ (MyAlphaBlendingCanvas 229 228 on: aCanvas) 230 229 alpha: self currentValue "Interpolated alpha value." 231 </pre> 230 }}} 232 231 233 232 Having this, a simple fade-out animation for morphs can be implemented as follows: 234 233 235 <pre> 234 {{{ 236 235 MyMorph>>fadeOut 237 236 AnimAlphaBlendAnimation new … … 243 242 register; 244 243 start: #deleteWhenFinished. 245 </pre> 246 247 Color mappings apply to all submorphs in a morph. To prevent a morph from being color-mapped by its owner use the property <code>#ignoresColorMappings</code>.244 }}} 245 246 Color mappings apply to all submorphs in a morph. To prevent a morph from being color-mapped by its owner use the property ''`#ignoresColorMappings`''. 248 247 249 248 If you want to hold a certain color mapping state, you must not delete an animation when it has finished. Otherwise the color mapping will disappear. An example would be to gray-out or darken a morph using <code>AnimBrightnessAnimation</code> or <code>AnimGrayscaleAnimation</code>. 250 249 251 = = [[Image:Icons_silk_wrench.png]] How to Extend ==250 = How to Extend = 252 251 253 252 Take a look at: 254 253 255 * memory management of <code>AnimAnimationRegistry</code>256 ** <code>#garbageCollect</code>257 * <code>Morph>>#fullDrawOn:</code>258 * <code>WorldState>>#doOneCycleFor:</code>259 260 = = [[Image:Icons_silk_star.png]] Acknowledgments ==254 * memory management of <code>AnimAnimationRegistry</code> 255 * <code>#garbageCollect</code> 256 * <code>Morph>>#fullDrawOn:</code> 257 * <code>WorldState>>#doOneCycleFor:</code> 258 259 = Acknowledgments = 261 260 262 261 The ''Animations'' package was inspired by the animation framework in the [http://qt.nokia.com Nokia Qt Framework].