/
githubmirror
/
amphtml
Обзор
Документация
Войти
/
githubmirror
/
amphtml
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
test/integration/test-position-observer.js
204 строки
6 KB
Kristofer Baxter
♻️ Remove Notice from JS and Markdown (#35717)
19 авг 2021, 21:21
Не верифицирован
19 авг 2021, 21:21
f564b7e
Код
Авторство
О чём код?
import {poll} from '#testing/iframe'; //TODO(aghassemi,#10878): Run in all platforms. //TODO(aghasemi, #10877): in-a-box, FIE integration tests. const config = describes.sandboxed.configure().ifChrome(); config.run('amp-position-observer', {}, function () { this.timeout(100000); const css = ` .spacer { height: 100vh; width: 2px; } #animTarget { opacity: 0; height: 10px; width: 100%; background-color: red; } `; const extensions = ['amp-animation', 'amp-position-observer']; const experiments = ['amp-animation']; const scrollboundBody = ` <amp-animation id="anim" layout="nodisplay"> <script type="application/json"> { "duration": "100ms", "animations": [ { "selector": "#animTarget", "fill": "both", "keyframes": [ { "opacity": "0" }, { "opacity": "1" } ] } ] } </script> </amp-animation> <div class="spacer"></div> <div> <amp-position-observer on="scroll:anim.seekTo(percent=event.percent)" layout="nodisplay"> </amp-position-observer> <div id="animTarget"></div> </div> <div class="spacer"></div> `; /* * scrollbound amp-animation will make the target will go * from opacity 0 to 1 with scroll. **/ describes.integration( 'scrollbound animation', { body: scrollboundBody, css, extensions, experiments, }, (env) => { it('runs animation with scroll', () => { // Not visible yet, opacity = 0; expect(getOpacity(env.win)).to.equal(0); // Scroll bring to middle of viewport, height of target is 10 env.win.scrollTo(0, getViewportHeight(env.win) / 2 + 5); // Half way: opacity = 0.5 return waitForOpacity(env.win, 'equals', 0.5) .then(() => { // Scroll to the end env.win.scrollTo(0, getViewportHeight(env.win) * 2); // All the way: opacity = 1; return waitForOpacity(env.win, 'equals', 1); }) .then(() => { // Scroll back to the top env.win.scrollTo(0, 0); // Back to starting position: opacity: 0 return waitForOpacity(env.win, 'equals', 0); }); }); } ); const animationSceneBody = ` <amp-animation id="anim" layout="nodisplay"> <script type="application/json"> { "duration": "120s", "animations": [ { "selector": "#animTarget", "fill": "both", "keyframes": [ { "opacity": "0" }, { "opacity": "1" } ] } ] } </script> </amp-animation> <div class="spacer"></div> <div> <amp-position-observer intersection-ratios="0.5" viewport-margins="10vh" on="enter:anim.start;exit:anim.pause" layout="nodisplay"> </amp-position-observer> <div id="animTarget"></div> </div> <div class="spacer"></div> `; /* * Animation scene will start when 50% visible above the 10vh margin * and paused when 50% invisible below the 10vh margin. * There is no scrollbound behavior, purely time-based animation. **/ describes.integration( 'animation scene', { body: animationSceneBody, css, extensions, experiments, }, (env) => { // TODO(#18657, aghassemi): Fails due to timeout. it.skip('plays/pauses animation scene based on visibility', () => { // Not visible yet, opacity = 0; expect(getOpacity(env.win)).to.equal(0); // Scroll to edge of visibility // ratio is 0.5 and height of element is 10 // exclusion margin is 10% of viewport // so we need to scroll = 10% * vh + 5px; const scrollBy = getViewportHeight(env.win) * 0.1 + 5; env.win.scrollTo(0, scrollBy); return waitForOpacity(env.win, 'greater-than', 0) .then(() => { // Scroll to the end env.win.scrollTo(0, getViewportHeight(env.win) * 2); // Now we need to ensure opacity is not changing anymore to prove // animation is paused. return ensureOpacityIsNoChangingAnymore(env.win); }) .then(() => { // Ok, animation is paused and given the long duration, opacity must be // stuck somewhere between 0 and 1 const opacity = getOpacity(env.win); expect(opacity).to.be.above(0); expect(opacity).to.be.below(1); }); }); } ); }); function getOpacity(win) { const animTarget = win.document.querySelector('#animTarget'); return parseFloat(win.getComputedStyle(animTarget).opacity); } function waitForOpacity(win, comparison, factor) { return poll('wait for opacity to ' + comparison + ': ' + factor, () => { if (comparison == 'equals') { return getOpacity(win) == factor; } if (comparison == 'greater-than') { return getOpacity(win) > factor; } }); } function ensureOpacityIsNoChangingAnymore(win) { return new Promise((resolve, reject) => { win.setTimeout(() => { const currOpacity = getOpacity(win); win.setTimeout(() => { if (currOpacity == getOpacity(win)) { resolve(); } else { reject('opacity changed, animation is not paused'); } }, 200); }, 200); }); } function getViewportHeight(win) { return win.document.querySelector('.spacer').offsetHeight; }