Я разрабатываю приложение React, которое будет встроено в веб-представление Android через Cordova.
Я пытаюсь анимировать Div.Deal, который должен выходить из потока HTML по умолчанию и медленно расширяться для отображения в видемодальное.
Эта проблема возникает в Android Webview, но не в Chrome на моем ноутбуке, где все работает хорошо.
При анализе анимации на DevTool (отладка USB на Android) я получаю следующие результаты:
Иногда отсутствует свойство top:
А иногда присутствует свойство top (мой эффект Ripple не выполняется, хотя может ли он быть связан?):
- Я уже пытался изменить свойство перехода 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.Я попытался поменять местами инструкцию, и она имеет тот же эффект, в зависимости от того, какая инструкция последняя.