summaryrefslogtreecommitdiffstats
path: root/servo/tests/unit/style/animated_properties.rs
blob: fe0b03af87a171e83895929466d0d5f610091bd1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use cssparser::RGBA;
use style::values::animated::{Animate, Procedure, ToAnimatedValue};
use style::values::computed::Percentage;
use style::values::generics::transform::{Transform, TransformOperation};

fn interpolate_rgba(from: RGBA, to: RGBA, progress: f64) -> RGBA {
    let from = from.to_animated_value();
    let to = to.to_animated_value();
    RGBA::from_animated_value(
        from.animate(&to, Procedure::Interpolate { progress }).unwrap(),
    )
}

// Color
#[test]
fn test_rgba_color_interepolation_preserves_transparent() {
    assert_eq!(interpolate_rgba(RGBA::transparent(),
                                RGBA::transparent(), 0.5),
               RGBA::transparent());
}

#[test]
fn test_rgba_color_interepolation_alpha() {
    assert_eq!(interpolate_rgba(RGBA::new(200, 0, 0, 100),
                                RGBA::new(0, 200, 0, 200), 0.5),
               RGBA::new(67, 133, 0, 150));
}

#[test]
fn test_rgba_color_interepolation_out_of_range_1() {
    // Some cubic-bezier functions produce values that are out of range [0, 1].
    // Unclamped cases.
    assert_eq!(interpolate_rgba(RGBA::from_floats(0.3, 0.0, 0.0, 0.4),
                                RGBA::from_floats(0.0, 1.0, 0.0, 0.6), -0.5),
               RGBA::new(154, 0, 0, 77));
}

#[test]
fn test_rgba_color_interepolation_out_of_range_2() {
    assert_eq!(interpolate_rgba(RGBA::from_floats(1.0, 0.0, 0.0, 0.6),
                                RGBA::from_floats(0.0, 0.3, 0.0, 0.4), 1.5),
               RGBA::new(0, 154, 0, 77));
}

#[test]
fn test_rgba_color_interepolation_out_of_range_clamped_1() {
    assert_eq!(interpolate_rgba(RGBA::from_floats(1.0, 0.0, 0.0, 0.8),
                                RGBA::from_floats(0.0, 1.0, 0.0, 0.2), -0.5),
               RGBA::from_floats(1.0, 0.0, 0.0, 1.0));
}

#[test]
fn test_rgba_color_interepolation_out_of_range_clamped_2() {
    assert_eq!(interpolate_rgba(RGBA::from_floats(1.0, 0.0, 0.0, 0.8),
                                RGBA::from_floats(0.0, 1.0, 0.0, 0.2), 1.5),
               RGBA::from_floats(0.0, 0.0, 0.0, 0.0));
}

// Transform
#[test]
fn test_transform_interpolation_on_translate() {
    use style::values::computed::{CalcLengthPercentage, Length, LengthPercentage};

    let from = Transform(vec![
        TransformOperation::Translate3D(LengthPercentage::Length(Length::new(0.)),
                                        LengthPercentage::Length(Length::new(100.)),
                                        Length::new(25.))]);
    let to = Transform(vec![
        TransformOperation::Translate3D(LengthPercentage::Length(Length::new(100.)),
                                        LengthPercentage::Length(Length::new(0.)),
                                        Length::new(75.))]);
    assert_eq!(
        from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
        Transform(vec![TransformOperation::Translate3D(
            LengthPercentage::Length(Length::new(50.)),
            LengthPercentage::Length(Length::new(50.)),
            Length::new(50.),
        )])
    );

    let from = Transform(vec![TransformOperation::Translate3D(
        LengthPercentage::Percentage(Percentage(0.5)),
        LengthPercentage::Percentage(Percentage(1.0)),
        Length::new(25.),
    )]);
    let to = Transform(vec![
        TransformOperation::Translate3D(LengthPercentage::Length(Length::new(100.)),
                                        LengthPercentage::Length(Length::new(50.)),
                                        Length::new(75.))]);
    assert_eq!(
        from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
        Transform(vec![TransformOperation::Translate3D(
            // calc(50px + 25%)
            LengthPercentage::Calc(CalcLengthPercentage::new(Length::new(50.),
                                                                 Some(Percentage(0.25)))),
            // calc(25px + 50%)
            LengthPercentage::Calc(CalcLengthPercentage::new(Length::new(25.),
                                                                 Some(Percentage(0.5)))),
            Length::new(50.),
        )])
    );
}

#[test]
fn test_transform_interpolation_on_scale() {
    let from = Transform(vec![TransformOperation::Scale3D(1.0, 2.0, 1.0)]);
    let to = Transform(vec![TransformOperation::Scale3D(2.0, 4.0, 2.0)]);
    assert_eq!(
        from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
        Transform(vec![TransformOperation::Scale3D(1.5, 3.0, 1.5)])
    );
}

#[test]
fn test_transform_interpolation_on_rotate() {
    use style::values::computed::Angle;

    let from = Transform(vec![TransformOperation::Rotate3D(0.0, 0.0, 1.0,
                                                           Angle::from_radians(0.0))]);
    let to = Transform(vec![TransformOperation::Rotate3D(0.0, 0.0, 1.0,
                                                         Angle::from_radians(100.0))]);
    assert_eq!(
        from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
        Transform(vec![
            TransformOperation::Rotate3D(0.0, 0.0, 1.0, Angle::from_radians(50.0)),
        ])
    );
}

#[test]
fn test_transform_interpolation_on_skew() {
    use style::values::computed::Angle;

    let from = Transform(vec![TransformOperation::Skew(Angle::from_radians(0.0),
                                                       Some(Angle::from_radians(100.0)))]);
    let to = Transform(vec![TransformOperation::Skew(Angle::from_radians(100.0),
                                                     Some(Angle::from_radians(0.0)))]);
    assert_eq!(
        from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
        Transform(vec![TransformOperation::Skew(
            Angle::from_radians(50.0),
            Some(Angle::from_radians(50.0)),
        )])
    );
}

#[test]
fn test_transform_interpolation_on_mismatched_lists() {
    use style::values::computed::{Angle, Length, LengthPercentage};

    let from = Transform(vec![TransformOperation::Rotate3D(0.0, 0.0, 1.0,
                                                           Angle::from_radians(100.0))]);
    let to = Transform(vec![
        TransformOperation::Translate3D(LengthPercentage::Length(Length::new(100.)),
                                        LengthPercentage::Length(Length::new(0.)),
                                        Length::new(0.))]);
    assert_eq!(
        from.animate(&to, Procedure::Interpolate { progress: 0.5 }).unwrap(),
        Transform(vec![TransformOperation::InterpolateMatrix {
            from_list: from.clone(),
            to_list: to.clone(),
            progress: Percentage(0.5),
        }])
    );
}