Web Animation API 实战:创建一个渐隐渐显的文字动画效果

1,674 阅读3分钟
原文链接: svgtrick.com

W3C推出的Web Animation API旨在带来CSS性能的强大,利用JavaScript的在性能和操作上的好处和灵活性,使编写动画效果更加方便和高效。

在这篇Web Animation API教程中,主要是教你使用Web Animation API实现一个渐隐渐显的文字动画效果,顺便也来熟悉下这个新的动画API在实际开发中的应用。

要实现的效果如下图所示:

先来准备基本的html结构,因为动画效果是使用Web Animation API来实现的,而现在浏览器并没有全部支持这个特性,所以在开发中特别是使用新特性的时候,要遵守优雅降级的开发原则。比如当浏览器不支持某一个特性的时候,要保证用户的基本使用体验,在这里就是保证没有动画效果的情况下,也能阅读文本。

<blockquote>
    <q>What we think, we become.</q>
    <cite>Gautama Buddha</cite>
</blockquote>

基本的CSS:

blockquote {
  font-size: 3rem;
}
cite {
  display: block;
  text-align: right;
  font-family: Verdana, Arial, sans-serif;
  margin-top: 1rem;
  font-size: .9rem;
  color: #aaa;
  font-style: normal;
}
blockquote q {
  font-family: Georgia, serif;
  font-style: italic;
  letter-spacing: .1rem;
}

这里提一下q这个元素,可以使用CSS的伪元素来定义前后的两个引号,非常方便来进行一些个性化的定制。使用伪元素也不会占用和增加实际的hmtl字符。

q {
  quotes: "“" "”" "‘" "’";
}
q:before {
    content: open-quote;
    margin-right: .8rem;
}
q:after {
  content: close-quote;
}
q:before, q:after {
  color: #ccc;
  font-size: 4rem;
}

由于动画效果是使用javascript来实现的。下面我们将会使用will-change这个属性,当javascript能正常运行的时候,它才运行;如果不能正常运行,也能正常的显示。

blockquote q span { 
  will-change: opacity, filter;
  opacity: 0;
  filter: blur(0px);
}

will-change 属性是用来提前告知浏览器我这里将会进行一些变动,分配资源来进行渲染。对于优化性能是一个不错的方法。

javascript

javascript主要包含了三个方法,splitWordsrandom number generatorfadeWords。下面来分别说下这三个方法具体干些什么。

splitWords方法是用来把q元素中的单词提取出来,使用span标签包裹起来,然后再针对每一个单词生成动画。代码如下:

function splitWords() {
  let quote = document.querySelector("blockquote q"),
  quotewords = quote.innerText.split(" "),
  wordCount = quotewords.length;
  quote.innerHTML = "";
  for (let i=0; i < wordCount; i++) {
    quote.innerHTML += "<span>"+quotewords[i]+"</span>";
    if (i < quotewords.length - 1) {
      quote.innerHTML += " ";
    }
  }
  quotewords = document.querySelectorAll("blockquote q span");
  fadeWords(quotewords);
}

第二个方法random number generator是用来生成一个随机数,在动画中用来随机的定义动画的延迟属性的值。

function getRandom(min, max) {
  return Math.random() * (max - min) + min;
}

最后一个方法是fadeWords用来实现动画效果:

function fadeWords(quotewords) {
  Array.prototype.forEach.call(quotewords, function(word) {
    let animate = word.animate([{
      opacity: 0,
      filter: "blur("+getRandom(2,5)+"px)"
    }, {
      opacity: 1,
      filter: "blur(0px)"
    }], 
    { 
      duration: 1000,
      delay: getRandom(500,3300),
      fill: "forwards"
    } 
   )
  })
}

通过改变span元素的透明度(opacity)和模糊滤镜(blur)的值来实现动画效果。在每一个元素的动画效果中,随机的定义了动画的延迟(delay),这样在实际的效果中每一个文字都是随机出现的。

最后调用splitWords这个方法来运行这个动画效果。

splitWords();

线上效果地址

当然,基于它我们还可以实现不同的动画效果:比如你可以使每个单词依次出现(通过依次增加每一个元素的延迟时间来实现),或者是指定特定的单词优先出现(通过给每一个span元素指定不同的类来实现)。充分发挥你的想象力,可以实现更多的有趣的动画效果。

本文主要是从Create a Word Fade-In Effect Using the Web Animation API这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!