支持xcode6的缓动函数Easing以及使用示例

用xcode6新建工程后,直接导致不支持之前的Easing缓动函数的代码,经过修改后就可以正常使用了,虽然比不上POP高大上的动画,但用缓动函数的动画还是能够实现很复杂的效果的。

注:Easing缓动函数服务于关键帧动画,理解这一点很重要,需要你对CoreAnimation有着很深入的了解才能够用得得心应手

提供源码如下:

Easing.h 与 Easing.m

//
// Easing.h
// Easing
//
// Created by YouXianMing on 14-10-10.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #ifndef __Easing__Easing__
#define __Easing__Easing__ #include <stdio.h>
#include <math.h> #if defined(__LP64__) && !defined(AH_EASING_USE_DBL_PRECIS)
#define AH_EASING_USE_DBL_PRECIS
#endif #ifdef AH_EASING_USE_DBL_PRECIS
#define AHFloat double
#else
#define AHFloat float
#endif // 函数指针
typedef AHFloat (*AHEasingFunction)(AHFloat); // Linear interpolation (no easing)
AHFloat LinearInterpolation(AHFloat p); // Quadratic easing; p^2
AHFloat QuadraticEaseIn(AHFloat p);
AHFloat QuadraticEaseOut(AHFloat p);
AHFloat QuadraticEaseInOut(AHFloat p); // Cubic easing; p^3
AHFloat CubicEaseIn(AHFloat p);
AHFloat CubicEaseOut(AHFloat p);
AHFloat CubicEaseInOut(AHFloat p); // Quartic easing; p^4
AHFloat QuarticEaseIn(AHFloat p);
AHFloat QuarticEaseOut(AHFloat p);
AHFloat QuarticEaseInOut(AHFloat p); // Quintic easing; p^5
AHFloat QuinticEaseIn(AHFloat p);
AHFloat QuinticEaseOut(AHFloat p);
AHFloat QuinticEaseInOut(AHFloat p); // Sine wave easing; sin(p * PI/2)
AHFloat SineEaseIn(AHFloat p);
AHFloat SineEaseOut(AHFloat p);
AHFloat SineEaseInOut(AHFloat p); // Circular easing; sqrt(1 - p^2)
AHFloat CircularEaseIn(AHFloat p);
AHFloat CircularEaseOut(AHFloat p);
AHFloat CircularEaseInOut(AHFloat p); // Exponential easing, base 2
AHFloat ExponentialEaseIn(AHFloat p);
AHFloat ExponentialEaseOut(AHFloat p);
AHFloat ExponentialEaseInOut(AHFloat p); // Exponentially-damped sine wave easing
AHFloat ElasticEaseIn(AHFloat p);
AHFloat ElasticEaseOut(AHFloat p);
AHFloat ElasticEaseInOut(AHFloat p); // Overshooting cubic easing;
AHFloat BackEaseIn(AHFloat p);
AHFloat BackEaseOut(AHFloat p);
AHFloat BackEaseInOut(AHFloat p); // Exponentially-decaying bounce easing
AHFloat BounceEaseIn(AHFloat p);
AHFloat BounceEaseOut(AHFloat p);
AHFloat BounceEaseInOut(AHFloat p); #endif /* defined(__Easing__Easing__) */
//
// Easing.c
// Easing
//
// Created by YouXianMing on 14-10-10.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #include "Easing.h" // Modeled after the line y = x
AHFloat LinearInterpolation(AHFloat p)
{
return p;
} // Modeled after the parabola y = x^2
AHFloat QuadraticEaseIn(AHFloat p)
{
return p * p;
} // Modeled after the parabola y = -x^2 + 2x
AHFloat QuadraticEaseOut(AHFloat p)
{
return -(p * (p - ));
} // Modeled after the piecewise quadratic
// y = (1/2)((2x)^2) ; [0, 0.5)
// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
AHFloat QuadraticEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return * p * p;
}
else
{
return (- * p * p) + ( * p) - ;
}
} // Modeled after the cubic y = x^3
AHFloat CubicEaseIn(AHFloat p)
{
return p * p * p;
} // Modeled after the cubic y = (x - 1)^3 + 1
AHFloat CubicEaseOut(AHFloat p)
{
AHFloat f = (p - );
return f * f * f + ;
} // Modeled after the piecewise cubic
// y = (1/2)((2x)^3) ; [0, 0.5)
// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
AHFloat CubicEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return * p * p * p;
}
else
{
AHFloat f = (( * p) - );
return 0.5 * f * f * f + ;
}
} // Modeled after the quartic x^4
AHFloat QuarticEaseIn(AHFloat p)
{
return p * p * p * p;
} // Modeled after the quartic y = 1 - (x - 1)^4
AHFloat QuarticEaseOut(AHFloat p)
{
AHFloat f = (p - );
return f * f * f * ( - p) + ;
} // Modeled after the piecewise quartic
// y = (1/2)((2x)^4) ; [0, 0.5)
// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
AHFloat QuarticEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return * p * p * p * p;
}
else
{
AHFloat f = (p - );
return - * f * f * f * f + ;
}
} // Modeled after the quintic y = x^5
AHFloat QuinticEaseIn(AHFloat p)
{
return p * p * p * p * p;
} // Modeled after the quintic y = (x - 1)^5 + 1
AHFloat QuinticEaseOut(AHFloat p)
{
AHFloat f = (p - );
return f * f * f * f * f + ;
} // Modeled after the piecewise quintic
// y = (1/2)((2x)^5) ; [0, 0.5)
// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
AHFloat QuinticEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return * p * p * p * p * p;
}
else
{
AHFloat f = (( * p) - );
return 0.5 * f * f * f * f * f + ;
}
} // Modeled after quarter-cycle of sine wave
AHFloat SineEaseIn(AHFloat p)
{
return sin((p - ) * M_PI_2) + ;
} // Modeled after quarter-cycle of sine wave (different phase)
AHFloat SineEaseOut(AHFloat p)
{
return sin(p * M_PI_2);
} // Modeled after half sine wave
AHFloat SineEaseInOut(AHFloat p)
{
return 0.5 * ( - cos(p * M_PI));
} // Modeled after shifted quadrant IV of unit circle
AHFloat CircularEaseIn(AHFloat p)
{
return - sqrt( - (p * p));
} // Modeled after shifted quadrant II of unit circle
AHFloat CircularEaseOut(AHFloat p)
{
return sqrt(( - p) * p);
} // Modeled after the piecewise circular function
// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5)
// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
AHFloat CircularEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return 0.5 * ( - sqrt( - * (p * p)));
}
else
{
return 0.5 * (sqrt(-(( * p) - ) * (( * p) - )) + );
}
} // Modeled after the exponential function y = 2^(10(x - 1))
AHFloat ExponentialEaseIn(AHFloat p)
{
return (p == 0.0) ? p : pow(, * (p - ));
} // Modeled after the exponential function y = -2^(-10x) + 1
AHFloat ExponentialEaseOut(AHFloat p)
{
return (p == 1.0) ? p : - pow(, - * p);
} // Modeled after the piecewise exponential
// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
AHFloat ExponentialEaseInOut(AHFloat p)
{
if(p == 0.0 || p == 1.0) return p; if(p < 0.5)
{
return 0.5 * pow(, ( * p) - );
}
else
{
return -0.5 * pow(, (- * p) + ) + ;
}
} // Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1))
AHFloat ElasticEaseIn(AHFloat p)
{
return sin( * M_PI_2 * p) * pow(, * (p - ));
} // Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1
AHFloat ElasticEaseOut(AHFloat p)
{
return sin(- * M_PI_2 * (p + )) * pow(, - * p) + ;
} // Modeled after the piecewise exponentially-damped sine wave:
// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
AHFloat ElasticEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return 0.5 * sin( * M_PI_2 * ( * p)) * pow(, * (( * p) - ));
}
else
{
return 0.5 * (sin(- * M_PI_2 * (( * p - ) + )) * pow(, - * ( * p - )) + );
}
} // Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
AHFloat BackEaseIn(AHFloat p)
{
return p * p * p - p * sin(p * M_PI);
} // Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
AHFloat BackEaseOut(AHFloat p)
{
AHFloat f = ( - p);
return - (f * f * f - f * sin(f * M_PI));
} // Modeled after the piecewise overshooting cubic function:
// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5)
// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1]
AHFloat BackEaseInOut(AHFloat p)
{
if(p < 0.5)
{
AHFloat f = * p;
return 0.5 * (f * f * f - f * sin(f * M_PI));
}
else
{
AHFloat f = ( - (*p - ));
return 0.5 * ( - (f * f * f - f * sin(f * M_PI))) + 0.5;
}
} AHFloat BounceEaseIn(AHFloat p)
{
return - BounceEaseOut( - p);
} AHFloat BounceEaseOut(AHFloat p)
{
if(p < /11.0)
{
return ( * p * p)/16.0;
}
else if(p < /11.0)
{
return (/40.0 * p * p) - (/10.0 * p) + /5.0;
}
else if(p < /10.0)
{
return (/361.0 * p * p) - (/1805.0 * p) + /1805.0;
}
else
{
return (/5.0 * p * p) - (/25.0 * p) + /25.0;
}
} AHFloat BounceEaseInOut(AHFloat p)
{
if(p < 0.5)
{
return 0.5 * BounceEaseIn(p*);
}
else
{
return 0.5 * BounceEaseOut(p * - ) + 0.5;
}
}

