这段代码创建了一个带有动画效果的邮票场景,通过 CSS 和 JavaScript 技术模拟了雪花的下落和邮票的装饰效果,为页面添加了节日气氛。
演示效果
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>
@import url('https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400..700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
:root {
--bg: #fffaed;
--blue: #90c2d1;
--red: #d14a45;
--white: #fffaed;
--brown: #363334;
}
body {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg);
}
div.stamp {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 200px;
width: 345px;
background: var(--blue);
}
div.stamp::before {
content: "";
bottom: 0;
position: absolute;
}
div.stamp::after {
content: "";
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 20px;
border-radius: 50%;
background: var(--blue);
transform: translateY(-12px) translateX(12px);
box-shadow: 30px 0px var(--blue), 60px 0px var(--blue), 90px 0px var(--blue), 120px 0px var(--blue), 150px 0px var(--blue), 180px 0px var(--blue), 210px 0px var(--blue), 240px 0px var(--blue), 270px 0px var(--blue), 300px 0px var(--blue), 0px 205px var(--blue), 30px 205px var(--blue), 60px 205px var(--blue), 90px 205px var(--blue), 120px 205px var(--blue), 150px 205px var(--blue), 180px 205px var(--blue), 210px 205px var(--blue), 240px 205px var(--blue), 270px 205px var(--blue), 300px 205px var(--blue), -23px 25px var(--blue), -23px 55px var(--blue), -23px 85px var(--blue), -23px 115px var(--blue), -23px 145px var(--blue), -23px 175px var(--blue), 324px 25px var(--blue), 324px 55px var(--blue), 324px 85px var(--blue), 324px 115px var(--blue), 324px 145px var(--blue), 324px 175px var(--blue);
}
div.inner-stamp {
display: flex;
align-items: flex-end;
position: relative;
overflow: hidden;
background-image: linear-gradient(#27272a, #304259);
height: 165px;
width: 310px;
}
div.inner-stamp::before {
content: "来自Hardy的祝福";
color: var(--white);
display: flex;
align-items: center;
justify-content: center;
position: absolute;
font-weight: 400;
font-family: Inter;
font-size: 12px;
width: 310px;
height: 26px;
background: var(--red);
letter-spacing: 3px;
z-index: 100;
}
.house {
display: flex;
justify-content: center;
margin-left: 19px;
height: 30px;
margin-bottom: 10px;
width: 40px;
background: var(--white);
}
.house::before {
content: "";
position: absolute;
bottom: 39px;
width: 40px;
height: 25px;
clip-path: polygon(0 100%, 50% 0, 100% 100%);
background: var(--white);
z-index: 2;
}
.house::after {
content: "";
position: absolute;
bottom: 40px;
width: 50px;
height: 31px;
clip-path: polygon(0 100%, 50% 0, 100% 100%);
background: var(--red);
z-index: 1;
}
.window {
transform: translateY(-10px);
height: 6.5px;
width: 5.2px;
background: var(--brown);
z-index: 3;
border-radius: 1px;
box-shadow: 12px 12px var(--brown), -12px 12px var(--brown), 0px 12px var(--brown), -12px 24px var(--brown), 0px 24px var(--brown), 12px 24px var(--brown);
}
.window::before {
content: "";
position: absolute;
width: 12px;
height: 18px;
background: var(--red);
border-radius: 1px;
z-index: 2;
transform: translateY(24px) translateX(-2.6px);
}
.snow {
position: absolute;
background: var(--white);
border-radius: 50%;
opacity: .7;
height: 2px;
width: 2px;
}
span {
position: absolute;
top: 10px;
right: 12px;
color: var(--white);
font-size: 18px;
letter-spacing: 1px;
font-family: "Dancing Script", cursive;
}
span::before {
content: "";
position: absolute;
height: 18px;
width: 18px;
border-radius: 50%;
transform: translateX(-220px) translateY(20px);
background: var(--white);
box-shadow: 0 0 14px yellow;
}
@media screen and (max-height: 600px) {
.stamp {
transform: scale(1.1);
}
}
</style>
</head>
<body>
<div class='stamp'>
<div id='innerStamp' class='inner-stamp'>
<span>你的家乡下雪了吗</span>
<div class='snow'></div>
<div class='house'>
<div class='window'></div>
</div>
<div class='house'>
<div class='window'></div>
</div>
<div class='house'>
<div class='window'></div>
</div>
<div class='house'>
<div class='window'></div>
</div>
<div class='house'>
<div class='window'></div>
</div>
</div>
</div>
<script>
innerStamp = document.getElementById("innerStamp");
for (let i = 0; i < 800; i++) {
makeSnow();
}
function makeSnow() {
const snow = document.createElement("div");
snow.classList.add('snow');
let positionX = Math.random() * (window.innerWidth);
let positionY = Math.random() * window.innerHeight;
let speed = Math.random(2);
snow.style.top = `${positionY}px`;
snow.style.left = `${positionX}px`;
function drop() {
positionY += speed;
snow.style.top = `${positionY}px`;
if (positionY > window.innerHeight) {
positionY = - 5;
}
requestAnimationFrame(drop);
}
drop();
innerStamp.appendChild(snow);
}
</script>
</body>
</html>
HTML 结构
- stamp: 创建一个类名为“stamp”的 div 元素,用于包含整个邮票场景。
- innerStamp inner-stamp: 包含内部场景的 div 元素,类名为“inner-stamp”。
- span: 显示文本“你的家乡下雪了吗”。
- 多个 house 和 window 元素,用于构建房子和窗户。
- snow: 用于创建雪花效果的 div 元素。
CSS 样式
- @import url(‘…’);: 导入 Google 字体
- :root: 定义了一些 CSS 变量,用于页面的背景色、蓝色、红色、白色和棕色。
- body: 设置页面的高度、显示方式、背景色等。
- .stamp: 设置邮票的样式,包括尺寸、背景色和定位。
- .stamp::before 和 .stamp::after: 用于创建邮票的装饰效果,如边框和背景。
- .inner-stamp: 设置内部场景的样式,包括尺寸、背景渐变和定位。
- .inner-stamp::before: 用于显示“来自 Hardy 的祝福”文本。
- .house 和 .window: 用于构建房子和窗户的样式。
- .snow: 用于创建雪花效果的样式。
- span: 用于显示文本“你的家乡下雪了吗”及其装饰效果。
- @media screen and (max-height: 600px): 媒体查询,用于在屏幕高度小于 600px 时调整邮票的尺寸。
JavaScript 部分
- makeSnow 函数: 创建雪花效果,通过随机生成雪花的位置和速度,并使用 requestAnimationFrame 实现雪花的下落动画。
- for 循环: 生成 800 个雪花,调用 makeSnow 函数。