File: animation.vala

package info (click to toggle)
deepin-terminal 5.0.0%2Bds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 4,144 kB
  • sloc: ansic: 128; exp: 25; sh: 18; makefile: 15
file content (141 lines) | stat: -rw-r--r-- 4,396 bytes parent folder | download | duplicates (2)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 4 -*-
 *
 * Copyright (C) 2011,2012 Canonical Ltd
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors: Robert Ancell <robert.ancell@canonical.com>
 *          Michael Terry <michael.terry@canonical.com>
 */

namespace Animation {
    public class AnimateTimer : Object {
        public bool is_running { get { return timeout != 0; } }
        public double progress { get; private set; }

        /* speed is in milliseconds */
        public int speed { get; set; }

        public unowned EasingFunc easing_func { get; private set; }

        /* progress is from 0.0 to 1.0 */
        public signal void animate (double progress);

        /* AnimateTimer requires two things: an easing function and a speed.

           The speed is just the duration of the animation in milliseconds.

           The easing function describes how fast the animation occurs at different
           parts of the duration.

           See http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html
           for examples of various easing functions.

           A few are provided with this class, notably ease_in_out and
           ease_out_quint.
        */
        /* speed is in milliseconds */

        /* x and y are 0.0 to 1.0 */
        public delegate double EasingFunc (double x);

        private TimeSpan extra_time = 0;
        private TimeSpan length = 0;
        private TimeSpan start_time = 0;
        private double extra_progress = 0.0;
        private uint timeout = 0;

        public AnimateTimer (EasingFunc func, int speed) {
            Object (speed: speed);
            this.easing_func = func;
        }

        ~AnimateTimer () {
            stop ();
        }

        /* temp_speed is in milliseconds */
        public void reset (int temp_speed = -1) {
            stop ();

            timeout = Timeout.add (16, animate_cb);
            progress = 0;
            start_time = 0;
            extra_time = 0;
            extra_progress = 0;

            if (temp_speed == -1)
                temp_speed = speed;

            length = temp_speed * TimeSpan.MILLISECOND;
        }

        public void stop () {
            if (timeout != 0)
                Source.remove (timeout);
            timeout = 0;
        }

        private bool animate_cb () {
            if (start_time == 0)
                start_time = GLib.get_monotonic_time ();

            var time_progress = normalize_time (GLib.get_monotonic_time ());
            progress = calculate_progress (time_progress);
            animate (progress);

            if (time_progress >= 1.0) {
                timeout = 0;
                return false;
            } else {
                return true;
            }
        }

        /* Returns 0.0 to 1.0 where 1.0 is at or past end_time */
        private double normalize_time (TimeSpan now) {
            if (length == 0)
                return 1.0f;

            return (((double)(now - start_time)) / length).clamp (0.0, 1.0);
        }

        /* Returns 0.0 to 1.0 where 1.0 is done.
           time is not normalized yet! */
        private double calculate_progress (double time_progress) {
            var y = easing_func (time_progress);
            return y.clamp (0.0, 1.0);
        }

        public static double ease_in_out (double x) {
            return (1 - Math.cos (Math.PI * x)) / 2;
        }

        public static double ease_in_quad (double x) {
          return Math.pow (x, 2);
          }

        public static double ease_out_quad (double x) {
          return -1 * Math.pow (x - 1, 2) + 1;
          }

        public static double ease_in_quint (double x) {
          return Math.pow (x, 5);
          }

        public static double ease_out_quint (double x) {
            return Math.pow (x - 1, 5) + 1;
        }
    }
}