Open ChristRm opened 7 years ago
I took the transform code for CoverFlow
https://github.com/nicklockwood/iCarousel/blob/master/iCarousel/iCarousel.m#L504
and modified it to be inverted
func carousel(
_ carousel: iCarousel,
itemTransformForOffset offset: CGFloat,
baseTransform transform: CATransform3D
) -> CATransform3D {
// Set up base transform
var transform = CATransform3DIdentity
transform.m34 = carousel.perspective
transform = CATransform3DTranslate(
transform,
-carousel.viewpointOffset.width,
-carousel.viewpointOffset.height,
0
)
// You could write this a little cleaner if you have the delegate implemented in the same class, but this way
// will work if the delegate has or has not been set
let tilt = carousel.delegate?.carousel?(carousel, valueFor: .tilt, withDefault: 0.9) ?? 0.9
let spacing = carousel.delegate?.carousel?(carousel, valueFor: .spacing, withDefault: 0.25) ?? 0.25
let clampedOffset = max(-1, min(1, offset))
let x = (clampedOffset * 0.9 * tilt + offset * spacing) * carousel.itemWidth
let z = fabs(clampedOffset) * -carousel.itemWidth * 0.5
if carousel.isVertical {
transform = CATransform3DTranslate(transform, 0, x, z)
return CATransform3DRotate(transform, clampedOffset / 2 * CGFloat.pi * tilt / 2, -1, 0, 0)
} else {
transform = CATransform3DTranslate(transform, x, 0, z)
return CATransform3DRotate(transform, clampedOffset / 2 * CGFloat.pi * tilt / 2, 0, 1, 0)
}
}
Most notable is changing (when compared to the default CoverFlow transform) from
return CATransform3DRotate(transform, clampedOffset * CGFloat.pi / 2 * tilt, -1, 0, 0)
...
return CATransform3DRotate(transform, clampedOffset * CGFloat.pi / 2 * tilt, 0, 1, 0)
to
return CATransform3DRotate(transform, clampedOffset / 2 * CGFloat.pi * tilt / 2, -1, 0, 0)
...
return CATransform3DRotate(transform, clampedOffset / 2 * CGFloat.pi * tilt / 2, 0, 1, 0)
This is what inverts the rotation.
I also had to change
let x = (clampedOffset * 0.5 * tilt + offset * spacing) * carousel.itemWidth
to
let x = (clampedOffset * 0.9 * tilt + offset * spacing) * carousel.itemWidth
to add a little more spacing so that cards would not go through each other.
You may want to play with all of the values to get something that looks better / works right for you.
Is there any way to implement "inverted" version of CoverFlow carousel as on this picture:
Thanks