Frage

Ich bin mit einigen Core Animation zum ersten Mal arbeiten und dabei eine Spielkarte zu implementieren, dass ich um Flip kann, habe ich beschlossen, eine CALayer zu verwenden, um die Inhalte anzuzeigen (nicht sicher, wie ich werde zwei Seiten zu bekommen, aber das ist eine andere Frage) und ich brauche es umdrehen zu können, bewegen sie, etc ...

Ich bin mit CATransaction mit einigem Erfolg - in der folgenden Code-Schnipsel, die Karte bewegt sich von unten nach links oben nach links und dreht sich um. Das Problem ist, dass ich wan't es die entgegengesetzte Richtung zu drehen, aber nicht wissen, wie es zu sagen: „Hey, du gehst in die falsche Richtung!“


[CATransaction begin]; 
[CATransaction setValue:[NSNumber numberWithFloat:2.0f] forKey:kCATransactionAnimationDuration];
myCard.position = CGPointMake(CGRectGetMidX(self.bounds)/2,CGRectGetMidY(self.bounds)/2);
myCard.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
[CATransaction commit]; 

Eine zweite Frage wäre: Wie kann ich es bekommen zwei Transformationen auf einmal zu tun? Ich habe versucht, zwei CATransactions nisten, aber der zweite überschreibt nur die erste. Ich habe auch versucht, den Vektor für die Rotation ändert 2D zu sein, wie wenn man sagt zum Drehen um die x und y-Achse, aber das ist nicht gleichbedeutend mit nur er um zwei Achsen durch einzelne pi Spiegeln. Hier ist der verschachtelte Code.


[CATransaction begin]; 
[CATransaction setValue:[NSNumber numberWithFloat:2.0f] forKey:kCATransactionAnimationDuration];
myCard.position = CGPointMake(CGRectGetMidX(self.bounds)/2,CGRectGetMidY(self.bounds)/2);
myCard.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0); // rotate about x

  [CATransaction begin]; 
  [CATransaction setValue:[NSNumber numberWithFloat:1.0f] forKey:kCATransactionAnimationDuration];
  myCard.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0); // rotate about y
  [CATransaction commit]; 

[CATransaction commit]; 

Und hier ist es mit UIView Animation Blöcken innerhalb ... Ich habe hinzugefügt Schieberegler für den Winkel, x, y, z für den Drehvektor und t für die Zeit. Die Übersetzung erfolgt über die Zeit = 2t und jeder der Drehungen sollte nimmt jeweils nur t.

[CATransaction begin]; 
[CATransaction setValue:[NSNumber numberWithFloat:t * 2] forKey:kCATransactionAnimationDuration];
myCard.position = CGPointMake(CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2);

  [UIView beginAnimations:nil context:nil];
  [UIView setAnimationDuration:t];
  myCard.transform = CATransform3DMakeRotation(angle, x, y, z);
  [UIView commitAnimations]; 

  [UIView beginAnimations:nil context:nil];
  [UIView setAnimationDuration:t];
  [UIView setAnimationDelay:t];
  myCard.transform = CATransform3DMakeRotation(angle * 2, x, y, z);
  [UIView commitAnimations];

[CATransaction commit]; 

Und das ist, wo ich jetzt bin: Es funktioniert alles mit einer Ausnahme. Die y-Rotation umkehrt (beginnt in der entgegengesetzten Richtung dreht), wenn die Karte zu pi bekommt / 2 und 3 * pi / 2. Es klappt auch um die x-Achse an diesen Punkten. Aber x und z Arbeit groß. So nah!

CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2*3);
CGPathAddCurveToPoint(thePath,NULL,
                      CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2*2,
                      CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2*1.5,
                      CGRectGetMidX(self.view.bounds)/2,CGRectGetMidY(self.view.bounds)/2);
CAKeyframeAnimation *moveAnimation=[CAKeyframeAnimation animationWithKeyPath:@"position"];
moveAnimation.path=thePath;
CFRelease(thePath);

CABasicAnimation *xRotation;
xRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
xRotation.fromValue = [NSNumber numberWithFloat:0.0];
xRotation.toValue = [NSNumber numberWithFloat:x * angle * M_PI];

CABasicAnimation *yRotation;
yRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
yRotation.fromValue = [NSNumber numberWithFloat:0.0];
yRotation.toValue = [NSNumber numberWithFloat:y * angle * M_PI];

CABasicAnimation *zRotation;
zRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
zRotation.fromValue = [NSNumber numberWithFloat:0.0];
zRotation.toValue = [NSNumber numberWithFloat:z * angle * M_PI];

CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.duration = t;
groupAnimation.removedOnCompletion = NO;
groupAnimation.fillMode = kCAFillModeForwards;
groupAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
groupAnimation.animations = [NSArray arrayWithObjects:moveAnimation, xRotation, yRotation, zRotation, nil];

