Re: problems with CAAnimation - SOLVED (kinda)
Re: problems with CAAnimation - SOLVED (kinda)
- Subject: Re: problems with CAAnimation - SOLVED (kinda)
- From: mm w <email@hidden>
- Date: Thu, 19 Mar 2009 15:30:19 -0700
you should really create a html page and play for instance with jQuery
to understand how those mechanisms/API have been designed, and when you will
understand what you are doing you will welcome to come again
Cheers!
On Thu, Mar 19, 2009 at 3:26 PM, Memo Akten <email@hidden> wrote:
> Hi Matt, thanks for lengthy reply. At this point, I"ve only tried the first
> part, and I cannot get it to use the time I'm supplying in the animation,
> basically its just doing an implicit animation not explicit. It doesn't
> matter whether I setValue before or after the addAnimation.
>
> Actually I ended up writing the generic code below. If I apply the
> CAAnimationGroup as a group (i.e. bApplyIndividually = NO), then it doesn't
> work at all for some reason, the values from the layer.presentationLayer do
> not represent what I am seeing so a lot of snapping going on if I apply
> animations before the previous one is finished. If I only use the
> CAAnimationGroup as a glorified array and apply all animations individually
> then all my animations are applied correctly. So I think this is my
> solution. I do find it strange that I had to resort to this (writing my own
> AnimationGroup!), and this behavior is not built in. Thanks for all the tips
> and help.
>
> (P.S. this assumes that all the animations in the CAAnimationGroup are
> CABasicAnimations).
>
>
> void applyBasicAnimation(CALayer *layer, CABasicAnimation *animation, BOOL
> bApply) {
> animation.fromValue =
> [layer.presentationLayer valueForKeyPath:animation.keyPath];
> animation.removedOnCompletion = NO;
> animation.fillMode =
> kCAFillModeBoth;
> NSLog(@"applyBasicAnimation forLayer:%@ key:%@ currentValue:%@",
> layer.name, animation.keyPath, animation.fromValue);
> if(bApply) [layer addAnimation:animation forKey:animation.keyPath];
> }
>
> void applyAnimationGroup(CALayer *layer, CAAnimationGroup *animationGroup,
> NSString* key, BOOL bApplyIndividually) {
> animationGroup.removedOnCompletion = NO;
> animationGroup.fillMode = kCAFillModeBoth;
> for(id animation in animationGroup.animations)
> applyBasicAnimation(layer, animation, bApplyIndividually);
> if(!bApplyIndividually) [layer addAnimation:animationGroup
> forKey:key];
> }
>
>
> On 19 Mar 2009, at 18:07, Matt Long wrote:
>
>> I'll address the issue with the animation ignoring your duration first.
>> Try placing your addAnimation call before the setValue:forKeyPath. Let me
>> know if that works. Also, you will *need* to specify a fromValue in your
>> animation. If you want the current value (in the case where an animation is
>> already running), get it from the presentationLayer, e.g. [[layer
>> presentationLayer] valueForKeyPath@"transform.scale"]; This is the
>> "in-flight" value.
>>
>> Now let me try to clarify what I mean with the derived layer. Say you've
>> declared a layer called RolloverLayer that inherits from CALayer. Calling
>> animationForKey will return the default animation for the keyPath you
>> specify in the key. If you override it, *you* determine what animation to
>> use. It would look something like this:
>>
>> - (CAAnimation *)animationForKey:(NSString *)key
>> {
>> if ([key isEqualToString:@"transform.scale"] )
>> {
>> CABasicAnimation *growAnimation = [[CABasicAnimation
>> animationWithKeyPath:@"transform.scale"] retain];
>> growAnimation.duration = 5; // very slow
>> // Need from value here
>> growAnimation.fromValue = [[self presentationLayer]
>> valueForKeyPath:@"transform.scale"];
>> growAnimation.toValue = [[[CardManager instance] config]
>> objectForKey:@"cardHoverScale"];
>> growAnimation.timingFunction = [CAMediaTimingFunction
>> functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
>> return growAnimation;
>> }
>> else if ([key isEqualToString:@"position"])
>> {
>> CABasicAnimation *postiionAnimation = [CABasicAnimation
>> animationWithKeyPath:@"position"];
>> positionAnimation.fromValue = [[self presentationLayer] position];
>> positionAnimation.toValue = // etc...
>>
>> }
>> // .........
>> else
>> {
>> return [super animationForKey:key];
>> }
>> }
>>
>> Now, when you have one of your derived layers in use, you can do this:
>>
>> // Assuming it's tied to a button or something
>> - (IBAction)animate:(id)sender
>> {
>> // rolloverLayer is a RolloverLayer ivar
>> [rolloverLayer setValue:[[[CardManager instance] config]
>> objectForKey:@"cardHoverScale"] forKeyPath:@"transform.scale"];
>> [rolloverLayer setPosition:CGPointMake(x,y)];
>> // etc.
>> }
>>
>> Your overridden animationForKey will get called to get the proper
>> animation.
>>
>> HTH,
>>
>> -Matt
>>
>> p.s. if you want to know when an animation has completed, set the layer's
>> delegate to your app delegate and then implement -
>> (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag . The
>> flag field tells you whether or not it stopped by interruption or by run
>> completion. YES means it completed its run, NO means it was interrupted.
>>
>>
>> On Mar 19, 2009, at 11:09 AM, Memo Akten wrote:
>>
>>> Hi Matt, yea it is a bit complex, but it seems to me that what I am
>>> trying to do is actually quite simple:
>>>
>>> - when I rollover a layer, it animates position, scale, rotation and
>>> alpha.
>>> - when I rollout, it animates back.
>>> - if I rollover, then midanimation, rollout again, it should animate back
>>> to original position *from where it was at the moment I rolled out*, NOT
>>> snapping to the hover position (which is why I can't use FromValues).
>>>
>>> I also would like the animation to be EaseInEaseOut and know when the
>>> animation is complete - which is why I'm using CAAnimation, so I can use
>>> delegate - instead of using implicit animation.
>>>
>>>
>>> Going back to what you were saying, I'm afraid I don't full understand.
>>> So I extend CALayer? How would I use animationForKey? Does that not only
>>> return the animation for a given arbitrary key?
>>>
>>> Also I tried the code below, and unfortunately the animation happened
>>> very quickly, not 5 seconds at all...
>>>
>>> growAnimation = [[CABasicAnimation
>>> animationWithKeyPath:@"transform.scale"] retain];
>>> growAnimation.duration = 5; // very slow
>>> growAnimation.toValue = [[[CardManager instance] config]
>>> objectForKey:@"cardHoverScale"];
>>> growAnimation.timingFunction = [CAMediaTimingFunction
>>> functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
>>>
>>> [rootLayer setValue:[[[CardManager instance] config]
>>> objectForKey:@"cardHoverScale"] forKeyPath:@"transform.scale"];
>>> [rootLayer addAnimation:growAnimation forKey:@"transform.scale"];
>>>
>>>
>>>
>>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
--
-mmw
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden