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

Intro to Material Motion

Intro to Material Motion

Material Motion is a toolkit for building responsive motion using Core Animation.

Learn more at https://github.com/material-motion

View the original deck at https://docs.google.com/presentation/d/1vXNpEYTMCXugFDNNBOWXBtQY9jHsB7FxxYa6BqpUnlM/pub?start=false&loop=false&delayms=3000

featherless

April 10, 2017
Tweet

Other Decks in Programming

Transcript

  1. An introduction to
    Material Motion
    by @featherless - engineering lead // April 10, 2017

    View full-size slide

  2. About @featherless
    Software designer on the Material Design team
    I build shared libraries for Google’s iOS apps and the open source community

    View full-size slide

  3. About @featherless
    Software designer on the Material Design team
    Previously:
    Facebook
    iOS app
    2009
    Nimbus
    iOS libraries
    2011
    Google Maps
    iOS app
    2012
    Material Components
    iOS libraries at Google
    2013, 2014-2015

    View full-size slide

  4. productive inspiring

    View full-size slide

  5. Material Motion

    View full-size slide

  6. engineering
    For considerations on motion design, visit our spec at
    material.io/guidelines/motion/

    View full-size slide

  7. hard get right

    View full-size slide

  8. Jank is any stuttering, juddering or just
    plain halting that users see when an app
    isn't keeping up with the refresh rate.
    - jankfree.org

    View full-size slide

  9. Gestural interactions should feed their
    velocity into animations in a simulation
    of continuous momentum.

    View full-size slide

  10. Gestural interactions should feed their
    velocity into animations in a simulation
    of continuous momentum.
    - from Facebook Paper’s tech talk
    youtu.be/OiY1cheLpmI?t=47m30s

    View full-size slide

  11. Don’t force users to wait for animations
    to complete before being allowed to take
    their next action.

    View full-size slide

  12. Animations don’t generally react well to breakpoints
    because breakpoints disconnect animations from time.

    View full-size slide

  13. Animations don’t generally react well to breakpoints
    because breakpoints disconnect animations from time.
    We need real-time tooling designed specifically for motion.

    View full-size slide

  14. Intro to Material Motion

    View full-size slide

  15. Intro to Material Motion
    How to make things move

    View full-size slide

  16. Intro to Material Motion
    How to make things move
    How to build transitions

    View full-size slide

  17. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  18. Common
    implementations
    of motion

    View full-size slide

  19. one-off animation code
    scattered in view
    controllers
    Common
    implementations
    of motion

    View full-size slide

  20. Interactions
    Constraints
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  21. Interactions
    Constraints
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  22. How to make things move

    View full-size slide

  23. How to make things move
    An object that conforms to the
    Interaction protocol.

    View full-size slide

  24. How to make things move

    View full-size slide

  25. Gestural interactions
    How to make things move

    View full-size slide

  26. How to make things move
    Gestural interactions
    Animated interactions

    View full-size slide

  27. How to make things move
    Gestural interactions
    Animated interactions
    Compositional interactions

    View full-size slide

  28. How to make things move
    Gestural

    View full-size slide

  29. let draggable = Draggable()
    let rotatable = Rotatable()
    let scalable = Scalable()
    How to make things move
    Gestural

    View full-size slide

  30. // Interaction: Draggable
    let view = UIView()
    How to make things move

    View full-size slide

  31. // Interaction: Draggable
    let view = UIView()
    let runtime = MotionRuntime()
    How to make things move

    View full-size slide

  32. // Interaction: Draggable
    let view = UIView()
    let runtime = MotionRuntime()
    let draggable = Draggable()
    How to make things move

    View full-size slide

  33. // Interaction: Draggable
    let view = UIView()
    let runtime = MotionRuntime()
    let draggable = Draggable()
    runtime.add(draggable, to: view)
    How to make things move

    View full-size slide

  34. // Interaction: Draggable
    let view = UIView()
    let runtime = MotionRuntime()
    runtime.add(Rotatable(), to: view)
    How to make things move

    View full-size slide

  35. // Interaction: Draggable
    let view = UIView()
    let runtime = MotionRuntime()
    runtime.add(Scalable(), to: view)
    How to make things move

    View full-size slide

  36. How to make things move

    View full-size slide

  37. Use Core Animation.
    How to make things move

    View full-size slide

  38. How to make things move
    Use Core Animation.
    Generic Interaction types.

    View full-size slide

  39. Use Core Animation.
    Generic Interaction types.
    let spring = Spring()
    How to make things move

    View full-size slide

  40. Use Core Animation.
    Generic Interaction types.
    let spring = Spring()
    let spring = Spring()
    How to make things move

    View full-size slide

  41. How to make things move
    Use Core Animation.
    Generic Interaction types.
    let spring = Spring()
    let spring = Spring()
    let tween = Tween()
    let tween = Tween()

    View full-size slide

  42. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    How to make things move

    View full-size slide

  43. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    How to make things move

    View full-size slide

  44. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    runtime.add(spring,
    How to make things move

    View full-size slide

  45. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    runtime.add(spring,
    to: runtime.get(view).position)
    How to make things move

    View full-size slide

  46. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    runtime.add(spring,
    to: runtime.get(view).position)
    How to make things move

    View full-size slide

  47. Reactive programming

    View full-size slide

  48. reactive
    Reactive programming

    View full-size slide

  49. Reactive programming
    view: UIView
    view

    View full-size slide

  50. Reactive programming
    view: UIView
    position: ReactiveProperty
    position
    50, 50
    view

    View full-size slide

  51. Reactive programming
    view: UIView
    position: ReactiveProperty
    let subscription = position
    .subscribe { value in
    print(value)
    }
    position
    50, 50
    view
    Subscription

    View full-size slide

  52. Reactive programming
    view: UIView
    position: ReactiveProperty
    let subscription = position
    .subscribe { value in
    print(value)
    }
    Subscription
    Console
    50, 50
    position
    50, 50
    view

    View full-size slide

  53. Reactive programming
    view: UIView
    position: ReactiveProperty
    let subscription = position
    .subscribe { value in
    print(value)
    }
    position.value = .init(x: 10, y: 20)
    Subscription
    Console
    50, 50
    10, 20
    position
    50, 50
    view

    View full-size slide

  54. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    runtime.add(spring,
    to: runtime.get(view).position)
    How to make things move

    View full-size slide

  55. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    runtime.add(spring,
    to: runtime.get(view).position)
    spring.destination
    How to make things move
    reactive property

    View full-size slide

  56. // Interaction: Spring
    let view = UIView()
    let runtime = MotionRuntime()
    let spring = Spring()
    runtime.add(spring,
    to: runtime.get(view).position)
    spring.destination.value = CGPoint(x: 75, y: 50)
    How to make things move

    View full-size slide

  57. Reactive programming
    connect

    View full-size slide

  58. Reactive programming
    runtime.add(spring, to: property)
    Spring()
    property

    View full-size slide

  59. Reactive programming
    Spring
    system
    value
    runtime.add(spring, to: property)
    property

    View full-size slide

  60. Reactive programming
    view
    runtime.add(Draggable(), to: view)
    Draggable()

    View full-size slide

  61. Reactive programming
    Pan
    Gesture
    translation position
    view
    runtime.add(Draggable(), to: view)

    View full-size slide

  62. Reactive programming
    composable

    View full-size slide

  63. Reactive programming
    Draggable + Rotatable + Scalable =

    View full-size slide

  64. Reactive programming
    Draggable + Rotatable + Scalable = DirectlyManipulable

    View full-size slide

  65. Reactive programming
    Draggable + Rotatable + Scalable = DirectlyManipulable
    Draggable + Spring =

    View full-size slide

  66. Reactive programming
    Draggable + Rotatable + Scalable = DirectlyManipulable
    Draggable + Spring = Tossable

    View full-size slide

  67. // Interaction: Tossable
    let view = UIView()
    let runtime = MotionRuntime()
    How to make things move

    View full-size slide

  68. // Interaction: Tossable
    let view = UIView()
    let runtime = MotionRuntime()
    let tossable = Tossable()
    How to make things move

    View full-size slide

  69. // Interaction: Tossable
    let view = UIView()
    let runtime = MotionRuntime()
    let tossable = Tossable()
    runtime.add(tossable, to: view)
    How to make things move

    View full-size slide

  70. // Interaction: Tossable
    let view = UIView()
    let runtime = MotionRuntime()
    let tossable = Tossable()
    runtime.add(tossable, to: view)
    // Under the hood:
    How to make things move

    View full-size slide

  71. // Interaction: Tossable
    let view = UIView()
    let runtime = MotionRuntime()
    let tossable = Tossable()
    runtime.add(tossable, to: view)
    // Under the hood:
    // runtime.add(spring, to: view.position)
    // runtime.add(draggable, to: view)
    How to make things move

    View full-size slide

  72. // Interaction: Tossable
    let view = UIView()
    let runtime = MotionRuntime()
    let tossable = Tossable()
    runtime.add(tossable, to: view)
    // Under the hood:
    // runtime.connect(draggable.finalVelocity,
    to: spring.initialVelocity)
    // runtime.add(spring, to: view.position)
    // runtime.add(draggable, to: view)
    How to make things move

    View full-size slide

  73. Interactions
    Constraints
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  74. Reactive programming
    Pan
    Gesture
    translation position
    view

    View full-size slide

  75. Reactive programming
    Pan
    Gesture
    translation position
    view
    constraint
    xLocked

    View full-size slide

  76. // Customizing interactions
    let draggable = Draggable()
    runtime.add(draggable, to: mochiView)
    How to make things move

    View full-size slide

  77. // Customizing interactions - Constraints
    let draggable = Draggable()
    runtime.add(draggable, to: mochiView, constraints: {
    return $0.xLocked(to: 100)
    })
    How to make things move

    View full-size slide

  78. // Customizing interactions - Constraints
    let draggable = Draggable()
    runtime.add(draggable, to: mochiView, constraints: {
    return $0.xLocked(to: 100)
    .rubberBanded(below: -50, above: 50, maxLength: 25)
    })
    How to make things move

    View full-size slide

  79. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Short summary:

    View full-size slide

  80. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Short summary:

    View full-size slide

  81. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Short summary:


    View full-size slide

  82. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Short summary:



    View full-size slide

  83. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  84. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Using custom transitions
    Creating a transition

    View full-size slide

  85. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Using custom transitions
    Creating a transition

    View full-size slide

  86. // Custom transitions
    viewController
    How to build transitions

    View full-size slide

  87. // Custom transitions
    viewController.transitionController
    transitionController
    How to build transitions

    View full-size slide

  88. // Custom transitions
    viewController.transitionController.transition = PushBackTransition.self
    How to build transitions
    PushBackTransition

    View full-size slide

  89. // Custom transitions
    viewController.transitionController.transition = PushBackTransition.self
    present(viewController, animated: true)
    How to build transitions

    View full-size slide

  90. // Custom transitions
    viewController.transitionController.transition = PushBackTransition.self
    present(viewController, animated: true)
    dismiss(animated: true)
    How to build transitions

    View full-size slide

  91. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Using custom transitions
    Creating a transition

    View full-size slide

  92. // Building a transition
    class PushBackTransition: Transition {
    }
    How to build transitions

    View full-size slide

  93. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    }
    }

    View full-size slide

  94. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    }
    }

    View full-size slide

  95. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    }
    }




    View full-size slide

  96. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    }
    }

    View full-size slide

  97. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    }
    }
    fore
    back fore

    View full-size slide

  98. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    }
    }
    fore back
    back fore back fore

    View full-size slide

  99. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    runtime.add(TransitionSpring(back: offscreen, fore: onscreen,
    direction: ctx.direction)
    to: ctx.fore.positionY)
    }
    }

    View full-size slide

  100. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    runtime.add(TransitionSpring(back: offscreen, fore: onscreen,
    direction: ctx.direction)
    to: ctx.fore.positionY)
    }
    }
    back fore

    View full-size slide

  101. How to build transitions
    // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    runtime.add(TransitionSpring(back: offscreen, fore: onscreen,
    direction: ctx.direction)
    to: ctx.fore.positionY)
    runtime.add(TransitionSpring(back: 1, fore: 0.95,
    direction: ctx.direction),
    to: ctx.back.scale)
    }
    }

    View full-size slide

  102. // Building a transition
    class PushBackTransition: Transition {
    func willBegin(ctx: TransitionContext, runtime: MotionRuntime) {
    let offscreen = ctx.height + ctx.fore.height / 2
    let onscreen = ctx.center.y
    runtime.add(TransitionSpring(back: offscreen, fore: onscreen,
    direction: ctx.direction)
    to: ctx.fore.positionY)
    runtime.add(TransitionSpring(back: 1, fore: 0.95,
    direction: ctx.direction),
    to: ctx.back.scale)
    }
    }
    How to build transitions

    View full-size slide

  103. Reactive programming

    View full-size slide

  104. Reactive programming
    reversible

    View full-size slide

  105. Reactive programming
    reversible

    View full-size slide

  106. Reactive programming
    position
    view

    View full-size slide

  107. Reactive programming
    value position
    view
    Spring

    View full-size slide

  108. Reactive programming
    value position
    view
    Spring
    destination

    View full-size slide

  109. Reactive programming
    value position
    view
    Spring
    destination
    fore value

    View full-size slide

  110. Reactive programming
    value position
    view
    Spring
    destination
    back value

    View full-size slide

  111. Reactive programming
    value position
    view
    Spring
    destination
    direction

    View full-size slide

  112. Reactive programming
    value position
    view
    Spring
    destination
    direction
    rewrite
    back fore

    View full-size slide

  113. Reactive programming
    value position
    view
    Spring
    destination
    direction
    rewrite
    fore

    View full-size slide

  114. Reactive programming
    value position
    view
    Spring
    destination
    direction
    rewrite
    back

    View full-size slide

  115. Summary:
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  116. Summary:

    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  117. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts
    Summary:

    ● reactive

    View full-size slide

  118. Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  119. responsive
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  120. responsive





    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  121. responsive





    github.com/material-motion
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  122. responsive





    github.com/material-motion
    discord.gg/ZJyGXza
    Intro to Material Motion
    How to make things move
    How to build transitions
    Closing thoughts

    View full-size slide

  123. github.com/material-motion discord.gg/ZJyGXza

    View full-size slide

  124. Some quick background on
    Core Animation (CA)
    Core Animation

    View full-size slide

  125. Some quick background on
    Core Animation (CA)
    ● CA animations occur on the render server.
    Core Animation

    View full-size slide

  126. Some quick background on
    Core Animation (CA)
    ● CA animations occur on the render server.
    ● The render server is independent from your
    app’s main thread.
    Core Animation

    View full-size slide

  127. Some quick background on
    Core Animation (CA)
    ● CA animations occur on the render server.
    ● The render server is independent from your
    app’s main thread.
    This means CA animations aren’t subject to
    main-thread jank.
    Core Animation

    View full-size slide

  128. Core Animation Some quick background on
    Core Animation (CA)
    ● CA animations occur on the render server.
    ● The render server is independent from your
    app’s main thread.
    This means CA animations aren’t subject to
    main-thread jank.
    Third-party animation libraries like Facebook’s
    POP operate on the main thread, which is why POP
    is often used hand-in-hand with AsyncDisplayKit.

    View full-size slide