每條游來游去的小魚,都是正在瀏覽這一頁的訪客,有一條是你自己 ( ´ ▽ ` )ノ 覺得干擾閱讀的話,可以把小魚關掉。
真暗黑模式
util真的很黑 (◐‿◑)
受此作品啟發
| 名稱 | 描述 |
|---|---|
| Babylon.js | 3D 引擎 |
| Canvas Shader | 使用 GLSL 開發,直接在 GPU 上執行,比 Canvas 2D API 更快,但也更難 |
| Post-processing | 增強渲染效果,例如:鏡頭模糊、顏色分割等等 |
| Pointer 事件 | 偵測滑鼠或觸控點移動、點擊、懸停等等事件,取得座標、目標等等資訊 |
| JS 動畫 | 基於 JavaScript 實現的動畫,達成更複雜、精準的動畫控制,常見套件有 GSAP、anime.js 等 |
| Vue Directive | 自定義 Vue 指令,用於封裝 DOM 操作邏輯和重複行為 |
光線隨著游標移動,按住後光線會停下來並指向滑鼠位置
使用 v-util-real-dark 指令可以標記欲產生影子的元素
甚麼是暗黑模式?
暗黑模式(Dark Mode)一種把介面背景變暗、文字變亮的顯示方式。
主要目的是為了在低光源環境下減少螢幕刺眼的亮度、降低視覺疲勞,在部分裝置上還能稍微省點電。
另外的好處是當你半夜睡不著覺,想把心情哼成歌,在黑暗中滑開手機時,避免手機變成閃光彈。
開啟暗黑模式之後,你會發現:
- 看起來比較專業,但依然無法提早下班
- 滑社群時比較不會眼睛痠,但還是會被閃照閃瞎鈦合金狗眼
以上,現在你知道我們說的黑是甚麼黑了吧?(⌐■_■)✧
#Canvas #Shader
路人:我很確定你這個黑不是暗黑模式的黑 Σ(ˊДˋ;)
查看範例原始碼
<template> <div class="example-wrap w-full p-4"> <div v-util-real-dark class="w-full rounded-lg" > <base-checkbox v-model="enable" :label="t('enableRealDarkMode')" class="example-ctrl" /> </div>
<div class="w-full py-4"> <div class="mb-3 text-2xl font-bold"> {{ t('whatIsDarkMode') }} </div>
<div class="text-base leading-relaxed space-y-3"> <p> {{ t('darkModeDescription') }} </p>
<p> {{ t('darkModePurpose') }} </p>
<p> {{ t('darkModeBenefit') }} </p>
<p> {{ t('darkModeAfterEnable') }} </p>
<ul class="list-disc list-inside space-y-1"> <li>{{ t('darkModeAfterEnableList1') }}</li> <li>{{ t('darkModeAfterEnableList2') }}</li> </ul>
<p> {{ t('darkModeAfterEnableConclusion') }} </p> </div>
<!-- tags --> <div class="mt-4 flex gap-2"> <span v-util-real-dark class="border border-gray-200 rounded-full p-2 px-4 text-sm text-gray-500 dark:text-gray-400" > #Canvas </span> <span v-util-real-dark class="border border-gray-200 rounded-full p-2 px-4 text-sm text-gray-500 dark:text-gray-400" > #Shader </span> </div> </div>
<util-real-dark class="fixed left-0 top-0 z-[100] h-full w-full" :disabled="!enable" /> </div></template>
<script setup lang="ts">import { onBeforeUnmount, ref, watch } from 'vue'import { useI18n } from 'vue-i18n'import { useSiteDark } from '../../../composables/use-site-dark'import BaseCheckbox from '../../base-checkbox.vue'import UtilRealDark from '../util-real-dark.vue'import { vUtilRealDark } from '../v-util-real-dark'
const isDark = useSiteDark()const oriValue = isDark.value
const { t } = useI18n()const enable = ref(false)
watch(enable, (value) => { if (value) { isDark.value = false } else { isDark.value = oriValue }})
onBeforeUnmount(() => { isDark.value = oriValue})</script>原本使用 p5.js 等等繪圖相關套件實作,但重現光線投影、暈光等等效果實在太難惹,以至於這個元件就這麼擱置了好一陣子...(›´ω`‹ )
某天忽然靈光一閃:「3D 套件不是本來就有光源了嗎?」,於是就改用 Babylon.js 實作。
關鍵在於以 Shader 根據灰度值設定 alpha,讓亮的地方變透明,完成光線效果。
最後在加上移動光源的效果,終於成功了!( •̀ ω •́ )✧
2025/12/14 更新:新增陰影效果
感謝 @po_han.chiu 提供的陰影效果點子,加上陰影後看起來更加有趣了
也藉此機會認真的閱讀了 Babylon.js 的 Shadow 章節
可以看到 Babylon.js 提供了多種陰影實作,看樣子陰影真的是一門學問 (´・ω・`)
interface Props { disabled?: boolean; /** 平滑係數。越小越慢,延遲越明顯 */ ease?: number; /** 甩尾強度。越大越明顯 */ offsetStrength?: number; /** 燈光尺寸 */ size?: number; lightColor?: string; /** 透明度 @default 0.9 */ opacity?: number;}