【GLM-5 陪练式创意 UI 实战】第二篇:创意魔法盒 ------ 从 "开心" 到 "科技感",AI 驱动的 UI 风格迭代
目录
[【GLM-5 陪练式创意 UI 实战】第二篇:创意魔法盒 ------ 从 "开心" 到 "科技感",AI 驱动的 UI 风格迭代](#【GLM-5 陪练式创意 UI 实战】第二篇:创意魔法盒 —— 从 “开心” 到 “科技感”,AI 驱动的 UI 风格迭代)
[引 言](#引 言)
[1 迭代背景与指令触发](#1 迭代背景与指令触发)
[1.1 迭代指令设计](#1.1 迭代指令设计)
[1.2 GLM-5 参数适配](#1.2 GLM-5 参数适配)
[2 科技感风格的设计拆解(与 "开心版" 差异对比)](#2 科技感风格的设计拆解(与 “开心版” 差异对比))
[2.1 配色方案:从暖黄到霓虹](#2.1 配色方案:从暖黄到霓虹)
[2.2 视觉特效:从呼吸到扫描](#2.2 视觉特效:从呼吸到扫描)
[3 核心代码实现与差异解析](#3 核心代码实现与差异解析)
[3.1 背景与特效实现](#3.1 背景与特效实现)
[3.2 故障艺术与霓虹发光](#3.2 故障艺术与霓虹发光)
[3.3 交互与动画触发](#3.3 交互与动画触发)
[4 本地效果验证:从 Flutter 到 HTML 的跨栈调试](#4 本地效果验证:从 Flutter 到 HTML 的跨栈调试)
[4.1 项目创建与代码替换](#4.1 项目创建与代码替换)
[4.2 效果验证要点](#4.2 效果验证要点)
[4.3 运行效果展示](#4.3 运行效果展示)
[5 实践感悟](#5 实践感悟)
✨ 主题 3:创意魔法盒 ------ 情绪驱动的动态 UI 生成器
引 言
在第一篇博客中,我借助 GLM-5 完成了 "开心、明亮、活泼" 主题的 Flutter UI 构建,实现了情绪与视觉的初步融合。而 "情绪驱动 UI" 的核心魅力,在于风格随情绪迭代的灵活性。本篇中,我将触发指令 ------"现在我想换成科技感的风格",重新让 GLM-5 完成从暖色调 "开心版" 到赛博朋克 "科技感版" 的 UI 重构,解锁 AI 辅助 UI 迭代的完整流程。
1 迭代背景与指令触发
1.1 迭代指令设计
基于主题 3 "情绪驱动 UI" 的核心要求,我向 GLM-5 触发了迭代指令:
现在我想换成科技感的风格。


同时,GLM-5 自动完成了需求分析,明确了 "科技感" 风格的关键特征:
-
配色:深色背景(黑 / 深蓝 / 深灰)+ 霓虹点缀(青色、品红、电光蓝);
-
排版:几何感无衬线字体(Orbitron/Rajdhani)+ 全大写标题;
-
视觉:网格背景、故障艺术、扫描线、发光边框;
-
动画:悬停霓虹脉冲、滚动触发的技能条填充。
用户想要将他们当前的网站风格切换为"科技感"风格。
1. 分析需求:
- 目标: 将现有网站设计转换为"科技感"风格。
- 语境: 我需要回顾之前的交互(虽然在这个无状态环境中我无法严格"记忆",但我假设用户指的是一个标准的个人主页或作品集网站,或者我需要提供一个通用的模板)。既然用户说"换成",这意味着存在一个之前的设计。我将假设一个标准的结构:导航栏、Hero区域、关于、技能、项目、联系方式。
- "科技感"风格的关键特征:
- 配色方案: 深色背景(黑色、深蓝、深灰),霓虹点缀(青色、品红、电光蓝、石灰绿)。
- 排版: 单间距字体、几何无衬线字体、大号标题、全大写文本。
- 视觉效果:
- 渐变(线性或径向)。
- 发光效果(盒阴影、文本阴影)。
- 网格背景、粒子、线条、电路图案。
- 玻璃拟态(半透明背景)。
- 动画: 悬停时的故障效果、打字机效果、平滑滚动、霓虹灯发光脉冲。
2. 设计策略(构思草稿):
- 背景: 深色(
#0a0a0a或#0f172a)。也许加一个微妙的网格覆盖。 - 主色调: 青色/电光蓝(
#00f2ea或#0ea5e9)。 - 辅助色: 品红/紫色(
#ff0055或#a855f7)。 - 字体: 'Orbitron'(经典科幻)或 'Roboto Mono'(代码感)。让我们使用 'Orbitron' 作为标题,'Rajdhani' 或 'Inter' 作为正文。
- 组件:
- 导航栏: 玻璃拟态效果,底部发光边框。
- Hero区域: 大号故障文本,粒子背景(CSS或简单JS),打字机效果。
- 卡片: 深色半透明背景,霓虹边框,悬停时的"扫描线"效果。
- 按钮: 霓虹边框,悬停时填充发光。
3. 实现细节(HTML/CSS/JS):
- HTML结构: 标准语义标签。
- CSS:
- 定义颜色的根变量。
font-family导入。- 故障效果: 使用
text-shadow和clip-path的 CSS 动画。 - 霓虹发光:
box-shadow。 - 网格背景: 使用
linear-gradient的 CSS 图案。
- JS: 用于打字机效果的简单脚本,也许还有一个基本的粒子系统(为了保持代码简洁,我将坚持使用纯CSS动画或非常简单的JS)。
4. 起草代码(迭代优化):
-
配色方案:
- 背景:
#0d0d0d(深黑) - 主要文本:
#e0e0e0(浅灰) - 强调色 1:
#00f0ff(青色) - 强调色 2:
#f000ff(品红)
- 背景:
-
Hero区域:
- 标题:"SYSTEM ONLINE"或类似内容。
- 副标题:打字机效果。
- 背景:一个微妙的网格。
-
技能/项目:
- 带有"科技"边框的卡片(角落装饰)。
5. 构建回复:
- 确认需求。
- 提供完整的 HTML 文件(包含 CSS 和 JS),以便用户可以直接复制粘贴。
- 解释关键设计元素(颜色、字体、效果),以便用户理解这些变化。
6. 优化代码(起草过程中的自我修正):
- 批评: 纯黑可能太刺眼了。让我们使用非常深的蓝灰色
#020617(slate-950)。 - 字体: Google Fonts 'Orbitron' 是"科技感"的标志性字体。我必须包含它。
- 动画: "故障"效果很酷,但对于主标题来说可能太分散注意力。我会将其应用于悬停或特定的静态元素。
- 背景: CSS 网格图案比导入沉重的粒子 JS 库更轻量且更容易。
background-image: linear-gradient(rgba(0, 255, 255, 0.1) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 255, 255, 0.1) 1px, transparent 1px);background-size: 30px 30px;
7. 最终代码结构:
<!DOCTYPE html><head>:Google Fonts 链接,内部<style>。<body>:- 导航栏(玻璃效果)。
- Hero(故障文本,打字机)。
- 关于(科技风格文本)。
- 技能(进度条或数据流风格)。
- 项目(卡片带霓虹边框)。
- 页脚。
- 背景网格(固定位置)。
<script>:打字机逻辑,滚动显示。
8. 撰写解释:
- 强调"赛博朋克/科幻"美学。
- 提及具体的 CSS 技巧(用于故障的
clip-path,用于霓虹的box-shadow)。
(最终输出生成过程中的自我修正):
确保代码是独立的。不要依赖外部图像;使用占位符或 CSS 形状。确保文本对比度高(深色背景上的霓虹色)。让我们生成代码好的,为您将网站风格切换为科技感风格。
这种风格通常具有以下特点:
- 配色:深色背景(黑/深蓝/深灰)搭配高亮霓虹色(青色、品红、电光蓝)。
- 字体:使用几何感强、类似于编码或未来主义的字体(如 Orbitron)。
- 视觉效果:网格背景、发光效果、故障艺术、扫描线、玻璃拟态。
以下是为您重构的完整 HTML 代码:
html<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>TECH SYSTEM | 个人主页</title> <!-- 引入科技感字体 Orbitron --> <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Rajdhani:wght@300;500;700&display=swap" rel="stylesheet"> <style> /* --- 全局变量定义 --- */ :root { --bg-color: #050505; --text-color: #e0e0e0; --primary-color: #00f3ff; /* 电光青 */ --secondary-color: #bc13fe; /* 霓虹紫 */ --accent-color: #2dff00; /* 终端绿 */ --card-bg: rgba(20, 20, 30, 0.7); --border-glow: 0 0 10px var(--primary-color), inset 0 0 5px var(--primary-color); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Rajdhani', sans-serif; background-color: var(--bg-color); color: var(--text-color); overflow-x: hidden; line-height: 1.6; } /* --- 背景网格效果 --- */ .grid-bg { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(rgba(0, 243, 255, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(0, 243, 255, 0.05) 1px, transparent 1px); background-size: 50px 50px; z-index: -1; pointer-events: none; } /* --- 扫描线动画 --- */ .scanline { position: fixed; top: 0; left: 0; width: 100%; height: 5px; background: rgba(0, 243, 255, 0.3); box-shadow: 0 0 15px var(--primary-color); z-index: 1000; pointer-events: none; animation: scan 4s linear infinite; } @keyframes scan { 0% { top: -5%; } 100% { top: 105%; } } /* --- 导航栏 --- */ nav { display: flex; justify-content: space-between; align-items: center; padding: 20px 5%; background: rgba(5, 5, 5, 0.8); backdrop-filter: blur(10px); border-bottom: 1px solid rgba(0, 243, 255, 0.2); position: fixed; width: 100%; top: 0; z-index: 100; } .logo { font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: 1.8rem; color: var(--primary-color); text-shadow: 0 0 10px var(--primary-color); letter-spacing: 2px; } .nav-links { list-style: none; display: flex; gap: 30px; } .nav-links a { text-decoration: none; color: var(--text-color); font-weight: 500; font-size: 1.1rem; text-transform: uppercase; letter-spacing: 1px; position: relative; padding: 5px 0; } .nav-links a::after { content: ''; position: absolute; width: 0; height: 2px; bottom: 0; left: 0; background-color: var(--primary-color); box-shadow: 0 0 5px var(--primary-color); transition: width 0.3s; } .nav-links a:hover { color: var(--primary-color); } .nav-links a:hover::after { width: 100%; } /* --- Hero 区域 --- */ .hero { height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; position: relative; } .hero-title { font-family: 'Orbitron', sans-serif; font-size: 4rem; font-weight: 900; margin-bottom: 20px; text-transform: uppercase; position: relative; color: #fff; } /* 故障艺术效果 */ .glitch { position: relative; } .glitch::before, .glitch::after { content: attr(data-text); position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .glitch::before { left: 2px; text-shadow: -1px 0 var(--secondary-color); clip: rect(24px, 550px, 90px, 0); animation: glitch-anim 2s infinite linear alternate-reverse; } .glitch::after { left: -2px; text-shadow: -1px 0 var(--primary-color); clip: rect(85px, 550px, 140px, 0); animation: glitch-anim2 3s infinite linear alternate-reverse; } @keyframes glitch-anim { 0% { clip: rect(30px, 9999px, 10px, 0); } 20% { clip: rect(15px, 9999px, 100px, 0); } 40% { clip: rect(50px, 9999px, 20px, 0); } 60% { clip: rect(80px, 9999px, 120px, 0); } 80% { clip: rect(10px, 9999px, 60px, 0); } 100% { clip: rect(40px, 9999px, 90px, 0); } } @keyframes glitch-anim2 { 0% { clip: rect(60px, 9999px, 10px, 0); } 20% { clip: rect(100px, 9999px, 30px, 0); } 40% { clip: rect(10px, 9999px, 80px, 0); } 60% { clip: rect(30px, 9999px, 50px, 0); } 80% { clip: rect(90px, 9999px, 10px, 0); } 100% { clip: rect(20px, 9999px, 70px, 0); } } .hero-subtitle { font-size: 1.5rem; color: var(--primary-color); margin-bottom: 40px; letter-spacing: 3px; text-shadow: 0 0 5px rgba(0, 243, 255, 0.5); } .cta-btn { padding: 15px 40px; background: transparent; border: 2px solid var(--primary-color); color: var(--primary-color); font-family: 'Orbitron', sans-serif; font-weight: 700; text-transform: uppercase; cursor: pointer; position: relative; overflow: hidden; transition: color 0.3s, box-shadow 0.3s; text-decoration: none; display: inline-block; } .cta-btn:hover { color: #050505; background: var(--primary-color); box-shadow: 0 0 20px var(--primary-color), inset 0 0 20px rgba(255,255,255,0.2); } /* --- 通用区块样式 --- */ .section { padding: 100px 10%; } .section-title { font-family: 'Orbitron', sans-serif; font-size: 2.5rem; color: var(--primary-color); margin-bottom: 50px; text-align: center; text-transform: uppercase; position: relative; } .section-title::after { content: ''; display: block; width: 100px; height: 2px; background: var(--secondary-color); margin: 10px auto; box-shadow: 0 0 10px var(--secondary-color); } /* --- 技能区域 --- */ .skills-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 30px; } .skill-card { background: var(--card-bg); border: 1px solid rgba(0, 243, 255, 0.1); padding: 30px; position: relative; transition: transform 0.3s, border-color 0.3s; clip-path: polygon(0 0, 100% 0, 100% 85%, 90% 100%, 0 100%); /* 切角效果 */ } .skill-card:hover { transform: translateY(-5px); border-color: var(--primary-color); box-shadow: 0 0 15px rgba(0, 243, 255, 0.1); } .skill-card h3 { font-family: 'Orbitron', sans-serif; color: var(--primary-color); margin-bottom: 15px; font-size: 1.2rem; } .skill-bar { height: 5px; background: rgba(255, 255, 255, 0.1); margin-top: 10px; position: relative; } .skill-progress { height: 100%; background: var(--primary-color); box-shadow: 0 0 10px var(--primary-color); width: 0; /* 动画初始值 */ transition: width 1.5s ease-in-out; } /* --- 项目区域 --- */ .projects-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 30px; } .project-card { background: linear-gradient(135deg, rgba(20,20,30,0.9), rgba(10,10,15,0.9)); border: 1px solid rgba(255, 255, 255, 0.05); overflow: hidden; position: relative; transition: 0.3s; } .project-card::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(0, 243, 255, 0.1), transparent); transition: 0.5s; } .project-card:hover::before { left: 100%; } .project-content { padding: 30px; border-top: 2px solid transparent; transition: border-color 0.3s; } .project-card:hover .project-content { border-top-color: var(--secondary-color); } .project-title { font-family: 'Orbitron', sans-serif; font-size: 1.3rem; margin-bottom: 15px; color: #fff; } .project-desc { font-size: 0.95rem; color: #aaa; margin-bottom: 20px; } .tag { display: inline-block; padding: 4px 8px; background: rgba(0, 243, 255, 0.1); color: var(--primary-color); font-size: 0.8rem; border: 1px solid rgba(0, 243, 255, 0.2); margin-right: 5px; margin-bottom: 5px; } /* --- 页脚 --- */ footer { padding: 50px 5%; background: rgba(0, 0, 0, 0.8); text-align: center; border-top: 1px solid rgba(0, 243, 255, 0.1); } .footer-text { font-family: 'Orbitron', sans-serif; color: #555; font-size: 0.8rem; letter-spacing: 2px; } /* --- 响应式 --- */ @media (max-width: 768px) { .hero-title { font-size: 2.5rem; } .nav-links { display: none; /* 移动端简化 */ } } </style> </head> <body> <!-- 背景特效层 --> <div class="grid-bg"></div> <div class="scanline"></div> <!-- 导航栏 --> <nav> <div class="logo">PORTFOLIO.IO</div> <ul class="nav-links"> <li><a href="#home">Home</a></li> <li><a href="#skills">Skills</a></li> <li><a href="#projects">Projects</a></li> <li><a href="#contact">Contact</a></li> </ul> </nav> <!-- Hero 区域 --> <section class="hero" id="home"> <h1 class="hero-title glitch" data-text="FUTURE IS NOW">FUTURE IS NOW</h1> <p class="hero-subtitle">// FULL STACK DEVELOPER & UI DESIGNER //</p> <a href="#projects" class="cta-btn">Initialize System</a> </section> <!-- 技能区域 --> <section class="section" id="skills"> <h2 class="section-title">System Modules</h2> <div class="skills-grid"> <div class="skill-card"> <h3>Frontend Architecture</h3> <p>React, Vue, Three.js 构建高性能交互界面。</p> <div class="skill-bar"><div class="skill-progress" data-width="90%"></div></div> </div> <div class="skill-card"> <h3>Backend Logic</h3> <p>Node.js, Python, Go 数据处理与API设计。</p> <div class="skill-bar"><div class="skill-progress" data-width="85%"></div></div> </div> <div class="skill-card"> <h3>UI/UX Design</h3> <p>Figma, After Effects 赛视觉与动效设计。</p> <div class="skill-bar"><div class="skill-progress" data-width="80%"></div></div> </div> </div> </section> <!-- 项目区域 --> <section class="section" id="projects"> <h2 class="section-title">Data Logs</h2> <div class="projects-grid"> <div class="project-card"> <div class="project-content"> <h3 class="project-title">Project: Cyberpunk-Dash</h3> <p class="project-desc">一个基于WebGL的数据可视化仪表盘,具有强烈的赛博朋克风格。</p> <span class="tag">Three.js</span> <span class="tag">React</span> <span class="tag">WebGL</span> </div> </div> <div class="project-card"> <div class="project-content"> <h3 class="project-title">Project: Neural-Net</h3> <p class="project-desc">模拟神经网络运算过程的交互式教育网站。</p> <span class="tag">Python</span> <span class="tag">TensorFlow</span> </div> </div> <div class="project-card"> <div class="project-content"> <h3 class="project-title">Project: E-Commerce</h3> <p class="project-desc">高并发电商系统架构设计与实现。</p> <span class="tag">Go</span> <span class="tag">Microservices</span> </div> </div> </div> </section> <!-- 页脚 --> <footer id="contact"> <p class="footer-text">SYSTEM STATUS: ONLINE // VERSION 2.0.1 // © 2023 TECH PORTFOLIO</p> </footer> <script> // 简单的打字机效果逻辑可以在这里添加 // 这里主要实现技能条动画的触发 // 观察技能条进入视口 const skillBars = document.querySelectorAll('.skill-progress'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const width = entry.target.getAttribute('data-width'); entry.target.style.width = width; observer.unobserve(entry.target); } }); }, { threshold: 0.5 }); skillBars.forEach(bar => { observer.observe(bar); }); // 导航栏平滑滚动 document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); document.querySelector(this.getAttribute('href')).scrollIntoView({ behavior: 'smooth' }); }); }); </script> </body> </html>主要修改点说明:
-
配色方案:
- 背景换成了极深的黑色 (
#050505),模拟终端或太空背景。 - 主色调换成了电光青 (
#00f3ff) 和霓虹紫 (#bc13fe),这是赛博朋克/科技风格的经典配色。
- 背景换成了极深的黑色 (
-
背景特效:
- 添加了
.grid-bg:使用 CSS 线性渐变绘制了透视网格背景。 - 添加了
.scanline:一条上下循环移动的扫描线,模拟老式CRT显示器或雷达扫描的效果。
- 添加了
-
字体选择:
- 标题使用了 Orbitron,这是一种非常有名的几何感、未来主义字体。
- 正文使用了 Rajdhani,看起来像技术文档或HUD(平视显示器)文字。
-
视觉效果:
- 故障艺术:Hero 区域的大标题添加了 CSS
clip-path动画,模拟信号干扰的抖动效果。 - 切角卡片:技能卡片使用了
clip-path: polygon(...)切掉右下角,这是科幻UI设计中常见的形状。 - 发光边框:按钮和卡片 hover 时都有明显的
box-shadow发光效果。 - 标签样式:项目中的标签看起来像代码编辑器中的关键字高亮。
- 故障艺术:Hero 区域的大标题添加了 CSS
您可以直接复制这段代码覆盖之前的文件,刷新浏览器即可看到充满未来科技感的新界面。
1.2 GLM-5 参数适配
为保证迭代代码的完整性与稳定性,延续了第一篇的参数设置:
Max Tokens:8192(避免长代码截断);Temperature:0.2(聚焦风格需求,减少冗余输出);- 其他参数保持默认,确保 AI 精准落地 "科技感" 设计。
2 科技感风格的设计拆解(与 "开心版" 差异对比)
GLM-5 基于 "科技感" 关键词,生成了一套与 "开心版" 完全不同的设计方案,核心差异如下:
| 模块 | 开心版(Flutter) | 科技感版(HTML/CSS/JS) | 设计逻辑 |
|---|---|---|---|
| 配色方案 | 暖白背景 + 向日葵黄 / 珊瑚橙 | 深黑背景 + 电光青 / 霓虹紫 | 暖色调传递快乐,冷霓虹强化未来感 |
| 背景特效 | 呼吸圆形装饰 | 网格背景 + 扫描线动画 | 模拟终端 / 雷达扫描的科技氛围 |
| 字体选择 | 系统默认字体 | Orbitron(标题)+ Rajdhani(正文) | 几何感字体强化未来主义风格 |
| 核心动画 | 弹性入场 + 呼吸动画 | 故障艺术 + 霓虹发光 + 切角卡片 | 故障效果模拟信号干扰,切角卡片贴合科幻 UI |
| 布局结构 | 响应式网格(移动端 2 列 / 桌面 4 列) | 玻璃拟态导航 + 卡片式技能 / 项目区 | 玻璃效果提升科技感,卡片布局强化信息层级 |
2.1 配色方案:从暖黄到霓虹
科技感版采用 深黑背景(#050505)+ 电光青(#00f3ff)+ 霓虹紫(#bc13fe) 的组合,既避免了纯黑的刺眼感,又通过霓虹色的发光效果,营造出赛博朋克的未来氛围。
2.2 视觉特效:从呼吸到扫描
- 网格背景:通过 CSS 线性渐变绘制透视网格,模拟终端界面;
- 扫描线动画:一条上下循环移动的青色扫描线,还原 CRT 显示器的扫描效果;
- 故障艺术 :Hero 标题通过
clip-path动画实现抖动偏移,模拟信号干扰; - 切角卡片 :技能卡片使用
clip-path: polygon(...)切掉右下角,贴合科幻 UI 的几何造型。
3 核心代码实现与差异解析
GLM-5 生成的科技感 UI 为完整的 HTML/CSS/JS 代码,核心实现与 "开心版" Flutter 代码的差异如下:
3.1 背景与特效实现
/* 网格背景 */
.grid-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
linear-gradient(rgba(0, 243, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 243, 255, 0.05) 1px, transparent 1px);
background-size: 50px 50px;
z-index: -1;
}
/* 扫描线动画 */
.scanline {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: rgba(0, 243, 255, 0.3);
box-shadow: 0 0 15px var(--primary-color);
animation: scan 4s linear infinite;
}
@keyframes scan {
0% { top: -5%; }
100% { top: 105%; }
}
对比 Flutter 版的AnimatedBuilder呼吸动画,HTML 版通过纯 CSS 实现了更轻量化的背景特效,无需依赖 Flutter 的动画控制器。
3.2 故障艺术与霓虹发光
/* 故障艺术效果 */
.glitch::before {
left: 2px;
text-shadow: -1px 0 var(--secondary-color);
clip: rect(24px, 550px, 90px, 0);
animation: glitch-anim 2s infinite linear alternate-reverse;
}
/* 霓虹发光按钮 */
.cta-btn:hover {
color: #050505;
background: var(--primary-color);
box-shadow: 0 0 20px var(--primary-color), inset 0 0 20px rgba(255,255,255,0.2);
}
通过text-shadow和box-shadow实现的霓虹发光效果,是科技感 UI 的核心视觉标识,而 Flutter 版则需要通过ShaderMask或自定义 Paint 来模拟类似效果。
3.3 交互与动画触发
// 技能条滚动触发动画
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const width = entry.target.getAttribute('data-width');
entry.target.style.width = width;
observer.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
skillBars.forEach(bar => observer.observe(bar));
对比 Flutter 版的AnimationController,HTML 版通过IntersectionObserver实现了更轻量化的滚动触发动画,无需依赖 Flutter 的状态管理。
全部代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TECH SYSTEM | 个人主页</title>
<!-- 引入科技感字体 Orbitron -->
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Rajdhani:wght@300;500;700&display=swap" rel="stylesheet">
<style>
/* --- 全局变量定义 --- */
:root {
--bg-color: #050505;
--text-color: #e0e0e0;
--primary-color: #00f3ff; /* 电光青 */
--secondary-color: #bc13fe; /* 霓虹紫 */
--accent-color: #2dff00; /* 终端绿 */
--card-bg: rgba(20, 20, 30, 0.7);
--border-glow: 0 0 10px var(--primary-color), inset 0 0 5px var(--primary-color);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Rajdhani', sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
overflow-x: hidden;
line-height: 1.6;
}
/* --- 背景网格效果 --- */
.grid-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
linear-gradient(rgba(0, 243, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 243, 255, 0.05) 1px, transparent 1px);
background-size: 50px 50px;
z-index: -1;
pointer-events: none;
}
/* --- 扫描线动画 --- */
.scanline {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 5px;
background: rgba(0, 243, 255, 0.3);
box-shadow: 0 0 15px var(--primary-color);
z-index: 1000;
pointer-events: none;
animation: scan 4s linear infinite;
}
@keyframes scan {
0% { top: -5%; }
100% { top: 105%; }
}
/* --- 导航栏 --- */
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 5%;
background: rgba(5, 5, 5, 0.8);
backdrop-filter: blur(10px);
border-bottom: 1px solid rgba(0, 243, 255, 0.2);
position: fixed;
width: 100%;
top: 0;
z-index: 100;
}
.logo {
font-family: 'Orbitron', sans-serif;
font-weight: 900;
font-size: 1.8rem;
color: var(--primary-color);
text-shadow: 0 0 10px var(--primary-color);
letter-spacing: 2px;
}
.nav-links {
list-style: none;
display: flex;
gap: 30px;
}
.nav-links a {
text-decoration: none;
color: var(--text-color);
font-weight: 500;
font-size: 1.1rem;
text-transform: uppercase;
letter-spacing: 1px;
position: relative;
padding: 5px 0;
}
.nav-links a::after {
content: '';
position: absolute;
width: 0;
height: 2px;
bottom: 0;
left: 0;
background-color: var(--primary-color);
box-shadow: 0 0 5px var(--primary-color);
transition: width 0.3s;
}
.nav-links a:hover {
color: var(--primary-color);
}
.nav-links a:hover::after {
width: 100%;
}
/* --- Hero 区域 --- */
.hero {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
position: relative;
}
.hero-title {
font-family: 'Orbitron', sans-serif;
font-size: 4rem;
font-weight: 900;
margin-bottom: 20px;
text-transform: uppercase;
position: relative;
color: #fff;
}
/* 故障艺术效果 */
.glitch {
position: relative;
}
.glitch::before, .glitch::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.glitch::before {
left: 2px;
text-shadow: -1px 0 var(--secondary-color);
clip: rect(24px, 550px, 90px, 0);
animation: glitch-anim 2s infinite linear alternate-reverse;
}
.glitch::after {
left: -2px;
text-shadow: -1px 0 var(--primary-color);
clip: rect(85px, 550px, 140px, 0);
animation: glitch-anim2 3s infinite linear alternate-reverse;
}
@keyframes glitch-anim {
0% { clip: rect(30px, 9999px, 10px, 0); }
20% { clip: rect(15px, 9999px, 100px, 0); }
40% { clip: rect(50px, 9999px, 20px, 0); }
60% { clip: rect(80px, 9999px, 120px, 0); }
80% { clip: rect(10px, 9999px, 60px, 0); }
100% { clip: rect(40px, 9999px, 90px, 0); }
}
@keyframes glitch-anim2 {
0% { clip: rect(60px, 9999px, 10px, 0); }
20% { clip: rect(100px, 9999px, 30px, 0); }
40% { clip: rect(10px, 9999px, 80px, 0); }
60% { clip: rect(30px, 9999px, 50px, 0); }
80% { clip: rect(90px, 9999px, 10px, 0); }
100% { clip: rect(20px, 9999px, 70px, 0); }
}
.hero-subtitle {
font-size: 1.5rem;
color: var(--primary-color);
margin-bottom: 40px;
letter-spacing: 3px;
text-shadow: 0 0 5px rgba(0, 243, 255, 0.5);
}
.cta-btn {
padding: 15px 40px;
background: transparent;
border: 2px solid var(--primary-color);
color: var(--primary-color);
font-family: 'Orbitron', sans-serif;
font-weight: 700;
text-transform: uppercase;
cursor: pointer;
position: relative;
overflow: hidden;
transition: color 0.3s, box-shadow 0.3s;
text-decoration: none;
display: inline-block;
}
.cta-btn:hover {
color: #050505;
background: var(--primary-color);
box-shadow: 0 0 20px var(--primary-color), inset 0 0 20px rgba(255,255,255,0.2);
}
/* --- 通用区块样式 --- */
.section {
padding: 100px 10%;
}
.section-title {
font-family: 'Orbitron', sans-serif;
font-size: 2.5rem;
color: var(--primary-color);
margin-bottom: 50px;
text-align: center;
text-transform: uppercase;
position: relative;
}
.section-title::after {
content: '';
display: block;
width: 100px;
height: 2px;
background: var(--secondary-color);
margin: 10px auto;
box-shadow: 0 0 10px var(--secondary-color);
}
/* --- 技能区域 --- */
.skills-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 30px;
}
.skill-card {
background: var(--card-bg);
border: 1px solid rgba(0, 243, 255, 0.1);
padding: 30px;
position: relative;
transition: transform 0.3s, border-color 0.3s;
clip-path: polygon(0 0, 100% 0, 100% 85%, 90% 100%, 0 100%); /* 切角效果 */
}
.skill-card:hover {
transform: translateY(-5px);
border-color: var(--primary-color);
box-shadow: 0 0 15px rgba(0, 243, 255, 0.1);
}
.skill-card h3 {
font-family: 'Orbitron', sans-serif;
color: var(--primary-color);
margin-bottom: 15px;
font-size: 1.2rem;
}
.skill-bar {
height: 5px;
background: rgba(255, 255, 255, 0.1);
margin-top: 10px;
position: relative;
}
.skill-progress {
height: 100%;
background: var(--primary-color);
box-shadow: 0 0 10px var(--primary-color);
width: 0; /* 动画初始值 */
transition: width 1.5s ease-in-out;
}
/* --- 项目区域 --- */
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
}
.project-card {
background: linear-gradient(135deg, rgba(20,20,30,0.9), rgba(10,10,15,0.9));
border: 1px solid rgba(255, 255, 255, 0.05);
overflow: hidden;
position: relative;
transition: 0.3s;
}
.project-card::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(0, 243, 255, 0.1), transparent);
transition: 0.5s;
}
.project-card:hover::before {
left: 100%;
}
.project-content {
padding: 30px;
border-top: 2px solid transparent;
transition: border-color 0.3s;
}
.project-card:hover .project-content {
border-top-color: var(--secondary-color);
}
.project-title {
font-family: 'Orbitron', sans-serif;
font-size: 1.3rem;
margin-bottom: 15px;
color: #fff;
}
.project-desc {
font-size: 0.95rem;
color: #aaa;
margin-bottom: 20px;
}
.tag {
display: inline-block;
padding: 4px 8px;
background: rgba(0, 243, 255, 0.1);
color: var(--primary-color);
font-size: 0.8rem;
border: 1px solid rgba(0, 243, 255, 0.2);
margin-right: 5px;
margin-bottom: 5px;
}
/* --- 页脚 --- */
footer {
padding: 50px 5%;
background: rgba(0, 0, 0, 0.8);
text-align: center;
border-top: 1px solid rgba(0, 243, 255, 0.1);
}
.footer-text {
font-family: 'Orbitron', sans-serif;
color: #555;
font-size: 0.8rem;
letter-spacing: 2px;
}
/* --- 响应式 --- */
@media (max-width: 768px) {
.hero-title {
font-size: 2.5rem;
}
.nav-links {
display: none; /* 移动端简化 */
}
}
</style>
</head>
<body>
<!-- 背景特效层 -->
<div class="grid-bg"></div>
<div class="scanline"></div>
<!-- 导航栏 -->
<nav>
<div class="logo">PORTFOLIO.IO</div>
<ul class="nav-links">
<li><a href="#home">Home</a></li>
<li><a href="#skills">Skills</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
<!-- Hero 区域 -->
<section class="hero" id="home">
<h1 class="hero-title glitch" data-text="FUTURE IS NOW">FUTURE IS NOW</h1>
<p class="hero-subtitle">// FULL STACK DEVELOPER & UI DESIGNER //</p>
<a href="#projects" class="cta-btn">Initialize System</a>
</section>
<!-- 技能区域 -->
<section class="section" id="skills">
<h2 class="section-title">System Modules</h2>
<div class="skills-grid">
<div class="skill-card">
<h3>Frontend Architecture</h3>
<p>React, Vue, Three.js 构建高性能交互界面。</p>
<div class="skill-bar"><div class="skill-progress" data-width="90%"></div></div>
</div>
<div class="skill-card">
<h3>Backend Logic</h3>
<p>Node.js, Python, Go 数据处理与API设计。</p>
<div class="skill-bar"><div class="skill-progress" data-width="85%"></div></div>
</div>
<div class="skill-card">
<h3>UI/UX Design</h3>
<p>Figma, After Effects 赛视觉与动效设计。</p>
<div class="skill-bar"><div class="skill-progress" data-width="80%"></div></div>
</div>
</div>
</section>
<!-- 项目区域 -->
<section class="section" id="projects">
<h2 class="section-title">Data Logs</h2>
<div class="projects-grid">
<div class="project-card">
<div class="project-content">
<h3 class="project-title">Project: Cyberpunk-Dash</h3>
<p class="project-desc">一个基于WebGL的数据可视化仪表盘,具有强烈的赛博朋克风格。</p>
<span class="tag">Three.js</span>
<span class="tag">React</span>
<span class="tag">WebGL</span>
</div>
</div>
<div class="project-card">
<div class="project-content">
<h3 class="project-title">Project: Neural-Net</h3>
<p class="project-desc">模拟神经网络运算过程的交互式教育网站。</p>
<span class="tag">Python</span>
<span class="tag">TensorFlow</span>
</div>
</div>
<div class="project-card">
<div class="project-content">
<h3 class="project-title">Project: E-Commerce</h3>
<p class="project-desc">高并发电商系统架构设计与实现。</p>
<span class="tag">Go</span>
<span class="tag">Microservices</span>
</div>
</div>
</div>
</section>
<!-- 页脚 -->
<footer id="contact">
<p class="footer-text">SYSTEM STATUS: ONLINE // VERSION 2.0.1 // © 2023 TECH PORTFOLIO</p>
</footer>
<script>
// 简单的打字机效果逻辑可以在这里添加
// 这里主要实现技能条动画的触发
// 观察技能条进入视口
const skillBars = document.querySelectorAll('.skill-progress');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const width = entry.target.getAttribute('data-width');
entry.target.style.width = width;
observer.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
skillBars.forEach(bar => {
observer.observe(bar);
});
// 导航栏平滑滚动
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
</script>
</body>
</html>
4 本地效果验证:从 Flutter 到 HTML 的跨栈调试
4.1 项目创建与代码替换
- 新建文件夹
tech_mood_ui,将 GLM-5 生成的 HTML 代码保存为test.html; - 用 VS Code 打开文件夹,通过 Live Server 插件启动本地服务(端口 5500),点击右下角Go Live即可运行;
- 浏览器访问
http://localhost:5500/test.html,也可验证科技感 UI 效果。
4.2 效果验证要点
- 视觉特效:网格背景、扫描线、故障标题均正常显示,霓虹发光效果清晰;
- 交互反馈:按钮 hover 时填充发光,技能条滚动时自动填充,导航链接平滑滚动;
- 响应式适配:移动端自动隐藏导航链接,布局无错乱。
4.3 运行效果展示



5 实践感悟
- AI 迭代效率:从 "开心版" 到 "科技感版",GLM-5 在 10 分钟内完成了从需求分析到代码生成的全流程,传统开发中至少需要数小时的风格重构,大幅降低了 UI 迭代门槛;
- 跨栈适配能力:GLM-5 能根据技术栈(Flutter/HTML)自动调整实现方式,既保证了效果落地,又适配了不同平台的开发习惯;
- 参数的核心作用 :
Max Tokens和Temperature的精准设置,是 AI 完整输出复杂特效代码的关键,避免了因截断导致的效果缺失。
参与链接:
GLM-5 在线体验:https://ai.atomgit.com/zai-org/GLM-5/model-inference