去年慕名去电影院看了星战的最新作《原力觉醒》 。故事简单,不过里面的场景和人物(非常喜欢汉·索洛,可惜了)特别有趣。光剑的吱吱声,武士的服饰,海岛上的拜师(卢克终于出现了)……和中土世界(You walk a lonely road, Oh! How far you are from home…)不同,星战世界处处展现出了一种神秘的东方哲学。
看完了电影后,我就把星战的整个系列看了一遍。星战,在每部电影的开头都会有一段经典的字幕动画,黄色的文字呈梯形向前方流动,渐渐消失,背景则是漆黑的宇宙星空。简单,但令人印象深刻。
昨天下午在查找资料的时候,无意中看到了一篇CSS3 3D 转换的介绍 ,胡乱看到了这张图:
等等,这不是星战的字幕吗?于是抱着好玩的心态,写出了这个 H5 动画 。
准备工作
文本编辑器
支持 H5 的浏览器
JQuery
乐事薯片
首先,我们来构建一个跟浏览器窗口大小一样的黑色画布 div.paper
。
<!DOCTYPE html>
<html lang= "en" >
<head>
<meta charset= "UTF-8" >
<title></title>
<script src= "https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js" ></script>
</head>
<body>
<div class= "paper" >
</div>
</body>
</html>
充满整个窗口……
.paper {
height : 100% ;
width : 100% ;
background-color : black ;
}
查看一下效果,整个界面惨白一片……
查看界面元素可以发现,此时 div.paper
的 hight 为 0,并没有像我们写的 height: 100%
那样等于窗口的高度。为什么呢?
我们知道这里的 100% 指的是相对父级元素高度的 100%,div.paper
的父级是 body
,而此时 body
的高度也为 0,于是我们加上
body {
height : 100% ;
}
查看一下效果,整个界面依旧惨白一片……
查看界面元素可以发现,此时 body
的高度依然为 0,再来看上面的 HTML 代码,原来 body
上面还有 html
元素,于是我们加上:
html {
height: 100%;
}
啧啧,大功造成。然后去除掉 body
的内边距(padding),再来看一下效果。
PERFECT
类容文字元素
我们加上一个 div#content
元素作为文字层。
<body>
<div class= "paper" >
<div id= "content" >
<p> A long time ago, in a galaxy far, far away...</p>
<br><br>
<p> Episode IV</p>
<p> A NEW HOPE</p>
<p> It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire.</p>
<p> During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon,the DEATH STAR,an armored space station with enough power to destroy an entire planet.</p>
<p> Pursued by the Empire's sinister agents,Princess Leia races home aboard her starship,custodian of the stolen plans that can save her people and restore freedom galaxy...</p>
</div>
</div>
</body>
设置字体、字号、颜色和文字居中。
body {
height : 100% ;
padding : 0 ;
margin : 0 ;
font-family : "lucida grande" , "lucida sans unicode" , lucida , helvetica , "Hiragino Sans GB" , "Microsoft YaHei" , "WenQuanYi Micro Hei" , sans-serif ;
color : #ffda00 ;
font-size : 4em ;
text-align : center ;
}
来看看效果。
噗……怎么上面出现了一个白框啊。
冷静下来,查看元素,原来上面之所以会出现一个白框,是因为“A long time ago”这一个段落 p
的外边距(margin)穿过了 div.paper
,到了 div.paper
的上方, 这种规则称为外边距叠加 ,由于外边距是透明的,因此它呈现出了父元素 body
的白色。
解决方法很简单。
设置 div.paper
内边框,使得子元素的外边距(margin)无法穿透。
设置 body
的背景色。
这里,我使用方法二。
添加滚动条
设置 content
的样式、高度、宽度、居中当然还有滚动条。
#content {
box-sizing : border-box ;
margin : 0 auto ;
width : 80% ;
height : 100% ;
overflow : scroll ;
}
看看效果。
哎哟,不错哦。
CSS3的3D转换
最关键的部分到了,根据 w3school 的这个示例 ,实现星战那样的 3D 字幕涉及到 perspective 和 rotateX 属性。
照葫芦画瓢, 我们给 body
和 div.paper
添加 3D 变换:
body {
/*省略*/
perspective : 500 ;
-webkit-perspective : 500 ;
}
.paper {
/*省略*/
transform : rotateX ( 60deg );
-webkit-transform : rotateX ( 60deg );
}
看看效果。
good。
jQuery动画
下面我们来一起加上动画,让字幕从开始滚动到结尾。
虽然 CSS3 有动画的功能,但是我还是选择用 jQuery 来做动画。(懒……)
jQuery 动画是用 animate
函数来完成的。只需要给出动画结束后某属性 的值和动画时间(非必需)等参数,即可创建针对该参数的动画,参考w3school 关于 JQuery 动画的介绍 。
这里涉及到两个属性,scrollTop 和scrollHeight 。
scrollTop 可以控制滚动条的滚动高度,scrollHeight 可以得到滚动内容的实际高度。具体可以参考上面的链接,讲的很详细。
知道了 animate
函数和必要时属性后,很快的写下了代码。scrollTop
属性从开始的 0,经过 scrollHeight * 20
毫秒,匀速的变为了 scrollHeight
。
$ ( function (){
var scrollHeight = $ ( "#content" )[ 0 ]. scrollHeight ;
var scrollTop = $ ( "#content" )[ 0 ]. scrollTop ;
$ ( "#content" ). animate ({ scrollTop : scrollHeight }, scrollHeight * 20 , "linear" );
};
最后,隐藏滚动条。
#content {
/*省略*/
overflow : hidden ;
}
嗯,大功告成。不过还是有些问题,一开始应该是没有文字的。我们可以在 div#content
开头加上一个空白区。
<div class= "content" >
<div class= "empty-content top" ></div>
<p> A long time ago, in a galaxy far, far away...</p>
...
.empty-content {
box-sizing : border-box ;
width : 100% ;
height : 100% ;
}
这样就差不多了。当然我们还可以加图片背景,加背景音乐。这里就不做了……
动画演示 |
源码