javascript动画_使用JavaScript的Web动画:动画文本

javascript动画

Julian Shapiro is a world class developer. I first met him when he dropped CSS vs. JS Animation: Which is Faster?, which caught industry attention, and then he was nice enough to return with The Simple Intro to SVG Animation. It didn't take long to realize that Julian was a special talent.

朱利安·夏皮罗(Julian Shapiro)是世界一流的开发商。 当他放弃CSS vs. JS Animation时,我第一次见到他:哪个更快? 引起了业界的关注,然后他很高兴能够将《简单入门》重新带回SVG动画 。 很快就意识到朱利安是一个特殊的才华。

Julian has recently written an exceptional book: Web Animation using JavaScript: Develop & Design. Julian has blessed us all with the fifth chapter of his book: Animating Text. Enjoy!

朱利安(Julian)最近写了一本非常出色的书:《 使用JavaScript的网络动画:开发与设计》 。 朱利安用他的书的第五章“动画文本”祝福了我们所有人。 请享用!

Since textual animation is rarely employed in webpages, using it is an easy way to impress users. That's precisely what makes this topic so much fun to learn: the underlying techniques are simple to program, but the results feel incredibly rich and complex to the user.

由于文本动画很少在网页中使用,因此使用它是打动用户的一种简便方法。 这正是使该主题变得如此有趣的原因:底层技术易于编程,但结果给用户带来了难以置信的丰富和复杂。

This article introduces you to tools that remove the tedious aspects of textual animation and equip you with an efficient workflow. Read on to learn the nuances of this dark art.

本文向您介绍了一些工具,这些工具可以消除文本动画的繁琐部分,并为您提供高效的工作流程。 继续阅读以了解这种黑暗艺术的细微差别。

文字动画的标准方法 (The standard approach to text animation)

The standard HTML elements we code sites with—divs, tables, anchor tags, and the like—are the lowest-level components of a webpage that can be styled. Consequently, these are the lowest-level components that can be animated.

我们使用divtable ,锚标记等对网站进行编码的标准HTML元素是可样式化的网页的最低级组件。 因此,这些是可以动画化的最低级别的组件。

Text does not constitute an element unto itself; a block of text is designated by the browser as a text node, which is an unstylable, lower-level component that must be contained by an element. Further complicating matters is the fact that the browser does not subdivide text nodes into grammatical components; there is no way to access individual letters, words, or sentences.

文字本身并不构成要素; 文本块由浏览器指定为文本节点 ,它是元素必须包含的无法样式化的较低级组件。 更复杂的是,浏览器没有将文本节点细分为语法成分。 无法访问单个字母,单词或句子。

Consequently, to animate text on a letter, word, or sentence basis, you have to break each text node into separate text nodes, and then wrap each of these in a new element. You can then animate them. But manually wrapping text in span elements, for example, is tedious work that results in bloated HTML.

因此,要以字母,单词或句子为基础的文本动画,必须将每个文本节点分解为单独的文本节点,然后将每个文本节点包装在一个新元素中。 然后可以为它们设置动画。 但是,例如,将文本手动包裹在span元素中是繁琐的工作,导致HTML膨胀。

It's no surprise then that text animation on the web is uncommon; it's typically too much of a hassle to deal with. This puts the web at an aesthetic disadvantage to dedicated motion design software, such as Adobe After Effects, which allows for the fine-grained animation of text—the results of which are commonly seen in TV commercials and movie title sequences. These effects can look absolutely beautiful. Unfortunately, in addition to being difficult to integrate on the web, they're also widely considered bad practice. After all, the web is a medium that prioritizes function over form, and text animation is largely about form.

不足为奇的是,网络上的文本动画并不常见。 通常这太麻烦了。 这使Web在专用运动设计软件(如Adobe After Effects)上在美学上处于劣势,该软件允许对文本进行细粒度的动画处理-其结果通常出现在电视广告和电影标题序列中。 这些效果看起来绝对漂亮。 不幸的是,除了很难集成到网络上之外,它们还被广泛认为是不好的做法。 毕竟,网络是一种优先考虑功能而不是形式的媒介,而文本动画在很大程度上与形式有关。

However, there is one textual animation use case that can carry over well to the web when used sparingly: if you pay close attention to the depictions of futuristic hardware interfaces in movies, you'll notice the common thread of text being animated into or out of view on a grammatical level. The future of computing, according to pop culture, consists of words and sentences animating with flickers, glitches, pops, and blurs. These effects look cool, and there isn't much downside to embracing them for the purposes of transitioning content into or out of view since the text had to undergo a visibility animation by one means or another. This concept of transitioning text visibility is precisely what you'll learn about in this article.

但是,有一种文本动画用例在少量使用时可以很好地延续到网络上:如果您密切关注电影中未来派硬件接口的描述,您会注意到被动画化为文本的通用线程。在语法层面上的观点。 根据流行文化,计算的未来由单词和句子组成,这些单词和句子具有闪烁,小故障,流行和模糊的动画效果。 这些效果看起来很酷,并且为了将内容转换为视图或从视图中移出,拥抱它们没有太多不利之处,因为文本必须通过一种或多种方式进行可见性动画处理。 过渡文本可见性的概念正是您将在本文中学到的。