进一步封装的面向对象的使用代码

YXEasing.m 与 YXEasing.h

//
// YXEasing.h
// Prize
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "Easing.h" /*--------------------------------------------- -动画简单的解析- BackEase :在某一动画开始沿指示的路径进行动画处理前稍稍收回该动画的移动。
BounceEase :创建弹跳效果。
CircleEase :创建使用循环函数加速和/或减速的动画。
CubicEase :创建使用公式 f(t) = t^3 加速和/或减速的动画。
ElasticEase :创建类似于弹簧在停止前来回振荡的动画。
ExponentialEase :创建使用指数公式加速和/或减速的动画。
PowerEase :创建使用公式 f(t) = t^p(其中,p 等于 Power 属性)加速和/或减速的动画。
QuadraticEase :创建使用公式 f(t) = t^2 加速和/或减速的动画。
QuarticEase :创建使用公式 f(t) = t^4 加速和/或减速的动画。
QuinticEase :创建使用公式 f(t) = t^5 加速和/或减速的动画。
SineEase :创建使用正弦公式加速和/或减速的动画。 LinearInterpolation QuadraticEaseIn
QuadraticEaseOut
QuadraticEaseInOut CubicEaseIn
CubicEaseOut
CubicEaseInOut QuarticEaseIn
QuarticEaseOut
QuarticEaseInOut QuinticEaseIn
QuinticEaseOut
QuinticEaseInOut SineEaseIn
SineEaseOut
SineEaseInOut CircularEaseIn
CircularEaseOut
CircularEaseInOut ExponentialEaseIn
ExponentialEaseOut
ExponentialEaseInOut ElasticEaseIn
ElasticEaseOut
ElasticEaseInOut BackEaseIn
BackEaseOut
BackEaseInOut BounceEaseIn
BounceEaseOut
BounceEaseInOut
---------------------------------------------*/ /*
// 计算好起始值,结束值
CGFloat oldValue = 0.f;
CGFloat newValue = 1.f; // 关键帧动画
CAKeyframeAnimation *animation = \
[CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; // 设置值
[animation setValues:[YXEasing calculateFrameFromValue:oldValue
toValue:newValue
func:ElasticEaseOut
frameCount:500]]; // 设置持续时间
animation.duration = 0.5f; // 每秒增加的角度(设定结果值,在提交动画之前执行)
layer.transform = \
CATransform3DMakeRotation(newValue, 0.0, 0.0, 1.0); // 提交动画
[layer addAnimation:animation forKey:nil]; */ @interface YXEasing : NSObject // 数组中存储的数据为 NSNumber float 型
+ (NSArray *)calculateFrameFromValue:(CGFloat)fromValue
toValue:(CGFloat)toValue
func:(AHEasingFunction)func
frameCount:(size_t)frameCount; // 数组中存储的数据为 NSValue CGPoint 型
+ (NSArray *)calculateFrameFromPoint:(CGPoint)fromPoint
toPoint:(CGPoint)toPoint
func:(AHEasingFunction)func
frameCount:(size_t)frameCount; // 数组中存储的数据为 NSValue CGSize 型
+ (NSArray *)calculateFrameFromSize:(CGSize)fromSize
toSize:(CGSize)toSize
func:(AHEasingFunction)func
frameCount:(size_t)frameCount; @end
//
// YXEasing.m
// Prize
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "YXEasing.h" @implementation YXEasing + (NSArray *)calculateFrameFromValue:(CGFloat)fromValue
toValue:(CGFloat)toValue
func:(AHEasingFunction)func
frameCount:(size_t)frameCount
{
// 设置帧数量
NSMutableArray *values = [NSMutableArray arrayWithCapacity:frameCount]; // 计算并存储
CGFloat t = 0.0;
CGFloat dt = 1.0 / (frameCount - );
for(size_t frame = ; frame < frameCount; ++frame, t += dt)
{
// 此处就会根据不同的函数计算出不同的值达到不同的效果
CGFloat value = fromValue + func(t) * (toValue - fromValue); // 将计算结果存储进数组中
[values addObject:[NSNumber numberWithFloat:(float)value]];
} // 数组中存储的数据为 NSNumber float 型
return values;
} + (NSArray *)calculateFrameFromPoint:(CGPoint)fromPoint
toPoint:(CGPoint)toPoint
func:(AHEasingFunction)func
frameCount:(size_t)frameCount
{
// 设置帧数量
NSMutableArray *values = [NSMutableArray arrayWithCapacity:frameCount]; // 计算并存储
CGFloat t = 0.0;
CGFloat dt = 1.0 / (frameCount - );
for(size_t frame = ; frame < frameCount; ++frame, t += dt)
{
// 此处就会根据不同的函数计算出不同的值达到不同的效果
CGFloat x = fromPoint.x + func(t) * (toPoint.x - fromPoint.x);
CGFloat y = fromPoint.y + func(t) * (toPoint.y - fromPoint.y); // 将计算结果存储进数组中
[values addObject:[NSValue valueWithCGPoint:CGPointMake(x, y)]];
} // 数组中存储的数据为 NSValue CGPoint 型
return values;
} + (NSArray *)calculateFrameFromSize:(CGSize)fromSize
toSize:(CGSize)toSize
func:(AHEasingFunction)func
frameCount:(size_t)frameCount
{
// 设置帧数量
NSMutableArray *values = [NSMutableArray arrayWithCapacity:frameCount]; // 计算并存储
CGFloat t = 0.0;
CGFloat dt = 1.0 / (frameCount - );
for(size_t frame = ; frame < frameCount; ++frame, t += dt)
{
// 此处就会根据不同的函数计算出不同的值达到不同的效果
CGFloat w = fromSize.width + func(t) * (toSize.width - fromSize.width);
CGFloat h = fromSize.height + func(t) * (toSize.height - fromSize.height); // 将计算结果存储进数组中
[values addObject:[NSValue valueWithCGSize:CGSizeMake(w, h)]];
} // 数组中存储的数据为 NSValue CGSize 型
return values;
} @end

