bcf8c002b3b943cc6957ddbf496db0e04b01fa91
[WebKit-https.git] / Source / WebCore / platform / animation / TimingFunction.h
1 /*
2  * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3  *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6  * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #pragma once
26
27 #include <wtf/Ref.h>
28 #include <wtf/RefCounted.h>
29
30 namespace WTF {
31 class TextStream;
32 }
33
34 namespace WebCore {
35
36 class TimingFunction : public RefCounted<TimingFunction> {
37 public:
38     virtual Ref<TimingFunction> clone() const = 0;
39
40     virtual ~TimingFunction() = default;
41
42     enum TimingFunctionType { LinearFunction, CubicBezierFunction, StepsFunction, SpringFunction };
43     TimingFunctionType type() const { return m_type; }
44
45     bool isLinearTimingFunction() const { return m_type == LinearFunction; }
46     bool isCubicBezierTimingFunction() const { return m_type == CubicBezierFunction; }
47     bool isStepsTimingFunction() const { return m_type == StepsFunction; }
48     bool isSpringTimingFunction() const { return m_type == SpringFunction; }
49
50     virtual bool operator==(const TimingFunction&) const = 0;
51     bool operator!=(const TimingFunction& other) const { return !(*this == other); }
52
53     double transformTime(double, double) const;
54
55 protected:
56     explicit TimingFunction(TimingFunctionType type)
57         : m_type(type)
58     {
59     }
60
61 private:
62     TimingFunctionType m_type;
63 };
64
65 class LinearTimingFunction final : public TimingFunction {
66 public:
67     static Ref<LinearTimingFunction> create()
68     {
69         return adoptRef(*new LinearTimingFunction);
70     }
71     
72     bool operator==(const TimingFunction& other) const final
73     {
74         return other.isLinearTimingFunction();
75     }
76
77 private:
78     LinearTimingFunction()
79         : TimingFunction(LinearFunction)
80     {
81     }
82
83     Ref<TimingFunction> clone() const final
84     {
85         return adoptRef(*new LinearTimingFunction);
86     }
87 };
88
89 class CubicBezierTimingFunction final : public TimingFunction {
90 public:
91     enum TimingFunctionPreset { Ease, EaseIn, EaseOut, EaseInOut, Custom };
92     
93     static Ref<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2)
94     {
95         return adoptRef(*new CubicBezierTimingFunction(Custom, x1, y1, x2, y2));
96     }
97
98     static Ref<CubicBezierTimingFunction> create()
99     {
100         return adoptRef(*new CubicBezierTimingFunction());
101     }
102     
103     static Ref<CubicBezierTimingFunction> create(TimingFunctionPreset preset)
104     {
105         switch (preset) {
106         case Ease:
107             return adoptRef(*new CubicBezierTimingFunction);
108         case EaseIn:
109             return adoptRef(*new CubicBezierTimingFunction(EaseIn, 0.42, 0.0, 1.0, 1.0));
110         case EaseOut:
111             return adoptRef(*new CubicBezierTimingFunction(EaseOut, 0.0, 0.0, 0.58, 1.0));
112         case EaseInOut:
113             return adoptRef(*new CubicBezierTimingFunction(EaseInOut, 0.42, 0.0, 0.58, 1.0));
114         case Custom:
115             break;
116         }
117         ASSERT_NOT_REACHED();
118         return adoptRef(*new CubicBezierTimingFunction);
119     }
120
121     bool operator==(const TimingFunction& other) const final
122     {
123         if (!other.isCubicBezierTimingFunction())
124             return false;
125         auto& otherCubic = static_cast<const CubicBezierTimingFunction&>(other);
126         if (m_timingFunctionPreset != otherCubic.m_timingFunctionPreset)
127             return false;
128         if (m_timingFunctionPreset != Custom)
129             return true;
130         return m_x1 == otherCubic.m_x1 && m_y1 == otherCubic.m_y1 && m_x2 == otherCubic.m_x2 && m_y2 == otherCubic.m_y2;
131     }
132
133     double x1() const { return m_x1; }
134     double y1() const { return m_y1; }
135     double x2() const { return m_x2; }
136     double y2() const { return m_y2; }
137     
138     void setValues(double x1, double y1, double x2, double y2)
139     {
140         m_x1 = x1;
141         m_y1 = y1;
142         m_x2 = x2;
143         m_y2 = y2;
144     }
145
146     TimingFunctionPreset timingFunctionPreset() const { return m_timingFunctionPreset; }
147     void setTimingFunctionPreset(TimingFunctionPreset preset) { m_timingFunctionPreset = preset; }
148
149     static const CubicBezierTimingFunction& defaultTimingFunction()
150     {
151         static const CubicBezierTimingFunction& function = create().leakRef();
152         return function;
153     }
154
155     Ref<CubicBezierTimingFunction> createReversed() const
156     {
157         return create(1.0 - m_x2, 1.0 - m_y2, 1.0 - m_x1, 1.0 - m_y1);
158     }
159
160 private:
161     explicit CubicBezierTimingFunction(TimingFunctionPreset preset = Ease, double x1 = 0.25, double y1 = 0.1, double x2 = 0.25, double y2 = 1.0)
162         : TimingFunction(CubicBezierFunction)
163         , m_x1(x1)
164         , m_y1(y1)
165         , m_x2(x2)
166         , m_y2(y2)
167         , m_timingFunctionPreset(preset)
168     {
169     }
170
171     Ref<TimingFunction> clone() const final
172     {
173         return adoptRef(*new CubicBezierTimingFunction(m_timingFunctionPreset, m_x1, m_y1, m_x2, m_y2));
174     }
175
176     double m_x1;
177     double m_y1;
178     double m_x2;
179     double m_y2;
180     TimingFunctionPreset m_timingFunctionPreset;
181 };
182
183 class StepsTimingFunction final : public TimingFunction {
184 public:
185     static Ref<StepsTimingFunction> create(int steps, bool stepAtStart)
186     {
187         return adoptRef(*new StepsTimingFunction(steps, stepAtStart));
188     }
189     static Ref<StepsTimingFunction> create()
190     {
191         return adoptRef(*new StepsTimingFunction(1, true));
192     }
193     
194     bool operator==(const TimingFunction& other) const final
195     {
196         if (!other.isStepsTimingFunction())
197             return false;
198         auto& otherSteps = static_cast<const StepsTimingFunction&>(other);
199         return m_steps == otherSteps.m_steps && m_stepAtStart == otherSteps.m_stepAtStart;
200     }
201     
202     int numberOfSteps() const { return m_steps; }
203     void setNumberOfSteps(int steps) { m_steps = steps; }
204
205     bool stepAtStart() const { return m_stepAtStart; }
206     void setStepAtStart(bool stepAtStart) { m_stepAtStart = stepAtStart; }
207
208 private:
209     StepsTimingFunction(int steps, bool stepAtStart)
210         : TimingFunction(StepsFunction)
211         , m_steps(steps)
212         , m_stepAtStart(stepAtStart)
213     {
214     }
215
216     Ref<TimingFunction> clone() const final
217     {
218         return adoptRef(*new StepsTimingFunction(m_steps, m_stepAtStart));
219     }
220     
221     int m_steps;
222     bool m_stepAtStart;
223 };
224
225 class SpringTimingFunction final : public TimingFunction {
226 public:
227     static Ref<SpringTimingFunction> create(double mass, double stiffness, double damping, double initialVelocity)
228     {
229         return adoptRef(*new SpringTimingFunction(mass, stiffness, damping, initialVelocity));
230     }
231
232     static Ref<SpringTimingFunction> create()
233     {
234         // This create() function should only be used by the argument decoders, and it is expected that
235         // real values will be filled in using setValues().
236         return create(0, 0, 0, 0);
237     }
238     
239     bool operator==(const TimingFunction& other) const final
240     {
241         if (!other.isSpringTimingFunction())
242             return false;
243         auto& otherSpring = static_cast<const SpringTimingFunction&>(other);
244         return m_mass == otherSpring.m_mass && m_stiffness == otherSpring.m_stiffness && m_damping == otherSpring.m_damping && m_initialVelocity == otherSpring.m_initialVelocity;
245     }
246
247     double mass() const { return m_mass; }
248     double stiffness() const { return m_stiffness; }
249     double damping() const { return m_damping; }
250     double initialVelocity() const { return m_initialVelocity; }
251     
252     void setValues(double mass, double stiffness, double damping, double initialVelocity)
253     {
254         m_mass = mass;
255         m_stiffness = stiffness;
256         m_damping = damping;
257         m_initialVelocity = initialVelocity;
258     }
259
260 private:
261     explicit SpringTimingFunction(double mass, double stiffness, double damping, double initialVelocity)
262         : TimingFunction(SpringFunction)
263         , m_mass(mass)
264         , m_stiffness(stiffness)
265         , m_damping(damping)
266         , m_initialVelocity(initialVelocity)
267     {
268     }
269
270     Ref<TimingFunction> clone() const final
271     {
272         return adoptRef(*new SpringTimingFunction(m_mass, m_stiffness, m_damping, m_initialVelocity));
273     }
274
275     double m_mass;
276     double m_stiffness;
277     double m_damping;
278     double m_initialVelocity;
279 };
280
281 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const TimingFunction&);
282
283 } // namespace WebCore