iOS CoreAnimation 逐帧动画 CADisplayLink

本文参考:http://www.cnblogs.com/kenshincui/p/3972100.html#autoid-3-0-0总结的:

逐帧动画 CADisplayLink

动画效果:

结合runloop 实现 每次屏幕刷新都会执行此方法(每秒接近60此)

在此方法更新图片, 或者更新layer的某个状态实现动画效果,感觉不到动画的停滞效果

当然UIImageView通过设置animationImages的属性, 然后startAnimating方法播放这组照片,也

可以达到逐帧的动画效果, 但是存在很大的性能问题,并且一旦设置完图片中间的过程就无法控

制了,

利用定时器NSTimer定时更新图片也可以达到逐帧的效果, 这种可以解决一次性加载多个图片

的性能问题, 而且播放也可以控制, 但是可能会因为系统执行某个方法而让动画变得断断续续

的连续性问题

这里系统提供了CADisplayLink对象, CADidsplayLink是一个定时器, 与timer不同的

是,CADidsplayLink的刷新周期同屏幕完全一致, 屏幕刷新的周期是每秒60次,使其完全感觉不

到动画的停滞情况

iOS程序在运行后就进入到一个消息循环中(这个消息循环被称为"主运行循环"), 这个循环相当

于一个死循环中, 始终等待用户输入, 将CADisplayLink加入到主运行循环队列后, 它的时钟周

期就和主运行循环保持一致, 而主运行循环周期就是屏幕刷新周期.CADidsplayLink加入到主运

行循环队列后就会循环调用目标方法, 完成逐帧动画,

这里里不得不强调的是逐帧动画性能势必较低,但是对于一些事物的运动又不得不选择使用

逐帧动画,例如人的运动,这是一个高度复杂的运动,基本动画、关键帧动画是不可能解决

的。所大家一定要注意在循环方法中尽可能的降低算法复杂度,同时保证循环过程中内存峰

值尽可能低。下面以一个鱼的运动为例为大家演示一下逐帧动画。

//
//  LinkViewController.m
//  CAKeyframeAnimation
//
//  Created by 帝炎魔 on 16/5/26.
//  Copyright © 2016年 帝炎魔. All rights reserved.
//

#import "LinkViewController.h"

#define IMAGE_COUNT 10

@interface LinkViewController ()
{
    CALayer *_layer;
    int _index;
    NSMutableArray *_images;
}

@end

@implementation LinkViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 设置背景
    // layer 有个属性可以直接设置内容 ----> 背景图片
    self.view.layer.contents = (id)[UIImage imageNamed:@"bg"].CGImage;

    // 创建图像显示图层
    _layer = [[CALayer alloc] init];
    _layer.bounds = CGRectMake(0, 0, 87, 32);
    _layer.position = CGPointMake(self.view.center.x, self.view.center.y);
    [self.view.layer addSublayer:_layer];

    // 由于小鱼的图片比较小, 所以直接创建
    _images = [NSMutableArray array];
    for (int i = 0; i < 10; ++i) {
        NSString *imageName = [NSString stringWithFormat:@"fish%i.png", i];
        UIImage *image = [UIImage imageNamed:imageName];
        [_images addObject:image];
    }

    // 定义时钟对象
    CADisplayLink *displayLink  = [CADisplayLink displayLinkWithTarget:self selector:@selector(step)];

    // 添加时钟对象到主运行循环
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

    //  添加动画
    [self addAnimation];

    // Do any additional setup after loading the view.
}

#pragma mark ---- 添加关键帧动画 --- > 给鱼一个游动的路线
-(void)addAnimation
{
    // 1. 创建动画对象
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 430, 600);
    CGPathAddCurveToPoint(path, NULL, 100, 600, 400, 200, -10, 50);
    animation.path = path;

    animation.repeatCount = HUGE_VALF;
    animation.duration = 8.0;
    animation.removedOnCompletion = NO;

    [_layer addAnimation:animation forKey:@"fishAnimation"];

     CGPathRelease(path);

}