使用示例:

//
// ViewController.m
// Easing
//
// Created by YouXianMing on 14-10-10.
// Copyright (c) 2014年 YouXianMing. All rights reserved.
// #import "ViewController.h"
#import "YXEasing.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; UIView *showView = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
showView.backgroundColor = [UIColor redColor];
showView.center = self.view.center;
[self.view addSubview:showView]; // 计算好起始值,结束值
CGFloat oldValue = .f;
CGFloat newValue = .f; // 关键帧动画
CAKeyframeAnimation *animation = \
[CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; // 设置值
[animation setValues:[YXEasing calculateFrameFromValue:oldValue
toValue:newValue
func:ElasticEaseOut
frameCount:]]; // 设置持续时间
animation.duration = 1.5f; // 每秒增加的角度(设定结果值,在提交动画之前执行)
showView.layer.transform = \
CATransform3DMakeRotation(newValue, 0.0, 0.0, 1.0); // 提交动画
[showView.layer addAnimation:animation forKey:nil]; } @end

效果如下图:

支持xcode6的缓动函数Easing以及使用示例的更多相关文章

  1. GSAP JS基础教程--使用缓动函数

    今天来了解一下缓动easeing函数. 开始,如果你还没有GSAP的类包,可以到GreenSock的官网去下载最新版本的类包,或者直接点击这里​来下载 学习之前,先来准备一下:     <!DO ...

  2. JS动画之缓动函数分析及动画库

    上一篇讲了JS动画定时器相关知识,这一篇介绍下缓动函数及流行的动画库. 熟悉的图 实际使用 jquery animate()+jquery.easing插件的使用: $(selector).anima ...

  3. NGUI缓动函数

    缓动函数:http://easings.net/zh-cn 研究NGUI的博客:http://dsqiu.iteye.com/category/295721

  4. iOS基本动画/关键帧动画/利用缓动函数实现物理动画效果

    先说下基本动画部分 基本动画部分比较简单, 但能实现的动画效果也很局限 使用方法大致为: #1. 创建原始UI或者画面 #2. 创建CABasicAnimation实例, 并设置keypart/dur ...

  5. Silverlight动画学习笔记(三):缓动函数

    (一)定义: 缓动函数:可以将自定义算术公式应用于动画 (二)为什么要用缓动函数: 您可能希望某一对象逼真地弹回或其行为像弹簧一样.您可以使用关键帧动画甚至 From/To/By 动画来大致模拟这些效 ...

  6. JS —— 轮播图中的缓动函数的封装

    轮播图的根本其实就是缓动函数的封装,如果说轮播图是一辆跑动的汽车,那么缓动函数就是它的发动机,今天本文章就带大家由简入繁,封装属于自己的缓动函数~~ 我们从需求的角度开始,首先给出一个简单需求: 1. ...

  7. EaseType 缓动函数

    EaseType(动画曲线) EaseType 缓动函数或者我习惯叫它动画曲线,在很多的软件或动画中都有涉及到,下面是摘取的一些资料: 缓函数图例 Tween效果 每一幅图像当鼠标移上去,会有路径效果 ...

  8. WPF中的动画——(四)缓动函数

    缓动函数可以通过一系列公式模拟一些物理效果,如实地弹跳或其行为如同在弹簧上一样.它们一般应用在From/To/By动画上,可以使得其动画更加平滑. var widthAnimation = new D ...

  9. Tween + 缓动函数

    Unity-Tween http://www.cnblogs.com/MrZivChu/p/UnityTween.html iTween: iTween大解构(一)之抛物线移动 http://blog ...