使用Blast.js为动画准备文本元素 (Preparing text elements for animation with Blast.js)

The tool of choice for typographic animation is Blast.js, which handily breaks blocks of text into characters, words, and sentences. You can then animate the resulting parts using Velocity and its UI pack plugin.

印刷动画的首选工具是Blast.js,它可以轻松地将文本块分解为字符,单词和句子。 然后,您可以使用Velocity及其UI Pack插件为生成的零件设置动画。

NOTE: Get Blast.js at Julian.com/research/blast.

注意:从Julian.com/research/blast获取Blast.js

Blast.js has three delimiter types to define the grammatical components to be individually extracted: character, word, and sentence. Suppose you have a div that looks like this:

Blast.js具有三种定界符类型,用于定义要单独提取的语法成分:字符,单词和句子。 假设您有一个如下所示的div


<div>
	Hello World
</div>


If you call Blast on this div using the following syntax:

如果您使用以下语法在此div上调用Blast:


$("div").blast({ delimiter: "word" });


the div would turn into this:

div会变成这样:


<div class="blast-root">
	<span class="blast">Hello</span>
	<span class="blast">World</span>
</div>


As you can see, Blast separated the target div's text into text parts that are individually wrapped in span elements. If you were to instead use the character delimiter, the result would have been:

如您所见,Blast将目标div的文本分成多个文本部分,这些文本部分分别包装在span元素中。 如果改为使用character定界符,则结果将是:


<div class="blast-root">
	<span class="blast">H</span>
	<span class="blast">e</span>
	<span class="blast">l</span>
	<span class="blast">l</span>
	<span class="blast">o</span>
	<span class="blast"> </span>
	<span class="blast">W</span>
	<span class="blast">o</span>
	<span class="blast">r</span>
	<span class="blast">l</span>
	<span class="blast">d</span>
</div>


You can now animate these span elements independently. Before you dive into textual animation, however, you're going to learn more about how Blast works so you can take full advantage of its powerful features.

现在,您可以独立为这些span元素设置动画。 但是,在深入研究文本动画之前,您将了解有关Blast如何工作的更多信息,以便您可以充分利用其强大的功能。

Blast.js的工作方式 (How Blast.js works)

The goal of this section is to make you comfortable with the prospect of using Blast to break apart the text on your beloved page. Let's dive in!

本部分的目的是使您对使用Blast拆分喜爱的页面上的文本的前景感到满意。 让我们潜入吧!

divs, tables, and the other HTML elements that you're familiar with are called element nodes. An element node commonly consists of two types of children: additional element nodes and text nodes (raw text).

divstables和您熟悉的其他HTML元素称为元素节点 。 元素节点通常由两种子元素组成:附加元素节点和文本节点(原始文本)。

Take this element, for example:

以这个元素为例:


<div>
	Hello <span>World</span>
</div>


This div element is composed of two children: a text node ("Hello") and a span element node. The span element node contains a child of its own: another text node ("World").

div元素由两个子元素组成:一个文本节点(“ Hello”)和一个span元素节点。 span元素节点包含自己的子节点:另一个文本节点(“世界”)。

When Blast is called, it traverses the entirety of the target element's descendant element chain to find text nodes. With each text node, Blast executes the RegEx query associated with the specified delimiter type (character, word, or sentence) to subdivide the node into new elements, each with its own text node part. Since Blast doesn't actually subdivide element nodes—only text nodes—you can safely apply it to the entire page without worrying about breaking elements' event handlers and other expected behaviors. This versatility is crucial when using Blast on user-generated content that is often dirtied with HTML. (Say, for example, you want to separate the words in a message posted to your site's comments section so you can highlight important passages. With Blast, you can safely do so without concern for breaking the user's embedded links.)

调用Blast时,它将遍历目标元素的所有后代元素链以查找文本节点。 对于每个文本节点,Blast执行与指定的定界符类型( characterwordsentence )关联的RegEx查询,以将该节点细分为新元素,每个元素都有其自己的文本节点部分。 由于Blast实际上并不细分元素节点(仅细分文本节点),因此您可以安全地将其应用于整个页面,而不必担心破坏元素的事件处理程序和其他预期行为。 当对用户生成的内容(通常会被HTML弄脏)使用Blast时,这种多功能性至关重要。 (例如,您要分隔发布到站点评论部分的消息中的单词,以便突出显示重要的段落。借助Blast,您可以放心地这样做,而不必担心破坏用户的嵌入式链接。)

In addition to its robustness, Blast provides a high level of accuracy. It doesn't dumbly split words at spaces, nor does it split sentences at periods within words. It leverages UTF-8 character sets for Latin alphabet languages, meaning that you can accurately apply it to French, German, Spanish, English, Italian, and Portuguese content.

