1 /++ 2 Module for animation of movement / frames and others. Contains a mutating 3 variable and a function that depends on it. 4 5 See_Also: 6 $(HREF https://github.com/ai/easings.net, Easing open source) 7 8 Macros: 9 LREF = <a href="#$1">$1</a> 10 HREF = <a href="$1">$2</a> 11 PHOBREF = <a href="https://dlang.org/phobos/$1.html#$2">$2</a> 12 13 Authors: $(HREF https://github.com/TodNaz,TodNaz) 14 Copyright: Copyright (c) 2020 - 2021, TodNaz. 15 License: $(HREF https://github.com/TodNaz/Tida/blob/master/LICENSE,MIT) 16 +/ 17 module tida.animobj; 18 19 /++ 20 Object animation interface. 21 +/ 22 interface IAnimated 23 { 24 @safe: 25 /++ 26 Object animation function. Through such a call and a coefficient argument, 27 an animation is produced. 28 29 Params: 30 k = Animation step. Its range is from zero to one. 31 +/ 32 void animation(float k); 33 } 34 35 /// Ease in sine animation 36 void easeInSine(ref float step, const(float) k) @safe nothrow pure 37 { 38 import std.math : cos, PI; 39 40 step = 1 - cos((k * PI) / 2); 41 } 42 43 /// Ease out sine animation 44 void easeOutSine(ref float step, const(float) k) @safe nothrow pure 45 { 46 import std.math : sin, PI; 47 48 step = sin((k * PI) / 2); 49 } 50 51 /// Ease in out sine animation 52 void easeInOutSine(ref float step, const(float) k) @safe nothrow pure 53 { 54 import std.math : cos, PI; 55 56 step = -(cos(PI * k) - 1) / 2; 57 } 58 59 /// Ease in degree animation 60 void easeIn(int degree)(ref float step, const(float) k) @safe nothrow pure 61 { 62 import std.math : pow; 63 64 step = pow(k, degree); 65 } 66 67 /// Ease out degree animation 68 void easeOut(int degree)(ref float step, const(float) k) @safe nothrow pure 69 { 70 import std.math : pow; 71 72 step = 1 - pow((1 - k), degree); 73 } 74 75 /// Ease in out degree animation 76 void easeInOut(int degree)(ref float step, const(float) k) @safe nothrow pure 77 { 78 import std.math : pow; 79 80 step = k < 0.5f ? (2 * degree) * pow(k, degree) : 1 - pow(-2 * k + 2, degree) / 2; 81 } 82 83 /// Ease in expo animation 84 void easeInExpo(ref float step, const(float) k) @safe nothrow pure 85 { 86 import std.math : pow; 87 88 step = k == 0 ? 0 : pow(2, 10 * k - 10); 89 } 90 91 /// Ease out expo animation 92 void easeOutExpo(ref float step, const(float) k) @safe nothrow pure 93 { 94 import std.math : pow; 95 96 step = k == 1 ? 1 : 1 - pow(2, -10 * k); 97 } 98 99 /// Ease in out expo 100 void easeInOutExpo(ref float step, const(float) k) @safe nothrow pure 101 { 102 import std.math : sqrt, pow; 103 104 step = k == 0 105 ? 0 106 : k == 1 107 ? 1 108 : k < 0.5f ? pow(2, 20 * k - 10) / 2 109 : (2 - pow(2, -20 * k + 10)) / 2; 110 } 111 112 /// Ease in circ animation 113 void easeInCirc(ref float step, const(float) k) @safe nothrow pure 114 { 115 import std.math : sqrt, pow; 116 117 step = 1 - sqrt(1 - pow(k, 2)); 118 } 119 120 /// Ease out circ animation 121 void easeOutCirc(ref float step, const(float) k) @safe nothrow pure 122 { 123 import std.math : sqrt, pow; 124 125 step = sqrt(1 - pow(k - 1, 2)); 126 } 127 128 /// Ease in out circ animation 129 void easeInOutCirc(ref float step, const(float) k) @safe nothrow pure 130 { 131 import std.math : pow, sqrt; 132 133 step = k < 0.5f 134 ? (1 - sqrt(1 - pow(2 * k, 2))) / 2 135 : (sqrt(1 - pow(-2 * k + 2, 2)) + 1) / 2; 136 } 137 138 /// Ease in back animation 139 void easeInBack(ref float step, const(float) k) @safe nothrow pure 140 { 141 immutable c1 = 1.70158f; 142 immutable c3 = c1 + 1.0f; 143 144 step = c3 * k * k * k - c1 * k * k; 145 } 146 147 /// Ease out back animation 148 void easeOutBack(ref float step, const(float) k) @safe nothrow pure 149 { 150 import std.math : pow; 151 152 immutable c1 = 1.70158f; 153 immutable c3 = c1 + 1.0f; 154 155 step = 1 + c3 * pow(k - 1, 3) + c1 * pow(k - 1, 2); 156 } 157 158 /// Ease in out animation 159 void easeInOutBack(ref float step, const(float) k) @safe nothrow pure 160 { 161 import std.math : pow; 162 163 immutable c1 = 1.70158f; 164 immutable c2 = c1 * 1.525; 165 166 step = k < 0.5f 167 ? (pow(2 * k, 2) * ((c2 + 1) * 2 * k - c2)) / 2 168 : (pow(2 * k - 2, 2) * ((c2 + 1) * (k * 2 - 2) + c2) + 2) / 2; 169 } 170 171 /++ 172 An object of smooth movement of an object along a function in a template. 173 174 The function should contain the parameters of the motion step and the animation 175 step, for example: 176 --- 177 void moveFunction(ref float step, const float k) @safe nothrow pure; 178 --- 179 +/ 180 class MoveAnimation(alias moveFunction) : IAnimated 181 { 182 import tida.vector; 183 184 private: 185 Vecf* vector; 186 Vecf begin; 187 188 public: 189 float distance; 190 Vecf direction; 191 192 /++ 193 Animation constructor. 194 195 Params: 196 vec = The position to move smoothly. 197 +/ 198 this(ref Vecf vec) @trusted 199 { 200 vector = &vec; 201 begin = vec; 202 } 203 204 override @safe: 205 void animation(float k) 206 { 207 float step = 0.0f; 208 moveFunction(step, k); 209 210 *vector = begin + (direction * (distance * step)); 211 } 212 } 213 214 /++ 215 Animation object. Animates an object. 216 +/ 217 class Animator 218 { 219 private: 220 float k = 0.0f; 221 222 public: 223 /// Speed animation. 224 float speed = 0.01f; 225 226 @safe: 227 void reset() @safe 228 { 229 k = 0.0f; 230 } 231 232 /++ 233 Object animation function. The input object receives an animation step from 234 which it can play any animation. 235 236 Params: 237 anim = Animation object. 238 +/ 239 void step(IAnimated anim) 240 { 241 if (k > 1.0f) 242 return; 243 244 k += speed; 245 246 anim.animation(k); 247 } 248 249 /// ditto 250 void stepArray(IAnimated[] anim) 251 { 252 if (k > 1.0f) 253 return; 254 255 k += speed; 256 257 foreach(a; anim) 258 a.animation(k); 259 } 260 }