Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Workshop Animations & Interactions Alicante

Workshop Animations & Interactions Alicante

Raúl Gómez Acuña

September 13, 2018
Tweet

More Decks by Raúl Gómez Acuña

Other Decks in Technology

Transcript

  1. Animations & Gestures
    with React Native
    Raul Gomez, Ferran Negre

    @rgommezz, @ferrannprannp

    View Slide

  2. Agenda
    • Everything is split into modules. We’ll cover 5 modules in
    total.

    • Theory + hands on exercises per module

    • Solutions attached for reference

    • We’ll use expo

    View Slide

  3. Module 1
    Introduction to Animation

    View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. translateX: 0 translateX: 500
    progress: 0% progress: 100%
    translateX: 250
    progress: 50%
    translateX = progress * 500
    translateX = 0.0 * 500 = 0
    translateX = 0.5 * 500 = 250
    translateX = 1.0 * 500 = 500
    To define a basic computed animation, we define duration, initial position and
    final position. The computer takes care of animating it.

    View Slide

  8. Why animations are important
    • Animation has a special role in interface design, as one of
    the most important tools of successful interaction.

    • It can be said that without animation, there cannot be
    interaction

    • Users have high expectations of the UI they use, specially
    nowadays where the high quality content is everywhere.

    View Slide

  9. Functional animation
    Build meaningful transitions

    View Slide

  10. Functional animation
    Provide visual feedback

    View Slide

  11. Functional animation
    Help the user get started

    View Slide

  12. Delightful animation
    To reward the user

    View Slide

  13. Delightful animation
    To entertain users

    View Slide

  14. Animate with purpose
    • Don’t distract the user from successfully completing what
    they intended to do.

    • The best animations are those that seem natural

    • If you disable animations, the flow should feel broken. If it
    is not, this might mean your animations are superfluous

    View Slide

  15. View Slide

  16. Module 2
    Animated API

    View Slide

  17. Animated API
    • Has been designed to make it very easy to concisely
    express a wide variety of interesting animation and
    interaction patterns in a very performant way.

    • Animated values bypass the usual render method, so they
    get updated even though there is no state change.

    • Animated exports four animatable component types:
    View, Text, Image and ScrollView.

    View Slide

  18. Static Drivers
    • There are 3 different animation types, also known as
    static drivers: timing, spring, decay
    • Each type provides a particular animation curve that
    controls how your values animate from their initial to the
    final value.

    View Slide

  19. View Slide

  20. Easing on timing animations

    View Slide

  21. View Slide

  22. Steps to perform animation
    • 1. Create animated value:
    const translateX = new Animated.Value(0);
    • 2. Bind the value to the Animated View (inside Render)

    • 3. Run the animation with the static driver
    Animated.timing(translateX, { toValue: 50, duration: 1000 }).start();

    View Slide

  23. Exercise 1
    Move a box from left to right using Animated timing, when
    the component mounts. Extra: use some elastic curve

    View Slide

  24. Interpolation

    View Slide

  25. const progress = new Animated.Value(0);
    const scale = progress.interpolate({
    inputRange: [0, 0.2, 0.4, 0.7, 1],
    outputRange: [1, 1.3, 2, 1.5, 1.2],
    });

    View Slide

  26. Interpolating to strings
    • Can interpolate to strings, provided that the string
    contains at least one number or is a color.
    • Numbers in the string are parsed and interpolated, then
    wrapped back in string again.

    • For rotation, we can use degrees or radians, i.e “360deg”
    or “1rad”

    View Slide

  27. Exercise 2
    • Move a box from left to right

    • It should change opacity from 1 to
    0,

    • It should rotate from 0 to 90
    degrees when it reaches half and
    from 90 to 360 degrees when it
    reaches the end

    • The animation should loop over 4
    times. Loop time can be 4000ms

    • Don’t press the button for now!

    View Slide

  28. Using the native driver
    • Rather than calling into JS every frame to update an
    animation, declare the animation configuration in JS and
    execute in UI thread on native.

    • As a consequence, JS thread can be blocked without
    affecting the animation.

    • Just add useNativeDriver: true to the animation config
    when starting it.
    Animated.timing(this.progress, {
    toValue: 1,
    duration: 1000,
    useNativeDriver: true // Add this line
    }).start();

    View Slide

  29. Native driver in depth

    View Slide

  30. requestAnimationFrame
    The bridge
    JS Native
    Value
    Interpolation
    Update prop Update Native View

    View Slide

  31. requestAnimationFrame
    The bridge
    JS Native
    Value
    Interpolation
    Update prop Update Native View
    Every frame

    View Slide

  32. Update Native View
    The bridge
    JS Native
    Execute
    Calculate intermediate
    values
    useNativeDriver: true
    (Serialize instructions)
    Deserialize Instructions

    View Slide

  33. Update Native View
    The bridge
    JS Native
    Execute
    Calculate intermediate
    values
    useNativeDriver: true
    (Serialize instructions)
    Deserialize Instructions
    Every frame

    View Slide

  34. Native driver caveats
    • You can only animate non-layout properties

    • Things like transform and opacity will work, but
    flexbox and position properties will not

    • That’s why we were using transformX for moving the
    box horizontally.

    • Still without using native driver, animating transformX is
    more efficient than animating left, because with the
    former, the layout doesn’t have to be recalculated every
    frame

    View Slide

  35. Exercise 2
    • Add useNativeDriver: true to the animation config.

    • Press the button to block the JS thread while the
    animation runs.

    • Set useNativeDriver to false and press the button again.
    Observe the difference

    View Slide

  36. Listening to value updates
    • It is useful sometimes to know what the value is at a given
    point in time

    • You can’t access the value synchronously through a
    public API

    this.progress.addListener(({ value }) => {
    // Do something with the value!
    });

    View Slide

  37. Exercise 3 !
    • Use interpolation to transition
    between colours in the
    Spanish flag.

    • Show a text to display the
    current animated value in a
    text component.

    • Show an Alert when the
    animation finishes.

    View Slide

  38. Exercise 4
    • Animate a button to emphasise active state, by scaling it
    up and down. The pressed state should scale it down
    10%
    Hint: use
    onPressIn and
    onPressOut

    View Slide

  39. Recap
    • We can think of the progress of an animation from 0 to 1 (or any
    arbitrary range of numbers)

    • We can derive other values from the progress value with linear
    interpolation

    • Those values can be assigned to style properties on Animated
    Views

    • When the progress value updates, the interpolated values update
    and the views that are bound to those update

    • We can drive updates to the progress value using functions such
    as Animated.timing

    View Slide

  40. Value
    Interpolation
    Views
    View
    Image
    Text
    ScrollView
    etc…
    Driver
    Event driver
    Static driver
    Number
    @notbrent

    View Slide

  41. Value
    Views
    View
    Image
    Text
    ScrollView
    etc…
    subscribe to
    value updates
    value
    Driver
    Event driver
    Static driver
    Interpolation
    Number
    @notbrent

    View Slide

  42. Value
    Interpolation
    Number
    Views
    View
    Image
    Text
    ScrollView
    etc…
    subscribe to
    value updates
    value
    set
    value
    Driver
    Event driver
    Static driver
    Interpolation
    @notbrent

    View Slide

  43. Value
    Interpolation
    Number
    value
    Views
    View
    Image
    Text
    ScrollView
    etc…
    Driver
    Event driver
    Static driver value
    subscribe to
    Value updates
    subscribe to
    Interpolated value
    updates
    @notbrent

    View Slide

  44. Value
    Interpolation
    Number
    value
    Views
    View
    Image
    Text
    ScrollView
    etc…
    value
    subscribe to
    Value updates
    subscribe to
    Interpolated value
    updates
    set
    value
    Driver
    Event driver
    Static driver
    @notbrent

    View Slide

  45. Module 3
    Event drivers

    View Slide

  46. Event drivers
    • Interactions

    • Scrolling

    • Swiping (next module)

    • Dragging (next module)

    • etc

    View Slide

  47. Scrolling is powerful…

    View Slide

  48. ScrollView super powers
    https://codeburst.io/horizontal-scroll-animations-in-react-native-18dac6e9c720
    - horizontal
    - pagingEnabled
    - rotateX, rotateY, scale

    View Slide

  49. Real life patterns

    View Slide

  50. Scrolling for today
    • onScroll

    • scrollEventThrottle

    • event.nativeEvent.contentOffset.y

    View Slide

  51. Collapse all the things!
    Exercise 5

    View Slide

  52. Collapsible header

    View Slide

  53. Collapsible header

    View Slide

  54. Collapsible header
    • We need to define several interpolation for:

    • Toolbar —> opacity

    • Image —> translate

    • Title —> translate

    • Several elements with absolute position

    • zIndex and elevation

    View Slide

  55. Make things to disappear
    Exercise 6

    View Slide

  56. Floating Action Button

    View Slide

  57. Floating Action Button
    • We need to listen for scroll events

    • Animate translation: Outside and inside the
    screen

    • A bit of manual work: Save offset (Y) and
    compare it to the listened value to know if we
    scroll up or down

    View Slide

  58. Floating Action Button

    View Slide

  59. Module 4
    Interactions

    View Slide

  60. Touchable




    View Slide

  61. JS Responder System
    @kzzzf

    View Slide

  62. Async fate
    @kzzzf

    View Slide

  63. Pan Responder

    View Slide

  64. Pan Responder
    It holds an InteractionManager handle to block
    long-running JS events from interrupting active
    gestures
    gestureState = {
    dx,
    dy,
    vx,
    vy,
    ...
    }

    View Slide

  65. Native gesture recognisers
    • ScrollView uses a native gesture recogniser instead of a
    JS based.

    • A Switch component is another example or native gesture
    recogniser where you can swipe or touch to flip the state

    • Drawer, NavigatorIOS, ViewPager…

    View Slide

  66. Problems
    1. Gesture recognition logic is distributed between threads
    that run in parallel.

    2. No API for defining interactions between native gesture
    recognisers, like a Drawer and a View Pager

    3. Touch events recognised by JS responder system can’t
    be connected with Views that animate on the native thread

    View Slide

  67. react-native-gesture-handler

    View Slide





  68. BEGAN
    ACTIVE
    FAILED
    CANCELLED
    END
    UNDETERMINED
    STATES
    onHandlerStateChange
    onGestureEvent
    HANDLERS

    View Slide

  69. Components
    • RN-gesture handler also offers some components that are
    built using those low level Gesture Recognisers

    • One of them is the component, which
    comes in handy in many use cases

    View Slide

  70. Native driver compliant
    onGestureEvent={Animated.event(
    [
    {
    nativeEvent: {
    translationX: this.translateX,
    },
    },
    ],
    { useNativeDriver: true },
    )}
    onHandlerStateChange={this.onHandlerStateChange}
    >

    View Slide

  71. Exercise 7
    Gmail swappable rows!

    View Slide

  72. Exercise 8
    Instagram story widget interaction!

    View Slide

  73. Module 5
    react-native-reanimated

    View Slide

  74. react-native-reanimated

    View Slide

  75. View Slide

  76. Key points
    • Reimplementation of Animated Module from scratch

    • It provides a more comprehensive, low level abstraction

    • Great flexibility for gesture based animations

    • Everything runs on the native thread by default!

    View Slide

  77. More resources
    • https://github.com/kmagiera/react-native-reanimated/
    tree/master/Example

    • https://blog.callstack.io/reanimating-your-react-native-
    experience-d1377d51118a

    View Slide

  78. View Slide

  79. Feedback
    https://goo.gl/Uss11W

    View Slide

  80. Thank you! :)
    @rgommezz @ferrannp

    View Slide