iCarousel icon indicating copy to clipboard operation
iCarousel copied to clipboard

Custom carousel with centred item bigger

Open ghost opened this issue 11 years ago • 8 comments

Hi guys,

I'm trying to achieve the functionality described in the attached image. So I want to have the standard item size like the small items, but only the centred one to become bigger.

carousel

For that, I'm using a iCarouselTypeCustom type for the carousel. I used this transformation but now I'm stuck.

  • (CATransform3D)carousel:(iCarousel *)_carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform { CGFloat distance = 30; CGFloat z = - fminf(1.0f, fabs(offset)) * distance; return CATransform3DTranslate(transform, offset * _carousel.itemWidth, 0.0f, z); }

ghost avatar Aug 29 '13 09:08 ghost

I've created a custom transform that is pretty close to what you want:

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform {
    CGFloat dx = carousel.itemWidth * offset;
    CGFloat dy = carousel.itemWidth * -0.95f;
    CGFloat dz = carousel.itemWidth * -3.0f;

    CGFloat o = ABS(offset);
    if (o < 1.0) {
        dy *= o;
        dz *= o;
    }
    transform = CATransform3DTranslate(transform, dx, dy, dz);

    return transform;
}

pegli avatar Sep 05 '13 23:09 pegli

I think that you'll need to increase the scale of the center item as well as the spacing. I'll upload an alternative transform shortly.

nicklockwood avatar Sep 06 '13 07:09 nicklockwood

Here you go. Adjust the two constants to change the effect. Note that it actually shrinks the side items instead of expanding the center item - this prevents it from getting pixelated.

- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
{
    const CGFloat centerItemZoom = 1.5;
    const CGFloat centerItemSpacing = 1.23;

    CGFloat spacing = [self carousel:carousel valueForOption:iCarouselOptionSpacing withDefault:1.0f];
    CGFloat absClampedOffset = MIN(1.0, fabs(offset));
    CGFloat clampedOffset = MIN(1.0, MAX(-1.0, offset));
    CGFloat scaleFactor = 1.0 + absClampedOffset * (1.0/centerItemZoom - 1.0);
    offset = (scaleFactor * offset + scaleFactor * (centerItemSpacing - 1.0) * clampedOffset) * carousel.itemWidth * spacing;

    if (carousel.vertical)
    {
        transform = CATransform3DTranslate(transform, 0.0f, offset, -absClampedOffset);
    }
    else
    {
        transform = CATransform3DTranslate(transform, offset, 0.0f, -absClampedOffset);
    }

    transform = CATransform3DScale(transform, scaleFactor, scaleFactor, 1.0f);
    return transform;
}

nicklockwood avatar Sep 06 '13 08:09 nicklockwood

Hi,

Is it possible to make always the first one or the left one to be the selected carousel index. Means the first one to be bigger.

RathishMarthandan avatar Oct 25 '13 15:10 RathishMarthandan

Here is the version for horizontal in swift 3, for c/p:

func carousel(_ carousel: iCarousel, itemTransformForOffset offset: CGFloat, baseTransform transform: CATransform3D) -> CATransform3D {
        let centerItemZoom: CGFloat = 1.1
        let centerItemSpacing: CGFloat = 1.23
        
        let spacing: CGFloat = self.carousel(iCarouselView, valueFor: .spacing, withDefault: 0.90)
        let absClampedOffset = min(1.0, fabs(offset))
        let clampedOffset = min(1.0, max(-1.0, offset))
        let scaleFactor = 1.0 + absClampedOffset * (1.0/centerItemZoom - 1.0)
        let offset = (scaleFactor * offset + scaleFactor * (centerItemSpacing - 1.0) * clampedOffset) * carousel.itemWidth * spacing
        var transform = CATransform3DTranslate(transform, offset, 0.0, -absClampedOffset)
        transform = CATransform3DScale(transform, scaleFactor, scaleFactor, 1.0)
        
        return transform;
    }

abraxascorner avatar Apr 19 '17 15:04 abraxascorner

Hi, it seems like this code has a problem with autolayout. My first item is ok on all devices, but second, third, ... are not ok on every device except iPhone 6. Has anyone had similar experience? When I set to linear and not custom, everything works perfectly.

abraxascorner avatar Jul 10 '17 14:07 abraxascorner

hi @nicklockwood, could you help explain centerItemSpacing from above code meaning? Example how can I set exactly spacing in pixel?

phuhk avatar May 04 '19 02:05 phuhk

Hello! Does anyone know how I can cycle custom type?

maukur avatar Jul 05 '22 13:07 maukur