除了强大的功能外,Blast还提供了很高的准确性。 它不会在空格处愚蠢地拆分单词,也不会在单词中的句点拆分句子。 它针对拉丁字母语言利用了UTF-8字符集,这意味着您可以将其准确地应用于法语,德语,西班牙语,英语,意大利语和葡萄牙语内容。

Suppose you used Blast's sentence delimiter on the following paragraph. (Note that bold and italic are used below to indicate the consecutive text matches that Blast detects.) Blast correctly identified six sentences in the paragraph:

假设您在以下段落中使用了Blast的sentence定界符。 (请注意,下面使用粗体斜体表示Blast检测到的连续文本匹配项。)Blast在段落中正确标识了六个句子:

¿Will the sentence delimiter recognize this full sentence containing Spanish punctuation? ¡Yes! « Mais, oui ! » "Nested "quotes" don't break the sentence delimiter!" Further, periods inside words (e.g. Blast.js), in formal titles (e.g. Mrs. Bluth, Dr. Fünke), and in "e.g." and "i.e." do not falsely match as sentence-final punctuation. Darn. That's pretty impressive.

¿句子定界符会识别出包含西班牙标点符号的完整句子吗? 是! «Mais,哦! » “嵌套的“引号”不要破坏句子定界符!” 此外,单词(例如Blast.js),正式标题(例如Bluth夫人,Fünke博士)以及“例如”和“即”中的句点不会错误地匹配为句末标点。 真是 真是令人印象深刻。

Notice how punctuation is associated with its proper sentence, and how errant periods don't falsely demarcate sentence matches.

注意标点符号如何与其适当的句子相关联,以及错误的期间不会错误地划分句子匹配项。

With these foundations covered, it's time to run through how to use Blast.

了解了这些基础之后,就该介绍如何使用Blast。

安装 (Installation)

Blast is installed on a page like any other JavaScript plugin: embed the appropriate script link before your page's </body> tag:

Blast与其他JavaScript插件一样都安装在页面上:在页面的</body>标记之前嵌入适当的脚本链接:


<html>
	<head>My Page</head>
	<body>
		My content.
		<script src="jquery.js"></script>
		<script src="velocity.js"></script>
		<script src="blast.js"></script>
	</body>
</html>


NOTE: Blast requires jQuery (or Zepto, a jQuery alternative), and therefore must be required after jQuery. It doesn't matter whether Blast is loaded before or after Velocity.

注意:Blast需要jQuery(或Zepto,它是jQuery的替代品),因此jQuery之后必须是Blast。 爆炸是在Velocity之前还是之后加载的都没关系。

Once Blast is loaded, use it by calling .blast() on a jQuery element object. It accepts an options object as its sole argument:

加载Blast后,可通过在jQuery元素对象上调用.blast()来使用它。 它接受一个options对象作为其唯一的参数:


$element.blast({ option1: value1, option2: value 2 });


Let's run through the available options.

让我们来看看可用的选项。

选项:定界符 (Option: Delimiter)

Blast's most important option is delimiter, which accepts "character", "word", or "sentence". To separate the text within $element using the "sentence" delimiter, your code would look like this:

Blast最重要的选择是delimiter 它接受"character""word""sentence" 。 要使用“句子”定界符分隔$ element中的文本,您的代码应如下所示:


$element.blast({ delimiter: "sentence" });


Note that Blast returns the generated text wrapper elements to the jQuery selector chain so you can manipulate them, like this:

请注意,Blast将生成的文本包装器元素返回到jQuery选择器链,以便您可以像这样操作它们:


$element.blast({ delimiter: "sentence" })
		.css("opacity", 0.5);


The .css() call is applied to the individual text elements, not the parent $element that you called Blast on.

.css()调用将应用于单个文本元素,而不是您调用了Blast的父$ element

选项:customClass (Option: customClass)

Blast provides two options to make text manipulation easier: customClass and generateValueClass. customClass behaves exactly as you would expect: supply a custom class (as a string value) to be assigned to the text node wrapper elements.

Blast提供了两个选项来简化文本操作:customClass和generateValueClasscustomClass行为与您期望的完全一样:提供一个自定义类(作为字符串值)以分配给文本节点包装器元素。

Suppose you had the following div and Blast call:

假设您有以下div和Blast调用:


<div>
	Hi Mom
</div>



$("div").blast({ delimiter: "word" , customClass: "myClass" });


The div would turn into the following (note how Blast automatically assigns every text part the "blast" class by default):

div将变为以下内容(请注意,默认情况下Blast如何自动为每个文本部分分配“ blast”类):


<div>
	<span class="blast myClass">Hi</span>
	<span class="blast myClass">Mom</span>
</div>


The value in providing a custom class is in differentiating the elements generated by each Blast call. If, for example, you used Blast in two locations on your page—once in the header and once in the footer—it might be helpful to assign these two calls different classes so your subsequent JavaScript code and CSS styles can act on the text elements appropriately.

