From fa8e2a55a83d9c881cfb2939dd8605b5b7d4b3ff Mon Sep 17 00:00:00 2001 From: yangyuqing <1614872855@qq.com> Date: Tue, 2 Jun 2026 11:20:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=E3=80=8C/=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README_IMAGES.md | 137 ++++++++++++ main.js | 149 +++++++++++++ style.css | 529 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 815 insertions(+) create mode 100644 README_IMAGES.md create mode 100644 main.js create mode 100644 style.css diff --git a/README_IMAGES.md b/README_IMAGES.md new file mode 100644 index 0000000..6cfe2c6 --- /dev/null +++ b/README_IMAGES.md @@ -0,0 +1,137 @@ +# 图片替换指南 + +## 📸 如何替换占位图为实际图片 + +### 方法一:直接替换(推荐) + +1. **将你的图片放入 `images/` 文件夹** + ``` + images/ + ├── analysis-geography.jpg # 地理分析图 + ├── analysis-climate.jpg # 气候分析图 + ├── analysis-site.jpg # 选址分析图 + ├── design-aerial.jpg # 鸟瞰渲染图 + ├── design-interior-1.jpg # 室内渲染图1 + ├── design-interior-2.jpg # 室内渲染图2 + ├── design-elevation.jpg # 立面效果图 + ├── design-detail.jpg # 细节特写 + ├── drawing-site-plan.jpg # 总平面图 + ├── drawing-floor-plan.jpg # 平面图 + ├── performance-structure.jpg # 结构受力分析图 + ├── performance-energy.jpg # 节能计算图表 + ├── self-solar.jpg # 太阳能系统示意图 + ├── self-water.jpg # 水循环系统图 + └── construction-site.jpg # 建造场地总图 + ``` + +2. **在 index.html 中替换对应的 div** + + **原代码:** + ```html +
+ 地理分析图 +
+ ``` + + **替换为:** + ```html +
+ 地理分析图 +
+ ``` + +3. **在 CSS 中添加图片样式**(在 `css/style.css` 末尾添加): + ```css + /* 卡片图片样式 */ + .card-image img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; + } + + /* 画廊图片样式 */ + .gallery-item img { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: var(--border-radius); + display: block; + } + ``` + +### 方法二:使用在线图片测试 + +如果你想先测试效果,可以使用在线占位图服务: + +```html + +
+ 地理分析图 +
+``` + +## 🎨 图片尺寸建议 + +| 位置 | 建议尺寸 | 说明 | +|------|---------|------| +| 卡片图片 | 800×600px | 4:3 比例,适合大多数内容 | +| 宽卡片图片 | 1200×600px | 2:1 比例,用于图纸展示 | +| 画廊小图 | 600×600px | 1:1 正方形 | +| 画廊大图 | 1200×900px | 4:3 比例,鸟瞰图等 | +| Hero背景 | 1920×1080px | 如需添加背景图 | + +## 💡 图片优化建议 + +1. **格式选择**: + - 照片类:使用 JPG(质量 80-85%) + - 带透明:使用 PNG + - 最优选择:使用 WebP(体积更小) + +2. **压缩工具**: + - TinyPNG (https://tinypng.com/) + - Squoosh (https://squoosh.app/) + - ImageOptim (Mac) + +3. **命名规范**: + - 使用小写字母 + - 用连字符 `-` 分隔单词 + - 避免中文和特殊字符 + - 例如:`design-aerial-view.jpg` + +## 🔧 常见问题 + +### Q: 图片显示变形怎么办? +A: 确保使用了 `object-fit: cover` 属性,它会自动裁剪图片以适应容器。 + +### Q: 如何让图片点击放大? +A: 可以添加简单的灯箱效果,需要额外的 JavaScript 代码。 + +### Q: 图片加载太慢怎么办? +A: +1. 压缩图片大小 +2. 使用 WebP 格式 +3. 实现懒加载(代码已预留) + +### Q: 如何添加图片说明文字? +A: 在 `` 标签后添加 `
`: +```html +
+ 示例图片 +

这是图片说明

