├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── example ├── addons.make ├── bin │ └── data │ │ └── .gitkeep └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h ├── example_plots ├── addons.make ├── bin │ └── data │ │ └── .gitkeep └── src │ ├── main.cpp │ ├── ofApp.cpp │ └── ofApp.h └── src ├── easing_terms_of_use.html └── ofxEasing.h /.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | os: Visual Studio 2015 RC 3 | 4 | environment: 5 | global: 6 | APPVEYOR_OS_NAME: windows 7 | matrix: 8 | #MSYS2 Building 9 | - platform: x86 10 | BUILDER: MSYS2 11 | 12 | #VisualStudio Building 13 | - platform: x86 14 | BUILDER : VS 15 | BITS: 32 16 | - platform: x64 17 | BUILDER : VS 18 | BITS: 64 19 | 20 | configuration: Debug 21 | shallow_clone: true 22 | clone_depth: 10 23 | init: 24 | - set MSYS2_PATH=c:\msys64 25 | - set CHERE_INVOKING=1 26 | - if "%BUILDER%_%PLATFORM%"=="MSYS2_x86" set MSYSTEM=MINGW32 27 | - if "%BUILDER%_%PLATFORM%"=="MSYS2_x64" set MSYSTEM=MINGW64 28 | - if "%BUILDER%"=="VS" set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH% 29 | 30 | install: 31 | - cd .. 32 | - git clone --depth=1 --branch=master https://github.com/openframeworks/openFrameworks 33 | - call openFrameworks\scripts\ci\addons\install.cmd 34 | 35 | build_script: 36 | - cd %OF_PATH% 37 | - scripts\ci\addons\build.cmd 38 | 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.xcuserstate 3 | *.xcscmblueprint 4 | */bin/* 5 | !*/bin/data 6 | */obj 7 | RemoteSystemsTempFiles/ 8 | .metadata 9 | */.project 10 | */.cproject 11 | */.settings 12 | */*/project.xcworkspace/** 13 | */*/xcuserdata 14 | .cproject 15 | .project 16 | .settings 17 | *.qbs.user 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This file allows testing your addon using travis CI servers to use it you'll need to 2 | # create an account in travis.org and enable your addon there. 3 | # 4 | # By default it will test linux 64bit and osx against the master and stable OF branches. 5 | # Other platforms can be enabled by uncommenting the corresponding sections. 6 | # 7 | # If any extra install is needed to use the addon it can be included in the corresponding 8 | # install script in: 9 | # 10 | # scripts/ci/$TARGET/install.sh 11 | # 12 | 13 | 14 | language: c++ 15 | compiler: gcc 16 | sudo: true 17 | matrix: 18 | include: 19 | # fully specify builds, include can't dynamically expand matrix entries 20 | # relative order of sudo and env is important so that addons: is recognized 21 | 22 | # Linux 64bit, OF master 23 | - os: linux 24 | dist: trusty 25 | sudo: required 26 | env: TARGET="linux64" OF_BRANCH="master" 27 | addons: 28 | apt: 29 | sources: 30 | - ubuntu-toolchain-r-test 31 | packages: 32 | - gcc-4.9 33 | - g++-4.9 34 | - gdb 35 | 36 | # Linux 64bit, OF stable: Not supported yet 37 | # - os: linux 38 | # dist: trusty 39 | # sudo: required 40 | # env: TARGET="linux64" OF_BRANCH="stable" 41 | # addons: 42 | # apt: 43 | # sources: 44 | # - ubuntu-toolchain-r-test 45 | # packages: 46 | # - gcc-4.9 47 | # - g++-4.9 48 | # - gdb 49 | 50 | # OSX, OF master 51 | - os: osx 52 | osx_image: xcode8 53 | compiler: clang 54 | env: TARGET="osx" OF_BRANCH="master" 55 | 56 | # OSX 57 | # - os: osx 58 | # osx_image: xcode8 59 | # compiler: clang 60 | # env: TARGET="osx" OF_BRANCH="stable" 61 | 62 | # Linux ARM6, OF master: Uncomment following lines to enable 63 | - os: linux 64 | sudo: required 65 | dist: trusty 66 | env: TARGET="linuxarmv6l" OF_BRANCH="master" 67 | 68 | 69 | # Linux ARM6, OF stable: Not supported yet 70 | # - os: linux 71 | # sudo: required 72 | # dist: trusty 73 | # env: TARGET="linuxarmv6l" OF_BRANCH="stable" 74 | 75 | # Linux ARM7, OF master: Uncomment following lines to enable 76 | - os: linux 77 | sudo: false 78 | env: TARGET="linuxarmv7l" OF_BRANCH="master" 79 | cache: 80 | directories: 81 | - ~/rpi2_toolchain 82 | - ~/firmware-master 83 | - ~/archlinux 84 | 85 | # Linux ARM7, OF stable: Not supported yet 86 | # - os: linux 87 | # sudo: false 88 | # env: TARGET="linuxarmv7l" OF_BRANCH="stable" 89 | # cache: 90 | # directories: 91 | # - ~/rpi2_toolchain 92 | # - ~/firmware-master 93 | # - ~/archlinux 94 | 95 | 96 | # Emscripten, OF master: Uncomment following lines to enable 97 | - os: linux 98 | sudo: false 99 | env: TARGET="emscripten" OF_BRANCH="master" 100 | addons: 101 | apt: 102 | sources: 103 | - ubuntu-toolchain-r-test 104 | packages: 105 | - libstdc++6 106 | 107 | 108 | # Emscripten, OF stable: Uncomment following lines to enable 109 | # - os: linux 110 | # sudo: false 111 | # env: TARGET="emscripten" OF_BRANCH="stable" 112 | # addons: 113 | # apt: 114 | # sources: 115 | # - ubuntu-toolchain-r-test 116 | # packages: 117 | # - libstdc++6 118 | 119 | 120 | # iOS, OF master: Not supported yet 121 | # - os: osx 122 | # osx_image: xcode8 123 | # compiler: clang 124 | # env: TARGET="ios" OF_BRANCH="master" 125 | 126 | 127 | # iOS, OF stable: Not supported yet 128 | # - os: osx 129 | # osx_image: xcode8 130 | # compiler: clang 131 | # env: TARGET="ios" OF_BRANCH="stable" 132 | 133 | 134 | # tvOS, OF master: Not supported yet 135 | # - os: osx 136 | # osx_image: xcode8 137 | # compiler: clang 138 | # env: TARGET="tvos" OF_BRANCH="master" 139 | 140 | 141 | # tvOS, OF stable: Not supported yet 142 | # - os: osx 143 | # osx_image: xcode8 144 | # compiler: clang 145 | # env: TARGET="tvos" OF_BRANCH="stable" 146 | 147 | 148 | # Android armv7, OF master: Uncomment following lines to enable 149 | # - os: linux 150 | # sudo: false 151 | # env: TARGET="android" OPT="armv7" OF_BRANCH="master" 152 | # cache: 153 | # directories: 154 | # - ~/android-ndk-r12b 155 | 156 | 157 | # Android armv7, OF stable: Uncomment following lines to enable 158 | # - os: linux 159 | # sudo: false 160 | # env: TARGET="android" OPT="armv7" OF_BRANCH="stable" 161 | # cache: 162 | # directories: 163 | # - ~/android-ndk-r12b 164 | 165 | 166 | # Android x86, OF master: Uncomment following lines to enable 167 | # - os: linux 168 | # sudo: false 169 | # env: TARGET="android" OPT="x86" OF_BRANCH="master" 170 | # cache: 171 | # directories: 172 | # - ~/android-ndk-r12b 173 | 174 | 175 | # Android x86, OF stable: Uncomment following lines to enable 176 | # - os: linux 177 | # sudo: false 178 | # env: TARGET="android" OPT="x86" OF_BRANCH="stable" 179 | # cache: 180 | # directories: 181 | # - ~/android-ndk-r12b 182 | 183 | 184 | # Exclude the default build that would otherwise be generated 185 | # see https://github.com/travis-ci/travis-ci/issues/1228 186 | exclude: 187 | - compiler: gcc 188 | 189 | install: 190 | - cd ~ 191 | - git clone --depth=1 --branch=$OF_BRANCH https://github.com/openframeworks/openFrameworks 192 | - cd openFrameworks 193 | - scripts/ci/addons/install.sh 194 | 195 | script: 196 | - scripts/ci/addons/build.sh 197 | 198 | git: 199 | depth: 10 200 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 (c) Arturo Castro. arturocastro.net 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, 8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following 11 | * conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be 14 | * included in all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | /** 27 | * Uses http://www.jesusgollonet.com/blog/2007/09/24/penner-easing-cpp/ 28 | */ 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ofxEasing 2 | 3 | [![Build status](https://travis-ci.org/arturoc/ofxEasing.svg?branch=master)](https://travis-ci.org/arturoc/ofxEasing) 4 | 5 | [![Build status](https://ci.appveyor.com/api/projects/status/r1u88c06u8jo8e8p/branch/master?svg=true)](https://ci.appveyor.com/project/arturoc/ofxeasing/branch/master) 6 | 7 | 8 | Replaces ofxTween with a simpler API and no external dependencies. 9 | 10 | Usage: 11 | 12 | ```cpp 13 | using namespace ofxeasing; 14 | map(value, minIn, maxIn, minOut, maxOut, linear::easeIn); 15 | ``` 16 | 17 | Some easing functions might have more parameters than the usual 4. Right now only the \_s version of the back functions which indicate which proportion of the distance is done in the back trajectory. In those cases you can pass the extra parameter at the end of the map function like: 18 | 19 | ```cpp 20 | using namespace ofxeasing; 21 | map(value, minIn, maxIn, minOut, maxOut, back::easeIn_s, 0.8); 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /example/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | -------------------------------------------------------------------------------- /example/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arturoc/ofxEasing/3a15beffb9cfdce26ffafb1f78e06e730b26c239/example/bin/data/.gitkeep -------------------------------------------------------------------------------- /example/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,240,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | #include "ofxEasing.h" 3 | 4 | //-------------------------------------------------------------- 5 | void ofApp::setup(){ 6 | ofSetBackgroundColor(0); 7 | positions.resize(5); 8 | initTime = 0; 9 | endPosition = ofGetWidth() - 40; 10 | 11 | easingNames = { 12 | "linear", 13 | "quad", 14 | "cubic", 15 | "bounce", 16 | "back", 17 | }; 18 | } 19 | 20 | //-------------------------------------------------------------- 21 | void ofApp::update(){ 22 | auto duration = 1.f; 23 | auto endTime = initTime + duration; 24 | auto now = ofGetElapsedTimef(); 25 | positions[0] = ofxeasing::map_clamp(now, initTime, endTime, 0, endPosition, &ofxeasing::linear::easeIn); 26 | positions[1] = ofxeasing::map_clamp(now, initTime, endTime, 0, endPosition, &ofxeasing::quad::easeIn); 27 | positions[2] = ofxeasing::map_clamp(now, initTime, endTime, 0, endPosition, &ofxeasing::cubic::easeIn); 28 | positions[3] = ofxeasing::map_clamp(now, initTime, endTime, 0, endPosition, &ofxeasing::bounce::easeOut); 29 | 30 | // the back easing equation can receive an extra parameter in the _s functions 31 | // that controls how much the easing goes forward or backwards 32 | positions[4] = ofxeasing::map_clamp(now, initTime, endTime, 0, endPosition, &ofxeasing::back::easeOut_s, 0.8); 33 | } 34 | 35 | //-------------------------------------------------------------- 36 | void ofApp::draw(){ 37 | ofSetColor(255); 38 | auto h = 20; 39 | auto y = 20; 40 | auto i = 0; 41 | for(auto & x: positions){ 42 | ofDrawRectangle(0, y, x, h); 43 | ofDrawBitmapString(easingNames[i], 10, y+h*1.6); 44 | y+=h*2; 45 | i++; 46 | } 47 | 48 | ofSetColor(200); 49 | ofDrawLine(endPosition, 0, endPosition, ofGetHeight()); 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void ofApp::keyPressed(int key){ 54 | 55 | } 56 | 57 | //-------------------------------------------------------------- 58 | void ofApp::keyReleased(int key){ 59 | 60 | } 61 | 62 | //-------------------------------------------------------------- 63 | void ofApp::mouseMoved(int x, int y ){ 64 | 65 | } 66 | 67 | //-------------------------------------------------------------- 68 | void ofApp::mouseDragged(int x, int y, int button){ 69 | 70 | } 71 | 72 | //-------------------------------------------------------------- 73 | void ofApp::mousePressed(int x, int y, int button){ 74 | initTime = ofGetElapsedTimef(); 75 | } 76 | 77 | //-------------------------------------------------------------- 78 | void ofApp::mouseReleased(int x, int y, int button){ 79 | 80 | } 81 | 82 | //-------------------------------------------------------------- 83 | void ofApp::mouseEntered(int x, int y){ 84 | 85 | } 86 | 87 | //-------------------------------------------------------------- 88 | void ofApp::mouseExited(int x, int y){ 89 | 90 | } 91 | 92 | //-------------------------------------------------------------- 93 | void ofApp::windowResized(int w, int h){ 94 | 95 | } 96 | 97 | //-------------------------------------------------------------- 98 | void ofApp::gotMessage(ofMessage msg){ 99 | 100 | } 101 | 102 | //-------------------------------------------------------------- 103 | void ofApp::dragEvent(ofDragInfo dragInfo){ 104 | 105 | } 106 | -------------------------------------------------------------------------------- /example/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | class ofApp : public ofBaseApp{ 6 | 7 | public: 8 | void setup(); 9 | void update(); 10 | void draw(); 11 | 12 | void keyPressed(int key); 13 | void keyReleased(int key); 14 | void mouseMoved(int x, int y ); 15 | void mouseDragged(int x, int y, int button); 16 | void mousePressed(int x, int y, int button); 17 | void mouseReleased(int x, int y, int button); 18 | void mouseEntered(int x, int y); 19 | void mouseExited(int x, int y); 20 | void windowResized(int w, int h); 21 | void dragEvent(ofDragInfo dragInfo); 22 | void gotMessage(ofMessage msg); 23 | 24 | std::vector positions; 25 | std::vector easingNames; 26 | float initTime; 27 | float endPosition; 28 | }; 29 | -------------------------------------------------------------------------------- /example_plots/addons.make: -------------------------------------------------------------------------------- 1 | ofxEasing 2 | -------------------------------------------------------------------------------- /example_plots/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arturoc/ofxEasing/3a15beffb9cfdce26ffafb1f78e06e730b26c239/example_plots/bin/data/.gitkeep -------------------------------------------------------------------------------- /example_plots/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "ofApp.h" 3 | 4 | //======================================================================== 5 | int main( ){ 6 | ofSetupOpenGL(1024,400,OF_WINDOW); // <-------- setup the GL context 7 | 8 | // this kicks off the running of my app 9 | // can be OF_WINDOW or OF_FULLSCREEN 10 | // pass in width and height too: 11 | ofRunApp(new ofApp()); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /example_plots/src/ofApp.cpp: -------------------------------------------------------------------------------- 1 | #include "ofApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void ofApp::setup(){ 5 | ofSetBackgroundColor(255); 6 | ofSetColor(0); 7 | 8 | positions.resize(easings.size()); 9 | 10 | initTime = 0; 11 | endPosition = 90; 12 | 13 | for(size_t i=0;iofGetWidth()){ 62 | x = 40; 63 | y += 200; 64 | } 65 | } 66 | } 67 | 68 | //-------------------------------------------------------------- 69 | void ofApp::keyPressed(int key){ 70 | 71 | } 72 | 73 | //-------------------------------------------------------------- 74 | void ofApp::keyReleased(int key){ 75 | 76 | } 77 | 78 | //-------------------------------------------------------------- 79 | void ofApp::mouseMoved(int x, int y ){ 80 | 81 | } 82 | 83 | //-------------------------------------------------------------- 84 | void ofApp::mouseDragged(int x, int y, int button){ 85 | 86 | } 87 | 88 | //-------------------------------------------------------------- 89 | void ofApp::mousePressed(int x, int y, int button){ 90 | 91 | } 92 | 93 | //-------------------------------------------------------------- 94 | void ofApp::mouseReleased(int x, int y, int button){ 95 | 96 | } 97 | 98 | //-------------------------------------------------------------- 99 | void ofApp::mouseEntered(int x, int y){ 100 | 101 | } 102 | 103 | //-------------------------------------------------------------- 104 | void ofApp::mouseExited(int x, int y){ 105 | 106 | } 107 | 108 | //-------------------------------------------------------------- 109 | void ofApp::windowResized(int w, int h){ 110 | 111 | } 112 | 113 | //-------------------------------------------------------------- 114 | void ofApp::gotMessage(ofMessage msg){ 115 | 116 | } 117 | 118 | //-------------------------------------------------------------- 119 | void ofApp::dragEvent(ofDragInfo dragInfo){ 120 | 121 | } 122 | -------------------------------------------------------------------------------- /example_plots/src/ofApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxEasing.h" 5 | 6 | class ofApp : public ofBaseApp{ 7 | 8 | public: 9 | void setup(); 10 | void update(); 11 | void draw(); 12 | 13 | void keyPressed(int key); 14 | void keyReleased(int key); 15 | void mouseMoved(int x, int y ); 16 | void mouseDragged(int x, int y, int button); 17 | void mousePressed(int x, int y, int button); 18 | void mouseReleased(int x, int y, int button); 19 | void mouseEntered(int x, int y); 20 | void mouseExited(int x, int y); 21 | void windowResized(int w, int h); 22 | void dragEvent(ofDragInfo dragInfo); 23 | void gotMessage(ofMessage msg); 24 | 25 | std::vector easings{ 26 | ofxeasing::linear::easeIn, 27 | ofxeasing::quad::easeIn, 28 | ofxeasing::cubic::easeIn, 29 | ofxeasing::quart::easeIn, 30 | ofxeasing::quint::easeIn, 31 | ofxeasing::circ::easeIn, 32 | ofxeasing::sine::easeIn, 33 | ofxeasing::exp::easeIn, 34 | ofxeasing::elastic::easeOut, 35 | ofxeasing::bounce::easeOut, 36 | ofxeasing::back::easeOut, 37 | }; 38 | 39 | std::vector easingNames{ 40 | "linear", 41 | "quad", 42 | "cubic", 43 | "quart", 44 | "quint", 45 | "circ", 46 | "sine", 47 | "exp", 48 | "elastic", 49 | "bounce", 50 | "back", 51 | }; 52 | 53 | std::vector plots{easings.size()}; 54 | 55 | std::vector positions; 56 | float initTime; 57 | float endPosition; 58 | }; 59 | -------------------------------------------------------------------------------- /src/easing_terms_of_use.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arturoc/ofxEasing/3a15beffb9cfdce26ffafb1f78e06e730b26c239/src/easing_terms_of_use.html -------------------------------------------------------------------------------- /src/ofxEasing.h: -------------------------------------------------------------------------------- 1 | #ifndef EASING_H_ 2 | #define EASING_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #if defined( __WIN32__ ) || defined( _WIN32 ) 8 | #include 9 | #endif 10 | namespace ofxeasing{ 11 | constexpr float pi = 3.14159265358979323846f; 12 | 13 | class back{ 14 | public: 15 | inline static float easeIn_s(float t,float b , float c, float d, float s) { 16 | float postFix = t/=d; 17 | return c*(postFix)*t*((s+1)*t - s) + b; 18 | } 19 | 20 | inline static float easeIn (float t,float b , float c, float d) { 21 | return easeIn_s(t, b, c, d, 1.70158f); 22 | } 23 | 24 | inline static float easeOut_s(float t,float b , float c, float d, float s) { 25 | t=t/d-1; 26 | return c*(t*t*((s+1)*t + s) + 1) + b; 27 | } 28 | 29 | inline static float easeOut(float t,float b , float c, float d) { 30 | return easeOut_s(t, b, c, d, 1.70158f); 31 | } 32 | 33 | inline static float easeInOut_s(float t,float b , float c, float d, float s) { 34 | s*=(1.525f); 35 | if ((t/=d/2) < 1){ 36 | return c/2*(t*t*((s+1)*t - s)) + b; 37 | } 38 | float postFix = t-=2; 39 | return c/2*((postFix)*t*((s+1)*t + s) + 2) + b; 40 | } 41 | 42 | inline static float easeInOut(float t,float b , float c, float d) { 43 | return easeInOut_s(t, b, c, d, 1.70158f); 44 | } 45 | }; 46 | 47 | class bounce{ 48 | public: 49 | inline static float easeIn (float t,float b , float c, float d) { 50 | return c - easeOut (d-t, 0, c, d) + b; 51 | } 52 | 53 | inline static float easeOut(float t,float b , float c, float d) { 54 | if ((t/=d) < (1/2.75f)) { 55 | return c*(7.5625f*t*t) + b; 56 | } else if (t < (2/2.75f)) { 57 | float postFix = t-=(1.5f/2.75f); 58 | return c*(7.5625f*(postFix)*t + .75f) + b; 59 | } else if (t < (2.5/2.75)) { 60 | float postFix = t-=(2.25f/2.75f); 61 | return c*(7.5625f*(postFix)*t + .9375f) + b; 62 | } else { 63 | float postFix = t-=(2.625f/2.75f); 64 | return c*(7.5625f*(postFix)*t + .984375f) + b; 65 | } 66 | } 67 | 68 | inline static float easeInOut(float t,float b , float c, float d) { 69 | if (t < d/2) return easeIn (t*2, 0, c, d) * .5f + b; 70 | else return easeOut (t*2-d, 0, c, d) * .5f + c*.5f + b; 71 | } 72 | }; 73 | 74 | class circ{ 75 | public: 76 | inline static float easeIn (float t,float b , float c, float d) { 77 | return -c * (sqrt(1 - (t/=d)*t) - 1) + b; 78 | } 79 | inline static float easeOut(float t,float b , float c, float d) { 80 | return c * sqrt(1 - (t=t/d-1)*t) + b; 81 | } 82 | 83 | inline static float easeInOut(float t,float b , float c, float d) { 84 | if ((t/=d/2) < 1) return c/2 * (1 - sqrt(1 - t*t)) + b; 85 | return c/2 * (sqrt(1 - (t-=2)*t) + 1) + b; 86 | } 87 | }; 88 | 89 | class cubic{ 90 | public: 91 | 92 | inline static float easeIn (float t,float b , float c, float d) { 93 | return c*(t/=d)*t*t + b; 94 | } 95 | inline static float easeOut(float t,float b , float c, float d) { 96 | return c*((t=t/d-1)*t*t + 1) + b; 97 | } 98 | 99 | inline static float easeInOut(float t,float b , float c, float d) { 100 | if ((t/=d/2) < 1) return c/2*t*t*t + b; 101 | return c/2*((t-=2)*t*t + 2) + b; 102 | } 103 | }; 104 | 105 | class elastic{ 106 | public: 107 | inline static float easeInPow (float t,float b , float c, float d, float power) { 108 | if (t==0) return b; if ((t/=d)==1) return b+c; 109 | float p=d*.3f; 110 | float a=c; 111 | float s=p/4; 112 | float postFix =a*pow(2,power*(t-=1)); // this is a fix, again, with post-increment operators 113 | return -(postFix * sin((t*d-s)*(2*float(pi))/p )) + b; 114 | } 115 | 116 | inline static float easeOutPow(float t,float b , float c, float d, float power) { 117 | if (t==0) return b; if ((t/=d)==1) return b+c; 118 | float p=d*.3f; 119 | float a=c; 120 | float s=p/4; 121 | return (a*pow(2,-power*t) * sin( (t*d-s)*(2*pi)/p ) + c + b); 122 | } 123 | 124 | inline static float easeInOutPow(float t,float b , float c, float d, float power) { 125 | if (t==0) return b; if ((t/=d/2)==2) return b+c; 126 | float p=d*(.3f*1.5f); 127 | float a=c; 128 | float s=p/4; 129 | 130 | if (t < 1) { 131 | float postFix =a*pow(2,power*(t-=1)); // postIncrement is evil 132 | return -.5f*(postFix* sin( (t*d-s)*(2*pi)/p )) + b; 133 | } 134 | float postFix = a*pow(2,-power*(t-=1)); // postIncrement is evil 135 | return postFix * sin( (t*d-s)*(2*pi)/p )*.5f + c + b; 136 | } 137 | 138 | inline static float easeIn (float t,float b , float c, float d) { 139 | return easeInPow(t,b,c,d,10); 140 | } 141 | 142 | inline static float easeOut(float t,float b , float c, float d) { 143 | return easeOutPow(t,b,c,d,10); 144 | } 145 | 146 | inline static float easeInOut(float t,float b , float c, float d) { 147 | return easeInOutPow(t,b,c,d,10); 148 | } 149 | }; 150 | 151 | 152 | class exp{ 153 | public: 154 | inline static float easeIn (float t,float b , float c, float d) { 155 | return (t==0) ? b : c * pow(2, 10 * (t/d - 1)) + b; 156 | } 157 | inline static float easeOut(float t,float b , float c, float d) { 158 | return (t==d) ? b+c : c * (-pow(2, -10 * t/d) + 1) + b; 159 | } 160 | 161 | inline static float easeInOut(float t,float b , float c, float d) { 162 | if (t==0) return b; 163 | if (t==d) return b+c; 164 | if ((t/=d/2) < 1) return c/2 * pow(2, 10 * (t - 1)) + b; 165 | return c/2 * (-pow(2, -10 * --t) + 2) + b; 166 | } 167 | }; 168 | 169 | class linear{ 170 | public: 171 | inline static float easeNone (float t,float b , float c, float d) { 172 | return c*t/d + b; 173 | } 174 | inline static float easeIn (float t,float b , float c, float d) { 175 | return c*t/d + b; 176 | } 177 | inline static float easeOut(float t,float b , float c, float d) { 178 | return c*t/d + b; 179 | } 180 | 181 | inline static float easeInOut(float t,float b , float c, float d) { 182 | return c*t/d + b; 183 | } 184 | }; 185 | 186 | class quad{ 187 | public: 188 | inline static float easeIn (float t,float b , float c, float d) { 189 | return c*(t/=d)*t + b; 190 | } 191 | inline static float easeOut(float t,float b , float c, float d) { 192 | return -c *(t/=d)*(t-2) + b; 193 | } 194 | 195 | inline static float easeInOut(float t,float b , float c, float d) { 196 | if ((t/=d/2) < 1) return c/2*t*t + b; 197 | return -c/2 * ((--t)*(t-2) - 1) + b; 198 | 199 | /* 200 | 201 | originally return -c/2 * (((t-2)*(--t)) - 1) + b; 202 | 203 | I've had to swap (--t)*(t-2) due to diffence in behaviour in 204 | pre-increment operators between java and c++, after hours 205 | of joy 206 | 207 | James George:: The fix refered to above actually broke the equation, 208 | it would land at 50% all the time at the end 209 | copying back the original equation from online fixed it... 210 | 211 | potentially compiler dependent. 212 | */ 213 | 214 | } 215 | }; 216 | 217 | class quart{ 218 | public: 219 | inline static float easeIn (float t,float b , float c, float d) { 220 | return c*(t/=d)*t*t*t + b; 221 | } 222 | inline static float easeOut(float t,float b , float c, float d) { 223 | return -c * ((t=t/d-1)*t*t*t - 1) + b; 224 | } 225 | 226 | inline static float easeInOut(float t,float b , float c, float d) { 227 | if ((t/=d/2) < 1) return c/2*t*t*t*t + b; 228 | return -c/2 * ((t-=2)*t*t*t - 2) + b; 229 | } 230 | }; 231 | 232 | class quint{ 233 | public: 234 | inline static float easeIn (float t,float b , float c, float d) { 235 | return c*(t/=d)*t*t*t*t + b; 236 | } 237 | inline static float easeOut(float t,float b , float c, float d) { 238 | return c*((t=t/d-1)*t*t*t*t + 1) + b; 239 | } 240 | 241 | inline static float easeInOut(float t,float b , float c, float d) { 242 | if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; 243 | return c/2*((t-=2)*t*t*t*t + 2) + b; 244 | } 245 | }; 246 | 247 | class sine{ 248 | public: 249 | inline static float easeIn (float t,float b , float c, float d) { 250 | return -c * cos(t/d * (float(pi)/2)) + c + b; 251 | } 252 | inline static float easeOut(float t,float b , float c, float d) { 253 | return c * sin(t/d * (float(pi)/2)) + b; 254 | } 255 | 256 | inline static float easeInOut(float t,float b , float c, float d) { 257 | return -c/2 * (cos(float(pi)*t/d) - 1) + b; 258 | } 259 | }; 260 | 261 | template 262 | std::function bind(Function f, Args... parameters){ 263 | return std::bind(f, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, parameters...); 264 | } 265 | 266 | inline float map(float v, float minIn, float maxIn, float minOut, float maxOut, std::function easing){ 267 | float t = v - minIn; 268 | float c = maxOut - minOut; 269 | float d = maxIn - minIn; 270 | float b = minOut; 271 | return easing(t,b,c,d); 272 | } 273 | 274 | template 275 | inline float map(float v, float minIn, float maxIn, float minOut, float maxOut, Function easing, Args... parameters){ 276 | return map(v, minIn, maxIn, minOut, maxOut, bind(easing, parameters...)); 277 | } 278 | 279 | inline float map_clamp(float v, float minIn, float maxIn, float minOut, float maxOut, std::function easing){ 280 | v = std::min(std::max(v, minIn), maxIn); 281 | return map(v,minIn,maxIn,minOut,maxOut,easing); 282 | } 283 | 284 | template 285 | inline float map_clamp(float v, float minIn, float maxIn, float minOut, float maxOut, Function easing, Args... parameters){ 286 | return map_clamp(v, minIn, maxIn, minOut, maxOut, bind(easing, parameters...)); 287 | } 288 | 289 | typedef std::function function; 290 | 291 | 292 | enum class Function { 293 | Linear, 294 | Sine, 295 | Circular, 296 | Quadratic, 297 | Cubic, 298 | Quartic, 299 | Quintic, 300 | Exponential, 301 | Back, 302 | Bounce, 303 | Elastic 304 | }; 305 | 306 | enum class Type { 307 | In, 308 | Out, 309 | InOut 310 | }; 311 | 312 | inline function easing(Function f, Type t){ 313 | static std::map, function> index = 314 | { 315 | {std::make_pair(Function::Linear, Type::In), linear::easeIn}, 316 | {std::make_pair(Function::Linear, Type::Out), linear::easeOut}, 317 | {std::make_pair(Function::Linear, Type::InOut), linear::easeInOut}, 318 | 319 | {std::make_pair(Function::Sine, Type::In), sine::easeIn}, 320 | {std::make_pair(Function::Sine, Type::Out), sine::easeOut}, 321 | {std::make_pair(Function::Sine, Type::InOut), sine::easeInOut}, 322 | 323 | {std::make_pair(Function::Circular, Type::In), circ::easeIn}, 324 | {std::make_pair(Function::Circular, Type::Out), circ::easeOut}, 325 | {std::make_pair(Function::Circular, Type::InOut), circ::easeInOut}, 326 | 327 | {std::make_pair(Function::Quadratic, Type::In), quad::easeIn}, 328 | {std::make_pair(Function::Quadratic, Type::Out), quad::easeOut}, 329 | {std::make_pair(Function::Quadratic, Type::InOut), quad::easeInOut}, 330 | 331 | {std::make_pair(Function::Cubic, Type::In), cubic::easeIn}, 332 | {std::make_pair(Function::Cubic, Type::Out), cubic::easeOut}, 333 | {std::make_pair(Function::Cubic, Type::InOut), cubic::easeInOut}, 334 | 335 | {std::make_pair(Function::Quartic, Type::In), quart::easeIn}, 336 | {std::make_pair(Function::Quartic, Type::Out), quart::easeOut}, 337 | {std::make_pair(Function::Quartic, Type::InOut), quart::easeInOut}, 338 | 339 | {std::make_pair(Function::Quintic, Type::In), quint::easeIn}, 340 | {std::make_pair(Function::Quintic, Type::Out), quint::easeOut}, 341 | {std::make_pair(Function::Quintic, Type::InOut), quint::easeInOut}, 342 | 343 | {std::make_pair(Function::Exponential, Type::In), exp::easeIn}, 344 | {std::make_pair(Function::Exponential, Type::Out), exp::easeOut}, 345 | {std::make_pair(Function::Exponential, Type::InOut), exp::easeInOut}, 346 | 347 | {std::make_pair(Function::Back, Type::In), back::easeIn}, 348 | {std::make_pair(Function::Back, Type::Out), back::easeOut}, 349 | {std::make_pair(Function::Back, Type::InOut), back::easeInOut}, 350 | 351 | {std::make_pair(Function::Bounce, Type::In), bounce::easeIn}, 352 | {std::make_pair(Function::Bounce, Type::Out), bounce::easeOut}, 353 | {std::make_pair(Function::Bounce, Type::InOut), bounce::easeInOut}, 354 | 355 | {std::make_pair(Function::Elastic, Type::In), elastic::easeIn}, 356 | {std::make_pair(Function::Elastic, Type::Out), elastic::easeOut}, 357 | {std::make_pair(Function::Elastic, Type::InOut), elastic::easeInOut}, 358 | }; 359 | 360 | return index[std::make_pair(f,t)]; 361 | } 362 | } 363 | 364 | #endif /* EASING_H_ */ 365 | --------------------------------------------------------------------------------