# HG changeset patch # User Steve Losh # Date 1467384103 0 # Node ID a5c7bfeb34c33879b811cf7f5618a13552cf788e # Parent 82a47826346dc868f2c9bc80703763f63dd129bc Episode 31: Tweening Part 3 diff -r 82a47826346d -r a5c7bfeb34c3 .lispwords --- a/.lispwords Thu Jun 30 13:17:09 2016 +0000 +++ b/.lispwords Fri Jul 01 14:41:43 2016 +0000 @@ -7,3 +7,4 @@ (2 with-cga) (1 with-elapsed) (1 tween-places!) +(1 with-normalized-time) diff -r 82a47826346d -r a5c7bfeb34c3 easing-functions.gcx Binary file easing-functions.gcx has changed diff -r 82a47826346d -r a5c7bfeb34c3 package.lisp --- a/package.lisp Thu Jun 30 13:17:09 2016 +0000 +++ b/package.lisp Fri Jul 01 14:41:43 2016 +0000 @@ -70,6 +70,15 @@ #:tween-quadratic-in #:tween-quadratic-out #:tween-quadratic-inout + #:tween-cubic-in + #:tween-cubic-out + #:tween-cubic-inout + #:tween-quartic-in + #:tween-quartic-out + #:tween-quartic-inout + #:tween-quintic-in + #:tween-quintic-out + #:tween-quintic-inout #:tween-place! #:tween-places! #:update-tweens! diff -r 82a47826346d -r a5c7bfeb34c3 src/2d/demo.lisp --- a/src/2d/demo.lisp Thu Jun 30 13:17:09 2016 +0000 +++ b/src/2d/demo.lisp Fri Jul 01 14:41:43 2016 +0000 @@ -48,6 +48,17 @@ (outsidep (- 0 r) (+ *height* r) (vec-y p)))) +(defmacro map-static (function-symbol &rest arguments) + `(progn + ,@(loop :for arg :in arguments :collect `(,function-symbol ,arg)))) + +(defun graph-tween (tweening-function) + (graph-function (curry tweening-function 0.0 1.0 1.0) + :fn-start 0.0 :fn-end 1.0 + :fn-min 0.0 :fn-max 1.0 + :graph-start 0 :graph-end *width* + :graph-min *height* :graph-max 0)) + (defsketch cm ((width *width*) (height *height*) (y-axis :down) (title "Coding Math 2D") (mouse (make-vec 0 0)) @@ -56,11 +67,35 @@ ;; Pens (particle-pen (make-pen :fill (gray 0.9) :stroke (gray 0.4))) (line-pen (make-pen :curve-steps 40 :stroke (gray 0.7))) + (black-function-pen (make-pen :curve-steps 20 :stroke (rgb 0 0 0) :weight 1)) + (red-function-pen (make-pen :curve-steps 40 :stroke (rgb 0.8 0 0) :weight 1)) + (green-function-pen (make-pen :curve-steps 40 :stroke (rgb 0 0.8 0) :weight 1)) + (blue-function-pen (make-pen :curve-steps 40 :stroke (rgb 0 0 0.8) :weight 1)) ) (with-setup ;; (in-context (draw-axes *width* *height*) + (with-pen black-function-pen + (graph-tween #'tween-linear)) + (with-pen red-function-pen + (map-static graph-tween + #'tween-quadratic-in + #'tween-cubic-in + #'tween-quartic-in + #'tween-quintic-in)) + (with-pen green-function-pen + (map-static graph-tween + #'tween-quadratic-out + #'tween-cubic-out + #'tween-quartic-out + #'tween-quintic-out)) + (with-pen blue-function-pen + (map-static graph-tween + #'tween-quadratic-inout + #'tween-cubic-inout + #'tween-quartic-inout + #'tween-quintic-inout)) (update-tweens!) (with-pen particle-pen (draw-circle current))) @@ -86,15 +121,8 @@ (declare (ignorable instance x y)) (with-slots (current) instance (tween-places! - (#'tween-quadratic-out 2.0 - :callback-progress #'draw-time - :callback-finished - (let ((x (vec-x current)) - (y (vec-y current))) - (lambda () - (tween-places! (#'tween-quadratic-in 2.0) - (vec-x current) x - (vec-y current) y)))) + (#'tween-quadratic-inout 10.0 + :callback-progress #'draw-time) (vec-x current) x (vec-y current) y))) diff -r 82a47826346d -r a5c7bfeb34c3 src/tween.lisp --- a/src/tween.lisp Thu Jun 30 13:17:09 2016 +0000 +++ b/src/tween.lisp Fri Jul 01 14:41:43 2016 +0000 @@ -65,14 +65,72 @@ ;;;; Tweening Functions +(defmacro with-normalized-time ((time-symbol duration-form) &body body) + `(let ((,time-symbol (/ ,time-symbol ,duration-form))) + ,@body)) + +(defmacro tween-inout% (start amount duration time in out) + (once-only (start amount duration) + (with-gensyms (half) + `(with-normalized-time (,time (/ ,duration 2.0)) + (let ((,half (/ ,amount 2.0))) + (if (< ,time 1.0) + (,in ,start ,half 1.0 ,time) + (,out (+ ,start ,half) ,half 1.0 (1- ,time)))))))) + (defun tween-linear (start amount duration time) - (let ((time (/ time duration))) + (with-normalized-time (time duration) (+ start (* amount time)))) + (defun tween-quadratic-in (start amount duration time) - (let ((time (/ time duration))) + (with-normalized-time (time duration) (+ start (* amount (* time time))))) (defun tween-quadratic-out (start amount duration time) - (let ((time (/ time duration))) + (with-normalized-time (time duration) (+ start (* (- amount) (* time (- time 2)))))) + +(defun tween-quadratic-inout (start amount duration time) + (tween-inout% start amount duration time + tween-quadratic-in tween-quadratic-out)) + + +(defun tween-cubic-in (start amount duration time) + (with-normalized-time (time duration) + (+ start (* amount (expt time 3))))) + +(defun tween-cubic-out (start amount duration time) + (with-normalized-time (time duration) + (+ start (* amount (1+ (expt (1- time) 3)))))) + +(defun tween-cubic-inout (start amount duration time) + (tween-inout% start amount duration time + tween-cubic-in tween-cubic-out)) + + +(defun tween-quartic-in (start amount duration time) + (with-normalized-time (time duration) + (+ start (* amount (expt time 4))))) + +(defun tween-quartic-out (start amount duration time) + (with-normalized-time (time duration) + (+ start (* (- amount) (1- (expt (1- time) 4)))))) + +(defun tween-quartic-inout (start amount duration time) + (tween-inout% start amount duration time + tween-quartic-in tween-quartic-out)) + + +(defun tween-quintic-in (start amount duration time) + (with-normalized-time (time duration) + (+ start (* amount (expt time 5))))) + +(defun tween-quintic-out (start amount duration time) + (with-normalized-time (time duration) + (+ start (* amount (1+ (expt (1- time) 5)))))) + +(defun tween-quintic-inout (start amount duration time) + (tween-inout% start amount duration time + tween-quintic-in tween-quintic-out)) +