I'm trying to copying the Colorful Confetti effect in iMessage using SwiftUI Canvas and I am wondering how to apply 3D transformation on each particle.
I have tried to add a projectionTransform in order to apply a CATransform3D
, but it rotates all the canvas, not a particular particle, which is not the effect I want.
Currently, I use the very basic ForEach(particles.indices, id: \.self)
loop to create each particle and use .rotation3DEffect
to apply that transformation, but it may result in a performance issue (so, I tried to use .drawingGroup()
).
Is there any solutions to apply 3D transformation to a particular particle in a Canvas??
My code (using ForEach
loop):
GeometryReader { proxy in
let size = proxy.size
TimelineView(.animation) { timeline in
let _: () = {
let now = timeline.date.timeIntervalSinceReferenceDate
model.update(at: now)
}()
ZStack {
ForEach(model.particles.indices, id: \.self) { index in
let particle = model.particles[index]
particle.shape
.fill(particle.color)
.rotation3DEffect(.degrees(particle.degrees), axis: (x: particle.x, y: particle.y, z: particle.z))
.frame(width: particle.frame.width, height: particle.frame.height)
.position(particle.frame.origin)
.tag(index)
}
}
.frame(width: size.width, height: size.height)
.drawingGroup()
}
.contentShape(Rectangle())
.gesture(
DragGesture(minimumDistance: 0)
.onEnded { _ in model.loadEffect(in: size) }
)
.task { model.loadEffect(in: size) }
}