动画剔除字母

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 提供适用于您旅程各个阶段的云产品。 立即开始使用 $200 免费积分!

前几天我在看一个广告,他们让一些字母飞入黑色屏幕,然后揭示下面的图像。 这是一个非常酷的效果,它让我想起了 WebKit 的酷炫 -webkit-background-clip 属性,它允许你通过文本显示背景。 所以,我开始尝试看看是否可以做类似的事情。 你可以,但有一些有趣的问题......

这是最终产品

查看演示   下载文件

这只会出现在 WebKit 浏览器中(Safari、Mobile Safari、Chrome)。 下载的文件将不会包含 fancy 字体(见下文)。

剔除基础知识

没什么特别的

.display-sweet-image-behind {
   /* fallback color */
   color: white; 

   /* overrides color with nothingness */
   -webkit-text-fill-color: transparent;
   
   /* remember non WebKit browsers will see all of this EXCEPT the text */
   background: url(images/zombies-making-out.jpg) no-repeat; 

   /* the magic */
   -webkit-background-clip: text;

   font: bold 100px Impact, Sans-Serif;
}
<div class="display-sweet-image-behind">Nom nom nom</div>

移动字母

事实证明,如果你将字母包裹在 span 中,就像这样,这太酷了

<div class="display-sweet-image-behind">
<span>N</span>
<span>o</span>
<span>m</span> 
nom nom
</div>

字母仍然会被剔除,一切正常。 它不仅仅是 span,而是你将它们包裹在一个内联级元素中。 如果你使用 inline-blockblock 或任何其他元素,剔除功能将停止工作。 =(

所以,由于 span 有效,你可能会认为我们可以使用相对定位来移动它们。 太棒了!

.display-sweet-image-behind span {
   position: relative;
}
.display-sweet-image-behind span:nth-child(1) {
   top: -20px;
   left: -20px;
}

上面的代码会将第一个字母向上和向左移动。 但是不行!失败!定位方面的某些问题导致剔除失败。 双重 =( =(

作为测试,我尝试在这些 span 上使用 margin,这是允许的,所以,感谢上帝,这将用于有趣的动画时间。 虽然,因为这些是内联元素,我们只能获得左右 margin,上下 margin 没有效果。

.display-sweet-image-behind span:nth-child(1) {
   margin-left: -100px; /* remember this will yank all the letters over this far */
}

Lettering.js

所以,你需要手动将每个字母都包裹在 span 中吗? 不,那是在浪费时间。 Lettering.js 是一个 jQuery 插件,它正是这么做的。 真的。 你在元素集上调用它,它将用一个引用其位置的类名将每个字母都包裹在 span 中。

$(".display-sweet-image-behind").lettering();

超级简单,超级酷。 我应该早点想到的。

动画

这里的最终目标是让字母自己动画到正确位置。 所以,以下是最终示例的标记

<div id="poster">
	<h1>Red Sonja</h1>
	<p>Coming 2011</p>
</div>

我们将使用 Lettering.js 将所有字母都包裹在 span 中,只需一行 JavaScript 代码

$("#poster h1, #poster p").lettering();

对于剔除字母,我们将赋予它们一个过渡效果,这样,它们任何发生变化的属性都会进行动画处理。 只有 WebKit 浏览器会进行剔除,但我们也可以让字母的行为保持一致。

#poster h1 span { 
	-webkit-transition: all 2.5s;
	-moz-transition: all 2.5s;
	-o-transition: all 2.5s;
}

Lettering.js 应用的类名为 char1char2 等。 所以,我们将使用这些类来应用较大的 margin,并将字母踢出页面。

#poster h1 span.char1 { margin-left: -1450px; } 
#poster h1 span.char2 { margin-left: 200px; }
#poster h1 span.char3 { margin-left: 200px; }
#poster h1 span.char5 { margin-left: 1450px; }
#poster h1 span.char6 { margin-left: 200px; }
#poster h1 span.char7 { margin-left: 200px; }
#poster h1 span.char8 { margin-left: 200px; }
#poster h1 span.char9 { margin-left: 200px; }

我们将让动画在短时间延迟后开始。 这将让 Lettering.js 有机会完成它的工作,并让 fancy 字体加载。 此外,这是一种“体验”效果,等待一秒钟只会让它更有悬念。

我们将做的是等待一秒钟,然后向 html 元素应用一个类名。

setTimeout(function() {$('html').addClass("step-one");}, 1000);

我们将使用该类名来覆盖我们设置的所有 margin,将它们重置为零,并将字母恢复到自然位置。

.step-one #poster h1 span { margin: 0; }

演示中的其他字母也使用 Lettering.js span,并通过 CSS 过渡和延迟应用的类名来完成它们的动画,只是它们不是剔除。 因为它们不是剔除(只是白色文本),所以我们**可以**使用 position: relative

让我们随机设置它们的 position,然后让动画的“第二步”在几秒钟后发生,此时一个类名将把它们踢回到正确位置。

$("#poster p span").each(function() {  
   $(this).css({ 
      top: -(Math.floor(Math.random()*1001)+1500), 
      left: Math.floor(Math.random()*1001)-500,  
   }); 
});

setTimeout(function() {$('html').addClass("step-two");}, 3000); 

这次,我们必须使用 !important 规则,因为 jQuery 会使用内联样式来应用 CSS 值,而 !important 是用来覆盖它的。

.step-two #poster p span { 
  top: 0 !important; 
  left: 0 !important; 
}

总结

如果你好奇,这里使用的字体是 Newcomen,可以在 Typekit 上获取。

尽管 margin 只能处理左右 margin,但我得到的上下动画是通过对父元素的顶部 padding 进行动画处理来实现的。 狡猾。

哦,我也不知道他们是否真的会重拍红索尼娅。 似乎是谣言

查看演示   下载文件