Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added all of Robert Penner's easing equations, moved operations to th…

…eir own class
  • Loading branch information...
commit 435fc916f43ea0be228dec754ece91708085ba5a 1 parent 826859b
Dominik Hofmann authored
View
8 LICENSE
@@ -0,0 +1,8 @@
+Copyright (c) 2011, Dominik Hofmann
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View
0  README
No changes.
View
114 README.md
@@ -0,0 +1,114 @@
+PRTween
+===
+
+PRTween is a lightweight tweening library built for iOS. While Apple has done an incredible job with UIView Animations and Core Animation, there are some conscious limitations in these systems that are difficult to get around. PRTween is a great alternative if you'd like to:
+
+* Animate a property Apple won't allow you to
+* Ensure that <pre>[someView layoutSubviews]</pre> is respected during an animation
+* Tween arbitrary numerical values, such as: sound volume, scroll position, a price counter, or many others
+* Define your timing curve as a function rather than a bezier with control points
+
+Installation
+===
+
+Simply grab the PRTween and PRTweenTimingFunction files from /lib/ and get them into your project.
+
+Example Project
+===
+
+If you prefer to learn by looking at code that is already written, you can check out the example project in /example/
+
+Usage
+===
+
+At its core, PRTween is broken into two components.
+
+A **period** is a representation of three points in time (beginning, current, and end) for a particular value that you plan on tweening. For example, suppose that are tweening a value from 100 to 200 over the course of 3 seconds. You can create an object to represent that period like this:
+
+ PRTweenPeriod *period = [PRTweenPeriod periodWithStartValue:100 endValue:200 duration:3];
+
+The second component that makes up PRTween is an **operation**. An operation contains logistic information about how a period should play out, as well as what should happen while it does. You can think of a period as an abstract representation of work that should be carried out, and an operation as the worker who decides *how* it gets carried out. An operation might get added to the queue like this:
+
+ PRTweenOperation *operation = [[PRTweenOperation new] autorelease];
+ operation.period = period;
+ operation.target = self;
+ operation.timingFunction = &PRTweenTimingFunctionLinear;
+ operation.updateSelector = @selector(update:)
+
+The code creates a new operation that carries out a tween over the period we defined earlier. Additionally, you've told the operation to call the <pre>update:</pre> selector every time the value is adjusted. <pre>update:</pre> might look like this:
+
+ - (void)update:(PRTweenPeriod*)period {
+ NSLog(@"%f", period.tweenedValue);
+ }
+
+Finally, you will need to add the operation to the queue.
+
+ [[PRTween sharedInstance] addTweenOperation:operation]
+
+As soon as you've done this and run your code, you should be able to see a console trace of a value moving from 100 to 200 over the course of 3 seconds. If you wanted to apply this to an object on screen, it could be as simple as changing <pre>update:</pre> to the following:
+
+ // will animate the Y offset of testView from 100 to 200 over the course of 3 seconds
+ - (void)update:(PRTweenPeriod*)period {
+ testView.frame = CGRectMake(0, period.tweenedValue, 100, 100);
+ }
+
+Timing Functions
+===
+
+Timing functions are a key feature of PRTween, and allow you to modify how an operation interprets a period. For example, try changing <pre>operation.period</pre> from <pre>&PRTweenTimingFunctionLinear</pre> to <pre>&PRTweenTimingFunctionBounceOut</pre> and running your code again. You should see a similar animation play out, but this time a bounce will be added to the end of it. PRTween comes bundled with a number of timing functions for your convenience:
+
+* PRTweenTimingFunctionLinear
+* PRTweenTimingFunctionBack*[In / Out / InOut]*
+* PRTweenTimingFunctionBounce*[In / Out / InOut]*
+* PRTweenTimingFunctionCircOut*[In / Out / InOut]*
+* PRTweenTimingFunctionCubicOut*[In / Out / InOut]*
+* PRTweenTimingFunctionElasticOut*[In / Out / InOut]*
+* PRTweenTimingFunctionExpoOut*[In / Out / InOut]*
+* PRTweenTimingFunctionQuadOut*[In / Out / InOut]*
+* PRTweenTimingFunctionQuartOut*[In / Out / InOut]*
+* PRTweenTimingFunctionQuintOut*[In / Out / InOut]*
+* PRTweenTimingFunctionSineOut*[In / Out / InOut]*
+
+We encourage you to experiment with PRTween's timing functions in your applications to see which ones you like best.
+
+Custom Functions
+---
+
+One of the most powerful capabilities of PRTween is the ability to write your own timing functions. In lieu of documentation at this time, have a look through PRTweenTimingFunctions.m for example timing functions.
+
+Advanced
+===
+
+API docs are coming with the next push. Until then, you are encouraged to dig through the code for details on advanced functionality. PRTween is incredibly minimal, so you can probably figure everything out in an hour or two.
+
+Contributing
+===
+
+PRTween is incredibly young, so there many rules right now.
+
+* Fork it
+* Fix it or add it
+* Add yourself to the contributor list
+* Commit
+* Send a pull request
+
+Contributors
+---
+
+* [This link](https://github.com/dominikhofmann/)Dominik Hofmann
+
+License
+===
+Surprise! It's a BSD license.
+
+<pre>
+Copyright (c) 2011, Dominik Hofmann
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</pre>
+
View
20 example/PRTween.xcodeproj/project.pbxproj
@@ -16,7 +16,8 @@
B25002D2139558F700670D11 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B25002D0139558F700670D11 /* MainWindow.xib */; };
B25002D5139558F700670D11 /* PRTweenExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B25002D4139558F700670D11 /* PRTweenExampleViewController.m */; };
B25002D8139558F700670D11 /* PRTweenExampleViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = B25002D6139558F700670D11 /* PRTweenExampleViewController.xib */; };
- B25002E01395591F00670D11 /* PRTween.m in Sources */ = {isa = PBXBuildFile; fileRef = B25002DF1395591F00670D11 /* PRTween.m */; };
+ B4A2EBFD13C8AFAE006EB549 /* PRTweenTimingFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = B4A2EBFB13C8AFAE006EB549 /* PRTweenTimingFunctions.m */; };
+ B4F3069513C8BFCA00355204 /* PRTween.m in Sources */ = {isa = PBXBuildFile; fileRef = B4F3069313C8BFCA00355204 /* PRTween.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -35,7 +36,9 @@
B25002D4139558F700670D11 /* PRTweenExampleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PRTweenExampleViewController.m; sourceTree = "<group>"; };
B25002D7139558F700670D11 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PRTweenExampleViewController.xib; sourceTree = "<group>"; };
B25002DE1395591F00670D11 /* PRTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PRTween.h; path = ../lib/PRTween.h; sourceTree = "<group>"; };
- B25002DF1395591F00670D11 /* PRTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PRTween.m; path = ../lib/PRTween.m; sourceTree = "<group>"; };
+ B4A2EBFB13C8AFAE006EB549 /* PRTweenTimingFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PRTweenTimingFunctions.m; path = ../lib/PRTweenTimingFunctions.m; sourceTree = "<group>"; };
+ B4A2EBFC13C8AFAE006EB549 /* PRTweenTimingFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PRTweenTimingFunctions.h; path = ../lib/PRTweenTimingFunctions.h; sourceTree = "<group>"; };
+ B4F3069313C8BFCA00355204 /* PRTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PRTween.m; path = ../lib/PRTween.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -84,7 +87,9 @@
isa = PBXGroup;
children = (
B25002DE1395591F00670D11 /* PRTween.h */,
- B25002DF1395591F00670D11 /* PRTween.m */,
+ B4F3069313C8BFCA00355204 /* PRTween.m */,
+ B4A2EBFB13C8AFAE006EB549 /* PRTweenTimingFunctions.m */,
+ B4A2EBFC13C8AFAE006EB549 /* PRTweenTimingFunctions.h */,
);
name = PRTween;
sourceTree = "<group>";
@@ -180,7 +185,8 @@
B25002CC139558F700670D11 /* main.m in Sources */,
B25002CF139558F700670D11 /* PRTweenExampleAppDelegate.m in Sources */,
B25002D5139558F700670D11 /* PRTweenExampleViewController.m in Sources */,
- B25002E01395591F00670D11 /* PRTween.m in Sources */,
+ B4A2EBFD13C8AFAE006EB549 /* PRTweenTimingFunctions.m in Sources */,
+ B4F3069513C8BFCA00355204 /* PRTween.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -256,8 +262,11 @@
GCC_DYNAMIC_NO_PIC = NO;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "PRTween-Prefix.pch";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
INFOPLIST_FILE = "PRTween-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
WRAPPER_EXTENSION = app;
};
name = Debug;
@@ -269,8 +278,11 @@
COPY_PHASE_STRIP = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "PRTween-Prefix.pch";
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
INFOPLIST_FILE = "PRTween-Info.plist";
+ IPHONEOS_DEPLOYMENT_TARGET = 3.0;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
};
View
7 example/PRTweenExampleAppDelegate.h
@@ -1,10 +1,3 @@
-//
-// JSTweenAppDelegate.h
-// JSTween
-//
-// Created by Dominik Hofmann on 5/31/11.
-// Copyright 2011 Jetsetter. All rights reserved.
-//
#import <UIKit/UIKit.h>
View
8 example/PRTweenExampleAppDelegate.m
@@ -1,13 +1,5 @@
-//
-// JSTweenAppDelegate.m
-// JSTween
-//
-// Created by Dominik Hofmann on 5/31/11.
-// Copyright 2011 Jetsetter. All rights reserved.
-//
#import "PRTweenExampleAppDelegate.h"
-
#import "PRTweenExampleViewController.h"
@implementation PRTweenExampleAppDelegate
View
10 example/PRTweenExampleViewController.h
@@ -1,17 +1,11 @@
-//
-// JSTweenViewController.h
-// JSTween
-//
-// Created by Dominik Hofmann on 5/31/11.
-// Copyright 2011 Jetsetter. All rights reserved.
-//
#import <UIKit/UIKit.h>
+#import "PRTween.h"
@interface PRTweenExampleViewController : UIViewController {
UIView *testView;
- NSDictionary *activeTweenOperation;
+ PRTweenOperation *activeTweenOperation;
}
View
1  example/PRTweenExampleViewController.m
@@ -1,6 +1,5 @@
#import "PRTweenExampleViewController.h"
-#import "PRTween.h"
@implementation PRTweenExampleViewController
View
32 lib/PRTween.h
@@ -1,13 +1,6 @@
#import <Foundation/Foundation.h>
-
-CGFloat PRTweenTimingFunctionLinear (CGFloat, CGFloat, CGFloat, CGFloat);
-CGFloat PRTweenTimingFunctionBounceOut (CGFloat, CGFloat, CGFloat, CGFloat);
-CGFloat PRTweenTimingFunctionBounceIn (CGFloat, CGFloat, CGFloat, CGFloat);
-CGFloat PRTweenTimingFunctionBounceInOut (CGFloat, CGFloat, CGFloat, CGFloat);
-CGFloat PRTweenTimingFunctionQuintOut (CGFloat, CGFloat, CGFloat, CGFloat);
-CGFloat PRTweenTimingFunctionQuintIn (CGFloat, CGFloat, CGFloat, CGFloat);
-CGFloat PRTweenTimingFunctionQuintInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+#import "PRTweenTimingFunctions.h"
@interface PRTweenPeriod : NSObject {
CGFloat startValue;
@@ -29,6 +22,22 @@ CGFloat PRTweenTimingFunctionQuintInOut (CGFloat, CGFloat, CGFloat, CGFloat);
@end
+@interface PRTweenOperation : NSObject {
+ PRTweenPeriod *period;
+ NSObject *target;
+ SEL updateSelector;
+ SEL completeSelector;
+ CGFloat (*timingFunction)(CGFloat, CGFloat, CGFloat, CGFloat);
+}
+
+@property (nonatomic, retain) PRTweenPeriod *period;
+@property (nonatomic, retain) NSObject *target;
+@property (nonatomic) SEL updateSelector;
+@property (nonatomic) SEL completeSelector;
+@property (nonatomic, assign) CGFloat (*timingFunction)(CGFloat, CGFloat, CGFloat, CGFloat);
+
+@end
+
@interface PRTween : NSObject {
NSMutableArray *tweenOperations;
NSMutableArray *expiredTweenOperations;
@@ -39,8 +48,9 @@ CGFloat PRTweenTimingFunctionQuintInOut (CGFloat, CGFloat, CGFloat, CGFloat);
@property (nonatomic, readonly) CGFloat timeOffset;
+ (PRTween *)sharedInstance;
-- (NSDictionary*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector;
-- (NSDictionary*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector timingFunction:(CGFloat (*)(CGFloat, CGFloat, CGFloat, CGFloat))timingFunction;
-- (void)removeTweenOperation:(NSDictionary*)tweenOperation;
+- (PRTweenOperation*)addOperation:(PRTweenOperation*)operation;
+- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector;
+- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector timingFunction:(CGFloat (*)(CGFloat, CGFloat, CGFloat, CGFloat))timingFunction;
+- (void)removeTweenOperation:(PRTweenOperation*)tweenOperation;
@end
View
96 lib/PRTween.m
@@ -1,49 +1,6 @@
#import "PRTween.h"
-// These timing functions were ported from Robert Penner's AS2 easing equations.
-// http://www.robertpenner.com/easing/
-
-CGFloat PRTweenTimingFunctionLinear (CGFloat time, CGFloat begin, CGFloat change, CGFloat duration) {
- return change * time / duration + begin;
-}
-
-CGFloat PRTweenTimingFunctionBounceOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
- if ((t/=d) < (1/2.75)) {
- return c*(7.5625*t*t) + b;
- } else if (t < (2/2.75)) {
- return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
- } else if (t < (2.5/2.75)) {
- return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
- } else {
- return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
- }
-}
-
-CGFloat PRTweenTimingFunctionBounceIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
- return c - PRTweenTimingFunctionBounceOut(d-t, 0, c, d) + b;
-}
-
-CGFloat PRTweenTimingFunctionBounceInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
- if (t < d/2) return PRTweenTimingFunctionBounceIn(t*2, 0, c, d) * .5 + b;
- else return PRTweenTimingFunctionBounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
-}
-
-CGFloat PRTweenTimingFunctionQuintOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
- return c*(t/=d)*t*t*t*t + b;
-}
-
-CGFloat PRTweenTimingFunctionQuintIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
- return c*((t=t/d-1)*t*t*t*t + 1) + b;
-}
-
-CGFloat PRTweenTimingFunctionQuintInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
- if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
- return c/2*((t-=2)*t*t*t*t + 2) + b;
-}
-
-
-
#define kPRTweenFramerate 1.0/60
@implementation PRTweenPeriod
@@ -71,7 +28,13 @@ - (void)dealloc {
@end
-
+@implementation PRTweenOperation
+@synthesize period;
+@synthesize target;
+@synthesize updateSelector;
+@synthesize completeSelector;
+@synthesize timingFunction;
+@end
@interface PRTween ()
- (void)update;
@@ -102,24 +65,28 @@ - (id)init {
return self;
}
-- (NSDictionary*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector {
+- (PRTweenOperation*)addOperation:(PRTweenOperation*)operation {
+ [tweenOperations addObject:operation];
+ return operation;
+}
+
+- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector {
return [self addTweenPeriod:period target:target selector:selector timingFunction:&PRTweenTimingFunctionLinear];
}
-- (NSDictionary*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector timingFunction:(CGFloat (*)(CGFloat, CGFloat, CGFloat, CGFloat))timingFunction {
+- (PRTweenOperation*)addTweenPeriod:(PRTweenPeriod *)period target:(NSObject *)target selector:(SEL)selector timingFunction:(CGFloat (*)(CGFloat, CGFloat, CGFloat, CGFloat))timingFunction {
- NSMutableDictionary *tweenOperation = [NSMutableDictionary dictionary];
- [tweenOperation setObject:period forKey:@"period"];
- [tweenOperation setObject:target forKey:@"target"];
- [tweenOperation setObject:[NSValue valueWithPointer:timingFunction] forKey:@"timingFunction"];
- [tweenOperation setObject:[NSValue valueWithBytes:&selector objCType:@encode(SEL)] forKey:@"selector"];
- [tweenOperations addObject:tweenOperation];
+ PRTweenOperation *tweenOperation = [[PRTweenOperation new] autorelease];
+ tweenOperation.period = period;
+ tweenOperation.target = target;
+ tweenOperation.timingFunction = timingFunction;
+ tweenOperation.updateSelector = selector;
- return tweenOperation;
+ return [self addOperation:tweenOperation];
}
-- (void)removeTweenOperation:(NSDictionary *)tweenOperation {
+- (void)removeTweenOperation:(PRTweenOperation *)tweenOperation {
if (tweenOperation != nil && [tweenOperations containsObject:tweenOperation]) {
[tweenOperations removeObject:tweenOperation];
@@ -129,20 +96,19 @@ - (void)removeTweenOperation:(NSDictionary *)tweenOperation {
- (void)update {
timeOffset += kPRTweenFramerate;
- for (NSDictionary *tweenOperation in tweenOperations) {
+ for (PRTweenOperation *tweenOperation in tweenOperations) {
- PRTweenPeriod *period = [tweenOperation valueForKey:@"period"];
+ PRTweenPeriod *period = tweenOperation.period;
// if operation is delayed, pass over it for now
if (timeOffset <= period.startOffset + period.delay) {
continue;
}
- CGFloat (*timingFunction)(CGFloat, CGFloat, CGFloat, CGFloat);
- [[tweenOperation objectForKey:@"timingFunction"] getValue:&timingFunction];
+ CGFloat (*timingFunction)(CGFloat, CGFloat, CGFloat, CGFloat) = tweenOperation.timingFunction;
if (timingFunction != NULL) {
-
+
if (timeOffset <= period.startOffset + period.delay + period.duration) {
// if tween operation is valid, calculate tweened value using timing function
period.tweenedValue = timingFunction(timeOffset - period.startOffset - period.delay, period.startValue, period.endValue - period.startValue, period.duration);
@@ -152,13 +118,8 @@ - (void)update {
[expiredTweenOperations addObject:tweenOperation];
}
- NSObject *target = [tweenOperation valueForKey:@"target"];
- SEL selector;
-
- // guard against buffer overflow
- if (strcmp([[tweenOperation objectForKey:@"selector"] objCType], @encode(SEL)) == 0) {
- [[tweenOperation objectForKey:@"selector"] getValue:&selector];
- }
+ NSObject *target = tweenOperation.target;
+ SEL selector = tweenOperation.updateSelector;
if (period != nil && target != nil && selector != NULL) {
[target performSelector:selector withObject:period afterDelay:0];
@@ -167,7 +128,8 @@ - (void)update {
}
// clean up expired tween operations
- for (NSDictionary *tweenOperation in expiredTweenOperations) {
+ for (PRTweenOperation *tweenOperation in expiredTweenOperations) {
+ if (tweenOperation.completeSelector) [tweenOperation.target performSelector:tweenOperation.completeSelector withObject:nil afterDelay:0];
[tweenOperations removeObject:tweenOperation];
tweenOperation = nil;
}
View
66 lib/PRTweenTimingFunctions.h
@@ -0,0 +1,66 @@
+/*
+
+ These timing functions are adapted from Robert Penner's excellent AS2 easing equations.
+ For more information, check out http://robertpenner.com/easing/
+
+ --
+
+ TERMS OF USE - EASING EQUATIONS
+
+ Open source under the BSD License.
+
+ Copyright © 2001 Robert Penner
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#import <Foundation/Foundation.h>
+
+CGFloat PRTweenTimingFunctionLinear (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionBackOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionBackIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionBackInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionBounceOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionBounceIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionBounceInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionCircOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionCircIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionCircInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionCubicOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionCubicIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionCubicInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionElasticOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionElasticIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionElasticInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionExpoOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionExpoIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionExpoInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionQuadOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionQuadIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionQuadInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionQuartOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionQuartIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionQuartInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionQuintOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionQuintIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionQuintInOut (CGFloat, CGFloat, CGFloat, CGFloat);
+
+CGFloat PRTweenTimingFunctionSineOut (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionSineIn (CGFloat, CGFloat, CGFloat, CGFloat);
+CGFloat PRTweenTimingFunctionSineInOut (CGFloat, CGFloat, CGFloat, CGFloat);
View
185 lib/PRTweenTimingFunctions.m
@@ -0,0 +1,185 @@
+/*
+
+ These timing functions are adapted from Robert Penner's excellent AS2 easing equations.
+ For more information, check out http://robertpenner.com/easing/
+
+ --
+
+ TERMS OF USE - EASING EQUATIONS
+
+ Open source under the BSD License.
+
+ Copyright © 2001 Robert Penner
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#import "PRTweenTimingFunctions.h"
+
+CGFloat PRTweenTimingFunctionLinear (CGFloat time, CGFloat begin, CGFloat change, CGFloat duration) {
+ return change * time / duration + begin;
+}
+
+CGFloat PRTweenTimingFunctionBackOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ CGFloat s = 1.70158;
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+}
+
+CGFloat PRTweenTimingFunctionBackIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ CGFloat s = 1.70158;
+ return c*(t/=d)*t*((s+1)*t - s) + b;
+}
+
+CGFloat PRTweenTimingFunctionBackInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ CGFloat s = 1.70158;
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+}
+
+CGFloat PRTweenTimingFunctionBounceOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if ((t/=d) < (1/2.75)) {
+ return c*(7.5625*t*t) + b;
+ } else if (t < (2/2.75)) {
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+ } else if (t < (2.5/2.75)) {
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+ } else {
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+ }
+}
+
+CGFloat PRTweenTimingFunctionBounceIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c - PRTweenTimingFunctionBounceOut(d-t, 0, c, d) + b;
+}
+
+CGFloat PRTweenTimingFunctionBounceInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if (t < d/2) return PRTweenTimingFunctionBounceIn(t*2, 0, c, d) * .5 + b;
+ else return PRTweenTimingFunctionBounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
+}
+
+CGFloat PRTweenTimingFunctionCircOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c * sqrt(1 - (t=t/d-1)*t) + b;
+}
+
+CGFloat PRTweenTimingFunctionCircIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return -c * (sqrt(1 - (t/=d)*t) - 1) + b;
+}
+
+CGFloat PRTweenTimingFunctionCircInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if ((t/=d/2) < 1) return -c/2 * (sqrt(1 - t*t) - 1) + b;
+ return c/2 * (sqrt(1 - (t-=2)*t) + 1) + b;
+}
+
+CGFloat PRTweenTimingFunctionCubicOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c*((t=t/d-1)*t*t + 1) + b;
+}
+
+CGFloat PRTweenTimingFunctionCubicIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c*(t/=d)*t*t + b;
+}
+
+CGFloat PRTweenTimingFunctionCubicInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
+ return c/2*((t-=2)*t*t + 2) + b;
+}
+
+CGFloat PRTweenTimingFunctionElasticOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ CGFloat p = d*.3;
+ CGFloat s, a;
+ if (t==0) return b; if ((t/=d)==1) return b+c;
+ if (!a || a < ABS(c)) { a=c; s=p/4; }
+ else s = p/(2*M_PI) * asin (c/a);
+ return (a*pow(2,-10*t) * sin( (t*d-s)*(2*M_PI)/p ) + c + b);
+}
+
+CGFloat PRTweenTimingFunctionElasticIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {\
+ CGFloat p = d*.3;
+ CGFloat s, a;
+ if (t==0) return b; if ((t/=d)==1) return b+c;
+ if (!a || a < ABS(c)) { a=c; s=p/4; }
+ else s = p/(2*M_PI) * asin (c/a);
+ return -(a*pow(2,10*(t-=1)) * sin( (t*d-s)*(2*M_PI)/p )) + b;
+}
+
+CGFloat PRTweenTimingFunctionElasticInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ CGFloat p = d*(.3*1.5);
+ CGFloat s, a;
+ if (t==0) return b; if ((t/=d/2)==2) return b+c;
+ if (!a || a < ABS(c)) { a=c; s=p/4; }
+ else s = p/(2*M_PI) * asin (c/a);
+ if (t < 1) return -.5*(a*pow(2,10*(t-=1)) * sin( (t*d-s)*(2*M_PI)/p )) + b;
+ return a*pow(2,-10*(t-=1)) * sin( (t*d-s)*(2*M_PI)/p )*.5 + c + b;
+}
+
+CGFloat PRTweenTimingFunctionExpoOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return (t==d) ? b+c : c * (-pow(2, -10 * t/d) + 1) + b;
+}
+
+CGFloat PRTweenTimingFunctioExpoIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return (t==0) ? b : c * pow(2, 10 * (t/d - 1)) + b;
+}
+
+CGFloat PRTweenTimingFunctionExpoInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if (t==0) return b;
+ if (t==d) return b+c;
+ if ((t/=d/2) < 1) return c/2 * pow(2, 10 * (t - 1)) + b;
+ return c/2 * (-pow(2, -10 * --t) + 2) + b;
+}
+
+CGFloat PRTweenTimingFunctionQuadOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return -c *(t/=d)*(t-2) + b;
+}
+
+CGFloat PRTweenTimingFunctioQuadIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c*(t/=d)*t + b;
+}
+
+CGFloat PRTweenTimingFunctionQuadInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if ((t/=d/2) < 1) return c/2*t*t + b;
+ return -c/2 * ((--t)*(t-2) - 1) + b;
+}
+
+CGFloat PRTweenTimingFunctionQuartOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
+}
+
+CGFloat PRTweenTimingFunctioQuartIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c*(t/=d)*t*t*t + b;
+}
+
+CGFloat PRTweenTimingFunctionQuartInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
+}
+
+CGFloat PRTweenTimingFunctionQuintOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c*(t/=d)*t*t*t*t + b;
+}
+
+CGFloat PRTweenTimingFunctionQuintIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
+}
+
+CGFloat PRTweenTimingFunctionQuintInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
+}
+
+CGFloat PRTweenTimingFunctionSineOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return c * sin(t/d * (M_PI/2)) + b;
+}
+
+CGFloat PRTweenTimingFunctioSineIn (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return -c * cos(t/d * (M_PI/2)) + c + b;
+}
+
+CGFloat PRTweenTimingFunctionSineInOut (CGFloat t, CGFloat b, CGFloat c, CGFloat d) {
+ return -c/2 * (cos(M_PI*t/d) - 1) + b;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.