name: fading layout: true class: animated, fadeInUp, slidein --- class: center, middle, inverse # Introduction to Animation Lauren Bricker CSE 340 Spring 2021 --- [//]: # (Outline Slide) # Today's goals - Reviewing Transformations - Reviewing Rotation - How to use Animation to move Interactors --- # Introducing Animation ![:img FB Messenger Animation, 40%, width](img/animation/messenger-bubble.gif) .footnote[Lots of interesting ways to use animations on [mobile devices](https://www.smashingmagazine.com/2013/10/smart-transitions-in-user-experience-design/)] --- # Animation becoming core pillar of UX design ![:img Android Animation Example with bouncing and spinning circles that eventually transition to spell out android, 100%](img/animation/android-animate.gif) Greater awareness of role for communicating UI behavior, provide context, delight, engage
1
.footnote[Google’s [material design guidelines on motion](https://material.io/design/motion/understanding-motion.html) are a good illustration of this] ??? Animation becoming core pillar of UX design Greater awareness of role for communicating UI behavior Guide, provide context, delight, engage Provide visual continuity Enhance perception/direct attention Trade space for time --- # Animation was popular in storytelling first ![:youtube The film tells the story of a boy who rather spends his time indoors playing videogames instead of discovering what’s waiting outside. One day his Mum decides to get a little surprise for her son which makes it hard for him to concentrate on his video game any longer; a puppy,C_nJJHaNmnY] ??? Old style animation: https://www.youtube.com/watch?v=fCNvwa2Kgzc --- # Human Perception and Animation .left-column[ ![:img Picture of a sabertooth tiger,100%, width](img/animation/tiger.png) ] .right-column[ *< ~20ms (1/50 sec) discrete images/flashes merge into continuous perception* Image you are looking at flickers 60 times per second Differences in peripheral vision - Sabertooth tigers ] --- # How fast can people see things? .left-column[ ![:img Picture of a sabertooth tiger,100%, width](img/animation/tiger.png) ] .right-column[ *< ~20ms (1/50 sec) discrete images/flashes merge into continuous perception* Modern day Graphics Processing Units (GPUs) - Get >120 million instructions per core (@3Ghz) - High end GPU theoretically as high as 26 *billion* instructions Compared to first GUIs which had ~20 *thousand* We don't *need* to be faster than this for user response! ] ??? But tell that to a gamer with high ping --- # Can use this for animation < ~20ms (1/50 sec) discrete images/flashes merge into continuous perception - minimum of 10 FPS - 50 FPS smoother --- # Conceptual model for animation ![:img A series of grey boxes with properties x and t interpolated from x=0 t=0ms to x=40 t=40ms. Below them is an arrow labeled duration=40ms](img/animation/animation-linear.png) Define an animate that changes on object's property (a field on a object) over a length of time --- # Conceptual model for animation ![:img A series of grey boxes with properties x and t interpolated from x=0 t=0ms to x=40 t=40ms. Below them is an arrow labeled duration=40ms](img/animation/animation-linear.png) Need the start and end value of the properties to be modified. Typically use a [Path](https://developer.android.com/reference/android/graphics/Path) for this. Need a *duration* (total time in ms for the animation) Need the *pacing function* for animation. Can explore subclasses of [Interpolator](https://developer.android.com/reference/android/view/animation/Interpolator) (or make your own!) for this --- # Taking Animation to the next level .quote[ Despite the differences between user interfaces and cartoons -- cartoons are frivolous, passive entertainment and user interfaces are serious, interactive tools -- cartoon animation has much to lend user interfaces to realize both affective and cognitive benefits] .small[Principals of animation borrowed from Johnston & Thomas ‘81, Lasseter ‘87] Interested in more? Check out [Pixar in a box](https://www.khanacademy.org/computing/pixar/start/introduction/v/pipeline-video), or [Danielle Feinberg](https://www.youtube.com/watch?v=Z1R1z9ipFnM)'s TED talk ??? Start at :51 in --- # Chang & Ungar, UIST '93 ![:youtube The film tells the story of a boy who rather spends his time indoors playing videogames instead of discovering what’s waiting outside. One day his Mum decides to get a little surprise for her son which makes it hard for him to concentrate on his video game any longer; a puppy,C_nJJHaNmnY] - What strategies do you see here? - e.g. 2:21 ??? Move frames using . and , - No teleportation! - Squash and Stretch (preserve volume; can approximate inertia) - Follow through (i.e. ear lags behind head) - Anticipation (small amount of counter movement (ear motion)) - Exaggeration (watch the tail around 2:28) - (not shown) Motion blur (doesn't need to be realistic --- # Chang & Ungar, UIST '93 ![:youtube The film tells the story of a boy who rather spends his time indoors playing videogames instead of discovering what’s waiting outside. One day his Mum decides to get a little surprise for her son which makes it hard for him to concentrate on his video game any longer; a puppy,C_nJJHaNmnY] .left-column50[ - Squash and Stretch - Anticipation - No teleportation ] .right-column50[ - Exaggeration - Other pacing choices (slow in/slowout; Overshoot; etc) ] --- # Why is pacing so important? Need to mimic real world - Observing motion tells us about size, weight, rigidity - No abrupt changes in velocity! Gives a feeling of reality and liveness - “animation” = “bring to life” - make inanimate object animate With this can come appeal and desirability --- # Example pacing functions in android .left-column[ ![:img Picture of for types of interpolation functions provided with android, 100%, width](img/animation/interpolators.gif) ] .right-column[ Slow in slow out (Accelerate/decelerate) Slow in (Accelerate) Anticipate (back up slightly, then accelerate) Anticipate Overshoot (same, then go too far and slow down) ] --- class: inverse, center, middle # How do we implement animation? --- # Linear ("affine") Transformations of Properties - Translate: Move origin (and everything else) in x and y ![:img a large moon and a large moon moved to the right a few pixels, 15%,width](img/animation/translate.png) ??? used extensively in GUIS because child objects just draw themselves at *their* origin, so a component doesn't have to calculate how to draw itself based on its position -- count: false - Scale: change size (negative == flip) ![:img a large and small moon, 15%, width](img/animation/scale.png) -- count: false - Rotate and Shear ![:img a rotated and angled moon, 25%, width](img/animation/shear.png) --- # Coordinate Transformations - Can modify any shape, including text. - In practice, complex transformations are done with matrices, and matrices are using `concat(Matrix)` - But Android helps with this by providing methods in the [Canvas](https://developer.android.com/reference/android/graphics/Canvas) object to transform a canvas such as ```java translate(float dx, float dy) rotate(float degrees) // the whole canvas around the canvas origin rotate (float degrees, float px, float py) // around a particular point scale(float, float) scale (float sx, float sy, float px, float py) // around a pivot point skew(float sx, float sy) // skew by sx and sy save() // save the current transform restore() // restore the previous transform ``` -- - These are defined relative to (0,0) ??? - important thing to point out here: This is a value proposition for a toolkit again – Affine transformations are based on two-dimensional matrices of the following form: P' = T*P where P is 1x3 and T is the transform matrix (3x3) with the bottom row 0 0 1 Thus, x' = ax + cy + t_x and y' = bx + dy + t_y *Note* Any sequence of transform, rotate and shear can be represented in a single matrix of this form (just multiple the matrices together) --- .left-column[ ## Example ![:img Three rectangle with a second rectangle displayed rotating around the origin of the rectangle, 80%, width](img/animation/rotatedrects-original-origin.png) ] .right-column[ New view created called `RotatedRectangleView` that has `mEndPoint` and `mBrush` defined in a similar way to your `LineView`. It also is given the number of degrees (stored in the variable mDegrees) by which to rotate the rectangle. ```java public void onDraw(Canvas canvas) { canvas.drawRect(0, 0, mEndPoint.x , mEndPoint.y, mBrush); int saveColor = mBrush.getColor(); mBrush.setColor(Color.GREEN); canvas.rotate(mDegrees); canvas.drawRect(0, 0, mEndPoint.x, mEndPoint.y, mBrush); } ``` ] --- ## Question: How can you rotate around the center of an object:
--- .left-column[ ## Example ![:img Three rectangle with a second rectangle displayed rotating around the origin of the rectangle, 80%, width](img/animation/rotatedrects-center.png) ] .right-column[ Move origin of the `canvas` to the center of the object, THEN rotate it, then move the origin back to it's original location (in this new rotated orientation) ```java public void onDraw(Canvas canvas) { canvas.drawRect(0, 0, mEndPoint.x , mEndPoint.y, mBrush); float px = mEndPoint.x / 2; float py = mEndPoint.y / 2; int saveColor = mBrush.getColor(); mBrush.setColor(Color.GREEN); canvas.translate(px, py); canvas.rotate(mDegrees); canvas.translate(-px, -py); canvas.drawRect(0, 0, mEndPoint.x, mEndPoint.y, mBrush); } ``` ] ??? Note we are moving the CANVAS here so direction of move changes --- # Naive implementation of Animation Frame-based - Redraw scene at regular intervals - Developer stores information about where they are in sequence - Developer uses coordinate transforms to move objects What toolkit principals does this violate? ??? it's bad because it doesn't provide any useful abstractions Fails to provide separation of concerns -- count: false - Doesn't provide supportive abstractions -- count: false - Fails to provide separation of concerns --- # Modern animation implementation Define an animation that changes on object's property (a field on a object) over a length of time. ![:img boxes showing position and time changing over a 40 ms duration, 80%](img/animation/animation-linear.png) .footnote[[image source: Android animation documentation](https://developer.android.com/guide/topics/graphics/prop-animation)] --- # Modern animation implementation Need the start and end value of the properties to be modified. Typically use a [Path](https://developer.android.com/reference/android/graphics/Path) for this. Need a *duration* (total time in ms for the animation) Need the *pacing function* for animation using an [Interpolator](https://developer.android.com/reference/android/view/animation/Interpolator) - Default is [AccelerateDecelerateInterpolator](https://developer.android.com/reference/android/view/animation/AccelerateDecelerateInterpolator) - Other subclasses include AccelerateInterpolator, AnticipateInterpolator, AnticipateOvershootInterpolator, BounceInterpolator, CycleInterpolator, DecelerateInterpolator, LinearInterpolator, OvershootInterpolator, PathInterpolator - Or make your own! --- # [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator) Directly animate a properties on an object **However**: the property that you are animating must have a setter function (in camel case) in the form of `set
()` for this to work Can use a string (like `"alpha"`) or a property (like `View.X` in [View](https://developer.android.com/reference/android/view/View)) --- # [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator) .left-column[ ![:img Boundless animation, 120%, width](img/animation/boundless.gif) ] .right-column[ ```java // takes a target view, a property name, and values ObjectAnimator anim = ObjectAnimator.ofFloat(boundlessView, "alpha", 0f, 1f); anim.setDuration(1000); anim.start(); ``` ] --- # Other useful properties for animation - `translationX` /`translationY` - view location as a delta from its top/left coordinates relative to the parent - `rotation` / `rotationX`/`rotationY` - control 2D rotation and 3D rotation around a pivot point - `scaleX` / `scaleY` - 2D scaliong of a `View` around a pivot point - `pivotX` / `pivotY` - changes location of thej pivot point (default is object's center) - `x` / `y` - utility property to describe the final location of a `View` in its container as a sum of (left, top) + `translationX`, `translationY`) - `alpha` .footnote[All found in the [View](https://developer.android.com/reference/android/view/View) class] --- ```java ImageView mouse = (ImageView) new DrawView(this, "mouse", "Picture of a mouse", 500f, 50f, size); Path path = new Path(); // code to set up the path.... path.moveTo(400f, 50f); path.arcTo(200f, 50f, 600f, 450, 270, -180, true); path.arcTo(200f, 450f, 600f, 850, 270f, 180f, true); ObjectAnimator anim = ObjectAnimator.ofFloat(mouse, View.X, View.Y, path); anim.setDuration(5000); anim.start(); ``` .left-column[ ![:img Path animation, 120%, width](img/animation/linear.gif) ] .right-column[ Example for position (using a [Path](https://developer.android.com/reference/android/graphics/Path)) The static functions (like `ofFloat`) in [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator) are "factories" - the method creates the [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator) object for you! ] --- ```java ImageView mouse = addImage(doodleView, "mouse", 500f, 50f, size); Path path = new Path(); // code to set up the path.... ObjectAnimator anim = ObjectAnimator.ofFloat(mouse, View.X, View.Y, path); anim.setDuration(5000); anim.start(); ObjectAnimator anim = ObjectAnimator.ofFloat(mouse,"rotation", 720); anim.setDuration(5000); anim.start(); ``` .left-column[ ![:img Path animation, 120%, width](img/animation/linearrotate.gif) ] .right-column[ Example for position and rotation You can have multiple [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator) working on a single view at the same time! ] --- # How implement pacing in animation? How would `t` and `x` change for slow in slow out? https://easings.net/en -- count: false ![:img boxes showing position and time changing over a 40 ms duration, 80%](img/animation/animation-nonlinear.png) .footnote[[image source: Android animation documentation](https://developer.android.com/guide/topics/graphics/prop-animation)] --- # Pacing Function implementation ```java step(fraction){x_now = x_start + fraction*(x_end - x_start);} ``` .left-column50[ ![:img Picture of a curve transforming motion over time to create a pacing effect, 80%, width](img/animation/pacing.png) ] .right-column50[ - Time normalized with respect to animation interval (0...1) - Normalized time is transformed by pacing function (0…1) - Paced value is then fed to curve function to interpolate final value - Timing and redraw managed by toolkit (Hudson & Stasko '93) ] --- # We implement these with `Interpolators` in Android .left-column50[ ![:img mouse moving along a path with linear interpolation,22%,width](img/animation/linear.gif) ![:img mouse moving along a path with linear interpolation,22%,width](img/animation/accelerate.gif) ![:img mouse moving along a path with overshoot interpolation,22%,width](img/animation/overshoot.gif) ![:img mouse moving along a path with bounce interpolation,22%,width](img/animation/bounce.gif) ] .right-column50[ The durations are the same for each of these animations - Left side is _Linear_ - Second one is _Accelerate_ - Third one is ?? - Right side is ?? ] ??? overshoot bounce --- # Using an Interpolator ```java ObjectAnimator anim = ObjectAnimator.ofFloat(mouse, View.X, View.Y, path); // Create the ObjectAnimator OvershootInterpolator interpolator = new OvershootInterpolator(); // Create an Interpolator anim.setInterpolator(interpolator); // Tell the animator to use the interpolator anim.setDuration(3000); // set the duration anim.start(); // Tell the animation to start ``` --- # Declaring Animations in XML ## What is XML? - XML stands for eXtensible Markup Language - A superset of HTML - Tag names are surrounded by '<' and '>''s (Alligators or "wakkas") - Tags are generally in pairs such as `` `` or can be self closing `
` - Tags can have attributes such as `
content
` --- # XML and Android .left-column[ ![:img Picture of the android ide file system with an xml file inside of res highlighted, 70%, width](img/animation/xml-files.png) ] .right-column[ Android uses XML for a lot of things, where all sorts of static properties can be specified (in the `res` directory) In XML you can set variables that we can access later in XML or code - In XML access a value `@(file name)/(value name)` , where the file name is a file somewhere in `res` and the value name is an xml value found in that file. - In code, you refer to that value by `R.(file name).(value name)` ] --- # Declaring Animations in XML ``` /res/animator/object_animator_ex.xml ``` ```xml
``` .footnote[Can do even *more* with ValueAnimator XML (will let you google this)] --- # Inflating the XML to run the animation You can then run the animation by doing the following: ```java Animator anim = (Animator) AnimatorInflater.loadAnimator(this, R.animator.object_animator_ex); anim.setTarget(myObject); anim.setDuration(2000); anim.start(); ``` Note that animations xml files should be in the `res/animator/` directory Make sure the animation info is inside of: ```xml
``` --- # An Aside: What is an Inflater? You will use these often! They give you access to XML data (part of the *model* of your application). Just saw an [AnimatorInflater](https://developer.android.com/reference/android/animation/AnimatorInflater) in the previous code. ```java [Type] [name] = ([Cast to Type]) [Inflator].load...([arguments]) ``` Will need the *path* to the part of the XML you care about, typically something like: ``` R.[dirname].[filename] ``` Specifics vary from situation to situation (*e.g.,* [LayoutInflater](https://developer.android.com/reference/android/view/LayoutInflater) works slightly differently), so you'll need to read the documentation. ??? Discuss model/view/controller --- # Using Animation Well - Accessbility .quote['The impact of animation on people with vestibular disorders can be quite severe. Triggered reactions include nausea, migraine headaches, and potentially needing bed rest to recover.' [W3C Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/Understanding/animation-from-interactions.html)] Best option: provide control, be minimalistic ??? --- # Summary: Animation Design Tips 1. Used sparingly and understandingly, animation can enhance the interface … otherwise can distract! 2. Need to mimic real world 3. Observing motion tells us about size, weight, rigidity 4. No abrupt changes in velocity! 5. Think about accessibility. --- # What to do for Doodle Part2Activity? Your chance to make something creative. Peers will reviewed your custom doodle to ensure it uses some combination of lines, text, images, and animation. Peers will also "evaluate" (give you feedback on how much they liked it).