我有一个带有CSS关键帧动画的React应用程序来更改文本的外观,并使用setState和setInterval通过JS动态更改字体。
我同步关键帧动画以便在调用setInterval的同时开始播放,并且Chrome / Safari桌面上的一切正常。在iOS上的Safari / Chrome / Firefox上,动画闪烁,并且通常不同步。有趣的是,在Safari上如果我在初始加载后刷新页面,一切都会正常工作。
我已经在这里阅读了许多类似问题的主题,但没有一个解决方案适合我。我尝试添加-webkit-backface-visibility: hidden;
,body {-webkit-transform:translate3d(0,0,0);}
,并尝试在动画开头添加延迟以抵消闪烁。没有任何效果。
以下是实时链接:https://stoic-khorana-e0bd2c.netlify.com/
这是代码 - 它是一个小应用程序,基本上只是一个启动页面:https://github.com/themarquisdesheric/el4d/tree/master/src
我延迟了“AKA'显示,然后另一个延迟的名称改变开始。
SCSS:
.aka-container {
.aka {
opacity: 0;
animation: showAKA 400ms 750ms ease-out forwards;
}
.name-changer {
animation: fade 1500ms infinite paused;
&.playing { animation-play-state: running; }
}
}
@keyframes showAKA {
20%,
100% { opacity: 1; }
}
@keyframes fade {
0% { opacity: 0; }
20%,
80% { opacity: 1; }
100% { opacity: 0; }
}
这是React组件:
class NameChanger extends Component {
state = {
name: null,
fontFamily: null,
index: 0,
playing: false
};
componentDidMount() {
window.setInterval(this.changeName, 1500);
this.setState({ playing: true });
}
changeFont = (index) => {
switch (index) {
case 0:
return 'Sedgwick Ave Display';
case 1:
return 'Bangers';
case 2:
return 'Luckiest Guy';
default:
return 'Bangers';
}
};
changeName = () => {
const names = ['ol lightsy', 'eladi-da', 'el-40'];
const { index } = this.state;
const { changeFont } = this;
this.setState(prevState => ({
name: names[index],
fontFamily: changeFont(index),
index: (index === names.length - 1)
? 0
: prevState.index + 1
}));
};
render() {
const { name, fontFamily, playing } = this.state;
return (
<span
className={`name-changer ${playing ? 'playing' : ''}`}
style={{
fontFamily,
position: 'relative',
top: (name === 'el-40') ? '.25rem' : ''
}}
>
{name}
</span>
);
}
}
我想知道为什么这在Chrome中运行良好,但在移动设备上有问题。预先感谢您的帮助!
答案 0 :(得分:0)
如果它认为页面正在滚动/缩放,则证明iOS pauses timers。这适用于iOS上的Safari,Chrome和Firefox。
我通过删除使用setInterval并使用animationiteration
事件实现相同效果来解决此问题。显然,动画自己的计时器是受到尊重的,而像setInterval这样的计时器则不然。
class NameChanger extends Component {
state = {
name: null,
fontFamily: null,
index: 0,
playing: false
};
componentDidMount() {
const { span, changeName } = this;
span.addEventListener('animationiteration',
() => changeName()
);
this.setState({ playing: true });
}
changeFont = (index) => {
switch (index) {
case 0:
return 'Sedgwick Ave Display';
case 1:
return 'Bangers';
case 2:
return 'Luckiest Guy';
default:
return 'Bangers';
}
};
changeName = () => {
const names = ['ol lightsy', 'eladi-da', 'el-40', 'elautopilot'];
const { index } = this.state;
const { changeFont } = this;
this.setState(prevState => ({
name: names[index],
fontFamily: changeFont(index),
index: (index === names.length - 1)
? 0
: prevState.index + 1
}));
};
render() {
const { name, fontFamily, playing } = this.state;
return (
<span
className={`name-changer ${playing ? 'playing' : ''}`}
ref={span => this.span = span}
style={{
fontFamily,
position: 'relative',
top: (name === 'el-40') ? '.25rem' : ''
}}
>
{name}
</span>
);
}
}