iT邦幫忙

2024 iThome 鐵人賽

DAY 9
1
Modern Web

創意前端設計:用 Vue.js 打造 30 個互動實用功能系列 第 9

Day09 Vue.js 動效分類實戰 (1) 微交互特輯 - 打造你的獨一無二視覺體驗

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240923/20124462SGDuN8PrCo.jpg


探索細膩互動設計,從零開始實踐 Vue.js 微交互動效

歡迎來到「微交互特輯」!
今天我們將一起深入探索那些讓畫面更有溫度的小巧思。

無論是按鈕按下的瞬間、滑鼠滑過的細微變化,還是輸入框那輕輕一閃的提示,這些看似不起眼的小動效,其實是 UI 設計中的秘密武器!
準備好和我一起用 Vue.js 打造屬於你的獨一無二視覺體驗了嗎?
Let’s go! 🚀✨


img

生活中的微交互(Micro-interaction)

微交互(Micro-interactions)的定義是指在使用者與界面進行操作時,發生的細小且短暫的互動,通常用來提供即時反饋或增強使用者體驗。這些互動往往是簡單的、不打斷流程的行為,但它們能有效地提升使用者在使用產品或界面時的愉悅感和操作流暢度。

微交互的四個組成部分:

  1. 觸發器(Trigger)

    • 觸發微交互的行為,可能是使用者的動作(例如點擊按鈕、滑動屏幕)或系統自身的行為(例如時間到期、狀態變更)。
  2. 規則(Rules)

    • 規定微交互應如何反應,即當觸發器被激活後,微交互應該執行什麼樣的行為。這部分定義了當使用者與界面互動時,系統的邏輯回應。
  3. 反饋(Feedback)

    • 微交互向使用者提供的反饋。這通常是用來告知使用者操作成功或失敗。例如,點擊按鈕後出現的狀態變化(如顏色改變或動效效果)。
  4. 循環與模式(Loops and Modes)

    • 這部分決定了微交互的可持續性和變化。例如,一個微交互是否會重複運行,或在某些條件下是否會發生變化。

微交互的例子:

  • 滑鼠 Hover 效果:當滑鼠移到按鈕或鏈接上時,按鈕會變色、放大、出現陰影等反應。
  • 進度條加載:文件上傳或下載時,進度條會顯示當前進度,讓使用者了解處理過程。
  • 通知提示:新消息到達時,系統會顯示彈窗提示,並伴隨音效或振動等反饋。
  • 按鈕回饋:比如臉書平台影音直播等等的按讚表情放大縮小的互動功能。

微交互的核心目的:

  • 提升可用性:微交互幫助使用者更容易理解系統狀態和操作結果,減少不必要的操作錯誤。
  • 增強使用者體驗:微交互能使使用者的操作過程更加直觀和愉快,增強對界面的感知和沉浸感。
  • 強化反饋:當使用者進行操作時,即時反饋能讓使用者知道操作是否成功完成,減少焦慮感。

簡單來說,微交互就是那些看似不顯眼,但又能在使用者與界面互動時,提供關鍵反饋的小細節。
它們雖然微小,但卻能極大地改善整體使用者體驗。
流暢度到反應的細節,這正是微交互的精髓所在。


微交互與交互的區別

微交互(Micro-interaction)

微交互是界面中的細緻互動,針對單一行為或狀態轉變,專注於細節並提供即時反饋。

特點

  1. 範圍小:專注於單一動作(如點擊、打字)。
  2. 即時反饋:簡單動效告知系統狀態。
  3. 持續短暫:幾秒內完成,流程流暢。

交互(Interaction)

交互是整體的互動體驗,涵蓋系統與使用者間的所有操作過程。

特點

  1. 範圍廣泛:包含多步驟、多狀態的互動。
  2. 完整流程:從操作開始到結果的全過程。
  3. 多樣互動方式:按鈕、語音、手勢等形式。

區別

  • 範圍:微交互小而精緻,交互覆蓋整體流程。
  • 目的:微交互強調細節反饋,交互著重完成完整任務。
  • 影響:微交互影響局部操作感受,交互影響整體體驗。

實作一個吸睛的微交互:互動式眼睛密碼框

接下來,我們將實作一個 Vue 3 和 TypeScript 的互動範例。
這個元件包含了趣味的眼睛動畫,結合微交互概念打造出吸引人的視覺效果。

** 主要功能:**

  1. 閃爍動畫:設計一個模擬眼睛眨動。
  2. 眼球運動:眼睛隨鼠標移動,增添互動感。
  3. 切換密碼顯示:文字和密碼之間切換,並附有擾亂文字的動效。

這個實作將展示如何使用微交互設計提升界面互動感。
微交互不僅能增強細節的反饋效果,還能讓整個操作變得更加生動有趣。

透過實作這些有趣的動效,你將學會如何在 Vue.js 中不只能發揮創意還能輕鬆實現這些讓人眼睛一亮的設計!

接著,請欣賞程式碼,並且跟者我們實做大心法吧!

<script setup>
import { ref, onMounted } from "vue";

