summaryrefslogtreecommitdiff
path: root/animise.lisp
blob: 5ba2d8665ece255c03de9981bb788c5d9ea00820 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
;;;; animise.lisp

(in-package #:animise)

(defun time-frac (start duration current)
  (let* ((end (+ start duration))
        (progress (max 0 (- end current))))
    (- 1.0 (/ progress duration))))

(defmacro def-ease (name &rest body)
  `(defun ,name (start duration current &optional (delta 1))
     (let ((frac (time-frac start duration current)))
       ,@body)))

(defmacro def-mirror-for (name-of-ease)
  (let ((mirror-name (read-from-string (format nil "mirror-~a" name-of-ease))))
    `(def-ease ,mirror-name
         (if (<= frac 0.5)
             (,name-of-ease start (* 0.5 duration) current delta)
             (,name-of-ease start (* 0.5 duration)
                            (- (+ start (* 0.5 duration))
                               (- current (+ start (* 0.5 duration))))
                            delta)))))

(def-ease linear (* delta frac))

(def-mirror-for linear)

(def-ease quad-in (* frac frac delta))

(def-mirror-for quad-in)

(def-ease quad-out (* frac (- frac 2.0) -1 delta))

(def-mirror-for quad-out)

(def-ease quad-in-out
  (setf frac (/ frac 0.5))
  (if (< frac 1) (* frac frac 0.5 delta)
      (progn (decf frac)
             (* -1 delta 0.5 (1- (* frac (- frac 2)))))))

(def-mirror-for quad-in-out)

(def-ease cubic-in (* frac frac frac delta))

(def-mirror-for cubic-in)

(def-ease cubic-out
    (decf frac)
    (* (1+ (* frac frac frac)) delta))

(def-mirror-for cubic-out)

(def-ease cubic-in-out
  (setf frac (/ frac 0.5))
  (if (< frac 1) (* delta 0.5 frac frac frac)
      (progn
        (decf frac 2)
        (* delta 0.5 (+ 2 (* frac frac frac))))))

(def-mirror-for cubic-in-out)

(def-ease sinusoidal-in
  (+ delta (* -1 delta (cos (* frac pi 0.5)))))

(def-mirror-for sinusoidal-in)

(def-ease sinusoidal-out
  (* delta (sin (* frac pi 0.5))))
(def-mirror-for sinusoidal-out)

(def-ease sinusoidal-in-out
  (* delta -0.5 (1- (cos (* pi frac)))))
(def-mirror-for sinusoidal-in-out)

(def-ease elastic-out
      (let ((sqrd (* frac frac))
            (cubed (* frac frac frac)))
        (* 100 delta (+ (* 0.33 sqrd cubed)
                        (* -1.06 sqrd sqrd)
                        (* 1.26 cubed)
                        (* -0.67 sqrd)
                        (* 0.15 frac)))))

(def-mirror-for elastic-out)


(def-ease bounce-out
    (let ((coeff 7.5627)
          (step (/ 1 2.75)))
      (cond ((< frac step)
             (* delta coeff frac frac))
            ((< frac (* 2 step))
             (decf frac (* 1.5 step))
             (* delta
                (+ 0.75
                   (* coeff frac frac))))
            ((< frac ( * 2.5 step))
             (decf frac (* 2.25 step))
             (* delta
                (+ 0.9375
                   (* coeff frac frac))))
            (t
             (decf frac (* 2.65 step))
             (* delta
                (+ 0.984375
                   (* coeff frac frac)))))))

(def-mirror-for bounce-out)

(defun frames (ease-fn &optional (step 0.1))
  (loop :for time :from 0 :upto (+ 1 step) :by step
        :collect (funcall ease-fn 0 1.0 time)))

(defun print-frames (fn &key (width 20) (mark #\.) (step 0.1))
  (loop for frame in (frames fn step) do
    (dotimes (x width) (princ #\Space))
    (dotimes (x (round (* frame width)))
      (princ #\Space))
    (princ mark)
    (terpri)))