Ready animation code for IOS app with SwiftUI. You can copy and paste to your project. This is a sample of how I do drawing with bezier curves and animate. All works are based on this principle.
import SwiftUI
struct ContentView: View {
var body: some View {
freeExampleCode()
.scaledToFit()
.frame(width: 300, height: 300) // change size
}
}
struct freeExampleCode: View {
@State private var speed = 1.0 // change animation speed
@State private var opacityLeaf = 0.0
@State private var scaleLeaf = 0.4
@State private var opacitySphere = 0.0
@State private var scaleSphere = 1.5
@State private var toggled = false
func move() {
if toggled {
toggled.toggle()
opacityLeaf = 0.0
scaleLeaf = 0.4
opacitySphere = 0.0
scaleSphere = 1.5
} else {
toggled.toggle()
withAnimation(Animation.easeIn.speed(1 / speed)) { opacityLeaf = 1.0 }
withAnimation(Animation.easeOut(duration: speed * 2)) { scaleLeaf = 1.0 }
withAnimation(Animation.linear.speed(1 / speed).delay(speed)) { opacitySphere = 1.0 }
withAnimation(Animation.interpolatingSpring(stiffness: 500, damping: 5).speed(1 / speed).delay(speed)) { scaleSphere = 1.0 }
}
}
var body: some View {
GeometryReader { geo in
let middle: CGFloat = min(geo.size.width, geo.size.height)
ZStack {
// down
Path { path in
path.move(to: CGPoint(x: middle * 0.283, y: middle * 0.711))
path.addCurve(to: CGPoint(x: middle * 0.821, y: middle * 0.696), control1: CGPoint(x: middle * 0.44, y: middle * 0.677), control2: CGPoint(x: middle * 0.656, y: middle * 0.674))
path.addCurve(to: CGPoint(x: middle * 0.866, y: middle * 0.774), control1: CGPoint(x: middle * 1.005, y: middle * 0.72), control2: CGPoint(x: middle * 1.033, y: middle * 0.772))
path.addCurve(to: CGPoint(x: middle * 0.29, y: middle * 0.826), control1: CGPoint(x: middle * 0.635, y: middle * 0.775), control2: CGPoint(x: middle * 0.754, y: middle * 0.914))
path.addCurve(to: CGPoint(x: middle * 0.283, y: middle * 0.711), control1: CGPoint(x: middle * 0.116, y: middle * 0.793), control2: CGPoint(x: middle * 0.144, y: middle * 0.741))
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 225 / 255, green: 69 / 255, blue: 123 / 255), Color(red: 255 / 255, green: 146 / 255, blue: 119 / 255), Color(red: 253 / 255, green: 234 / 255, blue: 238 / 255)]), startPoint: UnitPoint(x: 0.5, y: 0.67), endPoint: UnitPoint(x: 0.5, y: 0.87) ))
// bowl
Path { path in
path.addArc(center: CGPoint(x: middle * 0.5, y: middle * 0.524), radius: middle * 0.225, startAngle: .degrees(0), endAngle: .degrees(180), clockwise: false)
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 255 / 255, green: 255 / 255, blue: 255 / 255), Color(red: 252 / 255, green: 163 / 255, blue: 154 / 255)]), startPoint: UnitPoint(x: 0.35, y: 0.43), endPoint: UnitPoint(x: 0.68, y: 0.675) ))
// ellipse
Path { path in
path.move(to: CGPoint(x: middle * 0.275, y: middle * 0.524))
path.addCurve(to: CGPoint(x: middle * 0.725, y: middle * 0.524), control1: CGPoint(x: middle * 0.275, y: middle * 0.44), control2: CGPoint(x: middle * 0.725, y: middle * 0.44))
path.addCurve(to: CGPoint(x: middle * 0.275, y: middle * 0.524), control1: CGPoint(x: middle * 0.725, y: middle * 0.585), control2: CGPoint(x: middle * 0.275, y: middle * 0.585))
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 225 / 255, green: 69 / 255, blue: 123 / 255), Color(red: 255 / 255, green: 146 / 255, blue: 119 / 255), Color(red: 251 / 255, green: 186 / 255, blue: 166 / 255)]), startPoint: UnitPoint(x: 0.35, y: 0.42), endPoint: UnitPoint(x: 0.72, y: 0.65) ))
ZStack {
// right leaf
Path { path in
path.move(to: CGPoint(x: middle * 0.503, y: middle * 0.553))
path.addCurve(to: CGPoint(x: middle * 0.656, y: middle * 0.327), control1: CGPoint(x: middle * 0.481, y: middle * 0.393), control2: CGPoint(x: middle * 0.578, y: middle * 0.401))
path.addCurve(to: CGPoint(x: middle * 0.702, y: middle * 0.352), control1: CGPoint(x: middle * 0.704, y: middle * 0.282), control2: CGPoint(x: middle * 0.722, y: middle * 0.258))
path.addCurve(to: CGPoint(x: middle * 0.503, y: middle * 0.553), control1: CGPoint(x: middle * 0.68, y: middle * 0.453), control2: CGPoint(x: middle * 0.572, y: middle * 0.47))
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 254 / 255, green: 214 / 255, blue: 222 / 255), Color(red: 120 / 255, green: 84 / 255, blue: 247 / 255)]), startPoint: UnitPoint(x: 0.62, y: 0.27), endPoint: UnitPoint(x: 0.62, y: 0.54) ))
// left leaf
Path { path in
path.move(to: CGPoint(x: middle * 0.503, y: middle * 0.553))
path.addCurve(to: CGPoint(x: middle * 0.411, y: middle * 0.508), control1: CGPoint(x: middle * 0.473, y: middle * 0.536), control2: CGPoint(x: middle * 0.43, y: middle * 0.551))
path.addCurve(to: CGPoint(x: middle * 0.416, y: middle * 0.492), control1: CGPoint(x: middle * 0.408, y: middle * 0.501), control2: CGPoint(x: middle * 0.398, y: middle * 0.468))
path.addCurve(to: CGPoint(x: middle * 0.503, y: middle * 0.553), control1: CGPoint(x: middle * 0.43, y: middle * 0.514), control2: CGPoint(x: middle * 0.488, y: middle * 0.485))
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 254 / 255, green: 214 / 255, blue: 222 / 255), Color(red: 120 / 255, green: 84 / 255, blue: 247 / 255)]), startPoint: UnitPoint(x: 0.44, y: 0.48), endPoint: UnitPoint(x: 0.47, y: 0.57) ))
// middle leaf
Path { path in
path.move(to: CGPoint(x: middle * 0.503, y: middle * 0.553))
path.addCurve(to: CGPoint(x: middle * 0.385, y: middle * 0.437), control1: CGPoint(x: middle * 0.489, y: middle * 0.529), control2: CGPoint(x: middle * 0.494, y: middle * 0.481))
path.addCurve(to: CGPoint(x: middle * 0.208, y: middle * 0.285), control1: CGPoint(x: middle * 0.236, y: middle * 0.378), control2: CGPoint(x: middle * 0.304, y: middle * 0.363))
path.addCurve(to: CGPoint(x: middle * 0.172, y: middle * 0.187), control1: CGPoint(x: middle * 0.027, y: middle * 0.138), control2: CGPoint(x: middle * 0.134, y: middle * 0.179))
path.addCurve(to: CGPoint(x: middle * 0.503, y: middle * 0.553), control1: CGPoint(x: middle * 0.352, y: middle * 0.225), control2: CGPoint(x: middle * 0.572, y: middle * 0.372))
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 242 / 255, green: 251 / 255, blue: 232 / 255), Color(red: 80 / 255, green: 47 / 255, blue: 196 / 255)]), startPoint: UnitPoint(x: 0.29, y: 0.18), endPoint: UnitPoint(x: 0.31, y: 0.55) ))
}
.opacity(opacityLeaf)
.scaleEffect(scaleLeaf)
// sphere
Path { path in
path.addArc(center: CGPoint(x: middle * 0.51, y: middle * 0.224), radius: middle * 0.077, startAngle: .degrees(0), endAngle: .degrees(360), clockwise: false)
} .fill(LinearGradient(gradient: Gradient(colors: [Color(red: 253 / 255, green: 234 / 255, blue: 238 / 255), Color(red: 255 / 255, green: 146 / 255, blue: 119 / 255), Color(red: 225 / 255, green: 69 / 255, blue: 123 / 255)]), startPoint: UnitPoint(x: 0.5, y: 0.147), endPoint: UnitPoint(x: 0.5, y: 0.301) ))
.opacity(opacitySphere)
.scaleEffect(scaleSphere)
}
.onTapGesture { move() }
}
}
}
// Line: 88