随机推荐

  1. 创建自己的加密货币MNC——以太坊代币(二)

    创建一个基于以太坊平台的分红币MNC,根据持有的代币数量,进行分红的算法.github地址: https://github.com/lxr1907/MNC 1.使用以太坊根据比例换购token MNC ...

  2. Chrome DevTools的15个使用技巧(译)

    谷歌浏览器如今是Web开发者们所使用的最流行的网页浏览器.伴随每六个星期一次的发布周期和不断扩大的强大的开发功能,Chrome变成了一个必须掌握的工具.大多数前端开发者可能熟悉关于chorme的许多特 ...

  3. 一次java导出pdf的经历

    近期由于工作需要,需要将html代码导入到pdf中,经过了几种pdf的方案对比后发现IText是最简单和便捷的一种方式,于是乎采用了Itext. PDF生成 第一步:导入Maven依赖 <!-- ...

  4. 事务实现,redo,undo,锁

    事务(Transaction)是数据库区别于文件系统的重要特性之一.在文件系统中,如果你正在写文件,但是操作系统突然崩溃了,这个文件就很有可能被破坏.当然,有一些机制可以把文件恢复到某个时间点.不过, ...

  5. 如何在CentOS7上安装桌面环境?

    1.安装 GNOME-Desktop 安装GNOME桌面环境 # yum -y groups install "GNOME Desktop" 完成安装后,使用如下命令启动桌面 # ...

  6. 帧布局--FrameLayout

    <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android=" ...

  7. [C#]LockBits使用笔记

    昨天想基于一张图片做个手机锁屏来着,原图如下:主要是嫌白底太丑了,一开始是想画图工具直接油漆桶伺候,然而一浇上去就发现问题了,变成了这样:看来得手工处理一下把底色统一了,原图分辨率挺高的,SetPix ...

  8. 六、curator recipes之屏障barrier

    简介 curator针对分布式场景实现了分布式屏障:barrier.我们在分布式系统中可以使用barrier去阻塞进程,知道某个条件被触发.其实跟Java多线程的barrier是一样的. 例如:当两个 ...

  9. Linux 中文乱码

    开发中不免会接触到linux,Linux系统中文语言乱码也是我们常碰到的一个问题之一. 在网上查找了不少资料,参考了https://www.linuxidc.com/Linux/2017-07/145 ...

  10. HTTP2 概述

    HTTP/2,也就是超文本传输协议第2版,不论是1还是2,HTTP的基本语义是不变的,比如方法语义(GET/PUST/PUT/DELETE),状态码(200/404/500等),Range Reque ...