iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
Modern Web

微光採集瓶:用 Vue 3 打造每日美好記錄網頁系列 第 18 篇

【Day 18】時光篩選器:快速找到特定日子的回憶

  • 分享至 

  • xImage
  •  

昨天我們實作了「凌晨兩點跨日判定」與「自動補上純白光珠」的邏輯,整個系統在基本功能方面已經差不多具備。但也因為瓶子會如實記錄親手採集與留白補發的微光,瓶底的光珠越來越多。

如果想找回上週二記錄的微光,用滑鼠在瓶子裡一顆一顆碰運氣摸索,體驗難免有些不友善。今天我們要讓操作更得心應手:在瓶子上方加上一個「時光篩選器」。選定特定日期,瓶中該日的光珠立刻聚焦亮起,其餘微光則悄然黯淡,可即時重溫那天的美好回憶!

一、互動體驗設計

在思考篩選功能時,直覺的做法常是「只渲染符合條件的項目,不符合的直接從 DOM 移除」。

但在這個微光採集瓶中,光珠本來就是自然隨機堆疊在瓶底,有一個具體畫面。如果選了某一天,其他光珠全消失,瓶子看起來就會突然空掉,打破了「時光積累」的視覺感。

因此我們採用「聚焦高亮」的設計:

  • 不符合條件的光珠:不移除,而是降低透明度。
  • 符合條件的光珠:維持 100% 透明度 ,並給予微光放大的效果與更強的發光陰影。
  • 未選取狀態(顯示全部):所有光珠恢復均勻發光。

二、程式碼實作

這項功能的邏輯非常簡單,完全不需要複雜的時間運算,只需透過 Vue 的雙向綁定與動態 Class 就能完成。

1. 在 <script setup> 新增篩選狀態

我們需要一個狀態變數 filterDate 來記錄使用者當前挑選的日期字串,預設為空字串(代表顯示全部):

// 記錄使用者挑選的篩選日期,空字串代表顯示所有微光
const filterDate = ref('')

// 判斷某顆光珠是否應該變暗(當有選取日期,且日期不吻合時)
function isDimmed(gem) {
  if (!filterDate.value) return false
  return gem.date !== filterDate.value
}

// 判斷某顆光珠是否被選中
function isHighlighted(gem) {
  if (!filterDate.value) return false
  return gem.date === filterDate.value
}

// 清除篩選條件,重置回所有微光
function resetFilter() {
  filterDate.value = ''
}

2. 在 <template> 加入時光篩選列

在瓶子上方放一個簡約俐落的工具列,包含原生日期選取器與重置按鈕:

<!-- 時光篩選列 -->
<div class="filter-bar">
  <label for="filterDateInput" class="filter-label">時光檢索:</label>
  <input 
    id="filterDateInput"
    type="date" 
    v-model="filterDate" 
    class="filter-date-input"
  />
  <button 
    v-if="filterDate" 
    class="btn-reset-filter" 
    @click="resetFilter"
  >
    顯示全部
  </button>
</div>

3. 為光珠綁定動態樣式 Class

找到瓶子內渲染光珠的 gem-dot,透過物件語法動態掛載剛才的判斷邏輯:

<div
  v-for="gem in gems"
  :key="gem.id"
  class="gem-dot"
  :class="{
    'is-dimmed': isDimmed(gem),
    'is-highlighted': isHighlighted(gem)
  }"
  :style="{
    backgroundColor: gem.color,
    '--offset-x': `${gem.offsetX}px`,
    '--offset-y': `${gem.offsetY}px`
  }"
  @click="openGem(gem)"
></div>

4. CSS 聚焦與淡化過渡效果

在 <style scoped> 加入過渡與視覺變化:

/* 時光篩選列外層 */
.filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 0.8rem;
  color: #8b949e;
}

/* 日期選擇輸入框 */
.filter-date-input {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  color: #f0f6fc;
  font-size: 0.8rem;
  padding: 4px 8px;
  outline: none;
  cursor: pointer;
}

/* 清除篩選按鈕 */
.btn-reset-filter {
  background: rgba(255, 255, 255, 0.12);
  border: none;
  border-radius: 6px;
  color: #c9d1d9;
  font-size: 0.75rem;
  padding: 4px 10px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.btn-reset-filter:hover {
  background: rgba(255, 255, 255, 0.25);
  color: #ffffff;
}

/* 光珠被淡化狀態 */
.gem-dot.is-dimmed {
  opacity: 0.18;
  filter: blur(0.5px);
  transform: translate(var(--offset-x, 0), var(--offset-y, 0)) scale(0.85);
}

/* 光珠被選中狀態 */
.gem-dot.is-highlighted {
  opacity: 1;
  transform: translate(var(--offset-x, 0), var(--offset-y, 0)) scale(1.4);
  box-shadow: 0 0 16px rgba(255, 255, 255, 0.95), 0 0 8px currentColor;
  z-index: 5;
}

三、成果驗證

打開網頁並在瓶子裡擁有幾天累積的微光後:

  1. 選擇日期:點擊上方的日期框,挑選某一天的日期。
  2. 觀察瓶身:瓶底其他日子的所有光珠瞬間褪成淡淡的暗影,只有那一天的微光有些微放大,變得更明亮。
  3. 點擊查看:直接點擊該顆發亮的光珠,卡片隨即展開,精準回顧當天寫下的微小美好。
  4. 重置視角:按下「顯示全部」按鈕,所有微光變回原本的光亮狀態。

https://ithelp.ithome.com.tw/upload/images/20261002/20178067Uy6F13e6Lw.png

https://ithelp.ithome.com.tw/upload/images/20261002/20178067GxfiEtZHd9.png

明日預告

有了時光篩選器,找尋某個特定日子的記憶已經變得輕而易舉。
但隨著光珠一顆顆填滿瓶底,我不禁在想:如果能在每個月底,把這整個月採集到的所有微小美好回憶凝聚起來,做出一張專屬於當月的「美好總結卡片」,變成可視化的成果,那一定很有紀念意義吧!
明天(Day 19),我們要為採集瓶打造「月度微光卡片」,把整個月累積的美好記憶打包封存,成為陪伴未來的力量!


上一篇
【Day 17】忘了填寫怎麼辦:自動生成缺席的微光
下一篇
【Day 19】封存月份的美好:月度色卡的誕生及儀式感動畫
系列文
微光採集瓶:用 Vue 3 打造每日美好記錄網頁 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言