I'm trying to reproduce Apple's parallax effect code from their WWDC24 video here but it isn't quite working well. I have the following code:
struct AnimalView: View {
let imageName: String
var body: some View {
Image(imageName)
.resizable()
.frame(width: 300, height: 450)
.clipShape(RoundedRectangle(cornerRadius: 32))
}
}
struct ContentView: View {
private let animals = ["1", "2", "3", "4", "5", "6"]
var body: some View {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 16) {
ForEach(animals, id: \.self) { name in
AnimalView(imageName: name)
.scrollTransition(.interactive, axis: .horizontal) { content, phase in
content.offset(x: phase.value * -250)
}
.containerRelativeFrame(.horizontal)
.clipShape(RoundedRectangle(cornerRadius: 32))
}
}
.scrollTargetLayout()
}
.contentMargins(.horizontal, 32)
.scrollTargetBehavior(.paging)
}
}
The parallax effect is somewhat there but is jarring and not smooth at all as in Apple's video. I understand the video doesn't show the entire code but it seems to me that the AnimalView
needs additional offset to be applied for the transitions to be smoother but I can't quite nail it down. Any help is appreciated.
Took a while. Hope this helps.
struct paging: View {
var body: some View {
GeometryReader { geometry in
let width = geometry.size.width
ScrollView(.horizontal) {
LazyHStack(spacing: 22) {
ForEach(1...10, id: \.self) { index in
ZStack {
Image(((index % 2) != 0) ? .t : .h)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: 450) .scrollTransition(
axis: .horizontal
) { content, phase in
content.offset(x: phase.value * -(width/2))
}
}
.containerRelativeFrame(.horizontal)
.clipShape(RoundedRectangle(cornerRadius: 32))
}
}
.scrollTargetLayout()
}
.contentMargins(.horizontal, 44)
.scrollTargetBehavior(.paging)
}
}
}