├── README.md ├── .gitignore └── easing.go /README.md: -------------------------------------------------------------------------------- 1 | go-easing 2 | ========= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | out 9 | gen### Go template 10 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 11 | *.o 12 | *.a 13 | *.so 14 | 15 | # Folders 16 | _obj 17 | _test 18 | 19 | # Architecture specific extensions/prefixes 20 | *.[568vq] 21 | [568vq].out 22 | 23 | *.cgo1.go 24 | *.cgo2.c 25 | _cgo_defun.c 26 | _cgo_gotypes.go 27 | _cgo_export.* 28 | 29 | _testmain.go 30 | 31 | *.exe 32 | *.test 33 | *.prof 34 | 35 | -------------------------------------------------------------------------------- /easing.go: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by nazarigonzalez on 11/10/16. 3 | */ 4 | 5 | package easing 6 | 7 | import "math" 8 | 9 | type Easing func(t float64) float64 10 | 11 | const pid2 float64 = math.Pi / 2 12 | const pi2 float64 = math.Pi * 2 13 | 14 | func Interpolate(from, to, totalTime, elapsedTime float64, easing Easing) float64 { 15 | return from + ((to - from) * easing(elapsedTime/totalTime)) 16 | } 17 | 18 | func Linear() Easing { 19 | return func(t float64) float64 { 20 | return t 21 | } 22 | } 23 | 24 | func InQuad() Easing { 25 | return func(t float64) float64 { 26 | return t * t 27 | } 28 | } 29 | 30 | func OutQuad() Easing { 31 | return func(t float64) float64 { 32 | return t * (2 - t) 33 | } 34 | } 35 | 36 | func InOutQuad() Easing { 37 | return func(t float64) float64 { 38 | t *= 2 39 | 40 | if t < 1 { 41 | return 0.5 * t * t 42 | } 43 | 44 | t-- 45 | return -0.5 * (t*(t-2) - 1) 46 | } 47 | } 48 | 49 | func InCubic() Easing { 50 | return func(t float64) float64 { 51 | return t * t * t 52 | } 53 | } 54 | 55 | func OutCubic() Easing { 56 | return func(t float64) float64 { 57 | t-- 58 | return t*t*t + 1 59 | } 60 | } 61 | 62 | func InOutCubic() Easing { 63 | return func(t float64) float64 { 64 | t *= 2 65 | 66 | if t < 1 { 67 | return 0.5 * t * t * t 68 | } 69 | 70 | t -= 2 71 | return 0.5 * (t*t*t + 2) 72 | } 73 | } 74 | 75 | func InQuart() Easing { 76 | return func(t float64) float64 { 77 | return t * t * t * t 78 | } 79 | } 80 | 81 | func OutQuart() Easing { 82 | return func(t float64) float64 { 83 | t-- 84 | 85 | return 1 - t*t*t*t 86 | } 87 | } 88 | 89 | func InOutQuart() Easing { 90 | return func(t float64) float64 { 91 | t *= 2 92 | 93 | if t < 1 { 94 | return 0.5 * t * t * t * t 95 | } 96 | 97 | t -= 2 98 | return 0.5 * (t*t*t*t - 2) 99 | } 100 | } 101 | 102 | func InQuint() Easing { 103 | return func(t float64) float64 { 104 | return t * t * t * t * t 105 | } 106 | } 107 | 108 | func OutQuint() Easing { 109 | return func(t float64) float64 { 110 | t-- 111 | return t*t*t*t*t + 1 112 | } 113 | } 114 | 115 | func InOutQuint() Easing { 116 | return func(t float64) float64 { 117 | t *= 2 118 | 119 | if t < 1 { 120 | return 0.5 * t * t * t * t * t 121 | } 122 | 123 | t -= 2 124 | return 0.5 * (t*t*t*t*t + 2) 125 | } 126 | } 127 | 128 | func InSine() Easing { 129 | return func(t float64) float64 { 130 | return 1 - math.Cos(t*pid2) 131 | } 132 | } 133 | 134 | func OutSine() Easing { 135 | return func(t float64) float64 { 136 | return math.Sin(t * pid2) 137 | } 138 | } 139 | 140 | func InOutSine() Easing { 141 | return func(t float64) float64 { 142 | return 0.5 * (1 - math.Cos(math.Pi*t)) 143 | } 144 | } 145 | 146 | func InExpo() Easing { 147 | return func(t float64) float64 { 148 | if t == 0 { 149 | return 0 150 | } 151 | 152 | return math.Pow(1024, t-1) 153 | } 154 | } 155 | 156 | func OutExpo() Easing { 157 | return func(t float64) float64 { 158 | if t == 1 { 159 | return 1 160 | } 161 | 162 | return 1 - math.Pow(2, -10*t) 163 | } 164 | } 165 | 166 | func InOutExpo() Easing { 167 | return func(t float64) float64 { 168 | if t == 0 { 169 | return 0 170 | } else if t == 1 { 171 | return 1 172 | } 173 | 174 | t *= 2 175 | 176 | if t < 1 { 177 | return 0.5 * (math.Pow(1024, t-1)) 178 | } 179 | 180 | return 0.5 * (-math.Pow(2, -10*(t-1)) + 2) 181 | } 182 | } 183 | 184 | func InCirc() Easing { 185 | return func(t float64) float64 { 186 | return 1 - math.Sqrt(1-t*t) 187 | } 188 | } 189 | 190 | func OutCirc() Easing { 191 | return func(t float64) float64 { 192 | t-- 193 | return math.Sqrt(1 - (t * t)) 194 | } 195 | } 196 | 197 | func InOutCirc() Easing { 198 | return func(t float64) float64 { 199 | t *= 2 200 | 201 | if t < 1 { 202 | return -0.5 * (math.Sqrt(1-t*t) - 1) 203 | } 204 | 205 | return 0.5 * (math.Sqrt(1-(t-2)*(t-2)) + 1) 206 | } 207 | } 208 | 209 | func InElastic() Easing { 210 | return calculateInElastic(0.1, 0.4) 211 | } 212 | 213 | func InElasticCustom(a, p float64) Easing { 214 | return calculateInElastic(a, p) 215 | } 216 | 217 | func calculateInElastic(a, p float64) Easing { 218 | return func(t float64) float64 { 219 | if t == 0 { 220 | return 0 221 | } 222 | 223 | if t == 1 { 224 | return 1 225 | } 226 | 227 | s := 0.0 228 | 229 | if a < 1 { 230 | a = 1 231 | s = p / 4 232 | } else { 233 | s = p * math.Asin(1/a) / pi2 234 | } 235 | 236 | return (a * math.Pow(2, 10*(t-1)) * math.Sin(((t-1)-s)*pi2/p)) 237 | } 238 | } 239 | 240 | func OutElastic() Easing { 241 | return calculateOutElastic(0.1, 0.4) 242 | } 243 | 244 | func OutElasticCustom(a, p float64) Easing { 245 | return calculateOutElastic(a, p) 246 | } 247 | 248 | func calculateOutElastic(a, p float64) Easing { 249 | return func(t float64) float64 { 250 | if t == 0 { 251 | return 0 252 | } 253 | 254 | if t == 1 { 255 | return 1 256 | } 257 | 258 | s := 0.0 259 | 260 | if a < 1 { 261 | a = 1 262 | s = p / 4 263 | } else { 264 | s = p * math.Asin(1/a) / pi2 265 | } 266 | 267 | return (a*math.Pow(2, -10*t)*math.Sin((t-s)*pi2/p) + 1) 268 | } 269 | } 270 | 271 | func InOutElastic() Easing { 272 | return calculateInOutElastic(0.1, 0.4) 273 | } 274 | 275 | func InOutElasticCustom(a, p float64) Easing { 276 | return calculateInOutElastic(a, p) 277 | } 278 | 279 | func calculateInOutElastic(a, p float64) Easing { 280 | return func(t float64) float64 { 281 | if t == 0 { 282 | return 0 283 | } 284 | 285 | if t == 1 { 286 | return 1 287 | } 288 | 289 | s := 0.0 290 | 291 | if a < 1 { 292 | a = 1 293 | s = p / 4 294 | } else { 295 | s = p * math.Asin(1/a) / pi2 296 | } 297 | 298 | t *= 2 299 | 300 | if t < 1 { 301 | return -0.5 * (a * math.Pow(2, 10*(t-1)) * math.Sin(((t-1)-s)*pi2/p)) 302 | } 303 | 304 | return a*math.Pow(2, -10*(t-1))*math.Sin(((t-1)-s)*pi2/p)*0.5 + 1 305 | } 306 | } 307 | 308 | func InBack() Easing { 309 | return calculateInBack(1.70158) 310 | } 311 | 312 | func InBackCustom(v float64) Easing { 313 | return calculateInBack(v) 314 | } 315 | 316 | func calculateInBack(v float64) Easing { 317 | return func(t float64) float64 { 318 | return t * t * ((v+1)*t - v) 319 | } 320 | } 321 | 322 | func OutBack() Easing { 323 | return calculateOutBack(1.70158) 324 | } 325 | 326 | func OutBackCustom(v float64) Easing { 327 | return calculateOutBack(v) 328 | } 329 | 330 | func calculateOutBack(v float64) Easing { 331 | return func(t float64) float64 { 332 | t-- 333 | return t*t*((v+1)*t+v) + 1 334 | } 335 | } 336 | 337 | func InOutBack() Easing { 338 | return calculateInOutBack(1.70158) 339 | } 340 | 341 | func InOutBackCustom(v float64) Easing { 342 | return calculateInOutBack(v) 343 | } 344 | 345 | func calculateInOutBack(v float64) Easing { 346 | return func(t float64) float64 { 347 | v *= 1.525 348 | t *= 2 349 | 350 | if t < 1 { 351 | return 0.5 * (t * t * ((v+1)*t - v)) 352 | } 353 | 354 | return t*t*((v+1)*t+v) + 1 355 | } 356 | } 357 | 358 | //todo fix bounce ease 359 | 360 | func OutBounce() Easing { 361 | return func(t float64) float64 { 362 | if t < 1/2.75 { 363 | return 7.5625 * t * t 364 | } else if t < 2/2.75 { 365 | t -= 1.5 / 2.75 366 | return 7.5625*t*t + 0.75 367 | } else if t < 2.5/2.75 { 368 | t -= 2.25 / 2.75 369 | return 7.5625*t*t + 0.9375 370 | } 371 | 372 | t -= 2.625 / 2.75 373 | return 7.5625 * t * t * 0.984375 374 | } 375 | } 376 | 377 | //allocate here to avoid call each time 378 | var internalOutBounce Easing = OutBounce() 379 | 380 | func InBounce() Easing { 381 | return func(t float64) float64 { 382 | return 1 - internalOutBounce(1-t) 383 | } 384 | } 385 | 386 | var internalInBounce Easing = InBounce() 387 | 388 | func InOutBounce() Easing { 389 | return func(t float64) float64 { 390 | if t < 0.5 { 391 | return internalInBounce(t*2) * 0.5 392 | } 393 | 394 | return internalOutBounce(t*2-1)*0.5 + 0.5 395 | } 396 | } 397 | --------------------------------------------------------------------------------