a5c7bfeb34c3

Episode 31: Tweening Part 3
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Fri, 01 Jul 2016 14:41:43 +0000
parents 82a47826346d
children 12c6ece1710f
branches/tags (none)
files .lispwords easing-functions.gcx package.lisp src/2d/demo.lisp src/tween.lisp

Changes

--- 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)
Binary file easing-functions.gcx has changed
--- 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!
--- 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)))
 
--- 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))
+