这段代码创建了一个动态的 Flappy Bird 游戏动画,通过 CSS 动画技术模拟了小鸟的飞行动作和背景的滚动,为页面添加了趣味性的视觉效果。
演示效果
HTML&CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>公众号关注:前端Hardy</title>
<style>
body {
margin: 0;
padding: 0;
background: #e8e8e8;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.loader {
position: relative;
width: 18rem;
aspect-ratio: 1;
overflow: hidden;
background: linear-gradient(to bottom, #6ccee7 60%, white);
}
#bird {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-80%, -50%);
width: 3rem;
height: auto;
animation: flap 500ms linear infinite;
}
.flappyBirdScene,
.flappyBirdSceneBottom {
display: flex;
width: 20rem;
top: -23%;
position: relative;
}
.sceneTop {
display: flex;
width: fit-content;
animation: flow 5s linear infinite;
}
.sceneBottom {
display: flex;
width: fit-content;
animation: flowBottom 5s linear infinite;
}
#birdObstacle {
height: 8rem;
width: 2rem;
background: linear-gradient(to right,
#9de558 0px,
#9de558 3px,
#e7ff8d 3px,
#e7ff8d 5px,
#9de858 5px,
#9de858 10px,
#74c029 10px,
#74c029 13px,
#9de558 13px,
#9de558 15px,
#74c029 22px,
#74c029 28px,
#59811a 28px,
#59811a 100%);
border: solid;
position: relative;
}
.flappyBirdSceneBottom {
bottom: -25%;
left: 0;
}
#birdObstacle::after {
content: "";
position: absolute;
width: 135%;
height: 1.25rem;
top: 100%;
left: 50%;
border: solid;
transform: translate(-50%, 0);
background: linear-gradient(to right,
#9de558 0px,
#9de558 3px,
#e7ff8d 3px,
#e7ff8d 5px,
#9de858 5px,
#9de858 10px,
#74c029 10px,
#74c029 13px,
#9de558 13px,
#9de558 15px,
#74c029 22px,
#74c029 28px,
#59811a 28px,
#59811a 100%);
}
.birdObs2 {
transform: translate(0%, 15%);
left: 15%;
}
.birdObs3 {
transform: translate(0, 18%);
left: 30%;
}
.birdObs4 {
transform: translate(0, 15%);
left: 45%;
}
@keyframes flap {
from {
transform: translate(-80%, -50%);
}
25% {
transform: translate(-80%, -50%) rotate(-15deg);
}
50% {
transform: translate(-80%, -12%) rotate(5deg);
}
100% {
transform: translate(-80%, -50%);
}
}
@keyframes flow {
from {
transform: translate(0, -43%);
}
to {
transform: translate(-50%, -43%);
}
}
@keyframes flowBottom {
from {
transform: translate(0, 75%) rotateX(180deg);
}
to {
transform: translate(-50%, 75%) rotateX(180deg);
}
}
</style>
</head>
<body>
<div class="loader">
<svg width="115" height="81" viewBox="0 0 115 81" fill="none" xmlns="http://www.w3.org/2000/svg" id="bird">
<rect x="41" y="47" width="20" height="7" fill="#FFEB3B"></rect>
<rect x="35" y="67" width="33" height="7" fill="#FFC107"></rect>
<rect x="21" y="54" width="40" height="14" fill="#FFC107"></rect>
<rect x="48" y="40" width="20" height="7" fill="#FFEB3B"></rect>
<rect x="48" y="33" width="20" height="7" fill="#FFEB3B"></rect>
<rect x="41" y="27" width="20" height="7" fill="#FFEB3B"></rect>
<rect x="34" y="20" width="20" height="7" fill="#FFEB3B"></rect>
<rect x="28" y="14" width="20" height="7" fill="#FFEB3B"></rect>
<rect x="40" y="7" width="21" height="7" fill="#FFEB3B"></rect>
<rect x="41" y="34" width="7" height="13" fill="black"></rect>
<rect x="21" y="14" width="7" height="7" fill="black"></rect>
<rect x="41" width="40" height="7" fill="black"></rect>
<rect x="28" y="7" width="13" height="7" fill="black"></rect>
<rect x="7" y="27" width="34" height="27" fill="#FFFFCC"></rect>
<rect x="61" y="12" width="34" height="28" fill="white"></rect>
<rect x="7" y="20" width="27" height="7" fill="black"></rect>
<rect x="34" y="27" width="7" height="7" fill="black"></rect>
<rect x="7" y="40" width="7" height="7" fill="#FFEB3B"></rect>
<rect x="34" y="40" width="7" height="7" fill="#FFEB3B"></rect>
<rect x="48" y="14" width="7" height="7" fill="#FFEB3B"></rect>
<rect x="7" y="47" width="7" height="7" fill="black"></rect>
<rect x="14" y="47" width="20" height="7" fill="#FFEB3B"></rect>
<rect y="47" width="20" height="7" transform="rotate(-90 0 47)" fill="black"></rect>
<rect x="34" y="47" width="7" height="7" fill="black"></rect>
<rect x="88" y="13" width="7" height="7" fill="black"></rect>
<rect x="81" y="6" width="7" height="7" fill="black"></rect>
<rect x="95" y="40" width="20" height="7" transform="rotate(-90 95 40)" fill="black"></rect>
<rect x="81" y="33" width="13" height="7" transform="rotate(-90 81 33)" fill="black"></rect>
<rect x="81" y="13" width="13" height="7" transform="rotate(-180 81 13)" fill="white"></rect>
<rect x="61" y="33" width="7" height="7" fill="black"></rect>
<rect x="61" y="6" width="7" height="7" fill="black"></rect>
<rect x="54" y="33" width="20" height="7" transform="rotate(-90 54 33)" fill="black"></rect>
<rect x="14" y="60" width="7" height="7" fill="black"></rect>
<rect x="21" y="67" width="14" height="7" fill="black"></rect>
<rect x="35" y="74" width="33" height="7" fill="black"></rect>
<rect x="14" y="54" width="20" height="7" fill="black"></rect>
<rect x="108" y="47" width="7" height="7" fill="black"></rect>
<rect x="68" y="53" width="33" height="7" fill="black"></rect>
<rect x="68" y="46" width="40" height="7" fill="#F44336"></rect>
<rect x="65" y="60" width="40" height="7" fill="#F44336"></rect>
<rect x="101" y="67" width="14" height="7" transform="rotate(-90 101 67)" fill="black"></rect>
<rect x="61" y="46" width="7" height="7" fill="black"></rect>
<rect x="68" y="40" width="40" height="7" fill="black"></rect>
<rect x="68" y="67" width="33" height="7" fill="black"></rect>
<rect x="54" y="53" width="7" height="7" fill="black"></rect>
<rect x="61" y="53" width="7" height="7" fill="#F44336"></rect>
<rect x="61" y="60" width="7" height="7" fill="black"></rect>
</svg>
<div class="sceneTop">
<div class="flappyBirdScene">
<div class="birdObs1" id="birdObstacle"></div>
<div class="birdObs2" id="birdObstacle"></div>
<div class="birdObs3" id="birdObstacle"></div>
<div class="birdObs4" id="birdObstacle"></div>
</div>
<div class="flappyBirdScene">
<div class="birdObs1" id="birdObstacle"></div>
<div class="birdObs2" id="birdObstacle"></div>
<div class="birdObs3" id="birdObstacle"></div>
<div class="birdObs4" id="birdObstacle"></div>
</div>
</div>
<div class="sceneBottom">
<div class="flappyBirdSceneBottom">
<div class="birdObs1" id="birdObstacle"></div>
<div class="birdObs2" id="birdObstacle"></div>
<div class="birdObs3" id="birdObstacle"></div>
<div class="birdObs4" id="birdObstacle"></div>
</div>
<div class="flappyBirdSceneBottom">
<div class="birdObs1" id="birdObstacle"></div>
<div class="birdObs2" id="birdObstacle"></div>
<div class="birdObs3" id="birdObstacle"></div>
<div class="birdObs4" id="birdObstacle"></div>
</div>
</div>
</div>
</body>
</html>
HTML 结构
- loader: 创建一个类名为“loader”的 div 元素,用于包含整个 Flappy Bird 动画场景。
CSS 样式
- body: 设置页面的边距、填充、背景色、显示方式和高度。
- .loader: 设置容器的样式,包括位置、尺寸、宽高比、溢出隐藏和背景渐变。
- #bird: 设置小鸟的样式,包括位置、变换和动画。
- .flappyBirdScene 和 .flappyBirdSceneBottom: 设置场景的布局和位置。
- .sceneTop 和 .sceneBottom: 设置顶部和底部场景的布局和动画。
- #birdObstacle: 设置障碍物的样式,包括尺寸、背景渐变和边框。
- .birdObs2, .birdObs3, .birdObs4: 设置不同障碍物的位置。
- @keyframes flap: 定义小鸟翅膀扇动的动画。
- @keyframes flow 和 @keyframes flowBottom: 定义场景流动的动画。
- svg: SVG容器,包含了多个rect元素,这些矩形元素- 组合起来形成了小鸟的形象。
- 每个rect元素都有特定的位置、尺寸和颜色,用于构建小鸟的不同部分。
- #bird: 通过animation属性应用了flap动画,使小鸟的翅膀能够上下扇动。
- .sceneTop 和 .sceneBottom: 通过animation属性应用了flow和flowBottom动画,使场景能够左右移动,模拟游戏背景的滚动。