gallery/src/pages/index.astro

145 lines
3.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
import { galleryConfig } from '../data/gallery-config.js';
// 导入所有组件
import HeroSection from '../components/sections/HeroSection.astro';
import FullBleedSection from '../components/sections/FullBleedSection.astro';
import DualSection from '../components/sections/DualSection.astro';
import GridSection from '../components/sections/GridSection.astro';
import QuadGridSection from '../components/sections/QuadGridSection.astro';
import ScenerySection from '../components/sections/ScenerySection.astro';
// 组件映射表
const componentMap = {
'hero': HeroSection,
'full-bleed': FullBleedSection,
'dual': DualSection,
'grid': GridSection,
'quad-grid': QuadGridSection,
'scenery': ScenerySection
};
---
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<title>Gallery | 时光印记</title>
<meta name="description" content="定格美好瞬间,记录青春故事">
</head>
<body>
<main>
<!-- 渲染首屏 -->
<HeroSection {...galleryConfig.hero} />
<!-- 动态渲染所有 sections -->
{galleryConfig.sections.map((section, index) => {
// 如果 section 有 enabled 属性且为 false则跳过
if (section.enabled === false) return null;
const Component = componentMap[section.type];
return Component ? (
<Component {...section} data-index={index} />
) : null;
})}
<!-- 结尾区块 -->
<section class="end-section">
<div class="end-content">
<h2>时光不老,我们不散</h2>
<p>感谢每一个美好的瞬间</p>
</div>
</section>
</main>
</body>
</html>
<style is:global>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
color: #1a1a1a;
background: #ffffff;
overflow-x: hidden;
}
main {
width: 100%;
}
/* 淡入动画通用样式 */
.fade-in-section {
opacity: 0;
transform: translateY(50px);
transition: opacity 0.8s ease, transform 0.8s ease;
}
.fade-in-section.visible {
opacity: 1;
transform: translateY(0);
}
/* 结尾区块 */
.end-section {
padding: 8rem 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
text-align: center;
}
.end-content {
max-width: 800px;
margin: 0 auto;
color: white;
}
.end-content h2 {
font-size: clamp(2rem, 5vw, 3rem);
font-weight: 700;
margin-bottom: 1rem;
}
.end-content p {
font-size: clamp(1.1rem, 2vw, 1.5rem);
opacity: 0.95;
}
@media (max-width: 768px) {
.end-section {
padding: 4rem 1.5rem;
}
}
</style>
<script>
// Intersection Observer 用于滚动动画
const observerOptions = {
threshold: 0.15,
rootMargin: '0px 0px -100px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, observerOptions);
// 观察所有需要动画的元素
document.querySelectorAll('.fade-in-section').forEach(el => {
observer.observe(el);
});
</script>