Skip to content

Commit cb42434

Browse files
authored
Add support for more animation types (#1280)
* Add support for more animation types * Add `Symbols` import to generated modifiers file * Regenerate to combine symbol and text modifier changes
1 parent 1d60087 commit cb42434

File tree

5 files changed

+577
-263
lines changed

5 files changed

+577
-263
lines changed

Sources/LiveViewNative/Stylesheets/ParseableTypes/Animation+ParseableModifierValue.swift

Lines changed: 237 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,27 @@ extension Animation: ParseableModifierValue {
1717
Base.EaseOut.parser(in: context).map(Base.easeOut)
1818
Base.EaseInOut.parser(in: context).map(Base.easeInOut)
1919
Base.Linear.parser(in: context).map(Base.linear)
20-
ConstantAtomLiteral("spring").map({ Base.spring })
21-
ConstantAtomLiteral("interactiveSpring").map({ Base.interactiveSpring })
22-
ConstantAtomLiteral("interpolatingSpring").map({ Base.interpolatingSpring })
20+
Base.Spring.parser(in: context).map(Base.spring)
21+
ConstantAtomLiteral("spring").map({ Base.spring(.init()) })
22+
Base.InteractiveSpring.parser(in: context).map(Base.interactiveSpring)
23+
ConstantAtomLiteral("interactiveSpring").map({ Base.interactiveSpring(.init()) })
24+
Base.InterpolatingSpring.parser(in: context).map(Base.interpolatingSpring)
25+
ConstantAtomLiteral("interpolatingSpring").map({ Base.interpolatingSpring(.init()) })
2326
Base.TimingCurve.parser(in: context).map(Base.timingCurve)
27+
28+
BouncySpring.parser(in: context).map(Base.bouncy)
29+
ConstantAtomLiteral("bouncy").map({ Base.bouncy(.init()) })
30+
SmoothSpring.parser(in: context).map(Base.smooth)
31+
ConstantAtomLiteral("smooth").map({ Base.smooth(.init()) })
32+
SnappySpring.parser(in: context).map(Base.snappy)
33+
ConstantAtomLiteral("snappy").map({ Base.snappy(.init()) })
2434
}
2535
} member: {
2636
OneOf {
2737
Modifier.Delay.parser(in: context).map(Modifier.delay)
38+
Modifier.RepeatCount.parser(in: context).map(Modifier.repeatCount)
39+
Modifier.RepeatForever.parser(in: context).map(Modifier.repeatForever)
40+
Modifier.Speed.parser(in: context).map(Modifier.speed)
2841
}
2942
}
3043
.map { (base: Base, members: [Modifier]) in
@@ -55,14 +68,20 @@ extension Animation: ParseableModifierValue {
5568
} else {
5669
Self.linear
5770
}
58-
case .spring:
59-
Self.spring
60-
case .interactiveSpring:
61-
Self.interactiveSpring
62-
case .interpolatingSpring:
63-
Self.interpolatingSpring
71+
case let .spring(spring):
72+
spring.value
73+
case let .interactiveSpring(interactiveSpring):
74+
interactiveSpring.value
75+
case let .interpolatingSpring(interpolatingSpring):
76+
interpolatingSpring.value
6477
case let .timingCurve(timingCurve):
6578
timingCurve.value
79+
case let .bouncy(value):
80+
Self.bouncy(duration: value.duration, extraBounce: value.extraBounce)
81+
case let .smooth(value):
82+
Self.smooth(duration: value.duration, extraBounce: value.extraBounce)
83+
case let .snappy(value):
84+
Self.snappy(duration: value.duration, extraBounce: value.extraBounce)
6685
}
6786
for modifier in members {
6887
switch modifier {
@@ -86,10 +105,13 @@ extension Animation: ParseableModifierValue {
86105
case easeOut(EaseOut)
87106
case easeInOut(EaseInOut)
88107
case linear(Linear)
89-
case spring
90-
case interactiveSpring
91-
case interpolatingSpring
108+
case spring(Spring)
109+
case interactiveSpring(InteractiveSpring)
110+
case interpolatingSpring(InterpolatingSpring)
92111
case timingCurve(TimingCurve)
112+
case bouncy(BouncySpring)
113+
case smooth(SmoothSpring)
114+
case snappy(SnappySpring)
93115

94116
@ParseableExpression
95117
struct EaseIn {
@@ -135,6 +157,104 @@ extension Animation: ParseableModifierValue {
135157
}
136158
}
137159

160+
@ParseableExpression
161+
struct Spring {
162+
static let name = "spring"
163+
164+
let value: Animation
165+
166+
init() {
167+
self.value = .spring
168+
}
169+
170+
@available(iOS 17.0, macOS 14, tvOS 17, watchOS 10, *)
171+
init(
172+
_ spring: SwiftUI.Spring,
173+
blendDuration: Double = 0.0
174+
) {
175+
self.value = .spring(spring, blendDuration: blendDuration)
176+
}
177+
178+
init(
179+
duration: Double = 0.5,
180+
bounce: Double = 0.0,
181+
blendDuration: Double = 0
182+
) {
183+
self.value = .spring(duration: duration, bounce: bounce, blendDuration: blendDuration)
184+
}
185+
186+
init(
187+
response: Double = 0.5,
188+
dampingFraction: Double = 0.825,
189+
blendDuration: TimeInterval = 0
190+
) {
191+
self.value = .spring(response: response, dampingFraction: dampingFraction, blendDuration: blendDuration)
192+
}
193+
}
194+
195+
@ParseableExpression
196+
struct InteractiveSpring {
197+
static let name = "interactiveSpring"
198+
199+
let value: Animation
200+
201+
init() {
202+
self.value = .interactiveSpring
203+
}
204+
205+
init(
206+
response: Double = 0.15,
207+
dampingFraction: Double = 0.86,
208+
blendDuration: TimeInterval = 0.25
209+
) {
210+
self.value = .interactiveSpring(response: response, dampingFraction: dampingFraction, blendDuration: blendDuration)
211+
}
212+
213+
init(
214+
duration: TimeInterval = 0.15,
215+
extraBounce: Double = 0.0,
216+
blendDuration: TimeInterval = 0.25
217+
) {
218+
self.value = .interactiveSpring(duration: duration, extraBounce: extraBounce, blendDuration: blendDuration)
219+
}
220+
}
221+
222+
@ParseableExpression
223+
struct InterpolatingSpring {
224+
static let name = "interpolatingSpring"
225+
226+
let value: Animation
227+
228+
init() {
229+
self.value = .interpolatingSpring
230+
}
231+
232+
@available(iOS 17.0, macOS 14, tvOS 17, watchOS 10, *)
233+
init(
234+
_ spring: SwiftUI.Spring,
235+
initialVelocity: Double = 0.0
236+
) {
237+
self.value = .interpolatingSpring(spring, initialVelocity: initialVelocity)
238+
}
239+
240+
init(
241+
duration: TimeInterval = 0.5,
242+
bounce: Double = 0.0,
243+
initialVelocity: Double = 0.0
244+
) {
245+
self.value = .interpolatingSpring(duration: duration, bounce: bounce, initialVelocity: initialVelocity)
246+
}
247+
248+
init(
249+
mass: Double = 1.0,
250+
stiffness: Double,
251+
damping: Double,
252+
initialVelocity: Double = 0.0
253+
) {
254+
self.value = .interpolatingSpring(mass: mass, stiffness: stiffness, damping: damping, initialVelocity: initialVelocity)
255+
}
256+
}
257+
138258
@ParseableExpression
139259
struct TimingCurve {
140260
static let name = "timingCurve"
@@ -205,3 +325,108 @@ extension Animation: ParseableModifierValue {
205325
}
206326
}
207327
}
328+
329+
@available(iOS 17.0, macOS 14, tvOS 17, watchOS 10, *)
330+
extension Spring: ParseableModifierValue {
331+
public static func parser(in context: ParseableModifierContext) -> some Parser<Substring.UTF8View, Self> {
332+
OneOf {
333+
_Spring.parser(in: context).map(\.value)
334+
ImplicitStaticMember {
335+
OneOf {
336+
BouncySpring.parser(in: context).map({ Self.bouncy(duration: $0.duration, extraBounce: $0.extraBounce) })
337+
ConstantAtomLiteral("bouncy").map({ Self.bouncy })
338+
SmoothSpring.parser(in: context).map({ Self.smooth(duration: $0.duration, extraBounce: $0.extraBounce) })
339+
ConstantAtomLiteral("smooth").map({ Self.smooth })
340+
SnappySpring.parser(in: context).map({ Self.snappy(duration: $0.duration, extraBounce: $0.extraBounce) })
341+
ConstantAtomLiteral("snappy").map({ Self.snappy })
342+
}
343+
}
344+
}
345+
}
346+
347+
@ParseableExpression
348+
struct _Spring {
349+
static let name = "Spring"
350+
351+
let value: Spring
352+
353+
init(
354+
duration: Double = 0.5,
355+
bounce: Double = 0.0
356+
) {
357+
self.value = .init(duration: duration, bounce: bounce)
358+
}
359+
360+
init(
361+
mass: Double = 1.0,
362+
stiffness: Double,
363+
damping: Double,
364+
allowOverDamping: Bool = false
365+
) {
366+
self.value = .init(mass: mass, stiffness: stiffness, damping: damping, allowOverDamping: allowOverDamping)
367+
}
368+
369+
init(
370+
response: Double,
371+
dampingRatio: Double
372+
) {
373+
self.value = .init(response: response, dampingRatio: dampingRatio)
374+
}
375+
376+
init(
377+
settlingDuration: Double,
378+
dampingRatio: Double,
379+
epsilon: Double = 0.001
380+
) {
381+
self.value = .init(settlingDuration: settlingDuration, dampingRatio: dampingRatio, epsilon: epsilon)
382+
}
383+
}
384+
}
385+
386+
@ParseableExpression
387+
struct BouncySpring {
388+
static let name = "bouncy"
389+
390+
let duration: Double
391+
let extraBounce: Double
392+
393+
init(
394+
duration: Double = 0.5,
395+
extraBounce: Double = 0.0
396+
) {
397+
self.duration = duration
398+
self.extraBounce = extraBounce
399+
}
400+
}
401+
402+
@ParseableExpression
403+
struct SmoothSpring {
404+
static let name = "smooth"
405+
406+
let duration: Double
407+
let extraBounce: Double
408+
409+
init(
410+
duration: Double = 0.5,
411+
extraBounce: Double = 0.0
412+
) {
413+
self.duration = duration
414+
self.extraBounce = extraBounce
415+
}
416+
}
417+
418+
@ParseableExpression
419+
struct SnappySpring {
420+
static let name = "snappy"
421+
422+
let duration: Double
423+
let extraBounce: Double
424+
425+
init(
426+
duration: Double = 0.5,
427+
extraBounce: Double = 0.0
428+
) {
429+
self.duration = duration
430+
self.extraBounce = extraBounce
431+
}
432+
}

Sources/LiveViewNative/Stylesheets/ParseableTypes/AnySymbolEffect.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Symbols
1010
import LiveViewNativeStylesheet
1111

1212
@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
13-
struct AnySymbolEffect: SymbolEffect, ContentTransitionSymbolEffect, ParseableModifierValue {
13+
struct AnySymbolEffect: SymbolEffect, ContentTransitionSymbolEffect, ParseableModifierValue, IndefiniteSymbolEffect, DiscreteSymbolEffect {
1414
let configuration: SymbolEffectConfiguration
1515

1616
init(configuration: SymbolEffectConfiguration) {
@@ -363,3 +363,8 @@ extension SymbolEffectOptions: ParseableModifierValue {
363363
}
364364
}
365365
}
366+
367+
@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
368+
typealias AnyIndefiniteSymbolEffect = AnySymbolEffect
369+
@available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *)
370+
typealias AnyDiscreteSymbolEffect = AnySymbolEffect

Sources/LiveViewNative/Stylesheets/ParseableTypes/ContentTransition+ParseableModifierValue.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extension ContentTransition: ParseableModifierValue {
1818
ConstantAtomLiteral("opacity").map({ Self.opacity })
1919
NumericText.parser(in: context).map(\.value)
2020
if #available(iOS 17.0, macOS 14.0, tvOS 17.0, watchOS 10.0, *) {
21+
SymbolEffect.parser(in: context).map(\.value)
2122
ConstantAtomLiteral("symbolEffect").map({ Self.symbolEffect })
2223
}
2324
}

0 commit comments

Comments
 (0)