Skip to content

OSU 打擊鈕 button

如同 OSU 遊戲的打擊鈕,看準時機點擊按鈕吧!(ゝ∀・)b

至於甚麼是 OSU 遊戲,可以來這裡看看。

技術關鍵字

名稱 描述
Pointer 事件偵測滑鼠或觸控點移動、點擊、懸停等等事件,取得座標、目標等等資訊
JS 動畫基於 JavaScript 實現的動畫,達成更複雜、精準的動畫控制,常見套件有 GSAP、anime.js 等
Anime.js輕量級 JavaScript 動畫函式庫

使用範例

基本用法

觸碰後會出現接近圈圈,在圈圈大小與原本按鈕大小一致時,給他用力點下去!੭ ˙ᗜ˙ )੭

查看範例原始碼
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-osu-hit label="送出" />
    </div>
  </div>
</template>

<script setup lang="ts">
import BtnOsuHit from '../btn-osu-hit.vue'
</script>

表單範例

Perfect 判定才會觸發事件,同時縮短反應時間,氣死你同事吧 ᕕ( ゚ ∀。)ᕗ

真的不訂飲料?( ・ิω・ิ) 貼心小提醒,您即將損失:
  • 一杯好喝的飲料
  • 悠閒的午休時光
  • 美好的心情
操作已完成 (╥ω╥`)
查看範例原始碼
vue
<template>
  <div class="relative flex flex-col gap-3 border border-red-300 rounded-lg bg-red-50 p-6">
    <span class="text-xl text-red-800 font-bold">
      真的不訂飲料?( ・ิω・ิ)
    </span>

    <span class="mt-2 text-red-700">
      貼心小提醒,您即將損失:
    </span>

    <ul class="list-disc list-inside text-sm text-red-600 !m-0">
      <li>一杯好喝的飲料</li>
      <li>悠閒的午休時光</li>
      <li>美好的心情</li>
    </ul>

    <div class="flex justify-end gap-4">
      <base-btn label="取消" />

      <btn-osu-hit
        :reaction-time="400"
        @perfect="handleClick"
      >
        <base-btn
          label="確認"
          class="text-white active:scale-95 !border-none !bg-red-600"
        />
      </btn-osu-hit>
    </div>

    <div
      class="pointer-events-none absolute inset-0 flex items-center justify-center bg-black/90 duration-500"
      :class="done ? ' opacity-100' : 'opacity-0'"
    >
      <span class="text-2xl text-white font-bold">
        操作已完成 (╥ω╥`)
      </span>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import BaseBtn from '../../base-btn.vue'
import BtnOsuHit from '../btn-osu-hit.vue'

const done = ref(false)
function handleClick() {
  done.value = true
  setTimeout(() => {
    done.value = false
  }, 2000)
}
</script>

原理

使用了 Anime.js 來實作動畫並在點擊後依照縮放數值判斷打擊結果。

原始碼

API

Props

interface Props {
  label?: string;
  /** 反應時間,單位:毫秒 */
  reactionTime?: number;
}

Emits

interface Emits {
  perfect: [];
  great: [];
  good: [];
  miss: [];
}

Methods

interface Expose {
  /** 開始打擊,會出現 Approach Circle */
  startBeat: () => void;
}

Slots

interface Slots {
  default?: () => unknown;
  perfect?: () => unknown;
  great?: () => unknown;
  good?: () => unknown;
  miss?: () => unknown;
}

v0.49.3