const isBlinking = ref(false);

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const blinkSequence = async () => {
  for (let i = 0; i < 2; i++) {
    isBlinking.value = !isBlinking.value;
    await sleep(150);
    isBlinking.value = !isBlinking.value;
    if (i === 0) await sleep(150);
  }
};

onMounted(() => setInterval(blinkSequence, 3000));


</script>
<template>
  <div class="grid place-items-center min-h-screen font-mono text-gray-4 bg-dark-9">
    <div class="relative border-2 border-gray-400 rounded">
      <label
        class="absolute bottom-[calc(100%_+_0.5rem)] text-gray-400 tracking-[0.2ch] transition-colors duration-200"
        >Password</label
      >
      <input
        ref="passwordInput"
        v-model="password"
        type="password"
        required
        class="p-4 pr-16 text-[1.75rem] tracking-[0.2ch] rounded-[6px] text-gray-400 border-gray-400 border-solid bg-dark-9 outline-none transition-colors duration-200"
      />
      <button
        title="Reveal Password"
        @click="toggleScramble"
        class="absolute right-0 top-1/2 translate-y-[-50%] p-0 grid place-items-center h-full aspect-square rounded-lg border-none bg-dark-9 border-[6px] border-transparent transition-background duration-125 text-gray-400 outline-none"
      >
        <svg
          class="w-[75%]"
          :class="{ blinking: isBlinking }"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <defs>
            <mask id="eye-open">
              <path
                d="M1 12C1 12 5 4 12 4C19 4 23 12 23 12V20H12H1V12Z"
                fill="#D9D9D9"
                stroke="black"
                stroke-width="1.5"
                stroke-linejoin="round"
              />
            </mask>
            <mask id="eye-closed">
              <path
                d="M1 12C1 12 5 20 12 20C19 20 23 12 23 12V20H12H1V12Z"
                fill="#D9D9D9"
              />
            </mask>
          </defs>
          <path
            class="lid lid--upper"
            d="M1 12C1 12 5 4 12 4C19 4 23 12 23 12"
            stroke="currentColor"
            stroke-width="1.5"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
          <path
            class="lid lid--lower"
            d="M1 12C1 12 5 20 12 20C19 20 23 12 23 12"
            stroke="currentColor"
            stroke-width="1.5"
            stroke-linecap="round"
            stroke-linejoin="round"
          />
          <g :mask="isBlinking ? 'url(#eye-closed)' : 'url(#eye-open)'">
            <g class="eye">
              <circle cx="12" cy="12" r="4" fill="currentColor" />
              <circle cx="13" cy="11" r="1" fill="black" />
            </g>
          </g>
        </svg>
      </button>
    </div>
  </div>
</template>

<style>
.blinking .lid--upper {
  animation: blink-upper 0.3s forwards;
}

.blinking .lid--lower {
  animation: blink-lower 0.3s forwards;
}

@keyframes blink-upper {
  0% {
    d: path("M1 12C1 12 5 4 12 4C19 4 23 12 23 12");
  }
  100% {
    d: path("M1 12C1 12 5 20 12 20C19 20 23 12 23 12");
  }
}

@keyframes blink-lower {
  0% {
    d: path("M1 12C1 12 5 20 12 20C19 20 23 12 23 12");
  }
  100% {
    d: path("M1 12C1 12 5 20 12 20C19 20 23 12 23 12");
  }
}
</style>

解構微交互動效設計

  • SVG 眼睛圖示 (<svg>):

    • 這個 SVG 圖形代表了一隻眼睛,能隨著使用者的操作眨眼。
    • 使用 :class="{ blinking: isBlinking }" 動態綁定 blinking 樣式,當 isBlinking 狀態為真時觸發眨眼效果。
    • 透過 SVG 路徑和遮罩(mask)來呈現開眼和閉眼的效果,增添真實感。
  • 遮罩 (<mask id="eye-open"><mask id="eye-closed">):

    • 定義開眼和閉眼狀態的兩個遮罩形狀。
    • 根據 isBlinking 狀態在這兩個遮罩間切換,創造眨眼的動畫效果。
  • 上眼皮與下眼皮 (<path class="lid lid--upper"><path class="lid lid--lower">):

    • 代表上眼皮和下眼皮的路徑。
    • blinking 樣式啟用時,這些路徑會進行動畫,模擬眼睛的閉合與張開。
  • 眼睛瞳孔與虹膜 (<g class="eye">):

    • 瞳孔和虹膜的群組,被包含在眼睛的路徑內。
    • 包含一個較大的圓形作為虹膜,以及較小的黑色圓形作為瞳孔,使眼睛動畫更真實。

這次的實作不僅是技術的呈現,更是微交互設計的體現。
透過這些細小的互動,我們能為使用者創造更貼心、更有溫度的使用體驗。

希望你也能從中獲得靈感,將微交互應用到自己的專案中喔!


上一篇
Day08 Vue.js 簡單迷人的網頁動態效果 - TransitionGroup 篇
下一篇
Day10 Vue.js 動效分類實戰 (2) 背景動態特輯 - 打造療癒泡泡感
系列文
創意前端設計:用 Vue.js 打造 30 個互動實用功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言