Setting the file. One moment.
Easing · Slack GIF Creator · anthropics/skills · Skills Docs
ContentsBack to the top of the page def ease_out_elastic
— line 85
This file
Number 13.1
Position 1 of 6
Type Python
Size 6 KB
Lines 234 core/ easing.py
Python · 234 lines · 6 KB
15
16
17 def ease_in_quad (t: float ) -> float :
18 """Quadratic ease-in (slow start, accelerating)."""
19 return t * t
20
21
22 def ease_out_quad (t: float ) -> float :
23 """Quadratic ease-out (fast start, decelerating)."""
24 return t * ( 2 - t)
25
26
27 def ease_in_out_quad (t: float ) -> float :
28 """Quadratic ease-in-out (slow start and end)."""
29 if t < 0.5 :
30 return 2 * t * t
31 return - 1 + ( 4 - 2 * t) * t
32
33
34 def ease_in_cubic (t: float ) -> float :
35 """Cubic ease-in (slow start)."""
36 return t * t * t
37
38
39 def ease_out_cubic (t: float ) -> float :
40 """Cubic ease-out (fast start)."""
41 return (t - 1 ) * (t - 1 ) * (t - 1 ) + 1
42
43
44 def ease_in_out_cubic (t: float ) -> float :
45 """Cubic ease-in-out."""
46 if t < 0.5 :
47 return 4 * t * t * t
48 return (t - 1 ) * ( 2 * t - 2 ) * ( 2 * t - 2 ) + 1
49
50
51 def ease_in_bounce (t: float ) -> float :
52 """Bounce ease-in (bouncy start)."""
53 return 1 - ease_out_bounce( 1 - t)
54
55
56 def ease_out_bounce (t: float ) -> float :
57 """Bounce ease-out (bouncy end)."""
58 if t < 1 / 2.75 :
59 return 7.5625 * t * t
60 elif t < 2 / 2.75 :
61 t -= 1.5 / 2.75
62 return 7.5625 * t * t + 0.75
63 elif t < 2.5 / 2.75 :
64 t -= 2.25 / 2.75
65 return 7.5625 * t * t + 0.9375
66 else :
67 t -= 2.625 / 2.75
68 return 7.5625 * t * t + 0.984375
69
70
71 def ease_in_out_bounce (t: float ) -> float :
72 """Bounce ease-in-out."""
73 if t < 0.5 :
74 return ease_in_bounce(t * 2 ) * 0.5
75 return ease_out_bounce(t * 2 - 1 ) * 0.5 + 0.5
76
77
78 def ease_in_elastic (t: float ) -> float :
79 """Elastic ease-in (spring effect)."""
80 if t == 0 or t == 1 :
81 return t
82 return - math.pow( 2 , 10 * (t - 1 )) * math.sin((t - 1.1 ) * 5 * math.pi)
83
84
85 def ease_out_elastic (t: float ) -> float :
86 """Elastic ease-out (spring effect)."""
87 if t == 0 or t == 1 :
88 return t
89 return math.pow( 2 , - 10 * t) * math.sin((t - 0.1 ) * 5 * math.pi) + 1
90
91
92 def ease_in_out_elastic (t: float ) -> float :
93 """Elastic ease-in-out."""
94 if t == 0 or t == 1 :
95 return t
96 t = t * 2 - 1
97 if t < 0 :
98 return - 0.5 * math.pow( 2 , 10 * t) * math.sin((t - 0.1 ) * 5 * math.pi)
99 return math.pow( 2 , - 10 * t) * math.sin((t - 0.1 ) * 5 * math.pi) * 0.5 + 1
100
101
102 # Convenience mapping
103 EASING_FUNCTIONS = {
104 "linear" : linear,
105 "ease_in" : ease_in_quad,
106 "ease_out" : ease_out_quad,
107 "ease_in_out" : ease_in_out_quad,
108 "bounce_in" : ease_in_bounce,
109 "bounce_out" : ease_out_bounce,
110 "bounce" : ease_in_out_bounce,
111 "elastic_in" : ease_in_elastic,
112 "elastic_out" : ease_out_elastic,
113 "elastic" : ease_in_out_elastic,
114 }
115
116
117 def get_easing (name: str = "linear" ):
118 """Get easing function by name."""
119 return EASING_FUNCTIONS .get(name, linear)
120
121
122 def interpolate (start: float , end: float , t: float , easing: str = "linear" ) -> float :
123 """
124 Interpolate between two values with easing.
125
126 Args:
127 start: Start value
128 end: End value
129 t: Progress from 0.0 to 1.0
130 easing: Name of easing function
131
132 Returns:
133 Interpolated value
134 """
135 ease_func = get_easing(easing)
136 eased_t = ease_func(t)
137 return start + (end - start) * eased_t
138
139
140 def ease_back_in (t: float ) -> float :
141 """Back ease-in (slight overshoot backward before forward motion)."""
142 c1 = 1.70158
143 c3 = c1 + 1
144 return c3 * t * t * t - c1 * t * t
145
146
147 def ease_back_out (t: float ) -> float :
148 """Back ease-out (overshoot forward then settle back)."""
149 c1 = 1.70158
150 c3 = c1 + 1
151 return 1 + c3 * pow (t - 1 , 3 ) + c1 * pow (t - 1 , 2 )
152
153
154 def ease_back_in_out (t: float ) -> float :
155 """Back ease-in-out (overshoot at both ends)."""
156 c1 = 1.70158
157 c2 = c1 * 1.525
158 if t < 0.5 :
159 return ( pow ( 2 * t, 2 ) * ((c2 + 1 ) * 2 * t - c2)) / 2
160 return ( pow ( 2 * t - 2 , 2 ) * ((c2 + 1 ) * (t * 2 - 2 ) + c2) + 2 ) / 2
161
162
163 def apply_squash_stretch (
164 base_scale: tuple[ float , float ], intensity: float , direction: str = "vertical"
165 ) -> tuple[ float , float ]:
166 """
167 Calculate squash and stretch scales for more dynamic animation.
168
169 Args:
170 base_scale: (width_scale, height_scale) base scales
171 intensity: Squash/stretch intensity (0.0-1.0)
172 direction: 'vertical', 'horizontal', or 'both'
173
174 Returns:
175 (width_scale, height_scale) with squash/stretch applied
176 """
177 width_scale, height_scale = base_scale
178
179 if direction == "vertical" :
180 # Compress vertically, expand horizontally (preserve volume)
181 height_scale *= 1 - intensity * 0.5
182 width_scale *= 1 + intensity * 0.5
183 elif direction == "horizontal" :
184 # Compress horizontally, expand vertically
185 width_scale *= 1 - intensity * 0.5
186 height_scale *= 1 + intensity * 0.5
187 elif direction == "both" :
188 # General squash (both dimensions)
189 width_scale *= 1 - intensity * 0.3
190 height_scale *= 1 - intensity * 0.3
191
192 return (width_scale, height_scale)
193
194
195 def calculate_arc_motion (
196 start: tuple[ float , float ], end: tuple[ float , float ], height: float , t: float
197 ) -> tuple[ float , float ]:
198 """
199 Calculate position along a parabolic arc (natural motion path).
200
201 Args:
202 start: (x, y) starting position
203 end: (x, y) ending position
204 height: Arc height at midpoint (positive = upward)
205 t: Progress (0.0-1.0)
206
207 Returns:
208 (x, y) position along arc
209 """
210 x1, y1 = start
211 x2, y2 = end
212
213 # Linear interpolation for x
214 x = x1 + (x2 - x1) * t
215
216 # Parabolic interpolation for y
217 # y = start + progress * (end - start) + arc_offset
218 # Arc offset peaks at t=0.5
219 arc_offset = 4 * height * t * ( 1 - t)
220 y = y1 + (y2 - y1) * t - arc_offset
221
222 return (x, y)
223
224
225 # Add new easing functions to the convenience mapping
226 EASING_FUNCTIONS .update(
227 {
228 "back_in" : ease_back_in,
229 "back_out" : ease_back_out,
230 "back_in_out" : ease_back_in_out,
231 "anticipate" : ease_back_in, # Alias
232 "overshoot" : ease_back_out, # Alias
233 }
234 )