2
* Copyright (C) 2012 Google Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
13
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16
* DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#include "AnimationTranslationUtil.h"
29
#include "FloatSize.h"
30
#include "GraphicsLayer.h"
31
#include "IdentityTransformOperation.h"
33
#include "LengthFunctions.h"
34
#include "Matrix3DTransformOperation.h"
35
#include "MatrixTransformOperation.h"
36
#include "PerspectiveTransformOperation.h"
37
#include "RotateTransformOperation.h"
38
#include "ScaleTransformOperation.h"
39
#include "SkewTransformOperation.h"
40
#include "TransformOperations.h"
41
#include "TranslateTransformOperation.h"
43
#include <public/Platform.h>
44
#include <public/WebAnimation.h>
45
#include <public/WebAnimationCurve.h>
46
#include <public/WebCompositorSupport.h>
47
#include <public/WebFloatAnimationCurve.h>
48
#include <public/WebTransformAnimationCurve.h>
49
#include <public/WebTransformOperations.h>
50
#include <public/WebTransformationMatrix.h>
52
#include <wtf/OwnPtr.h>
53
#include <wtf/text/CString.h>
56
using namespace WebKit;
60
WebTransformOperations toWebTransformOperations(const TransformOperations& transformOperations, const FloatSize& boxSize)
62
// We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects.
63
WebTransformOperations webTransformOperations;
64
for (size_t j = 0; j < transformOperations.size(); ++j) {
65
TransformOperation::OperationType operationType = transformOperations.operations()[j]->getOperationType();
66
switch (operationType) {
67
case TransformOperation::SCALE_X:
68
case TransformOperation::SCALE_Y:
69
case TransformOperation::SCALE_Z:
70
case TransformOperation::SCALE_3D:
71
case TransformOperation::SCALE: {
72
ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get());
73
webTransformOperations.appendScale(transform->x(), transform->y(), transform->z());
76
case TransformOperation::TRANSLATE_X:
77
case TransformOperation::TRANSLATE_Y:
78
case TransformOperation::TRANSLATE_Z:
79
case TransformOperation::TRANSLATE_3D:
80
case TransformOperation::TRANSLATE: {
81
TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get());
82
webTransformOperations.appendTranslate(floatValueForLength(transform->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), floatValueForLength(transform->z(), 1));
85
case TransformOperation::ROTATE_X:
86
case TransformOperation::ROTATE_Y:
87
case TransformOperation::ROTATE_3D:
88
case TransformOperation::ROTATE: {
89
RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get());
90
webTransformOperations.appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
93
case TransformOperation::SKEW_X:
94
case TransformOperation::SKEW_Y:
95
case TransformOperation::SKEW: {
96
SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get());
97
webTransformOperations.appendSkew(transform->angleX(), transform->angleY());
100
case TransformOperation::MATRIX: {
101
MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get());
102
TransformationMatrix m = transform->matrix();
103
webTransformOperations.appendMatrix(WebTransformationMatrix(m));
106
case TransformOperation::MATRIX_3D: {
107
Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get());
108
TransformationMatrix m = transform->matrix();
109
webTransformOperations.appendMatrix(WebTransformationMatrix(m));
112
case TransformOperation::PERSPECTIVE: {
113
PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get());
114
webTransformOperations.appendPerspective(floatValueForLength(transform->perspective(), 0));
117
case TransformOperation::IDENTITY:
118
webTransformOperations.appendIdentity();
120
case TransformOperation::NONE:
124
} // for each operation
126
return webTransformOperations;
129
template <class Value, class Keyframe, class Curve>
130
bool appendKeyframeWithStandardTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize&)
132
curve->add(Keyframe(keyTime, value->value()), timingFunctionType);
136
template <class Value, class Keyframe, class Curve>
137
bool appendKeyframeWithCustomBezierTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, double x1, double y1, double x2, double y2, const FloatSize&)
139
curve->add(Keyframe(keyTime, value->value()), x1, y1, x2, y2);
143
bool isRotationType(TransformOperation::OperationType transformType)
145
return transformType == TransformOperation::ROTATE
146
|| transformType == TransformOperation::ROTATE_X
147
|| transformType == TransformOperation::ROTATE_Y
148
|| transformType == TransformOperation::ROTATE_Z
149
|| transformType == TransformOperation::ROTATE_3D;
153
bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize)
155
bool canBlend = !lastValue;
156
WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize);
158
WebTransformOperations lastOperations = toWebTransformOperations(*lastValue->value(), boxSize);
159
canBlend = lastOperations.canBlendWith(operations);
162
curve->add(WebTransformKeyframe(keyTime, operations), timingFunctionType);
169
bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize)
171
bool canBlend = !lastValue;
172
WebTransformOperations operations = toWebTransformOperations(*value->value(), boxSize);
174
WebTransformOperations lastOperations = toWebTransformOperations(*lastValue->value(), boxSize);
175
canBlend = lastOperations.canBlendWith(operations);
178
curve->add(WebTransformKeyframe(keyTime, operations), x1, y1, x2, y2);
184
template <class Value, class Keyframe, class Curve>
185
PassOwnPtr<WebKit::WebAnimation> createWebAnimation(const KeyframeValueList& valueList, const Animation* animation, int animationId, double timeOffset, Curve* curve, WebKit::WebAnimation::TargetProperty targetProperty, const FloatSize& boxSize)
187
bool alternate = false;
188
bool reverse = false;
189
if (animation && animation->isDirectionSet()) {
190
Animation::AnimationDirection direction = animation->direction();
191
if (direction == Animation::AnimationDirectionAlternate || direction == Animation::AnimationDirectionAlternateReverse)
193
if (direction == Animation::AnimationDirectionReverse || direction == Animation::AnimationDirectionAlternateReverse)
197
for (size_t i = 0; i < valueList.size(); i++) {
198
size_t index = reverse ? valueList.size() - i - 1 : i;
199
const Value* originalValue = static_cast<const Value*>(valueList.at(index));
200
const Value* lastOriginalValue = 0;
201
if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) || (!reverse && index > 0)))
202
lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));
204
const TimingFunction* originalTimingFunction = originalValue->timingFunction();
206
// If there hasn't been a timing function associated with this keyframe, use the
207
// animation's timing function, if we have one.
208
if (!originalTimingFunction && animation->isTimingFunctionSet())
209
originalTimingFunction = animation->timingFunction().get();
211
// Ease is the default timing function.
212
WebKit::WebAnimationCurve::TimingFunctionType timingFunctionType = WebKit::WebAnimationCurve::TimingFunctionTypeEase;
214
bool isUsingCustomBezierTimingFunction = false;
220
if (originalTimingFunction) {
221
switch (originalTimingFunction->type()) {
222
case TimingFunction::StepsFunction:
223
// FIXME: add support for steps timing function.
225
case TimingFunction::LinearFunction:
226
timingFunctionType = WebKit::WebAnimationCurve::TimingFunctionTypeLinear;
228
case TimingFunction::CubicBezierFunction:
229
const CubicBezierTimingFunction* originalBezierTimingFunction = static_cast<const CubicBezierTimingFunction*>(originalTimingFunction);
230
isUsingCustomBezierTimingFunction = true;
231
x1 = originalBezierTimingFunction->x1();
232
y1 = originalBezierTimingFunction->y1();
233
x2 = originalBezierTimingFunction->x2();
234
y2 = originalBezierTimingFunction->y2();
239
double duration = (animation && animation->isDurationSet()) ? animation->duration() : 1;
240
double keyTime = originalValue->keyTime() * duration;
243
keyTime = duration - keyTime;
245
bool addedKeyframe = false;
246
if (isUsingCustomBezierTimingFunction)
247
addedKeyframe = appendKeyframeWithCustomBezierTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, x1, y1, x2, y2, boxSize);
249
addedKeyframe = appendKeyframeWithStandardTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, timingFunctionType, boxSize);
254
OwnPtr<WebKit::WebAnimation> webAnimation = adoptPtr(Platform::current()->compositorSupport()->createAnimation(*curve, targetProperty, animationId));
256
int iterations = (animation && animation->isIterationCountSet()) ? animation->iterationCount() : 1;
257
webAnimation->setIterations(iterations);
258
webAnimation->setAlternatesDirection(alternate);
260
// If timeOffset > 0, then the animation has started in the past.
261
webAnimation->setTimeOffset(timeOffset);
263
return webAnimation.release();
266
PassOwnPtr<WebKit::WebAnimation> createWebAnimation(const KeyframeValueList& values, const Animation* animation, int animationId, double timeOffset, const FloatSize& boxSize)
270
if (values.property() == AnimatedPropertyWebkitTransform) {
271
OwnPtr<WebTransformAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createTransformAnimationCurve());
272
return createWebAnimation<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), WebKit::WebAnimation::TargetPropertyTransform, FloatSize(boxSize));
275
if (values.property() == AnimatedPropertyOpacity) {
276
OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createFloatAnimationCurve());
277
return createWebAnimation<FloatAnimationValue, WebFloatKeyframe, WebFloatAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), WebKit::WebAnimation::TargetPropertyOpacity, FloatSize());
283
} // namespace WebCore