+
+``` + +然后在 CSS 中添加: +```css +.image-caption { + padding: 0.5rem 1rem; + text-align: center; + color: var(--text-secondary); + font-size: 0.9rem; +} +``` + +--- + +**提示**: 在替换完所有图片后,建议在手机和电脑上分别测试显示效果。 diff --git a/main.js b/main.js new file mode 100644 index 0000000..c3a8b9e --- /dev/null +++ b/main.js @@ -0,0 +1,149 @@ +// ======================================== +// 导航栏滚动效果 +// ======================================== +const navbar = document.getElementById('navbar'); +let lastScroll = 0; + +window.addEventListener('scroll', () => { + const currentScroll = window.pageYOffset; + + // 添加滚动时的阴影效果 + if (currentScroll > 50) { + navbar.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.1)'; + } else { + navbar.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.05)'; + } + + lastScroll = currentScroll; +}); + +// ======================================== +// 移动端汉堡菜单 +// ======================================== +const hamburger = document.getElementById('hamburger'); +const navMenu = document.getElementById('navMenu'); +const navLinks = document.querySelectorAll('.nav-link'); + +hamburger.addEventListener('click', () => { + hamburger.classList.toggle('active'); + navMenu.classList.toggle('active'); +}); + +// 点击导航链接后关闭菜单 +navLinks.forEach(link => { + link.addEventListener('click', () => { + hamburger.classList.remove('active'); + navMenu.classList.remove('active'); + }); +}); + +// ======================================== +// 平滑滚动到锚点 +// ======================================== +document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function (e) { + e.preventDefault(); + const target = document.querySelector(this.getAttribute('href')); + + if (target) { + const offsetTop = target.offsetTop - 80; // 减去导航栏高度 + + window.scrollTo({ + top: offsetTop, + behavior: 'smooth' + }); + } + }); +}); + +// ======================================== +// 滚动时导航链接高亮 +// ======================================== +const sections = document.querySelectorAll('section[id]'); + +function highlightNavigation() { + const scrollY = window.pageYOffset; + + sections.forEach(section => { + const sectionHeight = section.offsetHeight; + const sectionTop = section.offsetTop - 100; + const sectionId = section.getAttribute('id'); + const navLink = document.querySelector(`.nav-link[href="#${sectionId}"]`); + + if (navLink) { + if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { + navLink.classList.add('active'); + } else { + navLink.classList.remove('active'); + } + } + }); +} + +window.addEventListener('scroll', highlightNavigation); + +// ======================================== +// 卡片进入视口时的动画效果 +// ======================================== +const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' +}; + +const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + } + }); +}, observerOptions); + +// 观察所有卡片元素 +document.querySelectorAll('.card').forEach(card => { + card.style.opacity = '0'; + card.style.transform = 'translateY(30px)'; + card.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out'; + observer.observe(card); +}); + +// ======================================== +// 页面加载完成后的初始化 +// ======================================== +window.addEventListener('load', () => { + // 添加页面加载完成的类,用于触发初始动画 + document.body.classList.add('loaded'); + + // 立即执行一次高亮检查 + highlightNavigation(); +}); + +// ======================================== +// 图片懒加载(可选优化) +// ======================================== +if ('IntersectionObserver' in window) { + const imageObserver = new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + const img = entry.target; + if (img.dataset.src) { + img.src = img.dataset.src; + img.removeAttribute('data-src'); + observer.unobserve(img); + } + } + }); + }); + + // 可以将来为实际图片添加 data-src 属性实现懒加载 +} + +// ======================================== +// 响应式处理 - 窗口大小改变时重置菜单 +// ======================================== +window.addEventListener('resize', () => { + if (window.innerWidth > 768) { + hamburger.classList.remove('active'); + navMenu.classList.remove('active'); + } +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..8232c05 --- /dev/null +++ b/style.css @@ -0,0 +1,529 @@ +/* ======================================== + 全局变量与基础设置 + ======================================== */ +:root { + /* 莫兰迪色系 - 苔绿色主题 */ + --primary-color: #8A9B7E; + --primary-light: #A8B89E; + --primary-dark: #6B7D60; + --primary-muted: #C5D1BE; + + /* 背景色 */ + --bg-primary: #F5F5F2; + --bg-secondary: #EDEDE8; + --bg-card: #FFFFFF; + + /* 文字颜色 */ + --text-primary: #3D3D3D; + --text-secondary: #6B6B6B; + --text-light: #999999; + + /* 阴影 */ + --shadow-soft: 0 4px 20px rgba(138, 155, 126, 0.12); + --shadow-medium: 0 8px 30px rgba(138, 155, 126, 0.18); + --shadow-hover: 0 12px 40px rgba(138, 155, 126, 0.25); + + /* 间距 */ + --spacing-xs: 0.5rem; + --spacing-sm: 1rem; + --spacing-md: 2rem; + --spacing-lg: 3rem; + --spacing-xl: 5rem; + + /* 圆角 */ + --border-radius: 12px; + + /* 过渡 */ + --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + font-size: 16px; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", + "Hiragino Sans GB", "Microsoft YaHei", sans-serif; + background-color: var(--bg-primary); + color: var(--text-primary); + line-height: 1.8; + overflow-x: hidden; +} + +/* ======================================== + 导航栏样式 + ======================================== */ +.navbar { + position: fixed; + top: 0; + left: 0; + right: 0; + background: rgba(255, 255, 255, 0.95); + backdrop-filter: blur(10px); + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05); + z-index: 1000; + transition: var(--transition); +} + +.nav-container { + max-width: 1400px; + margin: 0 auto; + padding: 1rem 2rem; + display: flex; + justify-content: space-between; + align-items: center; +} + +.nav-logo { + font-size: 1.25rem; + font-weight: 600; + color: var(--primary-color); + letter-spacing: 1px; +} + +.nav-menu { + display: flex; + list-style: none; + gap: 2rem; +} + +.nav-link { + text-decoration: none; + color: var(--text-secondary); + font-size: 0.9rem; + font-weight: 500; + padding: 0.5rem 0; + position: relative; + transition: var(--transition); +} + +.nav-link::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 0; + height: 2px; + background: var(--primary-color); + transition: var(--transition); +} + +.nav-link:hover { + color: var(--primary-color); +} + +.nav-link:hover::after { + width: 100%; +} + +.hamburger { + display: none; + flex-direction: column; + cursor: pointer; + gap: 4px; +} + +.hamburger span { + width: 25px; + height: 2px; + background: var(--primary-color); + transition: var(--transition); +} + +/* ======================================== + Hero区域 + ======================================== */ +.hero { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%); + padding: 6rem 2rem 4rem; + text-align: center; +} + +.hero-content { + max-width: 800px; +} + +.hero-title { + font-size: 3rem; + font-weight: 700; + color: var(--text-primary); + margin-bottom: 1.5rem; + letter-spacing: 2px; + line-height: 1.3; +} + +.hero-subtitle { + font-size: 1.5rem; + color: var(--primary-color); + margin-bottom: 1rem; + font-weight: 500; + letter-spacing: 3px; +} + +.hero-description { + font-size: 1.1rem; + color: var(--text-secondary); + letter-spacing: 1px; +} + +/* ======================================== + 通用区块样式 + ======================================== */ +.section { + padding: var(--spacing-xl) 2rem; +} + +.section-alt { + background-color: var(--bg-secondary); +} + +.container { + max-width: 1400px; + margin: 0 auto; +} + +.section-title { + font-size: 2.5rem; + font-weight: 600; + color: var(--text-primary); + text-align: center; + margin-bottom: var(--spacing-lg); + letter-spacing: 2px; + position: relative; +} + +.section-title::after { + content: ''; + display: block; + width: 60px; + height: 3px; + background: var(--primary-color); + margin: 1rem auto 0; + border-radius: 2px; +} + +/* ======================================== + 卡片样式 + ======================================== */ +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); + gap: var(--spacing-md); + margin-top: var(--spacing-md); +} + +.card-grid.two-columns { + grid-template-columns: repeat(auto-fit, minmax(500px, 1fr)); +} + +.card { + background: var(--bg-card); + border-radius: var(--border-radius); + overflow: hidden; + box-shadow: var(--shadow-soft); + transition: var(--transition); +} + +.card:hover { + transform: translateY(-5px); + box-shadow: var(--shadow-hover); +} + +.card-image { + width: 100%; + height: 300px; + overflow: hidden; +} + +.card-image.wide { + height: 400px; +} + +.card-content { + padding: var(--spacing-md); +} + +.card-content h3 { + font-size: 1.5rem; + color: var(--text-primary); + margin-bottom: var(--spacing-sm); + font-weight: 600; +} + +.card-content p { + color: var(--text-secondary); + line-height: 1.8; + margin-bottom: var(--spacing-sm); +} + +.single-card { + max-width: 900px; + margin: 0 auto; +} + +.centered { + text-align: center; +} + +.large-text { + font-size: 1.15rem; + line-height: 2; + margin-bottom: var(--spacing-md); +} + +.project-info { + margin-top: var(--spacing-lg); + padding-top: var(--spacing-md); + border-top: 1px solid var(--primary-muted); +} + +.project-info p { + margin-bottom: var(--spacing-xs); + color: var(--text-secondary); +} + +.mb-large { + margin-bottom: var(--spacing-lg); +} + +/* ======================================== + 占位图样式 + ======================================== */ +.placeholder-img { + width: 100%; + height: 100%; + background: linear-gradient(135deg, var(--primary-muted) 0%, var(--primary-light) 100%); + display: flex; + align-items: center; + justify-content: center; + color: var(--primary-dark); + font-size: 1.2rem; + font-weight: 500; + letter-spacing: 1px; +} + +.placeholder-img.tall { + height: 500px; +} + +/* ======================================== + 画廊样式 + ======================================== */ +.gallery-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: var(--spacing-md); + margin-top: var(--spacing-md); +} + +.gallery-item.large { + grid-column: span 2; + grid-row: span 2; +} + +.gallery-item .placeholder-img { + height: 300px; + border-radius: var(--border-radius); +} + +.gallery-item.large .placeholder-img { + height: 100%; + min-height: 600px; +} + +/* ======================================== + 列表样式 + ======================================== */ +.info-list { + list-style: none; + margin-top: var(--spacing-sm); +} + +.info-list li { + padding: var(--spacing-xs) 0; + color: var(--text-secondary); + position: relative; + padding-left: 1.5rem; +} + +.info-list li::before { + content: '•'; + position: absolute; + left: 0; + color: var(--primary-color); + font-weight: bold; +} + +/* ======================================== + 表格样式 + ======================================== */ +.data-table { + width: 100%; + border-collapse: collapse; + margin-top: var(--spacing-sm); +} + +.data-table thead { + background: var(--primary-muted); +} + +.data-table th { + padding: 1rem; + text-align: left; + font-weight: 600; + color: var(--text-primary); + border-bottom: 2px solid var(--primary-color); +} + +.data-table td { + padding: 1rem; + border-bottom: 1px solid var(--bg-secondary); + color: var(--text-secondary); +} + +.data-table tbody tr:hover { + background: var(--bg-secondary); + transition: var(--transition); +} + +/* ======================================== + 页脚样式 + ======================================== */ +.footer { + background: var(--text-primary); + color: var(--bg-primary); + padding: var(--spacing-lg) 2rem; + text-align: center; +} + +.footer p { + font-size: 0.9rem; + letter-spacing: 1px; +} + +/* ======================================== + 响应式设计 + ======================================== */ +@media (max-width: 768px) { + html { + font-size: 14px; + } + + .nav-menu { + position: fixed; + left: -100%; + top: 70px; + flex-direction: column; + background: white; + width: 100%; + text-align: center; + transition: var(--transition); + box-shadow: 0 10px 27px rgba(0, 0, 0, 0.05); + padding: 2rem 0; + gap: 0; + } + + .nav-menu.active { + left: 0; + } + + .nav-menu li { + margin: 1rem 0; + } + + .hamburger { + display: flex; + } + + .hamburger.active span:nth-child(1) { + transform: rotate(45deg) translate(5px, 5px); + } + + .hamburger.active span:nth-child(2) { + opacity: 0; + } + + .hamburger.active span:nth-child(3) { + transform: rotate(-45deg) translate(7px, -6px); + } + + .hero-title { + font-size: 2rem; + } + + .hero-subtitle { + font-size: 1.2rem; + } + + .section-title { + font-size: 2rem; + } + + .card-grid { + grid-template-columns: 1fr; + } + + .card-grid.two-columns { + grid-template-columns: 1fr; + } + + .gallery-item.large { + grid-column: span 1; + grid-row: span 1; + } + + .gallery-item.large .placeholder-img { + min-height: 300px; + } + + .section { + padding: var(--spacing-lg) 1rem; + } +} + +@media (max-width: 480px) { + .hero-title { + font-size: 1.75rem; + } + + .nav-container { + padding: 1rem; + } + + .card-content { + padding: var(--spacing-sm); + } +} + +/* ======================================== + 动画效果 + ======================================== */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(30px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.card { + animation: fadeInUp 0.6s ease-out; +} + +.section-title { + animation: fadeInUp 0.6s ease-out; +}