[myCard addAnimation:groupAnimation forKey:@"animateCard"];
War es hilfreich?

Lösung

Ich glaube, dass das, was Sie in diesem Fall wollen, ist ein Helfer Schlüsselpfad zu verwenden, wie in diese Antwort :

CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.x"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI];
rotationAnimation.duration = duration;
[myCard.layer addAnimation:rotationAnimation forKey:@"rotationAnimation1"];

, die um die X-Achse für die erste Stufe der Animation drehen sollten. Für die zweite, ich glaube, wenn Sie das folgende

verwenden
CABasicAnimation *rotationAnimation2 = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
rotationAnimation2.toValue = [NSNumber numberWithFloat: M_PI];
rotationAnimation2.duration = duration2;
rotationAnimation2.cumulative = YES;
[myCard.layer addAnimation:rotationAnimation2 forKey:@"rotationAnimation2"];

sollte es die Animationen kumulativ machen und kann die gewünschte Wirkung. Ich habe das selbst nicht versucht, so etwas Bastelei erforderlich sein kann, die genau zu erhalten führen Sie benötigen.

Wenn Sie arbeiten mit einer Transformation direkt, Core Animation interpoliert die von dem aktuellen Wert transformiert, um die Transformation angegeben. Es wird den kürzesten Weg zu der Transformation erhalten finden, die die Animation Richtung beschränken wird. Wenn Sie versuchen, die gleiche Eigenschaft trans zweimal zu animieren, wird einfach der zweite Wert des erste außer Kraft setzen, nicht die beiden Transformationen zusammen kombinieren.

Wenn jedoch ein Helfer Schlüsselpfad wie diese verwenden, Core Animation zwischen Startwinkel und interpolieren Endwinkel, so dass Sie Richtung durch Änderung des Vorzeichens des Endwinkel umkehren. Es optimiert die Änderung des Winkelwertes, nicht die Veränderung der zugrunde liegenden verwandeln. Sie sollten auch in der Lage sein, Animationen auf dem Schlüsselpfad zu kombinieren, weil die Transformation für jede Kombination von Schlüsselpfad Manipulationen für Sie unter der Haube erzeugt wird.

Andere Tipps

Ich vermute, das Umklappen auf einer Achse durch Gimbal Lock verursacht innerhalb Apples Bibliothek geschieht. Die einfache Lösung, die 99,999% der Zeit arbeitet, ist nur noch nicht genau 0, 90, 180, 270 und 360-Grad-Drehungen zu verwenden. Ich habe Sachen gesehen wie dies in meinem Code passieren, aber ich nur so etwas wie (M_PI * 0,99) statt M_PI. Dies ist immer ein Problem, wenn Sie die Grafikkarte des Matrix-Multiplizierer mit Euler-Winkel verwenden.

Um mehrere Transformationen gleichzeitig anwenden, können Sie nisten sie. Dies funktioniert genau wie Matrizen in OpenGL multipliziert wird.

// translate and scale at the same time
float scale = 1.6;
CATransform3D scaleMatrix = CATransform3DMakeScale(scale, scale, 1);
CATransform3D finalMatrix = CATransform3DTranslate(scaleMatrix, frame.size.width/scale, frame.size.height/scale, 0);
CABasicAnimation* animBottomTrans = [CABasicAnimation animationWithKeyPath:@"transform"];
[animBottomTrans setFromValue:[NSValue valueWithCATransform3D:finalMatrix]];
[animBottomTrans setToValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]];
[animBottomTrans setDuration:duration];
[myLayer addAnimation:animBottomTrans forKey:@"transform"];

Beachten Sie, dass da diese verschachtelt sind Sie mit dem vorherigen in allen Transformationen Transformation zu tun haben, die nach ihm kommen. In diesem Code muss ich den Betrag, den ich übersetzt ändern, weil ich schon skaliert haben. Wenn Sie 90Grad auf der z-Achse drehen und drehen dann um 90 Grad auf der y-Achse, haben Sie effektiv nur auf der z gedreht und x Achsen (die z Rotation tauscht Ihre x- und y-Achsen).

Transformation Das resultierende ist das gleiche: (CGAffineTransform){-1,0,0,-1,0,0}. Coreanimation nimmt die kürzeste Drehung, die den Trick tun wird, und standardmäßig im Uhrzeigersinn drehen (glaube ich).

Der einfachste Weg in die andere Richtung zu drehen, ist zu drehen, indem fast -M_PI (Ich bin nicht sicher, wie nah Sie bekommen können, bevor sie die „falsche“ Art und Weise zu drehen entscheiden).

Je komplizierter Weg, es zu brechen in zwei Umdrehungen: ein von 0 bis -M_PI / 2 und einem von -M_PI / 2 -M-PI. Ich denke, man kann eine Animation Verzögerung dies möglich zu machen ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top