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

軌道單選器 radio

可以抓住球拖曳並拋出,球會受到各個選項黑洞的引力影響,最終被最近的黑洞捕獲。

也可以直接點選選項,球會自動飛過去。

技術關鍵字

名稱 描述
Pointer 事件偵測滑鼠或觸控點移動、點擊、懸停等等事件,取得座標、目標等等資訊
物理模擬模擬真實世界物理現象,如重力、碰撞、速度等物理效果
JS 動畫基於 JavaScript 實現的動畫,達成更複雜、精準的動畫控制,常見套件有 GSAP、anime.js 等

使用範例

基本用法

不知道喝甚麼?放手交給物理學吧 (ノ>∀<)ノ ⌒*

珍珠奶茶
紅茶
可可
柳橙汁
查看範例原始碼
vue
<template>
  <div class="w-full flex flex-col gap-4 border border-gray-200 rounded-xl p-6 py-10">
    <div class="flex justify-center">
      <radio-orbital
        v-model="selected"
        :options="options"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import RadioOrbital from '../radio-orbital.vue'

const { t } = useI18n()

const options = computed(() => [
  { label: t('bubbleTea'), value: 'bubble-tea' },
  { label: t('blackTea'), value: 'black-tea' },
  { label: t('cocoa'), value: 'cocoa' },
  { label: t('orangeJuice'), value: 'orange-juice' },
])

const selected = ref('bubble-tea')
</script>

原理

每個選項就像宇宙中的黑洞,對球施加引力。

球被拋出後,根據牛頓萬有引力公式計算加速度,同時透過阻尼係數模擬空氣阻力讓球逐漸減速。


路人:「太空甚麼時候有空氣阻力了?」

鱈魚:「...我說有就是有 ( ・ิω・ิ)」


當球靠近某個黑洞且速度低於閾值時,就會被捕獲,觸發選取事件。

具體流程如下:

  1. 使用 Pointer Events 追蹤拖曳軌跡,透過滑動時間窗口計算釋放瞬間的速度。
  2. 釋放後進入物理模擬,每幀計算所有黑洞對球的引力加速度。
  3. 加入阻尼讓球逐漸減速,碰到視窗邊界則反彈。
  4. 球進入捕捉範圍且速度夠低時,吸入黑洞完成選取。

重力軟化(Softening)

在真實的 N 體模擬中,當兩個物體距離趨近於零時,引力公式中的分母也趨近於零,導致加速度趨近無限大。

重力軟化參數就是在分母加上一個小值,避免數值爆炸。∠( ᐛ 」∠)_

原始碼

API

Props

interface RadioOption {
  label: string;
  value: string;
}

interface Props {
  /** 目前選取的值 */
  modelValue?: string;
  /** 選項列表 */
  options?: RadioOption[];
  /**
   * 球的直徑(px)
   * @default 12
   */
  ballSize?: number;
  /**
   * 重力強度
   * @default 5_000_000
   */
  gravity?: number;
  /**
   * 阻尼係數(0-1)。數值越小球減速越快,會很快停下來;數值越大球滑行距離越長,減速越慢
   * @default 0.4
   */
  damping?: number;
  /**
   * 捕捉距離(px)。球進入此範圍且速度夠低時會被吸入。數值越大越容易被捕捉;數值越小需要更精確地靠近黑洞
   * @default 14
   */
  captureDistance?: number;
  /**
   * 捕捉速度閾值(px/s)。球速度低於此值才會被捕捉。數值越大球在較快速度時也能被吸入;數值越小球必須幾乎靜止才會被捕捉
   * @default 100
   */
  captureSpeed?: number;
  /**
   * 重力軟化參數,防止球靠近黑洞時加速度爆炸。數值越大重力變化越平滑,球不會突然加速;數值越小球靠近黑洞時會急劇加速
   * @default 12
   */
  softening?: number;
  /**
   * 點選黑洞時球移動過去的動畫時長(ms)
   * @default 350
   */
  moveDuration?: number;
  /**
   * 主色調,用於球顏色與選中時的邊框色。接受任何 CSS 合法顏色值
   * @default '#34c6eb'
   */
  color?: string;
}

Emits

interface Emits {
  'update:modelValue': [value: string];
}

v0.59.0