提供自定义类的价值在于区分每个Blast调用生成的元素。 例如,如果您在页面的两个位置(一次在页眉中,一次在页脚中)使用了Blast,则将这两个调用分配给不同的类可能会有所帮助,以便您以后JavaScript代码和CSS样式可以作用于文本元素适当地。

选项:generateValueClass (Option: generateValueClass)

generateValueClass takes a Boolean value (true or false) indicating whether a unique class, in the form of .blast-[delimiter]-[textValue], should be assigned to the generated text elements.

generateValueClass带有一个布尔值(true或false),指示是否应将.blast- [delimiter]-[textValue]形式的唯一类分配给生成的文本元素。

NOTE: This option is applicable only to the character and word delimiters.

注意:此选项仅适用于字符单词定界符。

The [delimiter] placeholder represents the delimiter type used in the call, and the [textValue] placeholder represents the text contained within an individual element. Consider the following example:

[delimiter]占位符表示调用中使用的定界符类型, [textValue]占位符表示单个元素中包含的文本。 考虑以下示例:


$("div").blast({ delimiter: "word" , generateValueClass: true });


The element would turn into this:

该元素将变为:


<div class="blast-root">
	<span class="blast blast-word-Hi">Hi</span>
	<span class="blast blast-word-Mom">Mom</span>
</div>


When Blast is called with the letter delimiter, the element would turn into this instead:

当使用letter定界符调用Blast时,该元素将变为:


<div class="blast-root">
	<span class="blast blast-letter-H">H</span>
	<span class="blast blast-letter-H">i</span>
	… and so on…
</div>


The generateValueClass option is useful when you need to use CSS or JavaScript to manipulate text matches based on the text contained with them. If, for example, you used this feature on a book excerpt, you could create a visualization of all instances of the word "and" by giving elements with the .blast.word-and class a yellow background:

当您需要使用CSS或JavaScript基于包含在其中的文本来操纵文本匹配时, generateValueClass选项很有用。 例如,如果您在书籍摘录中使用了此功能,则可以通过为带有.blast.word-的元素赋予类黄色背景来创建单词“ and”的所有实例的可视化:


// jQuery implementation
$(".blast-word-and").css("background", "yellow");

// Raw JavaScript implementation
document.querySelectorAll(".blast-word-and").forEach(function(item) { item.style.background = "yellow"; });



// CSS implementation
.blast-word-and {
	background: yellow;
}


Thanks to this feature, you can painlessly target text matches via either CSS or JavaScript without having to use messy custom code to individually check the text contents of each element.

借助此功能,您可以通过CSS或JavaScript轻松定位文本匹配,而不必使用混乱的自定义代码单独检查每个元素的文本内容。

选项:标签 (Option: Tag)

This option lets you specify the type of element that wraps text parts. The default value is span, but you can pass in any element type (for example, a, div, p). Consider this example:

此选项使您可以指定用于包装文本部分的元素的类型。 默认值为span ,但是您可以传入任何元素类型(例如,a,div,p)。 考虑以下示例:


<div>
Hi Mom
</div>



// Use the "div" element as the wrapper tag
$("div").blast({ delimiter: "word" , tag: "div" });


The element would consequently turn into this:

因此,该元素将变为:


<div class="blast-root">
	<div class="blast">Hi</div>
	<div class="blast">Mom</div>
</div>


This feature is useful to ensure that the resulting text elements mimic the structure of the surrounding HTML. Perhaps nearby sibling elements are all of the div type, in which case the above example may be appropriate.

此功能可用于确保生成的文本元素模仿周围HTML的结构。 也许附近的兄弟元素都是div类型的,在这种情况下,上面的示例可能是合适的。

You might also want to take advantage of the unique properties offered by different tag types. strong, for example, automatically bolds text, whereas div forces each text match to begin on a new line thanks to div's default display value of "block".

您可能还想利用不同标记类型提供的独特属性。 例如,“ strong”会自动使文本加粗,而div由于div的默认display值为"block" ,因此div强制每个文本匹配从新行开始。

命令:反向 (Command: Reverse)

You can undo Blast on an element by passing false as the sole parameter into a Blast call. Hence, if your Blasted element looked like this:

通过将false作为唯一参数传递给Blast调用,可以撤消元素上的Blast。 因此,如果您的Blasted元素如下所示:


<div class="blast-root">
	<div class="blast">Hi</div>
	<div class="blast">Mom</div>
</div>


and you passed in the following Blast call:

并且您传递了以下Blast调用:


$("div").blast(false);


the element would return to its original structure:

元素将返回其原始结构:


<div>
Hi Mom
</div>


You might be wondering how this works: when Blast is reversed, it simply destroys the generated wrapper elements, then inserts raw text where the wrapper elements were previously. Note that this will break event handlers assigned to the new elements generated by Blast, but it won't break event handlers associated with the HTML that existed prior to Blast being initially called.

您可能想知道这是如何工作的:反转Blast时,它只会破坏生成的包装器元素,然后在原始包装器元素之前插入原始文本。 请注意,这将中断分配给Blast生成的新元素的事件处理程序,但不会中断与最初调用Blast之前存在HTML关联的事件处理程序。

