1. 缓动效果
给过渡和动画加上缓动效果(比如具有回弹效果的过渡过程)
回弹效果是指当一个过渡达到最终值时,往回倒一点,然后再次回到最终值,如此往复一次或多次,并逐渐收敛,最终稳定在最终值。
假设要用一个元素来模拟一个下落的小球,我们会把 transform 属性从 none 过渡到 translateY(350px) 来模拟这个下落过程。
1.1 弹跳动画
CSS 提供了一个 cubic-bezier()
函数,允许我们指定自定义的调速函数。
- 它接受四个参数,分别代表两个控制锚点的坐标值,我们通过这两个控制锚点来指定想要的贝塞尔曲线。
- 语法形式是这样的:cubic-bezier(x1, y1, x2, y2),其中 (x1, y1) 表示第一个控制锚点的坐标,而 (x2, y2) 是第二个。
- 曲线片断的两个端点分别固定在(0,0) 和 (1,1),前者是整个过渡的起点(时间进度为零,动画进度为零),后者是终点(时间进度为 100%,动画进度为 100%)
<!DOCTYPE html>
<html><head><style> @keyframes bounce {60%, 80%, to {transform: translateY(400px);animation-timing-function: ease;}70% {transform: translateY(300px);}90% {transform: translateY(360px);}}.ball {width: 0;height: 0;padding: 1.5em;border-radius: 50%;margin: auto;background: red radial-gradient(at 30% 30%, #fdd, red);animation: bounce 2s cubic-bezier(0.1, 0.25, 1, 0.25) forwards;}body {background: linear-gradient(skyblue, white 450px, yellowgreen 0);min-height: 100vh;} </style></head><body><div class="ball"></div></body>
</html>
1.2 弹性过渡
假设有一个文本输入框,每当它被聚焦时,都需要展示一个提示框。这个提示框用来向用户提供帮助信息,比如字段值的正确格式等
CSS 属性
transform-origin
更改一个元素变形的原点。
<!DOCTYPE html>
<html><head><style> input:not(:focus) + .callout:not(:hover) {/*隐藏.callout*/transform: scale(0);transition: 0.25s transform;}.callout {transition: 0.5s cubic-bezier(0.25, 0.1, 0.3, 1.5) transform;transform-origin: 1.4em -0.4em;}/* Styling */body {padding: 1.5em;font: 200%/1.6 Baskerville;}input {display: block;padding: 0 0.4em;font: inherit;}/*提示框样式*/.callout {position: absolute;max-width: 14em;padding: 0.6em 0.8em;border-radius: 0.3em;margin: 0.3em 0 0 -0.2em;background: #fed;border: 1px solid rgba(0, 0, 0, 0.3);box-shadow: 0.05em 0.2em 0.6em rgba(0, 0, 0, 0.2);font-size: 75%;}/*三角形的箭头*/.callout:before {content: "";position: absolute;top: -0.4em;left: 1em;padding: 0.35em;background: inherit;border: inherit;border-right: 0;border-bottom: 0;transform: rotate(45deg);} </style></head><body><label>Your username:<input value="leaverou"></input><span class="callout">Only letters, numbers, underscores (_) and hyphens (-) allowed!</span></label></body>
</html>
2. 逐帧动画
以最常见的 “加载中” 的效果为例:
使用step()函数,它可以传入一个参数,表示此次动画是分几步完成的,例如,step(8) 表示此次动画是分8部完成,也就是总共8帧,且逐帧匀速去执行的。
<!DOCTYPE html>
<html><head><style> @keyframes loader {to {background-position: -800px 0;}}.loader {width: 100px;height: 100px;text-indent: 999px;overflow: hidden; /* Hide text */background: url(http://dabblet.com/img/loader.png) 0 0;animation: loader 1s infinite steps(8);} </style></head><body><div class="loader">Loading…</div></body>
</html>
3. 闪烁效果
通过数次闪烁(不超过三次)来提示用户界面中有某处发生了变化。
- 比如对整个元素进行闪烁(通过 opacity 属性),
- 对文字的颜色进行闪烁(通过 color 属性),
- 对边框进行闪烁(通过 border-color 属性),等等
animation-direction
的 唯 一 作 用 就 是 反 转 每 一 个 循 环 周 期(reverse),或第偶数个循环周期(alternate),或第奇数个循环周期(alternate-reverse)。它的伟大之处在于,它会同时反转调整函数,从而产生更加逼真的动画效果
<!DOCTYPE html>
<html><head><style> @keyframes blink-1 {/*让状态切换发生在每个循环周期的中间*/50% {color: transparent;}}@keyframes blink-2 {to {color: transparent;}}p {padding: 1em;background: gold;}.blink-smooth-1 {animation: 1s blink-1 3;}.blink-smooth-2 {animation: 0.5s blink-2 6;animation-direction: alternate;}.blink {animation: 1s blink-1 3 steps(1);} </style></head><body><p class="blink-smooth-1">Peek-a-boo!</p><p class="blink-smooth-2">Peek-a-boo!</p><p class="blink">Peek-a-boo!</p></body>
</html>
4. 打字动画
一段文本中的字符逐个显现,模拟出一种打字的效果。
核心思路就是让容器的宽度成为动画的主体:把所有文本包裹在这个容器中,然后让它的宽度从 0 开始以步进动画的方式、一个字一个字地扩张到它应有的宽度。并不适用于多行文本
- 用 white-space:nowrap; 来阻止文本折行
- overflflow: hidden;,超出宽度的文本裁切掉
- 逐帧动画steps()所需要的步进数量是由字符的数量来决定的
- ch 单位,表示“0”字形的宽度。在等宽字体中,“0”字形的宽度和其他所有字形的宽度是一样的。
- 用右边框来模拟光标效果,infinite 关键字循环闪烁光标
<!DOCTYPE html>
<html><head><style> @keyframes typing {from {width: 0;}}@keyframes caret {50% {border-right-color: transparent;}}h1 {font: bold 200% Consolas, Monaco, monospace;/*width: 8.25em;*/width: 15ch;white-space: nowrap;overflow: hidden;border-right: 0.05em solid;animation: typing 8s steps(15), caret 1s steps(1) infinite;} </style></head><body><h1>CSS is awesome!</h1></body>
</html>
5. 状态平滑的动画——暂停动画
不是所有动画都是在页面一加载好就立即播放的。
通过动画来响应用户的动作。用户的动作会随时中断动画,而此时在默认情况下,动画只会立即停止播放,并生硬地跳回开始状态
有一个属性正好是为暂停动画的需求专门设计的:animation-play-state
<!DOCTYPE html>
<html><head><style> @keyframes panoramic {to {background-position: 100% 0;}}.panoramic {width: 150px;height: 150px;background: url("http://c3.staticflickr.com/3/2671/3904743709_74bc76d5ac_b.jpg");background-size: auto 100%;animation: panoramic 10s linear infinite alternate;animation-play-state: paused;}.panoramic:hover,.panoramic:focus {animation-play-state: running;} </style></head><body><div class="panoramic"></div></body>
</html>
把动画加在 .panoramic
这条样式中,但是让它一开始就处于暂停状态,直到 :hover
时再启动动画。这再也不是添加和取消动画的问题了,而只是暂停和继续一个一直存在的动画,因此再也不会有生硬的 跳回现象了
6. 沿环形路径平移的动画
用CSS 动画来让一个元素沿着环形路径动起来
我们希望它只是沿着环形进行移动,同时保持自己本来的朝向
6.1 需要两个元素的解决方案
用内层的变形来抵消外层的变形效果
- 对头像元素设置另一个旋转动画,让它以相反的方向自转一周,这两层旋转的作用会在头像上相互抵消,我们只会看到父元素旋转所产生的环绕动作
- 让内层动画从父元素那里继承所有的动画属性,然后把动画名覆盖掉
<!DOCTYPE html>
<html><head><style> @keyframes spin {to {transform: rotate(1turn);}}.avatar {animation: spin 3s infinite linear;transform-origin: 50% 150px;}.avatar > img {animation: inherit;animation-direction: reverse;/*reverse 值,可以得到原始动画的反向版本*/}/* Anything below this is just styling */.avatar {width: 50px;margin: 0 auto;border-radius: 50%;overflow: hidden;}.avatar > img {display: block;width: inherit;}.path {width: 300px;height: 300px;padding: 20px;border-radius: 50%;background: #fb3;} </style></head><body><div class="path"><div class="avatar"><img src="http://lea.verou.me/book/adamcatlace.jpg" /></div></div></body>
</html>
6.2 单个元素的解决方案
用两次位移变形(translate)来代替变形原点(transform-origin)的作用
每个
transform-origin
都是可以被两个translate()
模拟出来的
transform: rotate(30deg);
transform-origin: 200px 300px;
/*等价*/
transform: translate(200px, 300px) rotate(30deg) translate(-200px, -300px);
transform-origin: 0 0;
每个变形函数并不是只对这个元素进行变形,而且会把整个元素的坐标系统进行变形,从而影响所有后续的变形操作。
可以把两套动画合并为一套,并只用在 .avatar这一个元素上
把头像放在圆心并以此作为起点,我们就可以消除最开始的那两个位移操作了
<!DOCTYPE html>
<html><head><style> @keyframes spin {from {transform: rotate(0turn) translateY(-150px) translateY(50%)rotate(1turn);}to {transform: rotate(1turn) translateY(-150px) translateY(50%)rotate(0turn);}}.avatar {animation: spin 3s infinite linear;}/* Anything below this is just styling */.avatar {display: block;width: 50px;margin: calc(50% - 25px) auto 0;border-radius: 50%;overflow: hidden;}.path {width: 300px;height: 300px;padding: 20px;margin: 100px auto;border-radius: 50%;background: #fb3;} </style></head><body><div class="path"><img src="http://lea.verou.me/book/adamcatlace.jpg" class="avatar" /></div></body>
</html>
最后
整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。
有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享
部分文档展示:
文章篇幅有限,后面的内容就不一一展示了
有需要的小伙伴,可以点下方卡片免费领取