Re: problems with CAAnimation - SOLVED (kinda)
Re: problems with CAAnimation - SOLVED (kinda)
- Subject: Re: problems with CAAnimation - SOLVED (kinda)
- From: Memo Akten <email@hidden>
- Date: Thu, 19 Mar 2009 23:50:27 +0000
lol, thank you very much! you couldn't help with the problem directly,
but at least you put a smile on my face :)
On 19 Mar 2009, at 23:39, mm w wrote:
your design simply sucks, you don't understand the library
I cannot help you on this, I am not Jesus and I cannot save all
people who
are pretending to program, once again I did complex design with CA
related API,
and I have never been stuck in this kind of issue, so I let you think,
nobody can solve
your issue you took the wrong way
Cheers!
On Thu, Mar 19, 2009 at 4:05 PM, Memo Akten <email@hidden> wrote:
Hi, I've used jQuery, but I don't understand the relevance or what
you mean?
On 19 Mar 2009, at 22:30, mm w wrote:
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
--
-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