Reversing Blast in this way is a crucial component of textual animation since the modus operandi when animating elements on a webpage is to leave things as they were before you touched them. If, for example, you've Blasted apart a sentence in order to animate its words into view one at a time, you would subsequently reverse Blast upon completion of the animation. Consequently, JavaScript code that later interacts with the text won't have unexpected child elements that it has to parse out. In short, it's good practice to avoid leaving your HTML unnecessarily bloated so that further programmatic interaction with your elements doesn't become increasingly convoluted.

以这种方式反转冲击波是文本动画的重要组成部分,因为在对网页上的元素进行动画处理时的作案手法是使事物保持原样,然后再触摸它们。 例如,如果您为了使动画中的单词每次都动画化而炸开了一个句子,那么您将在动画完成时反转Blast。 因此,以后与文本交互JavaScript代码不会包含必须解析的意外子元素。 简而言之,最好的做法是避免不必要地使HTML膨胀,以免与元素的进一步编程交互变得越来越复杂。

NOTE: To learn more about Blast, including its unique search capabilities and its compatibility with screen-reading software, visit its documentation at Julian.com/research/blast.

注意: 要了解有关Blast的更多信息,包括其独特的搜索功能以及与屏幕阅读软件的兼容性,请访问Julian.com/research/blast上的文档。

Now that you've separated your text elements, it's time to animate them.

现在,您已经分离了文本元素,是时候对其进行动画处理了。

将文本过渡到视图中或从视图中移出 (Transitioning text into or out of view )

The most common use of textual animation is animating text in and out of view. A basic implementation of this is to animate the words in a sentence into view one after another.

文本动画的最常见用途是使文本动画可见和不可见。 这的基本实现是使句子中的单词彼此动画化。

取代现有文字 (Replacing existing text)

Let's start by creating a container div with placeholder text that will be replaced by new text that animates into place:

让我们开始创建一个带有占位符文本的容器div ,该文本将被动画到位的新文本替换:


<div>
	A message will load here shortly…
</div>


Because the div starts out as visible, Blasting the div's text results in child text elements that are visible as well. Since your goal is to animate the generated text elements into view starting from a state of invisibility, you have to make the generated text elements invisible immediately after you call Blast:

由于div开始时是可见的,因此对div的文本进行div会导致子文本元素也可见。 由于您的目标是从不可见状态开始为生成的文本元素设置动画,因此您必须在调用Blast之后立即使生成的文本元素不可见:


$("div")
	.blast({ delimiter: "word" })
	.css("opacity", 0);
	.velocity({ opacity: 1 });


This replaces the div's existing text with a new message. Then it Blasts the div using the word delimiter. Since a call to Blast returns the generated text wrapper elements to the jQuery selector chain, you can easily extend the code to set the opacity of each text element to 0. This primes the elements for the subsequent Velocity call, which consists of a simple opacity animation.

这将用新消息替换div的现有文本。 然后使用word定界符对div进行Blast。 由于对Blast的调用将生成的文本包装器元素返回到jQuery选择器链,因此您可以轻松地扩展代码以将每个文本元素的不透明度设置为0。这将为随后的Velocity调用准备元素,该调用由一个简单的不透明度组成动画。

You may have noticed that the above code results in all text parts animating into view simultaneously. This, of course, defeats the purpose of using Blast in the first place: if you wanted all of the div's content to animate into view simultaneously, you could have simply animated the div itself. The goal here is actually to achieve a successive animation sequence that consists of one text element animating after another.

您可能已经注意到,上面的代码导致所有文本部分同时显示动画。 当然,这首先会破坏使用Blast的目的:如果您希望div的所有内容同时显示在动画中,则可以简单地对div本身进行动画处理。 此处的目标实际上是实现一个连续的动画序列,该序列由一个文本元素组成,然后逐个动画。

惊人的 (Staggering)

This is where Velocity's UI pack comes into play. To impose a successive delay between animation start times within an element set, use Velocity UI pack's stagger option, which expects a duration specified in milliseconds. Applying it to the previous code example, you get:

这是Velocity的UI包发挥作用的地方。 要在元素集中的动画开始时间之间施加连续的延迟,请使用Velocity UI pack的stagger选项,该选项期望的持续时间以毫秒为单位。 将其应用于前面的代码示例,您将获得:


$("div")
	.html("This is our new message.")
	.blast({ delimiter: "word" })
	.css("opacity", 0)
	.velocity("transition.fadeIn", { stagger: 50 });


The code above produces a successive delay of 50ms between the elements' animation start times. Importantly, note the Velocity call's previous { opacity: 1 } argument for "transition.fadeIn", which is a premade fade effect included with Velocity's UI pack. Since the stagger option works with UI pack effects, this example shows the effect that mirrors animating opacity to a value only of 1.

