1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "platform/animation/TimingFunction.h"
8 #include "wtf/MathExtras.h"
12 String LinearTimingFunction::toString() const
17 double LinearTimingFunction::evaluate(double fraction, double) const
22 String CubicBezierTimingFunction::toString() const
24 switch (this->subType()) {
25 case CubicBezierTimingFunction::Ease:
27 case CubicBezierTimingFunction::EaseIn:
29 case CubicBezierTimingFunction::EaseOut:
31 case CubicBezierTimingFunction::EaseInOut:
33 case CubicBezierTimingFunction::Custom:
34 return "cubic-bezier(" + String::numberToStringECMAScript(this->x1()) + ", " +
35 String::numberToStringECMAScript(this->y1()) + ", " + String::numberToStringECMAScript(this->x2()) +
36 ", " + String::numberToStringECMAScript(this->y2()) + ")";
43 double CubicBezierTimingFunction::evaluate(double fraction, double accuracy) const
46 m_bezier = adoptPtr(new UnitBezier(m_x1, m_y1, m_x2, m_y2));
47 return m_bezier->solve(fraction, accuracy);
50 String StepsTimingFunction::toString() const
52 StringBuilder builder;
53 switch (this->subType()) {
54 case StepsTimingFunction::Start:
56 case StepsTimingFunction::Middle:
58 case StepsTimingFunction::End:
60 case StepsTimingFunction::Custom:
61 builder.append("steps(" + String::numberToStringECMAScript(this->numberOfSteps()) + ", ");
63 if (this->stepAtPosition() == StepsTimingFunction::StepAtStart)
64 builder.append("start");
65 else if (this->stepAtPosition() == StepsTimingFunction::StepAtMiddle)
66 builder.append("middle");
67 else if (this->stepAtPosition() == StepsTimingFunction::StepAtEnd)
68 builder.append("end");
77 return builder.toString();
80 double StepsTimingFunction::evaluate(double fraction, double) const
82 double startOffset = 0;
83 switch (m_stepAtPosition) {
97 return clampTo(floor((m_steps * fraction) + startOffset) / m_steps, 0.0, 1.0);
101 bool operator==(const LinearTimingFunction& lhs, const TimingFunction& rhs)
103 return rhs.type() == TimingFunction::LinearFunction;
106 bool operator==(const CubicBezierTimingFunction& lhs, const TimingFunction& rhs)
108 if (rhs.type() != TimingFunction::CubicBezierFunction)
111 const CubicBezierTimingFunction& ctf = toCubicBezierTimingFunction(rhs);
112 if ((lhs.subType() == CubicBezierTimingFunction::Custom) && (ctf.subType() == CubicBezierTimingFunction::Custom))
113 return (lhs.x1() == ctf.x1()) && (lhs.y1() == ctf.y1()) && (lhs.x2() == ctf.x2()) && (lhs.y2() == ctf.y2());
115 return lhs.subType() == ctf.subType();
118 bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs)
120 if (rhs.type() != TimingFunction::StepsFunction)
123 const StepsTimingFunction& stf = toStepsTimingFunction(rhs);
124 if ((lhs.subType() == StepsTimingFunction::Custom) && (stf.subType() == StepsTimingFunction::Custom))
125 return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.stepAtPosition() == stf.stepAtPosition());
127 return lhs.subType() == stf.subType();
130 // The generic operator== *must* come after the
131 // non-generic operator== otherwise it will end up calling itself.
132 bool operator==(const TimingFunction& lhs, const TimingFunction& rhs)
134 switch (lhs.type()) {
135 case TimingFunction::LinearFunction: {
136 const LinearTimingFunction& linear = toLinearTimingFunction(lhs);
137 return (linear == rhs);
139 case TimingFunction::CubicBezierFunction: {
140 const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(lhs);
141 return (cubic == rhs);
143 case TimingFunction::StepsFunction: {
144 const StepsTimingFunction& step = toStepsTimingFunction(lhs);
145 return (step == rhs);
148 ASSERT_NOT_REACHED();
153 // No need to define specific operator!= as they can all come via this function.
154 bool operator!=(const TimingFunction& lhs, const TimingFunction& rhs)
156 return !(lhs == rhs);
159 } // namespace WebCore