transition
昨天我們利用 Svelte 提供的 Store 物件,在色票產生器的專案當中實作出了 toast 的效果,當使用者在色票產生器當中點選【色票加一】、【色票減一】、【鎖定色票】、【解鎖色票】等操作時,就會跳出相對應的 toast 提示使用者。看起來互動效果是不是很不錯呢。知道還有什麼更不錯的嗎?就是替我們的 toast 加入過場效果。
還記得 Svelte 的設計是藉由編譯器,將我們撰寫的 Svelte 檔案轉化為純純的 Javascript,藉此做出具有互動 (reactive) 能力的前端介面。也正是因為編譯器的緣故,開發者在撰寫專案程式碼時,可以寫得簡潔又乾淨,編譯器仍然可以幫我們輸出成互動 (reactive) 詳盡又效能突出 (effective) 的成品。除此之外,Svelte 還提供了一項福利,那就是透過編譯器幫我們做出漂亮的過場效果。
程式碼的撰寫方式也很簡單,話不多說,讓我們直接來 Svelte REPL (Read-Eval-Print-Loop) 寫寫看:
<script>
import { fade } from 'svelte/transition';
let checked = true;
</script>
<label>
<input type="checkbox" bind:checked />
visible
</label>
{#if checked}
<p transition:fade>
Fades in and out
</p>
{/if}
第二行:import { fade } from 'svelte/transition';
引入我們需要的函式 fade
。
第七行:<input type="checkbox" bind:checked />
用 bind:checked
資料綁定的方式,只要點擊這個 checkbox,就可以直接將 checked
的值在 true
跟 false
之間切換。
第十一行:{#if checked}
如果 checked
為 true
,就會顯示以下段落。更精確一點來說,是會掛載以下的 HTML 元素到 DOM 當中。否則,就會將該 HTML 元素從 DOM 當中卸載。
第十二行:<p transition:fade>
替我們在掛載/卸載之間切換的 HTML 元素加上 transition:fade
這一個屬性。看到 :
應該就知道這是 Svelte 所提供的特殊功能,用來處理 transition
,也就是過場效果。而我們選用的過場效果是 fade
。過場效果觸發的時機點是 HTML 元素從 DOM 當中掛載/卸載的那個瞬間。所以當我們將 checked
從 false
切換成 true
,或是從 true
切換成 false
,就會啟動過場的效果。
圖一、我淡出了!我又淡入了!我又淡出了!我又又淡入了!
除了 fade
之外,還有其他簡易的過場效果可以選擇,包括模糊 blur
、飛入 fly
、翻動 slide
、縮放 scale
、繪畫 draw
等等。有興趣的可以參考 Svelte 官方文件做更進一步的認識。
由於 toast 是隨著使用者在互動介面上操作而跳出來的提示,所以相當適合加上一個過場效果來營造出提示的感覺。就讓我們試著在專案當中練習看看如何使用 Svelte 的過場效果吧。直接來到需要過場效果的 Toast.svelte
:
/src/lib/Toast.svelte
<script>
import { scale } from "svelte/transition";
import { toastStore } from "./toastStore";
import plus from "../assets/plus.svg";
import minus from "../assets/minus.svg";
import lock from "../assets/lock.svg";
import unlock from "../assets/unlock.svg";
export let toast;
const icons = { plus, minus, lock, unlock };
$: icon = icons[toast.action];
</script>
<!-- svelte-ignore a11y-click-events-have-key-events a11y-no-static-element-interactions -->
<div
class="toast"
on:click={() => toastStore.removeToast({ id: toast.id })}
transition:scale
>
<div class="icon">
<img src={icon} alt={toast.action} />
</div>
<div class="hex" style="color: #{toast.hex}">{toast.hex}</div>
</div>
第二行:import { scale } from "svelte/transition";
剛才已經看過 fade
,這次換引入 scale
來玩玩。
第十八行:transition:scale
在我們想要加入過場效果的 HTML 元素 <div class="toast">
當中多寫一段 transition:scale
,這樣就算設定完成囉!
圖二、Q 彈的 toast
有了過場效果還不夠,我們還可以加入一些參數去調整過場效果的表現方式,讓過場效果符合不同專案的不同需求:
/src/lib/Toast.svelte
<script>
import { scale } from "svelte/transition";
import { elasticInOut } from "svelte/easing";
import { toastStore } from "./toastStore";
import plus from "../assets/plus.svg";
import minus from "../assets/minus.svg";
import lock from "../assets/lock.svg";
import unlock from "../assets/unlock.svg";
export let toast;
const icons = { plus, minus, lock, unlock };
$: icon = icons[toast.action];
</script>
<!-- svelte-ignore a11y-click-events-have-key-events a11y-no-static-element-interactions -->
<div
class="toast"
on:click={() => toastStore.removeToast({ id: toast.id })}
transition:scale={{ easing: elasticInOut }}
>
<div class="icon">
<img src={icon} alt={toast.action} />
</div>
<div class="hex" style="color: #{toast.hex}">{toast.hex}</div>
</div>
第三行:import { elasticInOut } from "svelte/easing";
除了 scale
這個處理過場效果的函式之外,再引入一個變化相關 (easing) 的函式 elasticInOut
。Svelte 同樣也提供了不少變化相關的函式,有興趣的可以參考 Svelte 官方文件做更進一步的認識。
第十九行:transition:scale={{ easing: elasticInOut }}
先用大括弧 {}
開啟一個 Javascript 的領域,接著放入一個 Javascript 物件當作 scale
這個函式的參數,用來調整 scale
的表現。不同的過場效果函式可以使用的參數也稍微有所不同,一般通用的參數包括有延遲開始的時間 delay
、效果持續時間 duration
、變化函式 easing
等等,更多的參數可以參考 Svelte 官方文件。
圖三、更加 Q 彈的 Toast
過場效果發生的時機包括 HTML 元素載入 DOM 的時候,以及 HTML 元素從 DOM 卸載的時候。如果這兩種不同的時間點想要採用不同的過場效果,可以嗎?Svelte 覺得沒問題!
/src/lib/Toast.svelte
<script>
import { scale, fade } from "svelte/transition";
import { elasticInOut } from "svelte/easing";
import { toastStore } from "./toastStore";
import plus from "../assets/plus.svg";
import minus from "../assets/minus.svg";
import lock from "../assets/lock.svg";
import unlock from "../assets/unlock.svg";
export let toast;
const icons = { plus, minus, lock, unlock };
$: icon = icons[toast.action];
</script>
<!-- svelte-ignore a11y-click-events-have-key-events a11y-no-static-element-interactions -->
<div
class="toast"
on:click={() => toastStore.removeToast({ id: toast.id })}
in:scale={{ easing: elasticInOut }}
out:fade
>
<div class="icon">
<img src={icon} alt={toast.action} />
</div>
<div class="hex" style="color: #{toast.hex}">{toast.hex}</div>
</div>
第二行:import { scale, fade } from "svelte/transition";
除了原本的 scale
,再引入一個過場效果的函式 fade
。
第十九行:in:scale={{ easing: elasticInOut }}
將原本的 transition:scale
改成 in:scale
,表示我們想要在 HTML 元件掛載到 DOM 時使用 scale
這個過場效果。
第二十行:out:fade
並解加上新的功能 out:fade
,表示我們想要在 HTML 元件從 DOM 當中卸載時使用 fade
這個過場效果。
圖四、Q 彈的 toast,淡出的退場
這就是我們今天關於 Svelte 過場效果的內容了,謝謝大家。