Skip to content
歡迎來票選你最喜歡的元件! 也可以告訴我任何你想說的話喔!(*´∀`)~♥

歪像按鈕 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 將按鈕隨機切割成多個不規則的多邊形切片(透過 rowCountcolCount 調整行列數量)。
  • 透過 CSS 3D 的 transform: translateZ 將這些切片在 Z 軸上前後錯開分布(透過 zSpread 調整深度)。在非正面的角度觀看時,切片之間會因為視差而支離破碎。◝( •ω• )◟

游標鎖定與視角旋轉

  • 藉由 VueUse 的 usePointerLockuseMouse,在使用者按下(pointerdown)元素時鎖定游標,並擷取游標的相對移動量(movementXmovementY)。
  • 將這些移動量轉換為元件容器的 3D 旋轉角度(rotateXrotateY),讓使用者能親手「轉動」這個破碎的物件。

視覺干擾

  • 為了增加難度與防堵效果,除了主切片外,還複製了多組旋轉過角度的「干擾切片」。
  • 隨著使用者將物件旋轉到越接近目標角度(rotateXrotateY 趨近於 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;
}

v0.58.0