上面的代码在元素的动画开始时间之间产生了50ms的连续延迟。 重要的是,请注意"transition.fadeIn"的Velocity调用的上一个{ opacity: 1 }参数,这是Velocity的UI包随附的预制淡入淡出效果。 由于stagger选项适用于UI Pack效果,因此本示例显示了将动画opacity镜像到仅1值的效果。

Be careful to keep stagger times to a low duration so that users aren't waiting needlessly while text fades into view. Keep in mind that the longer an element's word count, the greater the overall time an animation sequence will take to complete. Text element staggering is one of the easiest ways to slip into the bad practice of slowing down your interface.

请注意将交错时间保持较短的时间,以免用户在文本淡入时不必要地等待。 请记住,元素的字数越长,完成动画序列所花费的总时间就越长。 文本元素交错是陷入减慢界面速度的不良做法的最简单方法之一。

将文字移出视线 (Transitioning text out of view)

The code example in the previous section only animated text into—not out of—view; the div's preexisting text was immediately replaced by the new message. This doesn't necessarily make for poor motion design, but it is often beneficial from the perspective of motion design theory to unify animations such that an element fades out of view in a way that reflects the way it faded into view.

上一节中的代码示例仅将动画文本显示在视图中,而不是显示在视图之外。 div先前存在的文本立即被新消息替换。 这并不一定会导致不良的运动设计,但从运动设计理论的角度来看,统一动画通常是有益的,这样一来,元素以一种淡入视线的方式反映出其淡入视线的方式。

If you want the outward textual animation to mirror the inward animation, you could rework the code example as follows:

如果要使向外的文本动画反映向内的动画,可以对代码示例进行如下修改:


// Select the previously blasted text
$("div .blast").velocity(
	// Animate the existing text out of view with the appropriate UI pack effect
	"transition.fadeOut",
	{
		// Stagger the outward animation as you did the inward animation
		stagger: 50,
		backwards: true,
		// When this outward animation is complete, begin the inward animation
		complete: function() {
			// Proceed with the inward animation
			$("div")
			.html(message)
			.blast({ delimiter: "word" })
			.css("opacity", 0)
			.velocity({ opacity: 1 }, { stagger: 50 });
		}
	}
);


This begins by calling the Velocity UI pack transition.fadeOut effect on the text parts generated by the div having previously been Blasted. As with the inward direction, the stagger option successively offsets the individual text part animations in the outward direction. New to this call is the use of Velocity UI pack's backwards option, which pairs with stagger to reverse the target element set's order so that the last element (the last word in the sentence) animates out of view before the second-to-last element does, and that element animates out of view before the third-to-last element does, and so on. When this outward animation sequence is complete, the inward animation is called from within the complete callback.

首先从对先前已爆炸的div生成的文本部分调用Velocity UI包transition.fadeOut效果开始。 与向内方向一样,“ stagger选项会在向外方向上连续偏移各个文本部分的动画。 此调用的新功能是使用Velocity UI pack的backwards选项,该选项与stagger配对以颠倒目标元素集的顺序,以便最后一个元素(句子中的最后一个单词)在倒数第二个元素之前发出动画效果这样,该元素会在倒数第二个元素之前进行动画,以此类推。 当此向外动画序列完成时,将从complete回调中调用向内动画。

Using the backwards option for text animation provides two benefits. First, it helps mirror (create the inverse of) the inward animation, which consists of the first word animating into view before the second word does, and so on. Second, when the backward animation is immediately followed by the forward animation, the net result is an elegant chaining effect in which the last word in the backward direction and the first word in the forward direction occur back-to-back. This works to tie the two animation sequences together into what looks like one conjoined animation instead of two separate animations crudely glued together.

对文本动画使用backwards选项有两个好处。 首先,它有助于镜像(创建逆向)内向动画,该动画由第一个单词在第二个单词之前进行动画显示而组成,依此类推。 第二,当后向动画紧随其后是前向动画时,最终结果是优美的链接效果,其中后向的最后一个单词和前向的第一个单词背对背出现。 这样可以将两个动画序列捆绑在一起,看起来像一个联合动画,而不是将两个单独的动画粗暴地粘在一起。

过渡单个文本部分 (Transitioning individual text parts)

Movie title sequences are well known for their inventive typographic motion design. The technique underlying many of these effects is singling out individual text elements for animation. That's what this section covers.

电影标题序列以其创造性的印刷动作设计而闻名。 许多这些效果的基础技术是为动画选择单个文本元素。 这就是本节介绍的内容。

NOTE: For further inspiration for your UI's typographic animation, search YouTube for movie title sequences and take detailed notes! As long as you keep the principles of motion design in mind, you should feel encouraged to explore textual animation design in your interface.

注意:若要进一步了解UI的印刷动画,请在YouTube上搜索电影标题序列并做详细记录! 只要牢记运动设计的原则,就应该鼓励您在界面中探索文本动画设计。

