|
1 |
| -# Motion Animator |
| 1 | + |
2 | 2 |
|
3 |
| -> A Motion Animator creates performant, interruptible animations from motion specs. |
| 3 | +> An iOS animator that combines the best aspects of the UIView and CALayer animation APIs. |
4 | 4 |
|
5 | 5 | [](https://travis-ci.org/material-motion/motion-animator-objc)
|
6 | 6 | [](https://codecov.io/gh/material-motion/motion-animator-objc)
|
7 | 7 | [](https://cocoapods.org/pods/MotionAnimator)
|
8 | 8 | [](http://cocoadocs.org/docsets/MotionAnimator)
|
9 | 9 |
|
10 |
| ---- |
11 | 10 |
|
12 |
| -This library provides APIs that turn [Motion Interchange](https://github.com/material-motion/motion-interchange-objc) |
13 |
| -**motion specifications** into animations. |
14 |
| - |
15 |
| ---- |
16 |
| - |
17 |
| -#### What is a motion specification? |
18 |
| - |
19 |
| -A **motion specification** defines the delay, duration, and acceleration of animations in a simple |
20 |
| -data format that can live separate from your animation logic. |
21 |
| - |
22 |
| -For example, let's say we wanted to describe the motion for this animation: |
23 |
| - |
24 |
| -<img src="assets/chip.gif" /> |
25 |
| - |
26 |
| -We might create a specification like so: |
27 |
| - |
28 |
| -```objc |
29 |
| -struct CalendarChipTiming { |
30 |
| - MDMMotionTiming chipWidth; |
31 |
| - MDMMotionTiming chipHeight; |
32 |
| - MDMMotionTiming chipY; |
33 |
| - |
34 |
| - MDMMotionTiming chipContentOpacity; |
35 |
| - MDMMotionTiming headerContentOpacity; |
36 |
| - |
37 |
| - MDMMotionTiming navigationBarY; |
38 |
| -}; |
39 |
| -typedef struct CalendarChipTiming CalendarChipTiming; |
40 |
| - |
41 |
| -struct CalendarChipMotionSpec { |
42 |
| - CalendarChipTiming expansion; |
43 |
| - CalendarChipTiming collapse; |
44 |
| -}; |
45 |
| -typedef struct CalendarChipMotionSpec CalendarChipMotionSpec; |
46 |
| - |
47 |
| -FOUNDATION_EXTERN struct CalendarChipMotionSpec CalendarChipSpec; |
48 |
| -``` |
49 |
| - |
50 |
| -With our implementation of the spec looking like so: |
51 |
| - |
52 |
| -```objc |
53 |
| -struct CalendarChipMotionSpec CalendarChipSpec = { |
54 |
| - .expansion = { |
55 |
| - .chipWidth = { |
56 |
| - .delay = 0.000, .duration = 0.285, .curve = MDMEightyForty, |
57 |
| - }, |
58 |
| - .chipHeight = { |
59 |
| - .delay = 0.015, .duration = 0.360, .curve = MDMEightyForty, |
60 |
| - }, |
61 |
| - ... |
62 |
| - }, |
63 |
| - .collapse = { |
64 |
| - .chipWidth = { |
65 |
| - .delay = 0.045, .duration = 0.330, .curve = MDMEightyForty, |
66 |
| - }, |
67 |
| - .chipHeight = { |
68 |
| - .delay = 0.000, .duration = 0.330, .curve = MDMEightyForty, |
69 |
| - }, |
70 |
| - ... |
71 |
| - }, |
72 |
| -}; |
73 |
| -``` |
74 |
| - |
75 |
| -Our spec defines two different transition states: expansion and collapse. At runtime, we determine |
76 |
| -which of these two specs we need and then use the timings to animate our views with an instance of |
77 |
| -`MDMMotionAnimator`: |
78 |
| - |
79 |
| -```objc |
80 |
| -CalendarChipTiming timing = _expanded ? CalendarChipSpec.expansion : CalendarChipSpec.collapse; |
81 |
| - |
82 |
| -MDMMotionAnimator *animator = [[MDMMotionAnimator alloc] init]; |
83 |
| -animator.shouldReverseValues = !_expanded; |
84 |
| - |
85 |
| -[animator animateWithTiming:timing.chipHeight |
86 |
| - toLayer:chipView.layer |
87 |
| - withValues:@[ @(chipFrame.size.height), @(headerFrame.size.height) ] |
88 |
| - keyPath:MDMKeyPathHeight]; |
89 |
| -... |
90 |
| -``` |
91 |
| -
|
92 |
| -A working implementation of this example can be seen in the included example app. |
93 | 11 |
|
94 | 12 | ## Example apps/unit tests
|
95 | 13 |
|
|
0 commit comments