146 lines
4.3 KiB
JavaScript
146 lines
4.3 KiB
JavaScript
'use strict';
|
|
|
|
function assert_px_equals(observed, expected, description) {
|
|
assert_equals(observed.unit, 'px',
|
|
`Unexpected unit type for '${description}'`);
|
|
assert_approx_equals(observed.value, expected, 0.0001,
|
|
`Unexpected value for ${description}`);
|
|
}
|
|
|
|
function CreateViewTimelineOpacityAnimation(test, target, options) {
|
|
const timeline_options = {
|
|
subject: target,
|
|
axis: 'block'
|
|
};
|
|
if (options && 'timeline' in options) {
|
|
for (let key in options.timeline) {
|
|
timeline_options[key] = options.timeline[key];
|
|
}
|
|
}
|
|
const animation_options = {
|
|
timeline: new ViewTimeline(timeline_options)
|
|
};
|
|
if (options && 'animation' in options) {
|
|
for (let key in options.animation) {
|
|
animation_options[key] = options.animation[key];
|
|
}
|
|
}
|
|
|
|
const anim =
|
|
target.animate({ opacity: [0.3, 0.7] }, animation_options);
|
|
test.add_cleanup(() => {
|
|
anim.cancel();
|
|
});
|
|
return anim;
|
|
}
|
|
|
|
// Verify that range specified in the options aligns with the active range of
|
|
// the animation.
|
|
//
|
|
// Sample call:
|
|
// await runTimelineBoundsTest(t, {
|
|
// timeline: { inset: [ CSS.percent(0), CSS.percent(20)] },
|
|
// timing: { fill: 'both' }
|
|
// startOffset: 600,
|
|
// endOffset: 900
|
|
// });
|
|
async function runTimelineBoundsTest(t, options, message) {
|
|
const scrollOffsetProp = options.axis == 'block' ? 'scrollTop' : 'scrollLeft';
|
|
container[scrollOffsetProp] = 0;
|
|
await waitForNextFrame();
|
|
|
|
const anim =
|
|
options.anim ||
|
|
CreateViewTimelineOpacityAnimation(t, target, options);
|
|
if (options.timing)
|
|
anim.effect.updateTiming(options.timing);
|
|
|
|
const timeline = anim.timeline;
|
|
await anim.ready;
|
|
|
|
// Advance to the start offset, which triggers entry to the active phase.
|
|
container[scrollOffsetProp] = options.startOffset;
|
|
await waitForNextFrame();
|
|
assert_equals(getComputedStyle(target).opacity, '0.3',
|
|
`Effect at the start of the active phase: ${message}`);
|
|
|
|
// Advance to the midpoint of the animation.
|
|
container[scrollOffsetProp] = (options.startOffset + options.endOffset) / 2;
|
|
await waitForNextFrame();
|
|
assert_equals(getComputedStyle(target).opacity,'0.5',
|
|
`Effect at the midpoint of the active range: ${message}`);
|
|
|
|
// Advance to the end of the animation.
|
|
container[scrollOffsetProp] = options.endOffset;
|
|
await waitForNextFrame();
|
|
assert_equals(getComputedStyle(target).opacity, '0.7',
|
|
`Effect is in the active phase at effect end time: ${message}`);
|
|
|
|
// Return the animation so that we can continue testing with the same object.
|
|
return anim;
|
|
}
|
|
|
|
// Sets the start and end range for a view timeline and ensures that the
|
|
// range aligns with expected values.
|
|
//
|
|
// Sample call:
|
|
// await runTimelineRangeTest(t, {
|
|
// rangeStart: { rangeName: 'cover', offset: CSS.percent(0) } ,
|
|
// rangeEnd: { rangeName: 'cover', offset: CSS.percent(100) },
|
|
// startOffset: 600,
|
|
// endOffset: 900
|
|
// });
|
|
async function runTimelineRangeTest(t, options) {
|
|
const rangeToString = range => {
|
|
const parts = [];
|
|
if (range.rangeName)
|
|
parts.push(range.rangeName);
|
|
if (range.offset)
|
|
parts.push(`${range.offset.value}%`);
|
|
return parts.join(' ');
|
|
};
|
|
const range =
|
|
`${rangeToString(options.rangeStart)} to ` +
|
|
`${rangeToString(options.rangeEnd)}`;
|
|
|
|
options.timeline = {
|
|
axis: options.axis || 'inline'
|
|
};
|
|
options.animation = {
|
|
rangeStart: options.rangeStart,
|
|
rangeEnd: options.rangeEnd,
|
|
};
|
|
options.timing = {
|
|
// Set fill to accommodate floating point precision errors at the
|
|
// endpoints.
|
|
fill: 'both'
|
|
};
|
|
|
|
return runTimelineBoundsTest(t, options, range);
|
|
}
|
|
|
|
// Sets the Inset for a view timeline and ensures that the range aligns with
|
|
// expected values.
|
|
//
|
|
// Sample call:
|
|
// await runTimelineInsetTest(t, {
|
|
// inset: [ CSS.px(20), CSS.px(40) ]
|
|
// startOffset: 600,
|
|
// endOffset: 900
|
|
// });
|
|
async function runTimelineInsetTest(t, options) {
|
|
options.timeline = {
|
|
axis: 'inline',
|
|
inset: options.inset
|
|
};
|
|
options.timing = {
|
|
// Set fill to accommodate floating point precision errors at the
|
|
// endpoints.
|
|
fill: 'both'
|
|
}
|
|
const length = options.inset.length;
|
|
const range =
|
|
(options.inset instanceof Array) ? options.inset.join(' ')
|
|
: options.inset;
|
|
return runTimelineBoundsTest(t, options, range);
|
|
}
|