靈活的按鈕 button
動作極為靈活的按鈕 ◝( •ω• )◟
靈感來自劍星的 Doro 迷因連動,第一次看到時真的會笑死。(´,,•ω•,,)
技術關鍵字
| 名稱 | 描述 |
|---|---|
| Pointer 事件 | 偵測滑鼠或觸控點移動、點擊、懸停等等事件,取得座標、目標等等資訊 |
| JS 動畫 | 基於 JavaScript 實現的動畫,達成更複雜、精準的動畫控制,常見套件有 GSAP、anime.js 等 |
使用範例
基本用法
disabled 時,觸發按鈕會超高速閃避。─=≡Σ((( つ•̀ω•́)つ
查看範例原始碼
vue
<template>
<div class="w-full flex flex-col gap-4 border border-gray-200 rounded-xl p-6">
<div class="flex flex-col gap-4 border rounded">
<base-checkbox
v-model="disabled"
label="停用按鈕"
class="p-4"
/>
</div>
<div class="flex justify-center">
<btn-agile
label="按我"
:disabled="disabled"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import BaseCheckbox from '../../base-checkbox.vue'
import BtnAgile from '../btn-agile.vue'
const disabled = ref(true)
</script>表單範例
沒填完就沒得按。(╯•̀ὤ•́)╯
查看範例原始碼
vue
<template>
<div class="relative w-full flex justify-center border border-gray-200 rounded-xl p-6 py-24">
<div class="max-w-[20rem] flex flex-col gap-4">
<base-input
v-model="form.username"
:label="t('帳號 *')"
class="w-full"
/>
<base-input
v-model="form.password"
type="password"
:label="t('密碼 *')"
class="w-full"
/>
<div class="mt-3 flex justify-center">
<btn-agile
:label="t('登入')"
:disabled
z-index="30"
@click="handleSubmit"
/>
</div>
</div>
<transition name="opacity">
<div
v-if="isSubmitted"
class="absolute inset-0 z-[40] flex flex-col items-center justify-center gap-6 rounded-xl bg-slate-600 bg-opacity-90 text-white"
@click="reset"
>
<span class="text-xl tracking-wide">
{{ t('表單已送出!(*´∀`)~♥') }}
</span>
<span class="cursor-pointer text-xs">
{{ t('點一下再來一次') }}
</span>
</div>
</transition>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import BaseInput from '../../base-input.vue'
import BtnAgile from '../btn-agile.vue'
const { t } = useI18n()
const form = ref({
username: '',
password: '',
})
const disabled = computed(() => {
return form.value.username === '' || form.value.password === ''
})
const isSubmitted = ref(false)
function handleSubmit() {
if (disabled.value) {
return
}
isSubmitted.value = true
}
function reset() {
isSubmitted.value = false
form.value = {
username: '',
password: '',
}
}
</script>
<style lang="sass" scoped>
.rubbing
padding: 0.75rem
color: #ff7530
opacity: 0.8
border: 1px dashed #ff7530
border-radius: 0.2rem
white-space: nowrap
text-align: center
.opacity-enter-active, .opacity-leave-active
transition-duration: 0.4s
.opacity-enter-from, .opacity-leave-to
opacity: 0 !important
</style>原理
這次使用潮到出水的 Motion 來實現按鈕的動畫。( •̀ ω •́ )✧
Motion 會盡可能使用硬體加速,且 Vue 版本深度整合響應式系統,性能表現非常優秀,還內建許多實用元件。
強力推薦看看此文章:The Web Animation Performance Tier List
裡面詳細介紹各種動畫的性能表現與 Web 動畫知識,相當有趣。
原始碼
API
Props
interface Props {
/** 按鈕內文字 */
label?: string;
/** 是否停用 */
disabled?: boolean;
/** 同 CSS z-index */
zIndex?: number | string;
/** 同 html tabindex */
tabindex?: number | string;
}Emits
const emit = defineEmits<{
(e: 'click'): void;
}>()Methods
defineExpose({})Slots
defineSlots<{
/** 按鈕 */
default?: () => unknown;
}>()