cssanimation: Compute progress correctly

We were computing the wrong progress, in particular when the iteration
count was non-integer.

Test included.
This commit is contained in:
Benjamin Otte 2016-03-08 05:01:33 +01:00
parent fc7335bdb4
commit b7285592f9
5 changed files with 2435 additions and 21 deletions

View File

@ -68,37 +68,35 @@ static double
gtk_css_animation_get_progress_from_iteration (GtkCssAnimation *animation, gtk_css_animation_get_progress_from_iteration (GtkCssAnimation *animation,
double iteration) double iteration)
{ {
double d; gboolean reverse;
double completed;
iteration = CLAMP (iteration, 0, animation->iteration_count); iteration = CLAMP (iteration, 0.0, animation->iteration_count);
completed = floor (iteration);
switch (animation->direction) switch (animation->direction)
{ {
case GTK_CSS_DIRECTION_NORMAL: case GTK_CSS_DIRECTION_NORMAL:
if (iteration == animation->iteration_count) reverse = completed == iteration && iteration > 0;
return 1; break;
else
return iteration - floor (iteration);
case GTK_CSS_DIRECTION_REVERSE: case GTK_CSS_DIRECTION_REVERSE:
if (iteration == animation->iteration_count) reverse = !(completed == iteration && iteration > 0);
return 1; break;
else
return ceil (iteration) - iteration;
case GTK_CSS_DIRECTION_ALTERNATE: case GTK_CSS_DIRECTION_ALTERNATE:
d = floor (iteration); reverse = fmod (iteration, 2) >= 1.0;
if (fmod (d, 2)) break;
return 1 + d - iteration;
else
return iteration - d;
case GTK_CSS_DIRECTION_ALTERNATE_REVERSE: case GTK_CSS_DIRECTION_ALTERNATE_REVERSE:
d = floor (iteration); reverse = !(fmod (iteration, 2) >= 1.0);
if (fmod (d, 2)) break;
return iteration - d;
else
return 1 + d - iteration;
default: default:
g_return_val_if_reached (0); g_return_val_if_reached (0.0);
} }
iteration -= completed;
if (reverse)
iteration = 1.0 - iteration;
return iteration;
} }
static void static void

View File

@ -83,6 +83,9 @@ testdata = \
animation-direction.css \ animation-direction.css \
animation-direction.ref.ui \ animation-direction.ref.ui \
animation-direction.ui \ animation-direction.ui \
animation-fill-mode-iteration-count.css \
animation-fill-mode-iteration-count.ref.ui \
animation-fill-mode-iteration-count.ui \
background-area.css \ background-area.css \
background-area.ref.ui \ background-area.ref.ui \
background-area.ui \ background-area.ui \

View File

@ -0,0 +1,83 @@
@keyframes cssrocks {
from { background-color: yellow; }
to { background-color: red; }
}
box {
background-color: blue;
animation-fill-mode: both;
animation-duration: 100s;
padding: 1px;
background-clip: content-box;
animation-timing-function: linear;
}
.after {
animation-name: cssrocks;
animation-delay: -10000s;
}
.before {
animation-name: cssrocks;
animation-delay: 10000s;
}
.normal {
animation-direction: normal;
}
.reverse {
animation-direction: reverse;
}
.alternate {
animation-direction: alternate;
}
.alternate-reverse {
animation-direction: alternate-reverse;
}
.x0 {
animation-iteration-count: 0;
}
.x02 {
animation-iteration-count: 0.2;
}
.x1 {
animation-iteration-count: 1;
}
.x12 {
animation-iteration-count: 1.2;
}
.x2 {
animation-iteration-count: 2;
}
.x22 {
animation-iteration-count: 2.2;
}
.yellow {
animation: none;
background-color: yellow;
}
.red {
animation: none;
background-color: red;
}
.darkorange {
animation: none;
background-color: rgb(255,51,0);
}
.lightorange {
animation: none;
background-color: rgb(255,204,0);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff