一、效果预览
v.douyin.com/sGY12zHKLqQ... 复制此链接,打开Dou音搜索,直接观看视频!
本案例实现了一个充满未来感的赛博朋克风格动态海报,主要特性包括:
- 具有深度感的3D文字动画
- "START"与"FIGHT"的动态切入效果
- 标题字母的次第旋转动画
- 星空背景与动态光影效果
二、技术架构解析
1. 基础结构设计
html
<div class="startfight">
<img src="./hologram-start.png" class="start">
<img src="./hologram-fight.png" class="fight">
<h2 class="byline">
<span>T</span><span>h</span><span>e</span>...
</h2>
</div>
设计要点:
- 使用三层结构:背景层 + 主视觉层 + 标题层
- 图片使用透明PNG格式
- 标题采用拆分字母的独立动画方案
2. 核心CSS技术栈
(1) 现代CSS重置方案
css
/* 精准选择器重置 */
html, body, div, span, ... {
margin: 0;
padding: 0;
border: 0;
font: inherit;
vertical-align: baseline;
}
/* 可选优化方案 */
* {
box-sizing: border-box;
animation: forwards; /* 保持动画结束状态 */
}
优化建议:
- 使用Modern Normalize替代手动重置
- 添加
will-change
属性优化动画性能
css
.start, .fight {
will-change: transform, opacity;
}
(2) 三维空间构建
css
.startfight {
perspective: 800px;
transform-style: preserve-3d;
}
三维坐标系原理:
lua
+Y
|
|
+-------+X
/
/
+Z (用户视角方向)
perspective
:视距(类似摄像机焦距)transform-style: preserve-3d
:启用3D变换上下文
(3) 精准居中定位
css
.startfight {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
定位方案对比:
方法 | 优点 | 缺点 |
---|---|---|
transform居中法 | 自适应内容尺寸 | 需要明确父级定位 |
Flex布局 | 代码简洁 | 需要容器高度 |
Grid布局 | 二维控制灵活 | 兼容性要求 |
三、动画系统深度解析
1. 主视觉动画架构
css
@keyframes start {
0% { opacity: 0; transform: scale(1.5); }
20% { opacity: 1; }
89% { transform: scale(1); }
100% { transform: translateZ(-1000em); }
}
.start {
animation: start 10s ease-out infinite;
}
动画阶段分解:
- 初始爆发:放大150% + 透明度渐变
- 稳定展示:保持100%尺寸1.5秒
- 空间消逝:Z轴方向位移产生景深效果
2. 标题文字动画系统
css
.byline span {
animation: spin-letters 10s linear infinite;
display: inline-block;
}
@keyframes spin-letters {
0%,10% { transform: rotateY(90deg); }
30% { opacity: 1; }
70%,86% { transform: rotateY(0); }
95%,100% { opacity: 0; }
}
动画设计技巧:
- 字母独立动画:每个
<span>
独立触发动画 - 延迟触发机制:通过
animation-delay
实现波浪效果
css
.byline span:nth-child(1) { animation-delay: 0.1s; }
.byline span:nth-child(2) { animation-delay: 0.2s; }
/* ...以此类推... */
3. 三维运动曲线优化
css
.fight {
animation: fight 10s ease-out infinite;
}
@keyframes fight {
0% { transform: scale(1.5) translateY(1em); }
90% { transform: scale(1); }
100% { transform: translateZ(-1000em); }
}
贝塞尔曲线调优:
css
animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
四、性能优化方案
1. 渲染层提升
css
.start, .fight {
transform: translateZ(0);
backface-visibility: hidden;
}
2. 动画属性优化
优化属性 | 性能消耗 | 推荐度 |
---|---|---|
transform | 低 | ★★★★★ |
opacity | 低 | ★★★★★ |
box-shadow | 高 | ★★☆ |
filter | 中 | ★★★☆ |
3. 硬件加速策略
css
.startfight {
transform: translate3d(-50%, -50%, 0);
}
五、扩展实践建议
- 添加交互控制
javascript
document.querySelector('.startfight').addEventListener('click', () => {
element.style.animationPlayState = 'paused';
});
- 响应式适配方案
css
@media (max-width: 768px) {
.startfight {
perspective: 400px;
transform: translate(-50%, -50%) scale(0.8);
}
}
- WebGL增强效果
javascript
// 使用Three.js添加粒子效果
const particles = new THREE.Points(geometry, material);
scene.add(particles);
六、完整代码获取
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>xqdz</title>
<!-- 模块化思想 -->
<link rel="stylesheet" href="./common.css">
</head>
<body>
<div class="startfight">
<img src="./hologram-start-1742982734269.png" class="start" alt="">
<img src="./hologram-fight-1742983206763.png" class="fight" alt="">
<h2 class="byline">
<span>T</span>
<span>h</span>
<span>e</span>
<span>F</span>
<span>o</span>
<span>r</span>
<span>c</span>
<span>e</span>
<span>A</span>
<span>w</span>
<span>a</span>
<span>k</span>
<span>e</span>
<span>n</span>
<span>s</span>
</h2>
</div>
</body>
</html>
css
/* CSS Reset */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {/* * 性能不太好,所以我们宁愿列出来所有的标签 */
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* Optional: Remove default anchor styles */
a {
text-decoration: none;
color: inherit;
}
/* Optional: Set a consistent box-sizing */
* {
box-sizing: border-box;
}
/* 业务样式 */
html,body{
height: 100vh;
}
body{
background:#000 url('./background.jpg') no-repeat center;
background-size: cover;
}
.startfight{
perspective: 800px;
transform-style: preserve-3d;
/* em 相对长度单位 1em既是当前字体大小 */
height: 17em;
width: 34em;
position:absolute;
top:50%;
left:50%;
/* 移动 根据自身大小 */
transform: translate(-50%,-50%);
/* background-color:red 背景调试法 */
}
img{
width:100%;
}
.start,.fight,.byline{
position: absolute;
}
.start{
top:-0.75em;
transform: translate(0,-25%);
}
.fight{
bottom:-0.5em;
transform: translate(0,20%);
}
.byline{
color: white;
font-size: 2.25em;
left: -2em;
right: -2em;
text-align: center;
transform: translate(-5%,0);
text-transform: uppercase;
top: 42%;
}
/* 动画设计 */
.start{
/* 动画名字 + keyframes 定义动作 */
animation: start 10s ease-out infinite;
}
.fight{
animation: fight 10s ease-out infinite;
}
@keyframes start {
/* 动画开始,元素完全透明并放大到 1.5 倍 */
0% {
opacity: 0;
transform: scale(1.5);
}
/* 动画进行到 20%,元素变为完全不透明 */
20% {
opacity: 1;
}
/* 动画进行到 89%,元素保持不透明并恢复到原始大小 */
89% {
opacity: 1;
transform: scale(1);
}
/* 动画结束,元素再次变为完全透明并在 Z 轴上向后移动 1000em */
100% {
opacity: 0;
transform: translateZ(-1000em);
}
}
@keyframes fight {
0% {
opacity: 0; /* 初始状态下完全透明 */
transform: scale(1.5) translateY(1em); /* 放大到 1.5 倍,并在垂直方向上向下移动 1em */
}
20% {
opacity: 1; /* 在 20% 时间点变为完全不透明 */
}
90% {
opacity: 1; /* 在 90% 时间点仍然保持完全不透明 */
transform: scale(1); /* 缩放到原始大小(1 倍) */
}
100% {
opacity: 0; /* 在结束时变为完全透明 */
transform: translateZ(-1000em); /* 在 Z 轴上向远处移动,产生消失效果 */
}
}
/* 应用 byline 动画到 .byline 元素 */
.byline {
animation: byline 10s linear infinite; /* 动画持续 10 秒,线性运动,无限循环 */
}
/* 应用 spin-letters 动画到 .byline span 子元素 */
.byline span {
animation: spin-letters 10s linear infinite; /* 动画持续 10 秒,线性运动,无限循环 */
display: inline-block; /* 将 span 设置为行内块级元素,以便支持 transform 等属性 */
}
/* 定义一个名为 byline 的动画 */
@keyframes byline {
0% {
transform: translateZ(5em); /* 初始状态:在 Z 轴上向前移动 5em */
}
100% {
transform: translateZ(0em); /* 结束状态:回到原始位置 */
}
}
@keyframes spin-letters {
0%, 10% {
opacity: 0; /* 在 0%-10% 时间段内完全透明 */
transform: rotateY(90deg); /* 绕 Y 轴旋转 90 度,呈现侧面视角 */
}
30% {
opacity: 1; /* 在 30% 时间点变为完全不透明 */
}
70%, 86% {
transform: rotateY(0); /* 在 70%-86% 时间段内恢复到正面视角 */
opacity: 1; /* 保持完全不透明 */
}
95%, 100% {
opacity: 0; /* 在 95%-100% 时间段内逐渐变为完全透明 */
}
}
技术要点总结:
- 三维空间构建是动画深度的关键
- 分层动画实现复杂运动效果
- 性能优化保证流畅运行
- 响应式设计增强多端适配
通过本案例,可以掌握现代CSS动画的核心技术,为构建复杂交互场景奠定基础。