iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
自我挑戰組

賽博紓壓診所:從零打造純前端心理測驗與互動紓壓網頁系列 第 4

Day 04:不依賴套件!用 CSS Animation 刻出流暢的呼吸燈過場動畫

  • 分享至 

  • xImage
  •  

前言
昨天我們幫「賽博紓壓診所」加上了日夜切換功能,版面瞬間有了科技感。但是當使用者點擊「進入紓壓診所」準備做測驗時,如果畫面只是瞬間切換過去,會顯得有點生硬。

既然我們的專題主打的是「紓壓」,那在進入正式的心理測驗前,總得先幫大家把緊繃的心情緩和下來。因此,我決定在中間穿插一個「深呼吸引導過場畫面(#breathe-screen)」。

很多漂亮的過場動畫都會依賴大型前端動畫套件(像是 GSAP 或 Framer Motion),但我這次堅持「零套件、純手刻」的原則。今天要來分享我是怎麼用純 CSS 的 @keyframes 刻出一個有韻律感、會自己放大縮小的呼吸燈圓圈!

核心觀念:用 @keyframes 打造呼吸節奏
CSS 動畫的核心就是 @keyframes(關鍵影格)。我們可以設定一個動畫名稱(例如 breatheAnimation),然後定義它在 0%、50%、100% 的不同時間點要產生什麼變化。

為了讓這個呼吸燈看起來夠柔和,我讓圓圈在 50%(也就是吸氣到最大、最放鬆的時候)放大 1.3 倍,同時把背景藍色調得更亮一點;然後在 0% 和 100% 時縮回原本大小。最後加上 infinite 讓它無限循環,並且設定 ease-in-out 讓縮放過程有緩入緩出的滑順感,才不會看起來像機械在抽動。

動手寫 Code(上):呼吸燈的 CSS 樣式與動畫定義
首先,我們在樣式表裡加入圓圈的基礎樣式,並綁定 @keyframes 動畫:

    [data-theme="dark"] {
        --bg-color: #121212;
        --card-bg: #1e1e1e;
        --primary-color: #64b5f6;
        --text-main: #e0e0e0;
        --text-muted: #9e9e9e;
    }

    body {
        font-family: 'Segoe UI', Microsoft JhengHei, sans-serif;
        background: var(--bg-color);
        color: var(--text-main);
        margin: 0;
        padding: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        transition: background 0.3s, color 0.3s;
    }

    .container {
        width: 100%;
        max-width: 600px;
        padding: 20px;
    }

    .card {
        background-color: var(--card-bg);
        border-radius: var(--border-radius);
        box-shadow: 0 12px 30px rgba(0, 0, 0, 0.15);
        padding: 30px;
        text-align: center;
        transition: background-color 0.3s;
    }

    /* 呼吸燈圓圈設計 */
    .breathe-circle {
        width: 120px;
        height: 120px;
        background-color: #90caf9;
        border-radius: 50%;
        margin: 30px auto;
        display: flex;
        justify-content: center;
        align-items: center;
        color: white;
        font-weight: bold;
        /* 綁定動畫:總時長 4 秒、無限循環、緩入緩出 */
        animation: breatheAnimation 4s infinite ease-in-out;
    }

    /* 定義呼吸燈的放大縮小與顏色漸變 */
    @keyframes breatheAnimation {
        0% { transform: scale(1); background-color: #90caf9; }
        50% { transform: scale(1.3); background-color: #42a5f5; }
        100% { transform: scale(1.0); background-color: #90caf9; }
    }

    .btn {
        background-color: var(--primary-color);
        color: white;
        border: none;
        border-radius: 50px;
        padding: 12px 30px;
        font-size: 1rem;
        cursor: pointer;
        width: 100%;
        margin-top: 10px;
    }

    .hidden { display: none; }
</style>

動手寫 Code(下):過場畫面結構與互動邏輯
接著,我們把 #breathe-screen 的結構寫好。當使用者從首頁點擊進入後,除了切換畫面之外,我還用 JavaScript 寫了一個簡單的計時器,讓中間的文字隨著秒數在「吸氣...」和「呼氣...」之間切換,營造出更真實的引導感:

<div class="container">
    
    <!-- 1. 首頁區塊 -->
    <div id="welcome-screen" class="card">
        <h1>🧠 賽博紓壓診所與解碼器</h1>
        <p>結合廟宇抽籤、六角形能力雷達圖與惡搞處方籤的頂級心靈小工具。</p>
        <button class="btn" onclick="goToBreathe()">進入紓壓診所</button>
    </div>

    <!-- 2. 深呼吸過場區塊(預設隱藏) -->
    <div id="breathe-screen" class="card hidden">
        <h2>🧘 調整呼吸,放鬆心情</h2>
        <p>請跟隨圓縮放的節奏,深吸氣... 吐氣...</p>
        <!-- 呼吸燈圓圈本體 -->
        <div class="breathe-circle" id="breathe-text">吸氣...</div>
        <button class="btn" onclick="startQuiz()">準備好了,開始解碼</button>
    </div>

    <!-- 3. 測驗區塊(預設隱藏) -->
    <div id="quiz-screen" class="card hidden">
        <h2>心理測驗題目載入中...</h2>
    </div>

</div>

<script>
    // 切換到呼吸過場畫面,並用簡單的計時器切換文字提示
    function goToBreathe() {
        document.getElementById('welcome-screen').classList.add('hidden');
        document.getElementById('breathe-screen').classList.remove('hidden');

        let step = 0;
        const breatheText = document.getElementById('breathe-text');
        
        // 每 2 秒切換一次吸氣/呼氣文字,配合 4 秒的動畫週期
        const interval = setInterval(() => {
            step++;
            if (step === 1) breatheText.innerText = "呼氣...";
            if (step === 2) breatheText.innerText = "吸氣...";
            if (step >= 4) clearInterval(interval);
        }, 2000);
    }

    function startQuiz() {
        document.getElementById('breathe-screen').classList.add('hidden');
        document.getElementById('quiz-screen').classList.remove('hidden');
    }
</script>

開發小想法與設計巧思
在規劃這個過場畫面的時候,我花了很多時間思考:怎樣才能真正達到「減壓」的效果?

市面上很多測驗一進去就是密密麻麻的題目,對於已經很焦慮的人來說,有機率會造成額外的壓迫感。因此,我試著在前端互動中加入一點「儀式感」——透過純 CSS 的圓圈縮放與溫和的漸層色,讓使用者在點進測驗前,能下意識跟著畫面慢下呼吸。雖然只是很小的前端特效,但這是我在思考專題創新時,希望能為使用者多做的一點貼心小細節。

今日結語與明日預告
今天我們完全不靠任何外部套件,只用純 CSS 的 @keyframes 就刻出了流暢的呼吸燈動畫,順便用 JavaScript 串起了過場文字的切換。

明天 Day 05:SPA 單頁式應用架構:用原生 JS 控制畫面狀態與流暢切換,我們要把前面幾天零散的畫面串聯起來,建立一套乾淨、好擴充的單頁應用切換機制。我們明天見!


上一篇
Day 03:質感介面設計:CSS 變數與日夜模式實戰
下一篇
Day 05:SPA 單頁式應用架構:用原生 JS 控制畫面狀態與流暢切換
系列文
賽博紓壓診所:從零打造純前端心理測驗與互動紓壓網頁7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言