歪像按鈕 button
需要將按鈕旋轉至某個角度,才能正常顯示,可以有效防堵人類 ( •̀ ω •́ )✧
路人:「防機器人才對吧!(╯°Д°)╯︵ ┻━┻」
技術關鍵字
| 名稱 | 描述 |
|---|---|
| Pointer 事件 | 偵測滑鼠或觸控點移動、點擊、懸停等等事件,取得座標、目標等等資訊 |
| JS 動畫 | 基於 JavaScript 實現的動畫,達成更複雜、精準的動畫控制,常見套件有 GSAP、anime.js 等 |
| CSS 3D | 使用 CSS transform 和 perspective 實現 3D 效果 |
使用範例
基本用法
將按鈕轉回原樣吧!◝( •ω• )◟
查看範例原始碼
vue
<template>
<div class="w-full flex flex-col gap-4 border border-gray-200 rounded-xl p-6">
<div class="flex justify-center">
<btn-anamorphosis
:label="t('按鈕')"
@click="handleClick"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import BtnAnamorphosis from '../btn-anamorphosis.vue'
const { t } = useI18n()
function handleClick() {
// eslint-disable-next-line no-alert
alert(t('點擊成功'))
}
</script>原理
核心概念源自視覺歪像(Anamorphosis),透過將完整的畫面打碎並在 3D 空間中錯位排列,只有在特定的觀察角度下才能看到原本完整的模樣。實作細節如下:
多邊形切片與錯位:
- 使用 CSS
clip-path將按鈕隨機切割成多個不規則的多邊形切片(透過rowCount與colCount調整行列數量)。 - 透過 CSS 3D 的
transform: translateZ將這些切片在 Z 軸上前後錯開分布(透過zSpread調整深度)。在非正面的角度觀看時,切片之間會因為視差而支離破碎。◝( •ω• )◟
游標鎖定與視角旋轉:
- 藉由 VueUse 的
usePointerLock與useMouse,在使用者按下(pointerdown)元素時鎖定游標,並擷取游標的相對移動量(movementX、movementY)。 - 將這些移動量轉換為元件容器的 3D 旋轉角度(
rotateX、rotateY),讓使用者能親手「轉動」這個破碎的物件。
視覺干擾:
- 為了增加難度與防堵效果,除了主切片外,還複製了多組旋轉過角度的「干擾切片」。
- 隨著使用者將物件旋轉到越接近目標角度(
rotateX與rotateY趨近於 0 的倍數),這些干擾切片的透明度(noiseOpacity)會隨之降低,作為視覺回饋引導使用者找到正確的角度。
自動吸附歸位與解鎖:
- 當旋轉角度與正面差異極小(干擾切片透明度極低)時,自動解除游標鎖定,並觸發「自動對齊」(
isAligning),透過 CSS Transition 緩動強制歸零轉角。 - 對齊動畫結束後(
isDone),隱藏所有空間錯位特效與雜訊,此時底下真正的按鈕才會解除pointer-events-none狀態,讓使用者得以進行點擊等互動。
原始碼
API
Props
interface Props {
label?: string;
/** 行數 */
rowCount?: number;
/** 列數 */
colCount?: number;
/** 切片之間的 Z 軸間距 (px) */
zSpread?: number;
}Emits
const emit = defineEmits<{
click: [];
unlock: [];
}>()Methods
interface Expose {
init: () => void;
}Slots
interface Slots {
default?: () => unknown;
}