To achieve fine-grained control over the elements that Blast generates, simply use CSS's nth-child selector and jQuery's eq() function. These functions behave similarly to one another, in that they allow for the selection of an element within a set based on that element's index. In other words, if you passed an integer value of 3 into these functions, they would target the third element (that is, third word) in the full element set (that is, multiword sentence):

要实现对Blast生成的元素的细粒度控制,只需使用CSS的nth-child选择器和jQuery的eq()函数。 这些函数的行为类似,因为它们允许根据该元素的索引在一组元素中进行选择。 换句话说,如果将整数3传递给这些函数,它们将以完整元素集(即多字句子)中的第三个元素(即第三个单词)为目标:


// CSS implementation
.blast:nth-child(3) {
	color: red;
}



// jQuery implementation
$(".blast").eq(2).css("color", "red");


Both examples above target the third element on the page that has the .blast class applied. (Note that jQuery's eq function is 0-based whereas CSS' nth-child is 1-based, hence the different integer values being passed into the examples.) Continue with a jQuery implementation to work toward a complete example:

上面的两个示例都针对应用了.blast类的页面上的第三个元素。 (请注意,jQuery的eq函数是基于0的,而CSS的nth-child是基于1的,因此将不同的整数值传递给示例。)继续执行jQuery实现以完成完整的示例:


<div>
Current status: paused
</div>

div

This Blasts a sentence, selects its third word ("paused"), fades the word out of view, replaces the faded word with a new word ("running"), then fades the new word into view. The net effect is that the status-indicating keyword within a sentence gracefully fades into a new word to alert the user of a change. This is a tremendously elegant effect that consists of only a few lines of simple code. If you were to perform this effect many times over a larger block of text, you could achieve an impressive effect in which one message appears to sporadically change into another.

这将使句子爆炸,选择其第三个单词(“已暂停”),使该单词淡出视图,用一个新单词替换该淡入单词(“运行中”),然后使新单词淡入视图。 最终结果是,句子中的状态指示关键字会逐渐淡化为一个新单词,以提醒用户更改。 这是一个非常优雅的效果,仅包含几行简单的代码。 如果要在较大的文本块上多次执行此效果,则可能会获得令人印象深刻的效果,其中一条消息似乎偶尔会变成另一条消息。

幻想地过渡文本 (Transitioning text fancifully)

You could easily swap the transition.fadeIn effect you've used thus far with another effect from Velocity's UI pack. Some of the other effects are quite fanciful, ranging from transition.shrinkIn, which causes an element to scale down into view, to transition.perspectiveDownIn, which causes an element to rotate down into view like a hinged barn door.

您可以轻松地将到目前为止使用的transition.fadeIn效果与Velocity的UI包中的另一个效果交换。 其他一些效果也很奇特,从transition.shrinkIn (使元素按比例缩小到视图中)到transition.perspectiveDownIn (使元素像旋转的谷仓门一样向下旋转到视图)不等。

NOTE: For a complete list of UI pack effects, including live demos, visit VelocityJS.org/#uiPack.)

注意:有关UI Pack效果的完整列表,包括现场演示,请访问VelocityJS.org/#uiPack。)

Keep in mind that some effects use 3D transforms (rotateX, rotateY, and translateZ), which don't work with on elements whose CSS display value is set to "inline"—the default display value for span and anchor elements in particular. The workaround is to set Blast's generated text elements to a display value of "inline-block", which keeps "inline" elements behaving as they normally do while giving them the added functionality of "block" elements (such as div and p), in which position-related properties, including 3D transforms, can be styled. Taking this display tweak into account, the inward text transition example would now look like this:

请记住,某些效果使用3D变换(rotateX,rotateY和translateZ),这些变换不适用于CSS显示值设置为“内联”(特别是span和anchor元素的默认display值)的元素。 解决方法是将Blast的生成的文本元素设置为显示值"inline-block" ,以保持"inline"元素的正常运行,同时为它们添加"block"元素的附加功能(例如div和p),在其中可以设置与位置相关的属性(包括3D变换)的样式。 考虑到此display调整,现在向内文本转换示例如下所示:


$("div")
	.html(message)
	.blast({ delimiter: "word" })
	.css({ opacity: 0, display: "inline-block" })
	.velocity("transition.perspectiveDownIn", { stagger: 50 });


This sets the Blasted text parts' display values to "inline-block" in the same call to jQuery's css() function that sets the elements' opacity to a starting value of 0.

在对jQuery的css()函数的同一调用中,这会将Blasted文本部分的display值设置为"inline-block" ,该函数将元素的opacity设置为起始值0

文字繁华 (Textual flourishes)

The final topic in this discussion of textual animation is the concept of flourishes, ambient animations that produce ongoing effects for aesthetic purposes. One example might be a string of text that flickers like a dying light bulb. Another might be having all the words in a sentence continuously animate to different shades of blue.

本文本动画讨论中的最后一个主题是蓬勃发展的概念,即为美学目的而产生持续效果的环境动画。 一个示例可能是一串闪烁的文本,就像快要死的灯泡一样。 另一个可能是使句子中的所有单词连续呈现出不同的蓝色阴影。

