una transiciones transicion sirven salida que power plantilla para las entrada efectos concepto animaciones animacion ios core-animation avfoundation calayer cakeyframeanimation

ios - transiciones - que es animacion de salida



CoreAnimation-Opacidad La animaciĆ³n de entrada y salida no funciona (11)

Estoy intentando crear un CoreAnimation bastante simple para usar en una AVComposition . Mi objetivo es crear un CALayer que, a través de varias subcapas, difumina un título dentro y fuera, luego se desvanece en una imagen de salida. Una presentación de diapositivas, básicamente. Esto se está exportando a un .mov usando AVAssetWriter .

Con la ayuda de la WWDC 2011 AVEditDemo, he podido obtener un título y las imágenes que aparecen. ¡El problema es que todos están en pantalla al mismo tiempo!

He creado cada capa con una opacidad de 0.0. Luego agregué un CABasicAnimation para CABasicAnimation de 0.0 a 1.0, usando el siguiente código:

CABasicAnimation *fadeInAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; fadeInAnimation.fromValue = [NSNumber numberWithFloat:0.0]; fadeInAnimation.toValue = [NSNumber numberWithFloat:1.0]; fadeInAnimation.additive = NO; fadeInAnimation.removedOnCompletion = YES; fadeInAnimation.beginTime = 1.0; fadeInAnimation.duration = 1.0; fadeInAnimation.fillMode = kCAFillModeForwards; [titleLayer addAnimation:fadeInAnimation forKey:nil];

El problema parece ser la propiedad ''beginTime''. El "1.0" está destinado a ser un retraso, por lo que comienza 1 segundo después del inicio de la animación. Sin embargo, está apareciendo en la pantalla de inmediato. Una animación de fundido

El reverso de este código, para el desvanecimiento, simplemente cambia el valor de FromValue a 1.0 y el de toValue a 0.0. Tiene un tiempo de inicio de 4.0 y funciona perfectamente.

Estoy usando lo siguiente para crear el animatedTitleLayer :

CATextLayer *titleLayer = [CATextLayer layer]; titleLayer.string =self.album.title; titleLayer.font = @"Helvetica"; titleLayer.fontSize = videoSize.height / 6; titleLayer.alignmentMode = kCAAlignmentCenter; titleLayer.bounds = CGRectMake(0, 0, videoSize.width, videoSize.height / 6); titleLayer.foregroundColor = [[UIColor redColor]CGColor]; titleLayer.opacity = 0.0;

La imagen que se desvanece en las animaciones tiene un tiempo de inicio de 5 segundos. Al igual que el título, sus animaciones de desvanecimiento funcionan bien.

Cualquier ayuda sería muy apreciada!

¡Aclamaciones!

EDITAR

Las respuestas fueron útiles, pero al final descubrí que solo se podía agregar una animación a un CALayer . La animación de desvanecimiento funcionó ya que fue la última que se agregó.

Luego probé un CAAnimationGroup, pero esto no funcionó ya que estaba modificando la misma ruta de valor clave.

Así que me he dado cuenta de que CAKeyframeAnimation es lo mejor para esto. Solo que estoy teniendo un poco de dificultad con eso también! El código ahora se está desvaneciendo, pero no se está desvaneciendo. He probado varios modos de relleno, cambié la duración, etc. ¡¡No puedo hacer que funcione !!

Aquí está mi código:

CAKeyframeAnimation *fadeInAndOut = [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; fadeInAndOut.duration = 5.0; fadeInAndOut.autoreverses = NO; fadeInAndOut.keyTimes = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], [NSNumber numberWithFloat:4.0], [NSNumber numberWithFloat:5.0], nil]; fadeInAndOut.values = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], [NSNumber numberWithFloat:1.0], [NSNumber numberWithFloat:0.0], nil]; fadeInAndOut.beginTime = 1.0; fadeInAndOut.removedOnCompletion = NO; fadeInAndOut.fillMode = kCAFillModeBoth; [titleLayer addAnimation:fadeInAndOut forKey:nil];


Creo que estás buscando timeOffset , no beginTime ...



El punto es el nombre clave. Tienes que configurar la tecla de opacidad.

layer.add(animation, forKey: nil) // Not Working layer.add(animation, forKey: "opacity") // Working

Compruebe el código de muestra. He probado en Swift 4

