Processingでイージング
少し前に、fladdictさんの乱数にコクを出すという話がネットで盛り上がっていました。
私もかれこれ1年以上、Processingで作品を作ってきましたが、自分の作品のクオリティをもっと上げていくには、こういう細かい動きや配色にこだわっていかないのかなーと思っています。
そうぼんやりと思っているときに、jQueryを使う機会があり、アニメーションの動き方を設定するイージングというものを知りました。
Processingでも、今までだったらオブジェクトを線形に動かしていたところを、イージングで動きに変化をつけると面白いのではないかと思い、とりあえずProcessingに上の早見表に載っている30のイージングを移植してみました。
/* * easing test */ float startX = 150; float endX = 480; int duration = 200; float margin = 30; float ellipseSize = 20; void setup(){ size(1000, 480); } void draw(){ background(255); fill(60); stroke(60); text("1. easeInSine", 20, margin * 1); text("2. easeOutSine", 20, margin * 2); text("3. easeInOutSine", 20, margin * 3); text("4. easeInQuad", 20, margin * 4); text("5. easeOutQuad", 20, margin * 5); text("6. easeInOutQuad", 20, margin * 6); text("7. easeInCubic", 20, margin * 7); text("8. easeOutCubic", 20, margin * 8); text("9. easeInOutCubic", 20, margin * 9); text("10. easeinQuart", 20, margin * 10); text("11. easeOutQuart", 20, margin * 11); text("12. easeInOutQuart", 20, margin * 12); text("13. easeinQuint", 20, margin * 13); text("14. iaseOutQuint", 20, margin * 14); text("15. easeInOutQuint", 20, margin * 15); line(startX, 0, startX, height); line(endX, 0, endX, height); fill(128, 0, 0); noStroke(); ellipse(easeInSine(frameCount % duration, startX, endX - startX, duration), margin * 1, ellipseSize, ellipseSize); ellipse(easeOutSine(frameCount % duration, startX, endX - startX, duration), margin * 2, ellipseSize, ellipseSize); ellipse(easeInOutSine(frameCount % duration, startX, endX - startX, duration), margin * 3, ellipseSize, ellipseSize); ellipse(easeInQuad(frameCount % duration, startX, endX - startX, duration), margin * 4, ellipseSize, ellipseSize); ellipse(easeOutQuad(frameCount % duration, startX, endX - startX, duration), margin * 5, ellipseSize, ellipseSize); ellipse(easeInOutQuad(frameCount % duration, startX, endX - startX, duration), margin * 6, ellipseSize, ellipseSize); ellipse(easeInCubic(frameCount % duration, startX, endX - startX, duration), margin * 7, ellipseSize, ellipseSize); ellipse(easeOutCubic(frameCount % duration, startX, endX - startX, duration), margin * 8, ellipseSize, ellipseSize); ellipse(easeInOutCubic(frameCount % duration, startX, endX - startX, duration), margin * 9, ellipseSize, ellipseSize); ellipse(easeInQuart(frameCount % duration, startX, endX - startX, duration), margin * 10, ellipseSize, ellipseSize); ellipse(easeOutQuart(frameCount % duration, startX, endX - startX, duration), margin * 11, ellipseSize, ellipseSize); ellipse(easeInOutQuart(frameCount % duration, startX, endX - startX, duration), margin * 12, ellipseSize, ellipseSize); ellipse(easeInQuint(frameCount % duration, startX, endX - startX, duration), margin * 13, ellipseSize, ellipseSize); ellipse(easeOutQuint(frameCount % duration, startX, endX - startX, duration), margin * 14, ellipseSize, ellipseSize); ellipse(easeInOutQuint(frameCount % duration, startX, endX - startX, duration), margin * 15, ellipseSize, ellipseSize); translate(width / 2, 0); fill(60); stroke(60); text("16. easeInExpo", 20, margin * 1); text("17. easeOutExpo", 20, margin * 2); text("18. easeInOutExpo", 20, margin * 3); text("19. easeinCirc", 20, margin * 4); text("20. easeOutCirc", 20, margin * 5); text("21. easeInOutCirc", 20, margin * 6); text("22. easeInBack", 20, margin * 7); text("23. easeOutBack", 20, margin * 8); text("24. easeInOutBack", 20, margin * 9); text("25. easeInElastic", 20, margin * 10); text("26. easeOutElastic", 20, margin * 11); text("27. easeInOutElastic", 20, margin * 12); text("28. easeInBounce", 20, margin * 13); text("29. easeOutBounce", 20, margin * 14); text("30. easeInOutBounce", 20, margin * 15); line(startX, 0, startX, height); line(endX, 0, endX, height); fill(128, 0, 0); noStroke(); ellipse(easeInExpo(frameCount % duration, startX, endX - startX, duration), margin * 1, ellipseSize, ellipseSize); ellipse(easeOutExpo(frameCount % duration, startX, endX - startX, duration), margin * 2, ellipseSize, ellipseSize); ellipse(easeInOutExpo(frameCount % duration, startX, endX - startX, duration), margin * 3, ellipseSize, ellipseSize); ellipse(easeInCirc(frameCount % duration, startX, endX - startX, duration), margin * 4, ellipseSize, ellipseSize); ellipse(easeOutCirc(frameCount % duration, startX, endX - startX, duration), margin * 5, ellipseSize, ellipseSize); ellipse(easeInOutCirc(frameCount % duration, startX, endX - startX, duration), margin * 6, ellipseSize, ellipseSize); ellipse(easeInBack(frameCount % duration, startX, endX - startX, duration, 1.0), margin * 7, ellipseSize, ellipseSize); ellipse(easeOutBack(frameCount % duration, startX, endX - startX, duration, 1.0), margin * 8, ellipseSize, ellipseSize); ellipse(easeInOutBack(frameCount % duration, startX, endX - startX, duration, 1.0), margin * 9, ellipseSize, ellipseSize); ellipse(easeInElastic(frameCount % duration, startX, endX - startX, duration), margin * 10, ellipseSize, ellipseSize); ellipse(easeOutElastic(frameCount % duration, startX, endX - startX, duration), margin * 11, ellipseSize, ellipseSize); ellipse(easeInOutElastic(frameCount % duration, startX, endX - startX, duration), margin * 12, ellipseSize, ellipseSize); ellipse(easeInBounce(frameCount % duration, startX, endX - startX, duration), margin * 13, ellipseSize, ellipseSize); ellipse(easeOutBounce(frameCount % duration, startX, endX - startX, duration), margin * 14, ellipseSize, ellipseSize); ellipse(easeInOutBounce(frameCount % duration, startX, endX - startX, duration), margin * 15, ellipseSize, ellipseSize); } float easeInSine(float t, float b, float c, float d){ return -c * cos(t / d * (PI / 2)) + c + b; } float easeOutSine(float t, float b, float c, float d){ return c * sin(t / d * (PI / 2)) + b; } float easeInOutSine(float t, float b, float c, float d){ return -c / 2 * (cos(PI * t / d) - 1) + b; } float easeInQuad(float t, float b, float c, float d){ t /= d; return c * t * t + b; } float easeOutQuad(float t, float b, float c, float d){ t /= d; return -c * t * (t - 2) + b; } float easeInOutQuad(float t, float b, float c, float d){ t /= d / 2; if(t < 1) return c / 2 * t * t + b; t--; return -c / 2 * (t * (t - 2) - 1) + b; } float easeInCubic(float t, float b, float c, float d){ t /= d; return c * t * t * t + b; } float easeOutCubic(float t, float b, float c, float d){ t /= d; t--; return c * (t * t * t + 1) + b; } float easeInOutCubic(float t, float b, float c, float d){ t /= d / 2; if(t < 1) return c / 2 * t * t * t + b; t -= 2; return c / 2 * (t * t * t + 2) + b; } float easeInQuart(float t, float b, float c, float d){ t /= d; return c * t * t * t * t + b; } float easeOutQuart(float t, float b, float c, float d){ t /= d; t--; return -c * (t * t * t * t - 1) + b; } float easeInOutQuart(float t, float b, float c, float d){ t /= d / 2; if(t < 1) return c / 2 * t * t * t * t + b; t -= 2; return -c / 2 * (t * t * t * t - 2) + b; } float easeInQuint(float t, float b, float c, float d){ t /= d; return c * t * t * t * t * t + b; } float easeOutQuint(float t, float b, float c, float d){ t /= d; t--; return c * (t * t * t * t * t + 1) + b; } float easeInOutQuint(float t, float b, float c, float d){ t /= d / 2; if(t < 1) return c / 2 * t * t * t * t * t + b; t -= 2; return c / 2 * (t * t * t * t * t + 2) + b; } float easeInExpo(float t, float b, float c, float d){ return t == 0 ? b: c * pow(2, 10 * (t / d - 1)) + b; } float easeOutExpo(float t, float b, float c, float d){ return t == d ? b + c: c * (-pow(2, -10 * t / d) + 1) + b; } float easeInOutExpo(float t, float b, float c, float d){ if(t == 0) return b; if(t == d) return b + c; t /= d / 2; if(t < 1) return c / 2 * pow(2, 10 * (t - 1)) + b; t--; return c / 2 * (-pow(2, -10 * t) + 2) + b; } float easeInCirc(float t, float b, float c, float d){ t /= d; return -c * (sqrt(1 - t * t) - 1) + b; } float easeOutCirc(float t, float b, float c, float d){ t /= d; t--; return c * sqrt(1 - t * t) + b; } float easeInOutCirc(float t, float b, float c, float d){ t /= d / 2; if(t < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b; t -= 2; return c / 2 * (sqrt(1 - t * t) + 1) + b; } float easeInBack(float t, float b, float c, float d, float s){ t /= d; return c * t * t * ((s + 1) * t - s) + b; } float easeOutBack(float t, float b, float c, float d, float s){ t /= d; t--; return c * (t * t * ((s + 1) * t + s) + 1) + b; } float easeInOutBack(float t, float b, float c, float d, float s){ t /= d / 2; s *= 1.525; if(t < 1) return c / 2 * (t * t * ((s + 1) * t - s)) + b; t -= 2; return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b; } float easeInElastic(float t, float b, float c, float d){ float s = 1.70158; float a = c; if(t == 0) return b; t /= d; if(t == 1) return b + c; float p = d * 0.3; if(a < abs(c)){ a = c; s = p / 4; } else { s = p / (2 * PI) * asin(c / a); } t--; return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * PI) / p)) + b; } float easeOutElastic(float t, float b, float c, float d){ float s = 1.70158; float a = c; if(t == 0) return b; t /= d; if(t == 1) return b + c; float p = d * 0.3; if(a < abs(c)){ a = c; s = p / 4; } else { s = p / (2 * PI) * asin(c / a); } return a * pow(2, -10 * t) * sin((t * d - s) * (2 * PI) / p) + c + b; } float easeInOutElastic(float t, float b, float c, float d){ float s = 1.70158; float a = c; if(t == 0) return b; t /= d / 2; if(t == 2) return b + c; float p = d * (0.3 * 1.5); if(a < abs(c)){ a = c; s = p / 4; } else { s = p / (2 * PI) * asin(c / a); } if(t < 1){ t--; return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * PI) / p)) + b; } t--; return a * pow(2, -10 * t) * sin((t * d - s) * (2 * PI) / p) * 0.5 + c + b; } float easeInBounce(float t, float b, float c, float d){ return c - easeOutBounce(d - t, 0, c, d) + b; } float easeOutBounce(float t, float b, float c, float d){ t /= d; if(t < 1.0 / 2.75){ return c * (7.5265 * t * t) + b; } else if(t < 2.0 / 2.75){ t -= 1.5 / 2.75; return c * (7.5265 * t * t + 0.75) + b; } else if(t < 2.5 / 2.75){ t -= 2.25 / 2.75; return c * (7.5265 * t * t + 0.9375) + b; }else{ t -= 2.625 / 2.75; return c * (7.5265 * t * t + 0.984375) + b; } } float easeInOutBounce(float t, float b, float c, float d){ if(t < d / 2) return easeInBounce(t * 2, 0, c, d) * 0.5 + b; return easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; }
イージングを使うと、動きがこんな感じになります。