Source/WebCore: Implement reverse animation direction

Implement reverse animation direction
https://bugs.webkit.org/show_bug.cgi?id=60525

Implement reverse and alternate-reverse direction.

Reviewed by Dean Jackson.

Tests: animations/animation-direction-alternate-reverse.html
       animations/animation-direction-reverse.html
       animations/fill-mode-reverse.html

* css/CSSParser.cpp:
(WebCore::CSSParser::parseAnimationDirection):
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::mapAnimationDirection):
* css/CSSValueKeywords.in:
* page/WebKitAnimation.cpp:
(WebCore::WebKitAnimation::direction):
* page/WebKitAnimation.h:
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::fractionalTime):
* platform/animation/Animation.h:
(Animation):
* platform/graphics/texmap/TextureMapperAnimation.cpp:
(WebCore):
(WebCore::shouldReverseAnimationValue):
(WebCore::normalizedAnimationValue):

LayoutTests: Implement reverse animation direction
https://bugs.webkit.org/show_bug.cgi?id=60525

Add test for the new animation-direction values.

Reviewed by Dean Jackson.

* animations/animation-direction-alternate-reverse-expected.txt: Added.
* animations/animation-direction-alternate-reverse.html: Added.
* animations/animation-direction-reverse-expected.txt: Added.
* animations/animation-direction-reverse.html: Added.
* animations/fill-mode-reverse-expected.txt: Added.
* animations/fill-mode-reverse.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107162 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d738dcf0
2012-02-08 Igor Oliveira <igor.o@sisa.samsung.com>
Implement reverse animation direction
https://bugs.webkit.org/show_bug.cgi?id=60525
Add test for the new animation-direction values.
Reviewed by Dean Jackson.
* animations/animation-direction-alternate-reverse-expected.txt: Added.
* animations/animation-direction-alternate-reverse.html: Added.
* animations/animation-direction-reverse-expected.txt: Added.
* animations/animation-direction-reverse.html: Added.
* animations/fill-mode-reverse-expected.txt: Added.
* animations/fill-mode-reverse.html: Added.
2012-02-08 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=78157
PASS - "left" property for "box" element at 1s saw something close to: 200
PASS - "left" property for "box" element at 2s saw something close to: 0
PASS - "left" property for "box" element at 3s saw something close to: 200
PASS - "left" property for "box" element at 4s saw something close to: 400
<!DOCTYPE html>
<html>
<head>
<style type="text/css" media="screen">
#container {
position: relative;
border: 1px solid black;
height: 100px;
width: 500px;
}
#box {
position: absolute;
height: 100px;
width: 100px;
background-color: blue;
-webkit-animation-name: move;
-webkit-animation-duration: 2s;
-webkit-animation-direction: alternate-reverse;
-webkit-animation-iteration-count: 2;
-webkit-animation-timing-function: linear;
}
@-webkit-keyframes move {
0% {
left: 0;
}
100% {
left: 400px;
}
}
</style>
<script src="resources/animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
["move", 1.0, "box", "left", 200, 20],
["move", 2.0, "box", "left", 0, 20],
["move", 3.0, "box", "left", 200, 20],
["move", 4.0, "box", "left", 400, 20],
];
runAnimationTest(expectedValues);
</script>
</head>
<body>
<!-- Test animation-direction: alternate-reverse -->
<div id="container">
<div id="box"></div>
</div>
<div id="result"></div>
</body>
</html>
PASS - "webkitTransform" property for "box" element at 0.5s saw something close to: 1,0,0,1,150,0
PASS - "webkitTransform" property for "box" element at 1s saw something close to: 1,0,0,1,100,0
PASS - "webkitTransform" property for "box" element at 2.5s saw something close to: 1,0,0,1,200,0
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test of -webkit-animation-play-state</title>
<style type="text/css" media="screen">
body {
margin: 0;
}
#box {
position: absolute;
left: 0px;
top: 100px;
height: 100px;
width: 100px;
background-color: red;
margin: 0;
-webkit-animation-duration: 2s;
-webkit-animation-direction: reverse;
-webkit-animation-timing-function: linear;
-webkit-animation-name: "move1";
}
@-webkit-keyframes "move1" {
from { -webkit-transform: translateX(0px); }
to { -webkit-transform: translateX(200px); }
}
#result {
color: white; /* hide from pixel results */
}
</style>
<script src="resources/animation-test-helpers.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
const expectedValues = [
// [animation-name, time, element-id, property, expected-value, tolerance]
["move1", 0.5, "box", "webkitTransform", [1,0,0,1, 150,0], 20],
["move1", 1.0, "box", "webkitTransform", [1,0,0,1,100,0], 20],
["move1", 2.5, "box", "webkitTransform", [1,0,0,1, 200,0], 20],
];
function pauseAnimation()
{
document.getElementById("box").style.webkitAnimationPlayState = "paused";
}
function setTimers()
{
setTimeout(pauseAnimation, 2500);
}
runAnimationTest(expectedValues, setTimers, null, true);
</script>
</head>
<body>
<div id="box"></div>
<div id="result"></div>
</div>
</body>
</html>
This test performs an animation of the left property with four different fill modes. It animates over 0.1 second with a 0.1 second delay. It takes snapshots at document load and the end of the animation.
None
Backwards
Forwards
Both
Both iterating
PASS - start of animation - id: a expected: 100 actual: 100
PASS - start of animation - id: b expected: 300 actual: 300
PASS - start of animation - id: c expected: 100 actual: 100
PASS - start of animation - id: d expected: 300 actual: 300
PASS - start of animation - id: e expected: 200 actual: 200
PASS - end of animation - id: a expected: 100 actual: 100
PASS - end of animation - id: b expected: 100 actual: 100
PASS - end of animation - id: c expected: 300 actual: 300
PASS - end of animation - id: d expected: 300 actual: 300
PASS - end of animation - id: e expected: 200 actual: 200
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Test simple animation with fill modes</title>
<style type="text/css" media="screen">
.box {
position: relative;
left: 100px;
top: 10px;
height: 100px;
width: 100px;
-webkit-animation-delay: 0.1s;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: anim;
-webkit-animation-direction: reverse
}
@-webkit-keyframes anim {
from { left: 200px; }
to { left: 300px; }
}
#a {
background-color: blue;
-webkit-animation-fill-mode: none;
}
#b {
background-color: red;
-webkit-animation-fill-mode: backwards;
}
#c {
background-color: green;
-webkit-animation-fill-mode: forwards;
}
#d {
background-color: yellow;
-webkit-animation-fill-mode: both;
}
#e {
background-color: #999;
-webkit-animation-fill-mode: both;
-webkit-animation-iteration-count: 2;
-webkit-animation-direction: alternate;
}
</style>
<script type="text/javascript" charset="utf-8">
const numAnims = 5;
var animsFinished = 0;
const allowance = 5;
const expectedValues = [
{id: "a", start: 100, end: 100},
{id: "b", start: 300, end: 100},
{id: "c", start: 100, end: 300},
{id: "d", start: 300, end: 300},
{id: "e", start: 200, end: 200}
];
var result = "";
if (window.layoutTestController) {
layoutTestController.dumpAsText();
layoutTestController.waitUntilDone();
}
function animationEnded(event) {
if (++animsFinished == numAnims) {
setTimeout(endTest, 0); // this set timeout should be ok in the test environment
// since we're just giving style a chance to resolve
}
};
function endTest() {
for (var i=0; i < expectedValues.length; i++) {
var el = document.getElementById(expectedValues[i].id);
var expectedValue = expectedValues[i].end;
var realValue = window.getComputedStyle(el).getPropertyCSSValue("left").getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
if (Math.abs(expectedValue - realValue) < allowance) {
result += "PASS";
} else {
result += "FAIL";
}
result += " - end of animation - id: " + expectedValues[i].id + " expected: " + expectedValue + " actual: " + realValue + "<br>";
}
document.getElementById('result').innerHTML = result;
if (window.layoutTestController)
layoutTestController.notifyDone();
}
window.onload = function () {
for (var i=0; i < expectedValues.length; i++) {
var el = document.getElementById(expectedValues[i].id);
var expectedValue = expectedValues[i].start;
var realValue = window.getComputedStyle(el).getPropertyCSSValue("left").getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
if (Math.abs(expectedValue - realValue) < allowance) {
result += "PASS";
} else {
result += "FAIL";
}
result += " - start of animation - id: " + expectedValues[i].id + " expected: " + expectedValue + " actual: " + realValue + "<br>";
}
document.addEventListener("webkitAnimationEnd", animationEnded, false);
};
</script>
</head>
<body>
This test performs an animation of the left property with four different
fill modes. It animates over 0.1 second with a 0.1 second delay.
It takes snapshots at document load and the end of the animation.
<div id="a" class="box">
None
</div>
<div id="b" class="box">
Backwards
</div>
<div id="c" class="box">
Forwards
</div>
<div id="d" class="box">
Both
</div>
<div id="e" class="box">
Both iterating
</div>
<div id="result">
</div>
</body>
</html>
2012-02-08 Igor Oliveira <igor.o@sisa.samsung.com>
Implement reverse animation direction
Implement reverse animation direction
https://bugs.webkit.org/show_bug.cgi?id=60525
Implement reverse and alternate-reverse direction.
Reviewed by Dean Jackson.
Tests: animations/animation-direction-alternate-reverse.html
animations/animation-direction-reverse.html
animations/fill-mode-reverse.html
* css/CSSParser.cpp:
(WebCore::CSSParser::parseAnimationDirection):
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::mapAnimationDirection):
* css/CSSValueKeywords.in:
* page/WebKitAnimation.cpp:
(WebCore::WebKitAnimation::direction):
* page/WebKitAnimation.h:
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::fractionalTime):
* platform/animation/Animation.h:
(Animation):
* platform/graphics/texmap/TextureMapperAnimation.cpp:
(WebCore):
(WebCore::shouldReverseAnimationValue):
(WebCore::normalizedAnimationValue):
2012-02-08 James Robinson <jamesr@chromium.org>
[chromium] Avoid creating a temporary GraphicsContext3D if someone requests the WebView's GraphicsContext3D before initialization is complete
......@@ -3376,7 +3376,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDelay()
PassRefPtr<CSSValue> CSSParser::parseAnimationDirection()
{
CSSParserValue* value = m_valueList->current();
if (value->id == CSSValueNormal || value->id == CSSValueAlternate)
if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse)
return cssValuePool()->createIdentifierValue(value->id);
return 0;
}
......
......@@ -4318,7 +4318,20 @@ void CSSStyleSelector::mapAnimationDirection(Animation* layer, CSSValue* value)
return;
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(value);
layer->setDirection(primitiveValue->getIdent() == CSSValueAlternate ? Animation::AnimationDirectionAlternate : Animation::AnimationDirectionNormal);
switch (primitiveValue->getIdent()) {
case CSSValueNormal:
layer->setDirection(Animation::AnimationDirectionNormal);
break;
case CSSValueAlternate:
layer->setDirection(Animation::AnimationDirectionAlternate);
break;
case CSSValueReverse:
layer->setDirection(Animation::AnimationDirectionReverse);
break;
case CSSValueAlternateReverse:
layer->setDirection(Animation::AnimationDirectionAlternateReverse);
break;
}
}
void CSSStyleSelector::mapAnimationDuration(Animation* animation, CSSValue* value)
......
......@@ -700,6 +700,8 @@ lines
//
// alternate
alternate-reverse
//
// CSS_PROP__WEBKIT_ANIMATION_FILL_MODE
//
......
......@@ -84,9 +84,18 @@ bool WebKitAnimation::ended() const
WebKitAnimation::Direction WebKitAnimation::direction() const
{
if (m_keyframeAnimation->animation()->direction() == Animation::AnimationDirectionNormal)
switch (m_keyframeAnimation->animation()->direction()) {
case Animation::AnimationDirectionNormal:
return DIRECTION_NORMAL;
return DIRECTION_ALTERNATE;
case Animation::AnimationDirectionAlternate:
return DIRECTION_ALTERNATE;
case Animation::AnimationDirectionReverse:
return DIRECTION_REVERSE;
case Animation::AnimationDirectionAlternateReverse:
return DIRECTION_ALTERNATE_REVERSE;
}
ASSERT_NOT_REACHED();
return DIRECTION_NORMAL;
}
WebKitAnimation::FillMode WebKitAnimation::fillMode() const
......
......@@ -59,7 +59,7 @@ public:
bool ended() const;
// direction
enum Direction { DIRECTION_NORMAL, DIRECTION_ALTERNATE };
enum Direction { DIRECTION_NORMAL, DIRECTION_ALTERNATE, DIRECTION_REVERSE, DIRECTION_ALTERNATE_REVERSE };
Direction direction() const;
// fill mode
......
......@@ -1673,7 +1673,9 @@ double AnimationBase::fractionalTime(double scale, double elapsedTime, double of
integralTime = min(integralTime, m_animation->iterationCount() - 1);
fractionalTime -= integralTime;
if ((m_animation->direction() == Animation::AnimationDirectionAlternate) && (integralTime & 1))
if (((m_animation->direction() == Animation::AnimationDirectionAlternate) && (integralTime & 1))
|| ((m_animation->direction() == Animation::AnimationDirectionAlternateReverse) && !(integralTime & 1))
|| m_animation->direction() == Animation::AnimationDirectionReverse)
fractionalTime = 1 - fractionalTime;
if (scale != 1 || offset)
......
......@@ -42,7 +42,7 @@ public:
static PassRefPtr<Animation> create() { return adoptRef(new Animation); }
static PassRefPtr<Animation> create(const Animation* o) { return adoptRef(new Animation(*o)); }
bool isDelaySet() const { return m_delaySet; }
bool isDirectionSet() const { return m_directionSet; }
bool isDurationSet() const { return m_durationSet; }
......@@ -96,7 +96,12 @@ public:
double delay() const { return m_delay; }
enum AnimationDirection { AnimationDirectionNormal, AnimationDirectionAlternate };
enum AnimationDirection {
AnimationDirectionNormal,
AnimationDirectionAlternate,
AnimationDirectionReverse,
AnimationDirectionAlternateReverse
};
AnimationDirection direction() const { return static_cast<AnimationDirection>(m_direction); }
unsigned fillMode() const { return m_fillMode; }
......@@ -144,7 +149,7 @@ private:
double m_delay;
double m_duration;
RefPtr<TimingFunction> m_timingFunction;
unsigned m_direction : 1; // AnimationDirection
unsigned m_direction : 2; // AnimationDirection
unsigned m_fillMode : 2;
unsigned m_playState : 2;
......
......@@ -26,7 +26,17 @@
#if USE(TEXTURE_MAPPER)
namespace WebCore {
static double normalizedAnimationValue(double runningTime, double duration, bool alternate)
static bool shouldReverseAnimationValue(Animation::AnimationDirection direction, int loopCount)
{
if (((direction == Animation::AnimationDirectionAlternate) && (loopCount & 1))
|| ((direction == Animation::AnimationDirectionAlternateReverse) && !(loopCount & 1))
|| direction == Animation::AnimationDirectionReverse)
return true;
return false;
}
static double normalizedAnimationValue(double runningTime, double duration, Animation::AnimationDirection direction)
{
if (!duration)
return 0;
......@@ -35,7 +45,8 @@ static double normalizedAnimationValue(double runningTime, double duration, bool
const double lastFullLoop = duration * double(loopCount);
const double remainder = runningTime - lastFullLoop;
const double normalized = remainder / duration;
return (loopCount % 2 && alternate) ? (1 - normalized) : normalized;
return shouldReverseAnimationValue(direction, loopCount) ? 1 - normalized : normalized;
}
static float applyOpacityAnimation(float fromOpacity, float toOpacity, double progress)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment