Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I animate a CAlayer's bounds to progressively reveal an image?

For certain reasons, I'm trying to avoid using a CAScrollLayer to do this. The effect I'm going after is to progressively reveal (from bottom to top) a CALayer's content (a png I previously loaded in). So I thought about doing this:

    layer.anchorPoint = CGPointMake(.5, 1);
    CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:@"bounds.size.height"];
    a.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    a.fillMode = kCAFillModeBoth;
    a.removedOnCompletion = NO;
    a.duration = 1;
    a.fromValue = [NSNumber numberWithFloat:0.];
    a.toValue = [NSNumber numberWithFloat:layer.bounds.size.height];
    [layer addAnimation:a forKey:nil];

The problem with this is you can tell the layer's content is scaled with the bounds. I was trying for the bounds to change but the content to stay always the original size, so that effectively the bounds clip the image and as I increase bounds.height, the image "Reveals" itself.

Any ideas as to how to pull it off or what might I be missing?

like image 894
SaldaVonSchwartz Avatar asked Apr 26 '12 18:04

SaldaVonSchwartz


1 Answers

Ok I got it to work, but I basically had to update the layer's frame too, to reflect the change in anchor point:

  [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
  layer.contentsGravity = kCAGravityTop;
  layer.masksToBounds = YES;
  layer.anchorPoint = CGPointMake(.5, 1);
  CGRect newFrame = layer.frame;
  newFrame.origin.y += newFrame.size.height / 2;
  layer.frame = newFrame;
  [CATransaction setValue:(id)kCFBooleanFalse forKey:kCATransactionDisableActions];

  a.toValue = [NSNumber numberWithFloat:layer.bounds.size.height];
  [layer addAnimation:a forKey:nil];
like image 86
SaldaVonSchwartz Avatar answered Oct 04 '22 02:10

SaldaVonSchwartz