#pragma mark --- 每次屏幕刷新都会执行一次此方法(每秒接近60次)
- (void)step

{
    // 定义一个变量记录执行次数
    static int a = 0;
    if (++a % 10  == 0) {
        UIImage *image = _images[_index];
        _layer.contents = (id)image.CGImage; // 更新图片
        _index = (_index + 1) % IMAGE_COUNT;
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
时间: 2024-11-01 08:07:32

iOS CoreAnimation 逐帧动画 CADisplayLink的相关文章

window.requestAnimationFrame() ,做逐帧动画,你值得拥有

window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画.该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用. 如果你想做逐帧动画的时候,你应该用这个方法.这就要求你的动画函数执行会先于浏览器重绘动作.通常来说,被调用的频率是每秒60次,但是一般会遵循W3C标准规定的频率.如果是后台标签页面,重绘频率则会大大降低. 基本语法: requestID = window.requestAnimatio

逐帧动画-AnimationDrawable的简单用法

将Animation设置为ImageView的backgrond即可 MainActivity.java: import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget

实现逐帧动画和补间动画两种动画效果

1.逐帧动画(Frame Animation)通常在Android项目的res/drawable/目录下面定义逐帧动画的XML模板文件.编码的时候,需要在动画模板文件的<animation-list>标签中依次放入需要播放的图片,并设置好播放的间隔时间. <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"

android 逐帧动画的播放与播放结束操作对象

逐帧动画的xml代码: 1 <?xml version="1.0" encoding="utf-8"?> 2 <animation-list xmlns:android="http://schemas.android.com/apk/res/android" 3 android:oneshot="true" > 4 5 <item 6 android:drawable="@drawabl

Android中的动画具体解释系列【1】——逐帧动画

逐帧动画事实上非常easy,以下我们来看一个样例: <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawa

Esfog_UnityShader教程_逐帧动画

有段日子没出这个系列的新文章了,今天就拿一个比较常见也比较基础的利用改变Shader来改变不断调整UV实现播放逐帧动画的小功能.很久没写了就当练练手了.在新版本的Unity中早就已经集成了Sprite2D的功能,而且可以编辑不规则的图形,不过了解一下它的原理,也是蛮好的! 逐帧动画 帧动画大家应该都不陌生,经常会看到把一个动画几帧的的状态按一定顺序整合在同一张图片上,如下图: 从上图中我们可以看出,这个图片动画一共有20帧,从左到右,从上到下依次排布(基本上都是这个规律).为了展示效果我们需要一

Android -- 逐帧动画

在处理耗时工作的时候,大多数会弹出一个加载的框,里面有一个连续旋转的图片,很多时候都是用一张图片,使用rotate来设定旋转,不过看起来不太美观,没有形象感,在3.0之前Android有两种动画效果分别是补间动画和帧动画,用一张图片实现的是使用补间动画,定义给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变. 动画布局                                                                               

Android Animation 动画Demo(Frame逐帧动画)

上一篇介绍了Animation动画其一:Tween补间动画. 这篇文章接下来介绍Animation另一种动画形式:Frame逐帧动画. Frame动画是一系列图片按照一定的顺序展示的过程,和放电影的机制很相似,我们称为逐帧动画.Frame动画可以被定义在XML文件中,也可以完全编码实现(后面会给出这两种实现方式的源代码Demo). 下面分别介绍: 一.定义在xml中实现: 实现效果图: 源代码: 布局文件:main.xml: <?xml version="1.0" encodin

css3 实现逐帧动画

实现逐帧动画需要使用到的是Animation动画,该CSS3的Animation有八个属性:分别是如下:1: animation-name2: animation-duration3: animation-delay4: animation-iteration-count5: animation-direction6: animation-play-state7: animation-fill-mode8: animation-timing-function 含义分别如下:animation-n