2024-11-21
人类之所以有进步,主要原因是下一代不怎么听上一代的话。——倪匡
效果在右下角,请滚动页面查看~
引子:渐变的难题
在一个静谧的下午,阿超,一个对代码有着近乎苛求完美的前端开发者,面对着一个挑战。他需要实现一个文字渐变效果:滚动时,文字从顶部的纯白渐变为底部的纯黑,中间的渐变必须平滑优雅,没有任何多余的断裂或重复。
阿超心想:“这应该只是几行 CSS 和一点滚动监听事件的事吧?”然而,当他开始写代码时,他发现问题远比他想象的复杂。顶部的纯白无法保持纯净,中间的渐变总是断裂,底部的黑色也似乎总有一丝不和谐。
他打开 ChatGPT 4o,输入了他的需求。这一刻,他与 ChatGPT 4o 的代码探险开始了。
第一章:原始实现的局限
阿超:
“我要实现一个文字滚动渐变动画,顶部完全是白色,中间渐变自然,底部完全是黑色。”
ChatGPT 4o:
“我们可以使用 linear-gradient
和动态 background-position
来实现。”它快速生成了代码:
1 | background: linear-gradient(180deg, white, black); |
1 | textElement.style.backgroundPosition = `center ${scrollPosition * 100}%`; |
阿超的心理活动:
“看起来不错。”他把代码复制到自己的项目中,满怀期待地刷新页面。然而,他很快发现顶部的白色有些发灰,中间的渐变生硬到底部,始终拖着尾巴。
阿超:
“顶部需要完全纯白,中间渐变要自然,底部也必须纯黑。”
ChatGPT 4o:
“让我调整 linear-gradient
的节点比例。”
第二章:渐变的尝试与失败
ChatGPT 4o 尝试增加渐变节点:
1 | background: linear-gradient(180deg, white 0%, white 50%, black 100%); |
阿超刷新页面,发现顶部确实变白了,但中间的渐变完全消失,文字直接从白色跳到了黑色,毫无过渡。
第三章:变量的启发
阿超若有所思:“能不能更优雅一些?动态调整样式的逻辑如果交给 CSS 变量会不会更好?”
ChatGPT 4o 听出了阿超的期望,决定重新设计逻辑:
ChatGPT 4o 的分析:
“我们可以通过 CSS 自定义属性(--scroll
)来动态调整背景位置,将 JavaScript 的控制逻辑转移到 CSS 中。”
第四章:优雅的实现
ChatGPT 4o 开始重构:
-
在
:root
中定义--scroll
变量:1
2
3:root {
--scroll: 0;
} -
动态通过
calc()
使用变量调整background-position
:1
background-position: center calc(var(--scroll) * 100%);
-
在 JavaScript 中动态更新
--scroll
的值:1
document.documentElement.style.setProperty('--scroll', scrollValue);
阿超将代码替换运行,发现顶部纯白、中间渐变自然,底部纯黑,所有问题迎刃而解。
完整代码
1 |
|
教学知识点引申
1. background-repeat
的妙用
-
问题:如果未设置
background-repeat: no-repeat;
,滚动背景会重复,导致渐变区域出现断裂或重影。 -
常见用法:
1
2
3
4background-repeat: no-repeat; /* 禁止背景重复 */
background-repeat: repeat-x; /* 水平方向重复 */
background-repeat: repeat-y; /* 垂直方向重复 */
background-repeat: repeat; /* 默认,背景在两个方向重复 */
2. background
属性的缩写
-
语法顺序:
1
background: [颜色] [图片] [重复模式] [位置/大小];
-
示例:
1
background: linear-gradient(180deg, white, black) no-repeat center/100% 200%;
3. calc()
的动态计算
-
作用:
calc()
可以混合单位进行动态计算,比如将 CSS 变量与百分比结合。 -
示例:
1
2width: calc(100% - 50px); /* 总宽度减去50px */
background-position: center calc(var(--scroll) * 100%);
4. 另一个只平滑改变颜色,而不是渐变比例的版本
-
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scroll Percentage</title>
<style>
:root {
--scroll: 0; /* 滚动百分比变量 */
}
body {
margin: 0;
height: 200vh;
}
#scroll-percent {
position: fixed;
bottom: 10px;
right: 10px;
font-size: 2rem;
color: rgb(calc(255 - var(--scroll) * 255), calc(255 - var(--scroll) * 255), calc(255 - var(--scroll) * 255));
transition: color 0.1s linear;
}
</style>
</head>
<body>
<div id="scroll-percent">0%</div>
<script>
const scrollPercent = document.getElementById('scroll-percent');
window.addEventListener('scroll', () => {
const scrollValue = window.pageYOffset / (document.body.offsetHeight - window.innerHeight);
document.documentElement.style.setProperty('--scroll', scrollValue);
scrollPercent.textContent = Math.round(scrollValue * 100) + '%';
});
</script>
</body>
</html>
结尾:渐变的意义
阿超合上电脑,满意地笑了。这不仅是一段代码,更是一场关于优雅与效率的探索。从变量的引入到渐变的平滑设计,他收获的不只是视觉效果,还有对 CSS 深度的理解。
ChatGPT 4o 也感到满足:“渐变的不止是颜色,还有思维方式。”