let animation = CAKeyframeAnimation() animation.duration = 1.53 animation.autoreverses = false animation.keyTimes = [0, 0.51, 0.85, 1.0] animation.values = [0.5, 0.5, 1.0, 0.5] animation.beginTime = 0 animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeBoth animation.repeatCount = .greatestFiniteMagnitude layer.add(animation, forKey: "opacity")


Esto funciona para mí:

let fadeAnimation = CAKeyframeAnimation(keyPath:"opacity") fadeAnimation.beginTime = AVCoreAnimationBeginTimeAtZero + start fadeAnimation.duration = duration fadeAnimation.keyTimes = [0, 1/8.0, 5/8.0, 1] fadeAnimation.values = [0.0, 1.0, 1.0, 0.0] fadeAnimation.removedOnCompletion = false fadeAnimation.fillMode = kCAFillModeForwards layer.addAnimation(fadeAnimation, forKey:"animateOpacity") layer.opacity = 0.0


Hombre, tantas respuestas complicadas. La forma más sencilla es simplemente agregar autoreverse. Voila

CABasicAnimation *fadeInAndOut = [CABasicAnimation animationWithKeyPath:@"opacity"]; fadeInAndOut.duration = 5.0; fadeInAndOut.autoreverses = YES; fadeInAndOut.fromValue = [NSNumber numberWithFloat:0.0]; fadeInAndOut.toValue = [NSNumber numberWithFloat:1.0]; fadeInAndOut.repeatCount = HUGE_VALF; fadeInAndOut.fillMode = kCAFillModeBoth; [titleLayer addAnimation:fadeInAndOut forKey:@"myanimation"];


La forma alternativa es el uso de CAAnimationGroup. CAKeyframeAnimation también funciona bien para la interfaz de usuario. Este código funciona bien en la interfaz de usuario para mostrar la animación en tiempo real. Pero no funcionará en absoluto en AVVideoCompositionCoreAnimationTool ; desplácese hacia abajo si lo necesita. No es un código listo para copiar y pegar, pero puede obtener la idea. Además, puede agregar animaciones de adición al grupo:

for (HKAnimatedLayer *animLayer in layersList) { overlayLayer = [CALayer layer]; [overlayLayer setContents:(id)[animLayer.image CGImage]]; overlayLayer.frame = CGRectMake(0, 0, size.width, size.height); [overlayLayer setMasksToBounds:YES]; NSMutableArray *animations = [NSMutableArray array]; // Step 1 { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.toValue = @(0); animation.duration = kLayerFadeDuration; animation.beginTime = kMovieDuration/5; animation.fillMode = kCAFillModeForwards; [animations addObject:animation]; } { CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.toValue = @(1.0); animation.duration = kLayerFadeDuration; animation.beginTime = kMovieDuration*2/3; animation.fillMode = kCAFillModeForwards; [animations addObject:animation]; } CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; animationGroup.animations = animations; animationGroup.duration = kMovieDuration; animationGroup.fillMode = kCAFillModeForwards; animationGroup.removedOnCompletion = YES; [overlayLayer addAnimation:animationGroup forKey:nil]; [parentLayer addSublayer:overlayLayer]; }

Aquí una pequeña nota sobre la animación en capas para AVVideoCompositionCoreAnimationTool . Puedes ver la imagen gif relevante (los títulos deben aparecer y desaparecer uno por uno). Para resolver este problema, uso 2 CALayer separados porque, por alguna razón, en una capa 2, se CALayer las animaciones opaque de varias capas.

// set up the parent layer CALayer *parentLayer = [CALayer layer]; parentLayer.frame = CGRectMake(0, 0, size.width, size.height); // one layer for one animation CALayer *overlayLayer, *barrierLayer; CABasicAnimation *animation; for (HKAnimatedLayer *animLayer in layersList) { overlayLayer = [CALayer layer]; overlayLayer.contents = (id)[animLayer.image CGImage]; overlayLayer.frame = CGRectMake(0, 0, size.width, size.height); overlayLayer.masksToBounds = YES; // layer with appear animation if (animLayer.fromTime != 0 && (animLayer.fromTime - kLayerFadeDuration)>0) { overlayLayer.opacity = 0.0; animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.fromValue = @(0); animation.toValue = @(1); animation.additive = NO; animation.removedOnCompletion = NO; animation.beginTime = animLayer.fromTime - kLayerFadeDuration; animation.duration = kLayerFadeDuration; animation.fillMode = kCAFillModeForwards; [overlayLayer addAnimation:animation forKey:@"fadeIn"]; } if (animLayer.toTime == kMovieDuration) { [parentLayer addSublayer:overlayLayer]; } else { // layer with dissappear animation barrierLayer = [CALayer layer]; barrierLayer.frame = CGRectMake(0, 0, size.width, size.height); barrierLayer.masksToBounds = YES; [barrierLayer addSublayer:overlayLayer]; animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.fromValue = @(1); animation.toValue = @(0); animation.additive = NO; animation.removedOnCompletion = NO; animation.beginTime = animLayer.toTime; animation.duration = kLayerFadeDuration; animation.fillMode = kCAFillModeForwards; [overlayLayer addAnimation:animation forKey:@"fadeOut"]; [parentLayer addSublayer:barrierLayer]; } }

Y al final, podemos obtener la secuencia de animación adecuada.


La respuesta de funcionó perfectamente para mí. Si alguien está interesado, reescribí para Obj-C (nota que también cambié ligeramente los fotogramas clave en el fundido):

CAKeyframeAnimation *fadeInAndOutAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; fadeInAndOutAnimation.beginTime = CACurrentMediaTime() + beginTime; fadeInAndOutAnimation.duration = duration; fadeInAndOutAnimation.keyTimes = @[@0.0, @( 2.0 / 8.0 ), @( 5.0 / 8.0 ), @1.0]; fadeInAndOutAnimation.values = @[@0.0, @1.0, @1.0, @0.0]; fadeInAndOutAnimation.removedOnCompletion = false; fadeInAndOutAnimation.fillMode = kCAFillModeForwards;


Me enfrento al mismo problema y el problema es que una capa no puede contener la aparición y desaparición. Así que puedes agregar la otra animación a la capa principal como lo hice

CALayer *parentLayer = [CALayer layer]; CALayer *animtingLayer = [CALayer layer]; //FADE IN CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.beginTime = CMTimeGetSeconds(img.startTime); animation.duration = CMTimeGetSeconds(_timeline.transitionDuration); animation.fromValue = [NSNumber numberWithFloat:0.0f]; animation.toValue = [NSNumber numberWithFloat:1.0f]; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeBoth; animation.additive = NO; [parentLayer addAnimation:animation forKey:@"opacityIN"]; //FADE OUT CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; animation.beginTime = CMTimeGetSeconds(CMTimeAdd(img.passTimeRange.start, img.passTimeRange.duration)); animation.duration = CMTimeGetSeconds(_timeline.transitionDuration); animation.fromValue = [NSNumber numberWithFloat:1.0f]; animation.toValue = [NSNumber numberWithFloat:0.0f]; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeBoth; animation.additive = NO; [animtingLayer addAnimation:animation forKey:@"opacityOUT"]; [parentLayer addSublayer:animtingLayer];


Mira mi respuesta https://.com/a/44204846/667483

En resumen: para usar beginTime , debe establecer fillMode en kCAFillModeBackwards en su objeto de animación.


Tomando prestado el enlace mencionado por gamblor87 y agregando mis comentarios como explicación.

//create a fadeInOut CAKeyframeAnimation on opacticy CAKeyframeAnimation *fadeInAndOut = [CAKeyframeAnimation animationWithKeyPath:@"opacity"]; //set duration fadeInAndOut.duration = 5.0; //autoreverses defaults to NO so we don''t need this. //fadeInAndOut.autoreverses = NO; //keyTimes are time points on duration timeline as a fraction of animation duration (here 5 seconds). fadeInAndOut.keyTimes = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.20], [NSNumber numberWithFloat:0.80], [NSNumber numberWithFloat:1.0], nil]; //set opacity values at various points during the 5second animation fadeInAndOut.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0],//opacity 0 at 0s (corresponds to keyTime = 0s/5s) [NSNumber numberWithFloat:1.0],//opacity 1 at 1s (corresponds to keyTime = 1s/5s) [NSNumber numberWithFloat:1.0],//opacity 1 upto 4s (corresponds to keyTime = 4s/5s) [NSNumber numberWithFloat:0.0],//opacity 0 at 5s (corresponds to keyTime = 5s/5s) nil]; //delay in start of animation. What we are essentially saying is to start the 5second animation after 1second. fadeInAndOut.beginTime = 1.0; //don''t remove the animation on completion. fadeInAndOut.removedOnCompletion = NO; //fill mode. In most cases we won''t need this. fadeInAndOut.fillMode = kCAFillModeBoth; //add the animation to layer [titleLayer addAnimation:fadeInAndOut forKey:nil];


Tratar:

fadeInAnimation.beginTime = CACurrentMediaTime()+1.0;