Both of these are bad ideas.

这两个都是坏主意。

These effects distract users and ultimately amuse only you—the developer who enjoys toying with motion design. Never include animation just for the sake of animation; if a part of your page is meaninglessly drawing the user's attention away from the parts that have utility, go back to the drawing board.

这些效果分散了用户的注意力,并最终仅使您感到开心,这是喜欢运动设计的开发人员。 切勿仅出于动画目的而包括动画。 如果页面的一部分无意义地将用户的注意力从具有实用程序的部分上移开,请返回到绘图板。

The rare exception to this is status indicators—text such as "Loading…"—that keep the user abreast of what the interface is doing. These are appropriate targets for textual flourishes because the flourishes tell the user that the interface is still processing data (as opposed to having frozen). In this way, flourishes act as an engaging visual heartbeat.

罕见的例外是状态指示符(如“ Loading…”之类的文本),它使用户了解界面的功能。 这些是文本繁荣的适当目标,因为繁荣告诉用户界面仍在处理数据(而不是冻结)。 这样,繁华便成为引人入胜的视觉心跳。

So if textual flourishes are generally considered bad practice, why are we talking about this? Because flourishes that aren't animated are often a great idea! Consider this a non-animation bonus provided by Blast: you can stylize the text elements generated by Blast to produce colorful collages and other unique typographic designs. For example, you could break apart a website's slogan text ("Delivering happiness right to your door!") word-by-word to reduce the opacity of each successive word, thereby creating a subtle gradient effect that spans the entire sentence. Here's what that code would look like:

因此,如果通常认为文字文字繁文bad节是不好的做法,那么为什么我们要谈论这一点呢? 因为没有动画的繁荣通常是个好主意! 将此视为Blast提供的非动画奖励:您可以对Blast生成的文本元素进行样式化,以生成彩色拼贴和其他独特的版式设计。 例如,您可以逐字分解网站的口号文本(“将幸福传递给您的家!”),以减少每个连续单词的不透明性,从而在整个句子中产生细微的渐变效果。 该代码如下所示:


<div>
	Hi Mom
</div>



// Blast the div then iterate through the generated text elements
$("div").blast({ delimiter: "character" }).each(function(i, element) {
	// Successively reduce the opacity of each element with an arbitrary formula
	var adjustedOpacity = 1 - i/10;
	element.style.opacity = adjustedOpacity;
});


Instead of iterating opacity values, you could also iterate RGB values to create color-based gradients. For example, if you increased the blue component of text whose color initially starts as gray, you'd produce elements that are increasingly rich in blue as you go from first to last:

除了迭代opacity值,您还可以迭代RGB值以创建基于颜色的渐变。 例如,如果您增加了文本的蓝色部分,其颜色最初以灰色开始,那么您生成的元素从头到尾的颜色会越来越丰富:


 // Blast the div then iterate through the generated text elements 
 $("div").blast({ delimiter: "character" }).each(function(i, element) { 
	 // Successively increase the blue color component of each element with an arbitrary formula 
	 var adjustedBlue = i*20; 
	 element.style.color = "rgb(0, 0," + adjustedBlue + ")"; 
 }); 


结语 (Wrapping up)

This is just the beginning of the possibilities created by granular text control. Other techniques include fine-tuning the coordinates of every letter in a word to produce a collage effect, or placing words around the circumference of a circle to mimic the typographic design you might find on a drink coaster.

这仅仅是细化文本控件创建可能性的开始。 其他技术包括微调单词中每个字母的坐标以产生拼贴效果,或将单词放置在圆圈周围以模仿您在杯垫上可能发现的版式设计。

While these techniques may be well-suited for bold, homepage centerpieces, they may not be appropriate for critical parts of your UI that are subject to repeated user interaction. Why? Because stylized text is harder to read at a glance than unstylized text. But if you consider the balance between form and function, you'll be fine!

虽然这些技术可能非常适用于粗体的主页核心内容,但它们可能不适用于UI的关键部分,而这些部分会受到重复的用户交互作用。 为什么? 因为风格化的文字比未风格化的文字一目了然。 但是,如果您考虑形式和功能之间的平衡,那会很好的!

This post has been a chapter taken from Julian's Web Animation using JavaScript book. Read the book to master the latest web animation principles--including animation performance, theory, workflow, and more.

这篇文章摘自朱利安(Julian)的《 使用JavaScript网络动画》一书 。 阅读本书以掌握最新的网络动画原理-包括动画性能,理论,工作流程等。

最新功能 (Recent Features)

令人难以置信的演示 (Incredible Demos)

讨论区 (Discussion)

  1. C
    C

    What happened to blast.js? Not working anymore and can’t find any relevant info about that.

    blast.js怎么了? 不再工作,找不到任何相关信息。

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

将您的代码包装在<pre class="{language}"></pre>标签中,链接到要嵌入的GitHub gist,JSFiddle小提琴或CodePen笔!

翻译自: https://davidwalsh.name/animating-text

javascript动画

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值