Javascript Web动画API或CSS动画关键帧?

时间:2019-08-16 09:50:46

标签: javascript css-animations web-animations-api

我希望我的页面从一个简单的动画开始,该动画介绍了我可以做的“嗨,我叫Paul,我创建网站”之类的事情。

为了实现这一目标,我认为使用Javascript Web Animations API将是一个很好的机会来立即展示我使用普通javascript的能力(我将在各节中演示框架和WordPress的能力),但是,当我开始注意到发生了一些奇怪的事情,可能是由于我没有正确使用它。

const fade = (a = 0, b = 1) => {
  return [
    { opacity: a },
    { opacity: b }
  ];
}
const glideX = (a = '-10000px', b = '0px') => {
  return [
    { marginLeft: a, position: 'absolute' },
    { display: 'block', offset:0.1 },
    { marginLeft: b, position: 'unset' }
  ];
}
const glideY = (a = '-10000px', b = '0px') => {
  return [
    { marginTop: a, position: 'absolute' },
    { display: 'block', offset:0.1 },
    { marginTop: b, position: 'unset' }
  ];
}
const animateSettings = (dur = 1500, it = 1, fill = 'forwards', ease = 'ease-in-out') => {
  return {
    duration: 1500,
    iterations: 1,
    fill: 'forwards',
    easing: 'ease-in-out'
  };
}
const start = h1.animate( fade(), animateSettings() );
start.onfinish = () => {
  myNameIs.style.display = 'block';
  const nameIn = myNameIs.animate( glideX(), animateSettings() );
  nameIn.onfinish = () => {
    const welcomeGo = h1.animate ( glideY( '0px', '10000px' ), animateSettings() )
    welcomeGo.onfinish = () => {
      console.log('all done');
    }
  }
}

Codepen:https://codepen.io/makingstuffs/pen/xxKVoKK

我希望初始文本Hi淡入。 完成后,我希望我的名字叫保罗从左边来 完成后,我希望Hi掉入页面。

这是动画的前三帧,我已经使用onfinish事件/承诺来使它起作用。

但是,一个问题是,最后一帧似乎也影响了之前一帧中的文本。

我想问一下这是我使用API​​的结果还是这是API中的错误,我最好只使用CSS关键帧和链接事件侦听器来侦听每个过渡,完成并应用特定的关键帧类?

1 个答案:

答案 0 :(得分:1)

两者都是在您的项目中使用的不错的候选人。但是请注意,Web动画API尚未(supported in Safari),因此它将在那里中断。

我在您的代码中注意到了几件事。

  • 您正在使用边距来更改元素的位置。尝试使用transform属性,因为它对动画效果更好,并且不会干扰文档流中的其他元素。我的猜测是,这会导致您的元素之间发生干扰。
  • 您要在完成前一个动画后触发下一个动画,并使用finish事件来完成。尽管在动画的持续时间是动态的情况下这是一个选项,但它似乎与您的情况无关。触发后续动画时,可以使用动画的delay属性。

您要实现的目标

第一个动画必须立即开始,并且持续时间为1500毫秒。秒动画必须在第一个动画完成后开始。只需添加一个1500毫秒的延迟,使其在第一个延迟之后开始。 第三个动画必须在前两个动画完成后开始。在开始时间的延迟中,这总计1500 * 2毫秒。我认为这应该使您更进一步。

在CSS中,它看起来像这样:

.el-one { animation: first-animation 1500ms forwards ease-in-out; }
.el-two { animation: second-animation 1500ms 1500ms forwards ease-in-out; }
.el-three { animation: third-animation 1500ms 3000ms forwards ease-in-out; }

在JS中,您必须创建3种不同的动画设置。您已经有了一个功能,可以控制动画属性,将其重写为:

const animateSettings = (delay = 0) => ({
    delay: delay,
    duration: 1500,
    iterations: 1,
    fill: 'forwards',
    easing: 'ease-in-out'
});

const animationOne = elementOne.animate(yourFirstAnimation, animateSettings());
const animationTwo = elementTwo.animate(yourSecondAnimation, animateSettings(1500));
const animationThree = elementThree.animate(yourThirdAnimation, animateSettings(3000));

何时使用Web动画API或CSS关键帧?

这取决于您是否需要计算动画。如果您无法在CSS中对动画进行硬编码,则需要使用Web动画API计算从点 a 到点 b 的距离,或者使用持续时间,延迟或其他任何方式其他属性取决于用户的输入,请使用API​​。

如果您已经知道点 a 和点 b 的像素,百分比等位置,那么使用CSS关键帧会更容易。 / p>

CSS为什么会变形?

对于拥有良好性能的动画而言,转换至关重要。它们之所以能很好地工作,是因为在转换元素时,它永远不会脱离流程,而只会操纵元素的视觉表示。这样可以防止每次移动元素时都重新绘制整个页面,例如使用margintopleft属性时发生的情况。 The chrome devtools have a tool to see what is going on with repaints.

结论

  • 使用transform属性来操作元素,这样可以提高性能,并且不会弄乱您的流程。
  • delay属性将使您能够触发 动画接after而至。
  • 如果需要使用Web动画API计算动画,则只需使用CSS。