❤️ 我們結婚了 | 電子喜帖

by j91157j91157

HTML

<div class="global-petals-container" id="globalPetalsContainer"></div>
<link rel="stylesheet" href="style.css" />
<link href="https://unpkg.com/[email protected]/dist/aos.css" rel="stylesheet" />
<!-- 引入 Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
  href="https://fonts.googleapis.com/css2?family=Noto+Serif+TC:wght@400;700&family=Noto+Sans+TC:wght@300;400;500;700&display=swap"
  rel="stylesheet"
/>

<!-- 載入畫面 -->
<div class="loader" id="loader">
  <div class="loader-content">
    <div class="heart-loader">
      <div class="heart-wrapper">
        <div class="heart"></div>
      </div>
      <div class="heart-wrapper">
        <div class="heart"></div>
      </div>
    </div>
    <p class="loader-text">Loading...</p>
  </div>
</div>

<!-- 漢堡選單按鈕 -->
<button class="menu-toggle" onclick="toggleMenu()" aria-label="開啟選單">
  <span></span>
  <span></span>
  <span></span>
</button>

<!-- 側邊導航列 -->
<nav class="sidebar" id="sidebar">
  <div class="sidebar-header">
    <h3>💕 選單</h3>
    <button class="close-btn" onclick="toggleMenu()">✕</button>
  </div>
  <div class="nav-links">
    <a href="#home" onclick="toggleMenu()">
      <span class="icon">🏠</span>
      <span>首頁</span>
    </a>
    <a href="#date" onclick="toggleMenu()">
      <span class="icon">📅</span>
      <span>婚宴日期</span>
    </a>
    <a href="#location" onclick="toggleMenu()">
      <span class="icon">📍</span>
      <span>婚宴地點</span>
    </a>
    <a href="#schedule" onclick="toggleMenu()">
      <span class="icon">⏰</span>
      <span>婚禮流程</span>
    </a>
    <a href="#gallery" onclick="toggleMenu()">
      <span class="icon">📸</span>
      <span>相簿</span>
    </a>
  </div>
</nav>

<!-- 遮罩層 -->
<div class="overlay" id="overlay" onclick="toggleMenu()"></div>

<!-- 音樂控制 -->
<button class="music-toggle" id="musicToggle" onclick="toggleMusic()">
  🎵
</button>
<audio id="bgMusic" loop>
  <source...

CSS

/* ==================== 基礎設定 ==================== */
:root {
    --primary: #ff6b9d;
    --secondary: #ff4081;
    --accent: #ffc1e3;
    --dark: #2c2c2c;
    --gold: #d4af37;
    --gradient-pink: linear-gradient(135deg, #ff6b9d 0%, #ff4081 100%);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    font-family: 'Noto Sans TC', sans-serif;
    line-height: 1.8;
    color: var(--dark);
    overflow-x: hidden;
    background: #fff;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

/* ==================== 載入畫面 ==================== */
.loader {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 99999;
    transition: opacity 0.5s, visibility 0.5s;
}

.loader.hidden {
    opacity: 0;
    visibility: hidden;
}

.loader-content {
    text-align: center;
}

.heart-loader {
    position: relative;
    width: 100px;
    height: 100px;
    margin: 0 auto 30px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 包裝層 - 負責旋轉 */
.heart-wrapper {
    position: absolute;
    transform: rotate(-45deg); /* 固定旋轉角度 */
}

/* 愛心本體 - 只負責縮放動畫 */
.heart-loader .heart {
    position: relative;
    width: 50px;
    height: 50px;
    background: white;
    animation: heartBeat 1.2s infinite;
}

.heart-loader .heart:before,
.heart-loader .heart:after {
    content: '';
    position: absolute;
    width: 50px;
    height: 50px;
    background: white;
    border-radius: 50%;
}

.heart-loader .heart:before {
    top: -25px;
    left: 0;
}

.heart-loader .heart:after {
    top: 0;
    left: 25px;
}

/* 第二個愛心 */
.heart-wrapper:nth-child(2) .heart {
    animation-delay: 0.3s;
    opacity:...

JavaScript

// ==================== 初始化 ====================
document.addEventListener('DOMContentLoaded', function () {
  AOS.init({
    duration: 1000,
    once: true,
    offset: 100,
    easing: 'ease-out-cubic',
  });

  initLoader();
  initPetals();
  initGallery();
  initScrollEffects();
  initCountdownDisplay();
  initScrollAnimations();

  console.log('💕 電子喜帖載入完成!');
});

// ==================== 載入畫面 ====================
function initLoader() {
  const loader = document.getElementById('loader');
  setTimeout(() => {
    loader.classList.add('hidden');
    setTimeout(() => {
      loader.remove();
    }, 500);
  }, 2000);
}

// ==================== 花瓣飄落 ====================
function initPetals() {
  const container = document.getElementById('globalPetalsContainer');
  if (!container) return;

  const isMobile = window.innerWidth < 768;
  const maxPetals = isMobile ? 12 : 20;
  let petalCount = 0;

  const petalColors = [
    'radial-gradient(circle, #ffc1e3, #ff6b9d)',
    'radial-gradient(circle, #ffb3d9, #ff4081)',
    'radial-gradient(circle, #ffd4e8, #ff8fab)',
    'radial-gradient(circle, #ffe0f0, #ffa5c0)',
    'radial-gradient(circle, #fff0f7, #ffcce0)',
  ];

  function createPetal() {
    if (petalCount >= maxPetals) return;
    petalCount++;

    const petal = document.createElement('div');
    petal.className = 'petal';
    petal.style.left = (Math.random() * 90 + 5) + '%';

    const size = Math.random() * 12 + 14;
    petal.style.width = size + 'px';
    petal.style.height = size + 'px';
    petal.style.background = petalColors[Math.floor(Math.random() * petalColors.length)];

    container.appendChild(petal);

    const duration = (Math.random() * 8 + 12) * 1000;
    const driftX = (Math.random() - 0.5) * 100;

    const animation = petal.animate([
      { transform: 'translate3d(0, -50px, 0) rotate(0deg) scale(0)', opacity: 0 },
      { transform: `translate3d(${driftX * 0.3}px, 25vh,...