<!DOCTYPE html><metacharset=utf-8><title>Transformed progress</title><linkrel="help"href="https://drafts.csswg.org/web-animations/#calculating-the-transformed-progress"><scriptsrc="/resources/testharness.js"></script><scriptsrc="/resources/testharnessreport.js"></script><scriptsrc="../../testcommon.js"></script><scriptsrc="../../resources/easing-tests.js"></script><body><divid="log"></div><divid="target"></div><script>'use strict';for(constparamsofgEasingTests){test(t=>{consttarget=createDiv(t);constanim=target.animate(null,{duration:1000,fill:'forwards',easing:params.easing});for(constsampleTimeof[0,250,500,750,1000]){anim.currentTime=sampleTime;constportion=sampleTime/anim.effect.getComputedTiming().duration;constexpectedProgress=params.easingFunction(portion);assert_approx_equals(anim.effect.getComputedTiming().progress,expectedProgress,0.01,'The progress should be approximately '+`${expectedProgress} at ${sampleTime}ms`);}},`Transformed progress for ${params.desc}`);}// Additional tests for various boundary conditions of step timing functions.constgStepTimingFunctionTests=[{description:'Test bounds point of step-start easing',effect:{delay:1000,duration:1000,fill:'both',easing:'steps(2, start)'},conditions:[{currentTime:0,progress:0},{currentTime:999,progress:0},{currentTime:1000,progress:0.5},{currentTime:1499,progress:0.5},{currentTime:1500,progress:1},{currentTime:2000,progress:1}]},{description:'Test start bounds of step-start easing with no delay',effect:{delay:0,duration:1000,fill:'backwards',easing:'steps(1, start)'},conditions:[{currentTime:-1,progress:0},{currentTime:0,progress:1}]},{description:'Test bounds point of step-start easing with reverse direction',effect:{delay:1000,duration:1000,fill:'both',direction:'reverse',easing:'steps(2, start)'},conditions:[{currentTime:0,progress:1},{currentTime:1001,progress:1},{currentTime:1500,progress:1},{currentTime:1501,progress:0.5},{currentTime:2000,progress:0},{currentTime:2500,progress:0}]},{description:'Test bounds point of step-start easing '+'with iterationStart not at a transition point',effect:{delay:1000,duration:1000,fill:'both',iterationStart:0.25,easing:'steps(2, start)'},conditions:[{currentTime:0,progress:0.5},{currentTime:999,progress:0.5},{currentTime:1000,progress:0.5},{currentTime:1249,progress:0.5},{currentTime:1250,progress:1},{currentTime:1749,progress:1},{currentTime:1750,progress:0.5},{currentTime:2000,progress:0.5},{currentTime:2500,progress:0.5},]},{description:'Test bounds point of step-start easing '+'with iterationStart and delay',effect:{delay:1000,duration:1000,fill:'both',iterationStart:0.5,easing:'steps(2, start)'},conditions:[{currentTime:0,progress:0.5},{currentTime:999,progress:0.5},{currentTime:1000,progress:1},{currentTime:1499,progress:1},{currentTime:1500,progress:0.5},{currentTime:2000,progress:1}]},{description:'Test bounds point of step-start easing '+'with iterationStart and reverse direction',effect:{delay:1000,duration:1000,fill:'both',iterationStart:0.5,direction:'reverse',easing:'steps(2, start)'},conditions:[{currentTime:0,progress:1},{currentTime:1000,progress:1},{currentTime:1001,progress:0.5},{currentTime:1499,progress:0.5},{currentTime:1500,progress:1},{currentTime:1999,progress:1},{currentTime:2000,progress:0.5},{currentTime:2500,progress:0.5}]},{description:'Test bounds point of step(4, start) easing '+'with iterationStart 0.75 and delay',effect:{duration:1000,fill:'both',delay:1000,iterationStart:0.75,easing:'steps(4, start)'},conditions:[{currentTime:0,progress:0.75},{currentTime:999,progress:0.75},{currentTime:1000,progress:1},{currentTime:2000,progress:1},{currentTime:2500,progress:1}]},{description:'Test bounds point of step-start easing '+'with alternate direction',effect:{duration:1000,fill:'both',delay:1000,iterations:2,iterationStart:1.5,direction:'alternate',easing:'steps(2, start)'},conditions:[{currentTime:0,progress:1},{currentTime:1000,progress:1},{currentTime:1001,progress:0.5},{currentTime:2999,progress:1},{currentTime:3000,progress:0.5},{currentTime:3500,progress:0.5}]},{description:'Test bounds point of step-start easing '+'with alternate-reverse direction',effect:{duration:1000,fill:'both',delay:1000,iterations:2,iterationStart:0.5,direction:'alternate-reverse',easing:'steps(2, start)'},conditions:[{currentTime:0,progress:1},{currentTime:1000,progress:1},{currentTime:1001,progress:0.5},{currentTime:2999,progress:1},{currentTime:3000,progress:0.5},{currentTime:3500,progress:0.5}]},{description:'Test bounds point of step-end easing',effect:{delay:1000,duration:1000,fill:'both',easing:'steps(2, end)'},conditions:[{currentTime:0,progress:0},{currentTime:999,progress:0},{currentTime:1000,progress:0},{currentTime:1499,progress:0},{currentTime:1500,progress:0.5},{currentTime:2000,progress:1}]},{description:'Test bounds point of step-end easing '+'with iterationStart and delay',effect:{duration:1000,fill:'both',delay:1000,iterationStart:0.5,easing:'steps(2, end)'},conditions:[{currentTime:0,progress:0},{currentTime:999,progress:0},{currentTime:1000,progress:0.5},{currentTime:1499,progress:0.5},{currentTime:1500,progress:0},{currentTime:1999,progress:0},{currentTime:2000,progress:0.5},{currentTime:2500,progress:0.5}]},{description:'Test bounds point of step-end easing '+'with iterationStart not at a transition point',effect:{delay:1000,duration:1000,fill:'both',iterationStart:0.75,easing:'steps(2, end)'},conditions:[{currentTime:0,progress:0.5},{currentTime:999,progress:0.5},{currentTime:1000,progress:0.5},{currentTime:1249,progress:0.5},{currentTime:1250,progress:0},{currentTime:1749,progress:0},{currentTime:1750,progress:0.5},{currentTime:2000,progress:0.5},{currentTime:2500,progress:0.5},]},{description:'Test bounds point of steps(jump-both) easing',effect:{delay:1000,duration:1000,fill:'both',easing:'steps(2, jump-both)'},conditions:[{currentTime:0,progress:0},{currentTime:999,progress:0},{currentTime:1000,progress:1/3},{currentTime:1499,progress:1/3},{currentTime:1500,progress:2/3},{currentTime:2000,progress:1}]},{description:'Test bounds point of steps(jump-both) easing '+'with iterationStart and delay',effect:{duration:1000,fill:'both',delay:1000,iterationStart:0.5,easing:'steps(2, jump-both)'},conditions:[{currentTime:0,progress:1/3},{currentTime:999,progress:1/3},{currentTime:1000,progress:2/3},{currentTime:1499,progress:2/3},{currentTime:1500,progress:1/3},{currentTime:1999,progress:1/3},{currentTime:2000,progress:2/3},{currentTime:2500,progress:2/3}]},{description:'Test bounds point of steps(jump-both) easing '+'with iterationStart not at a transition point',effect:{delay:1000,duration:1000,fill:'both',iterationStart:0.75,easing:'steps(2, jump-both)'},conditions:[{currentTime:0,progress:2/3},{currentTime:999,progress:2/3},{currentTime:1000,progress:2/3},{currentTime:1249,progress:2/3},{currentTime:1250,progress:1/3},{currentTime:1749,progress:1/3},{currentTime:1750,progress:2/3},{currentTime:2000,progress:2/3},{currentTime:2500,progress:2/3}]},{description:'Test bounds point of steps(jump-none) easing',effect:{delay:1000,duration:1000,fill:'both',easing:'steps(2, jump-none)'},conditions:[{currentTime:0,progress:0},{currentTime:1000,progress:0},{currentTime:1499,progress:0},{currentTime:1500,progress:1},{currentTime:2000,progress:1}]},{description:'Test bounds point of steps(jump-none) easing '+'with iterationStart and delay',effect:{duration:1000,fill:'both',delay:1000,iterationStart:0.5,easing:'steps(2, jump-none)'},conditions:[{currentTime:0,progress:0},{currentTime:999,progress:0},{currentTime:1000,progress:1},{currentTime:1499,progress:1},{currentTime:1500,progress:0},{currentTime:1999,progress:0},{currentTime:2000,progress:1},{currentTime:2500,progress:1}]},{description:'Test bounds point of steps(jump-none) easing '+'with iterationStart not at a transition point',effect:{delay:1000,duration:1000,fill:'both',iterationStart:0.75,easing:'steps(2, jump-none)'},conditions:[{currentTime:0,progress:1},{currentTime:999,progress:1},{currentTime:1000,progress:1},{currentTime:1249,progress:1},{currentTime:1250,progress:0},{currentTime:1749,progress:0},{currentTime:1750,progress:1},{currentTime:2000,progress:1},{currentTime:2500,progress:1}]},];for(constoptionsofgStepTimingFunctionTests){test(t=>{consttarget=createDiv(t);constanimation=target.animate(null,options.effect);for(constconditionofoptions.conditions){animation.currentTime=condition.currentTime;assert_equals(animation.effect.getComputedTiming().progress,condition.progress,`Progress at ${animation.currentTime}ms`);}},options.description);}test(t=>{consttarget=createDiv(t);constanim=target.animate([{easing:'steps(1, start)',opacity:0},{opacity:1}],{easing:'linear(-2, 2)',duration:1000,fill:'both'});anim.currentTime=0;assert_equals(anim.effect.getComputedTiming().progress,-2);// Input < 0 ==> output = 0.assert_equals(getComputedStyle(target).opacity,"0");anim.currentTime=500;assert_equals(anim.effect.getComputedTiming().progress,0);// Input = 0 & before flag = false ==> output = 1.assert_equals(getComputedStyle(target).opacity,"1");anim.currentTime=1000;// Input > 0 & before flag = false ==> output = 1.assert_equals(anim.effect.getComputedTiming().progress,2);assert_equals(getComputedStyle(target).opacity,"1");},'Test global timing function with values outside [0,1] with a step '+'timing function on the keyframe');</script></body>