流畅更新运行动画 [英] Updating running animations smoothly

查看:20
本文介绍了流畅更新运行动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有许多图像可以连续运行动画.如何平滑地更新这些正在运行的动画,以便它们之间没有可见的过渡,除非是动画的一部分.

I have a number of images I run continuous animations on. How does one update these running animations smoothly so that there is no visible transition between them, unless part of the animation.

例如旋转和缩放图像,然后更新动画以按原样旋转,但稍微放大.我目前得到了明显的变化.

e.g. rotating and scaling an image, and then updating the animation to rotate as it was, but scale up slightly. I currently get a visible change.

我可以想象,缩放应该在动画块内完成,他们只是像以前一样运行旋转动画,问题是旋转会在放大时停止.

I can imagine that that scaling should be done within an animation block and them just run the rotation animation as before, the issue would be then that the rotation would stop while it scales up.

我需要它是无缝的.例如此代码块不会导致平滑缩放,即使它使用 UIViewAnimationOptionBeginFromCurrentState

I need it to be seamless. e.g. this code block does not cause a smooth scaling, even though it uses UIViewAnimationOptionBeginFromCurrentState

[UIView animateWithDuration:0.5
                      delay:0
                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut //| UIViewAnimationOptionRepeat
                 animations:(void (^)(void)) ^{
                     imageViewToScale.transform = CGAffineTransformMakeScale(1.2, 1.2);
                 }
                 completion:^(BOOL finished){
                     //imageViewToScale.transform=CGAffineTransformIdentity;
                 }];

推荐答案

老实说,如果你的视图上有连续的动画会在运行时改变那里的状态 UIView 动画不是最好的方法,可能会导致抖动而完成处理程序被一遍又一遍地调用等

To be honest if your going to have continuous animations on your views that will alter there states at run time UIView animations isn't he best approach and might cause jitter whilst the completion handler is called over and over e.t.c.

然而,你想在块中做 2 个动画,你可以在同一个块中设置缩放和旋转,它们会同时发生.或者您可以调用一个函数来启动块并在完成时再次调用它以查看该视图是否有任何新动画.当没有时,完成块会停止,有点递归地使用它们,尽管如果您在很多视图上连续制作大量动画,这不是我不推荐的方法.

However is you want to do 2 animations in the block you can either set the scale and the rotation in the same block and they will happend simultaneously. Or you could call a function that starts the block and on completion calls it again to see if there are any new animations for that view. When there are none, the completion block just stops, sort of using them recursively, though this isn't the approach i wouldn't recommend if you are doing a lot of animations on a lot of views continuouly.

在 OpenGLES 中,您使用 NSTimer 来运行连续动画,以处理应用中所有动画的更新.如果你走这条路,它的工作会更加艰巨,你需要自己实现缓动/二次曲线函数以获得平滑的动画.但是,如果您扩展类,您可以为每个图像设置状态,然后当计时器触发时,您可以根据您提供的状态更新其转换.因此,当它旋转了一定的度数/弧度时,您可以将其设置为缩放.现在为了保持动画流畅,您需要使用 NSTimerIntervals 来确保将移动的距离乘以经过的时间以获得流畅的动画.就我个人而言,这是我用于处理可能在屏幕上不断移动但如果您只需要移动两次然后完成的事情可能会结束的路线.

In OpenGLES you use NSTimer to run continuous animation that would handle the updating of all animations in your app. If you go this route its a lot more hard work and you need to implement the easing/quadratic curve functions for smooth animation yourself. However if you extend the clases you could set states for each image and then when the timer fires you could update its transformation based one the states you have given it. So when it has rotated a certain amount of degrees/radians then you could set it to scale. Now to keep animation smoothly you will need to use NSTimerIntervals to make sure you multiply the distance moved by time elapsed in order to get smooth animation. Personally this is the route i use for things that might be moving on screen constantly but might be over kill if you need to only move things twice and then be done.

按照您的要求执行第二步的代码!

The code for doing the second step as you asked!

因此,您需要声明一个 NSTimer 来轮询您的动画步骤和一个 NSTimeInterval,以便您仅根据已过去的时间来更新每个步骤的动画.

So you need to declare a NSTimer that wil poll your animation steps and an NSTimeInterval so that you update your animation each step only by the amount of time that has passed.

NSTimer *animationTimer;
NSTimeInterval animationInterval;
NSTimeInterval lastUpdateTime;
float currentRotation;
float current scale;

第三,你需要设置一个 NSTimer 来触发你的视图更新:

Thirdly you need to set up an NSTimer to fire off updating of your views:

- (void)startAnimation
{
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView:) userInfo:nil repeats:YES];
}

- (void)stopAnimation
{    
    [animationTimer invalidate];
    animationTimer = nil;
}

然后你需要在你的视图开始时或者当你想要开始动画时开始工作

Then you need to kick the thing off when your view starts or when you want to start anmation something like this works

- (void)setAnimationInterval:(NSTimeInterval)interval
{
    animationInterval = interval;

    if(animationTimer)
    { 
        [self stopAnimation];
        [self startAnimation];
    } 
} 

然后在您的 drawView: 方法中,您需要根据计时器每次触发之间经过的时间更新您的变换,以便动画随着时间的推移变得平滑和恒定.在这一点上本质上是一个线性变换.

Then In your drawView: Method you need to update your transforms based on time elapsed between each fire of the timer so that the animation is smooth and constant over time. Essentially a linear transform at this point.

- (void)drawView:(id)sender
{
    if(lastUpdateTime == -1)
    {
        lastUpdateTime = [NSDate timeIntervalSinceReferenceDate];
    }

    NSTimeInterval timeSinceLastUpdate = [NSDate timeIntervalSinceReferenceDate] - lastUpdateTime;

    currentRotation = someArbitrarySCALEValue * timeSinceLastUpdate;
    currentScale = someArbitraryROTATIONValue * timeSinceLastUpdate;

    CGAffineTransform scaleTrans =  CGAffineTransformMakeScale(currentScale,currentScale);
    CGAffineTransform rotateTrans =  CGAffineTransformMakeRotation(currentRotation * M_PI / 180);

    imageViewToScale.transform = CGAffineTransformConcat(scaleTrans, rotateTrans);


    lastUpdateTime = [NSDate timeIntervalSinceReferenceDate];
}

请注意,这不会为您的动画添加缓动,也不会在物理上停止您需要玩弄的东西.此外,您可能需要确保当旋转超过 360 度时,您将其重置为 0,并分别在度数和弧度之间进行转换.

Note this will not add easing to your animations nor will it at physics to the stopping you will need to play around with that. Also you may need to make sure that when the rotation goes over 360 you reset it to 0 and that you convert between degrees and radians respectively.

考虑使用物理来处理诸如反弹和摩擦之类的事情,以使事情变慢.

Look into using physics for things like bounces, and friction to make things slow nicely.

查看二次图,以便轻松使事物随时间平滑移动,本质上是二次插值.

Look into quadratic graphs for easing to make things move smoothly over time, quadratic interpolation essentially.

这篇关于流畅更新运行动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