Changes between Version 1 and Version 2 of animations


Ignore:
Timestamp:
11/22/2010 11:17:53 AM (13 years ago)
Author:
tobias.mohr
Comment:

--

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.''
    44
    55This project provides such an extension to Morphic with the following key-features:
    66
    7 * respect timeliness no matter how high the cpu load is
    8 * 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 morph
    10 
    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
     28Just load the ''`Animations`'' package into your Squeak image.
    2929
    3030'''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.
     
    3737<div style="clear:both;"></div>
    3838
    39 == [[Image:Icons_silk_book_open.png]] How to Use ==
    40 
    41 === Simple Example ===
     39= How to Use =
     40
     41== Simple Example ==
    4242
    4343Open a workspace and create a new morph:
    4444
    45 <pre>
     45{{{
    4646| myMorph |
    4747myMorph := Morph new topLeft: 100@100; extent: 400@400; openInWorld.
    48 </pre>
     48}}}
    4949
    5050Now let this morph disappear. Try the close all unnecessary morphs for performance reasons:
    5151
    52 <pre>
     52{{{
    5353myMorph fadeOut.
    54 </pre>
     54}}}
    5555
    5656It's gone! Now get it back:
    5757
    58 <pre>
     58{{{
    5959myMorph fadeIn.
    60 </pre>
     60}}}
    6161
    6262This animation is about 200 milliseconds. If your Squeak image is quite busy it will be not that smooth.
    6363
    64 === Basic Animation Concept ===
     64== Basic Animation Concept ==
    6565
    6666In principle, an animation is a timer that has a duration and can run several times to produce loops.
    6767
    68 <pre>
     68{{{
    6969AnimAnimation new
    7070   duration: 500; "milliseconds"
    7171   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
     74You 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.
    7575
    7676Animations were designed to be used in the Squeak UI process. Therefore, the best reference time to be used is:
    7777
    78 <pre>
     78{{{
    7979WorldState lastCycleTime.
    80 </pre>
     80}}}
    8181
    8282One possibility (there is a better one) could be to use morph's stepping or a custom process:
    8383
    84 <pre>
     84{{{
    8585"Using morph stepping."
    8686MyMorph>>stepTime
     
    9595   (Delay forMilliseconds: 16) wait. "Avoid high load. Get 60 cycles per second."
    9696] 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
     99Having 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{{{
    102102AnimAnimation
    103103   duration: 500; "Always needed!"
     
    111111   start: #keepWhenFinished. "Memory management. Not needed for infinite animations.
    112112                              Not used in base class."
    113 </pre>
     113}}}
    114114
    115115You can perform an action after the animation is finished using a block:
    116116
    117 <pre>
     117{{{
    118118AnimAnimation
    119119   duration: 500;
    120120   finishBlock: [Transcript cr; show: 'Animation finished!'];
    121121   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
     126Variant 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{{{
    129129AnimVariantAnimation new
    130130   duration: 500;
     
    132132   endValue: 10;
    133133   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
     136Having ''`#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{{{
    139139MyVariantAnimation>>updateCurrentValue: newValue
    140140   Transcript cr; show: newValue asString.
    141 </pre>
     141}}}
    142142
    143143The 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:
    144144
    145 <pre>
     145{{{
    146146MyEasingCurve>>valueForProgress: aFloat
    147147   ^ aFloat * aFloat
     
    153153   easingCurve: MyEasingCurve new;
    154154   start.
    155 </pre>
     155}}}
    156156
    157157Variant 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:
    158158
    159 <pre>
     159{{{
    160160AnimVariantAnimation new
    161161   duration: 500;
     
    164164   offsetBlock: [ActiveHand position]; "or just #offset:"
    165165   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
     170Property 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{{{
    173173AnimPropertyAnimation new
    174174   duration: 500;
     
    178178   endValue: 100@100;
    179179   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
     184Animations 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{{{
    187187AnimPropertyAnimation new
    188188   duration: 500;
     
    193193   start: #deleteWhenFinished; "Automatic registry clean-up. No need to unregister."
    194194   register. "Add to animation registry."
    195 </pre>
    196 
    197 Only <code>AnimPropertyAnimation</code> and <code>AnimGraphicsAnimation</code> can be registered.
     195}}}
     196
     197Only ''`AnimPropertyAnimation`'' and ''`AnimGraphicsAnimation`'' can be registered.
    198198
    199199If you want to keep animations after they finished, you need to unregister them manually, e.g., if it has stopped:
    200 
    201 <pre>
     200{{{
    202201myAnimation isStopped
    203202   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
     207The 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 ==
    211210
    212211Graphics 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.''
    213212
    214 <pre>
     213{{{
    215214AnimAlphaBlendAnimation new
    216215   morph: myMorph;
     
    220219   start;
    221220   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
     223There is no need to reimplement ''`#updateCurrentValue:`'' but ''`#transformedCanvas:`'' which returns a custom ''`AnimColorMappingCanvas`'' to be used during the drawing routine of morphs:
     224
     225{{{
    227226MyAlphaBlendingAnimation>>transformedCanvas: aCanvas
    228227   ^ (MyAlphaBlendingCanvas
    229228      on: aCanvas)
    230229      alpha: self currentValue "Interpolated alpha value."
    231 </pre>
     230}}}
    232231
    233232Having this, a simple fade-out animation for morphs can be implemented as follows:
    234233
    235 <pre>
     234{{{
    236235MyMorph>>fadeOut
    237236   AnimAlphaBlendAnimation new
     
    243242      register;
    244243      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
     246Color mappings apply to all submorphs in a morph. To prevent a morph from being color-mapped by its owner use the property ''`#ignoresColorMappings`''.
    248247
    249248If 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>.
    250249
    251 == [[Image:Icons_silk_wrench.png]] How to Extend ==
     250= How to Extend =
    252251
    253252Take a look at:
    254253
    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 =
    261260
    262261The ''Animations'' package was inspired by the animation framework in the [http://qt.nokia.com Nokia Qt Framework].