Android Webview не анимирует все свойства CSS - PullRequest
0 голосов
/ 19 мая 2019

Я разрабатываю приложение React, которое будет встроено в веб-представление Android через Cordova.

Я пытаюсь анимировать Div.Deal, который должен выходить из потока HTML по умолчанию и медленно расширяться для отображения в видемодальное.

Эта проблема возникает в Android Webview, но не в Chrome на моем ноутбуке, где все работает хорошо.

При анализе анимации на DevTool (отладка USB на Android) я получаю следующие результаты:

Иногда отсутствует свойство top: The issue

А иногда присутствует свойство top (мой эффект Ripple не выполняется, хотя может ли он быть связан?): Nominal

  • Я уже пытался изменить свойство перехода CSS с all 0.5s linear на height 0.5s linear, width 0.5s linear, left 0.5s linear, top 0.5s linear
  • Я также следовал за значением window.getBouncingClientRect(), которое является правильным для всех свойств.

Вот код по умолчанию для моего div.Deal:

.Deal {
    border-radius: var(--deal-border-radius);
    background-color: var(--deal-background-color);
    position: relative;
    height: 100%;
    z-index: 0;
}

А вот метод, который выполняет анимацию (открытая анимация происходит в части 'else'ботаникdition):

 handleClick() {

          this.setState({
               opened: !this.state.opened
          })

          if (this.state.opened) {

               // I get the current height, width, top, left value of its 
               // position on the page with window.getBouncingClientRect().
               // I apply those values to get rid of % values and have px values

               this.deal.current.style.height = `${this.deal.current.getBoundingClientRect().height}px`;
               this.deal.current.style.width = `${this.deal.current.getBoundingClientRect().width}px`;
               this.deal.current.style.left = `${this.deal.current.getBoundingClientRect().x}px`;
               this.deal.current.style.top = `${this.deal.current.getBoundingClientRect().y}px`;


               // I set back position values to those kept in cssStyleState and the close animation occurs

               this.deal.current.style.height = `${this.cssStyleState.height}px`;
               this.deal.current.style.width = `${this.cssStyleState.width}px`;
               this.deal.current.style.left = `${this.cssStyleState.left}px`;
               this.deal.current.style.top = `${this.cssStyleState.top}px`;

               this.deal.current.style.boxShadow = 'var(--deal-box-shadow)';

               // I wait 500ms that the animation finish and I set up manually 
               // the CSS property to those in my CSS file, emptying the 
               // transition property value.

               setTimeout(() => {

                    this.deal.current.style.position = 'relative';

                    this.deal.current.style.height = '100%';
                    this.deal.current.style.width = '';
                    this.deal.current.style.left = '';
                    this.deal.current.style.top = '';

                    this.deal.current.style.zIndex = '0';
                    this.deal.current.style.transition = '';

               }, 500);

          } else {

               // I get the height, width, top, left value of its position on the page with window.getBouncingClientRect(), 
               // I save it in cssStyleState to keep the starting state.

               this.cssStyleState = {
                    width: this.deal.current.getBoundingClientRect().width,
                    height: this.deal.current.getBoundingClientRect().height,
                    left: this.deal.current.getBoundingClientRect().x,
                    top: this.deal.current.getBoundingClientRect().y
               };

               // I change position value to position: absolute;
               // and I manually set height, width, top, left value; 
               // Which visually gives the same result.

               // After more investigation it appears that : in the set 
               // of 4 instructions below (without zIndex), the last 
               // line will be sometime missed by android webview. I 
               // tried swaping instruction and it gives the same 
               // result.

               this.deal.current.style.height = `${this.deal.current.getBoundingClientRect().height}px`;
               this.deal.current.style.width = `${this.deal.current.getBoundingClientRect().width}px`;
               this.deal.current.style.left = `${this.deal.current.getBoundingClientRect().x}px`;
               this.deal.current.style.top = 
`${this.deal.current.getBoundingClientRect().y}px`;

               this.deal.current.style.zIndex = '1';

               this.deal.current.style.position = 'absolute';

               // Then I apply the CSS transition property on those 4 properties to fire 
               // my animation with new values. I use the timeout make sure the handler 
               // executes after the instructions aboves (to avoid a glitch).

               setTimeout(() => {
                    this.deal.current.style.transition = 'height 0.5s linear, width 0.5s linear, left 0.5s linear, top 0.5s linear';

                    this.deal.current.style.height = '50%';
                    this.deal.current.style.width = '80%';
                    this.deal.current.style.left = '10%';
                    this.deal.current.style.top = '25%';

                    this.deal.current.style.boxShadow = 'var(--deal-opened-box-shadow)';
               }, 0)

          }

Иногда мой переводчик перемещается из своей позиции и расширяется до модального режима, что является хорошим поведением (в основном на ПК и иногда на Android), иногда анимация запускается без заботы о top свойство (только на Android).РЕДАКТИРОВАТЬ: После дополнительных исследований выясняется, что: в наборе из 4 инструкций (см. Код), последняя строка будет когда-нибудь пропущено в веб-просмотре Android.Я попытался поменять местами инструкцию, и она имеет тот же эффект, в зависимости от того, какая инструкция последняя.

...