2025-06-27 08:42:27 +08:00

200 lines
4.6 KiB
Vue

<script setup lang="ts">
const ea = new EasyAudio([{
name: 'button-down',
audioUrl: audios.button_down
}, {
name: 'button-up',
audioUrl: audios.button_up
}])
const props = defineProps<{
content: string;
theme: 'blue' | 'green' | 'red';
sm?: boolean;
disabled?: boolean;
}>();
const emit = defineEmits(['click']);
// 导入背景图片
import bgPlainBlue from "../assets/imgs/BluePlain.webp";
import bgHoverBlue from "../assets/imgs/BlueHover.webp";
import bgPressedBlue from "../assets/imgs/BluePressed.webp";
import bgPlainGreen from "../assets/imgs/GreenPlain.webp";
import bgHoverGreen from "../assets/imgs/GreenHover.webp";
import bgPressedGreen from "../assets/imgs/GreenPressed.webp";
import bgPlainRed from "../assets/imgs/RedPlain.webp";
import bgHoverRed from "../assets/imgs/RedHover.webp";
import bgPressedRed from "../assets/imgs/RedPressed.webp";
import bgSmPlain from "../assets/imgs/SmPlain.webp";
import bgSmHover from "../assets/imgs/SmHover.webp";
import bgPressedSm from "../assets/imgs/SmPressed.webp";
import { EasyAudio } from "../utils";
import audios from "../assets/audios";
// 优化背景图片映射结构
const backgrounds = {
normal: {
blue: {
plain: bgPlainBlue,
hover: bgHoverBlue,
pressed: bgPressedBlue
},
green: {
plain: bgPlainGreen,
hover: bgHoverGreen,
pressed: bgPressedGreen
},
red: {
plain: bgPlainRed,
hover: bgHoverRed,
pressed: bgPressedRed
}
},
sm: {
plain: bgSmPlain,
hover: bgSmHover,
pressed: bgPressedSm
}
};
// 处理点击事件
const handleClick = (event: MouseEvent) => {
// 只有在非禁用状态下才触发事件
if (!props.disabled) {
emit('click', event);
}
};
</script>
<template>
<div class="button" @pointerdown="disabled||ea.play('button-down')"
@pointerup="disabled||ea.play('button-up')"
:class="{ 'sm': sm, 'disabled': disabled }" @click="handleClick">
<span class="content" v-if="!sm">{{ content }}</span>
<img class="content" v-else :src="content" alt="">
<!-- 背景图片 -->
<img class="bg plain"
:src="sm ? backgrounds.sm.plain : backgrounds.normal[theme].plain"
alt="">
<img class="bg hover"
:src="sm ? backgrounds.sm.hover : backgrounds.normal[theme].hover"
alt="">
<img class="bg pressed"
:src="sm ? backgrounds.sm.pressed : backgrounds.normal[theme].pressed"
alt="">
</div>
</template>
<style lang="scss" scoped>
.button {
width: 30vh;
aspect-ratio: 195/45;
background-color: transparent;
background-repeat: no-repeat;
background-size: cover;
border: none;
color: white;
font-size: 18px;
font-weight: bold;
text-align: center;
text-shadow: 1px 1px 2px black;
cursor: pointer;
position: relative;
-webkit-tap-highlight-color: transparent;
user-select: none;
transition: filter 0.2s ease;
&.sm {
width: 10vh;
aspect-ratio: 1/.9;
.content {
top: 50%;
width: 40%;
filter: drop-shadow(0 0 2vh black);
}
}
.content {
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
text-align: center;
font-family: "Cambria";
text-shadow: 0 0vh 2vh rgba(0, 0, 0, 1);
pointer-events: none;
z-index: 1;
font-size: 2.8vh;
transition: opacity 0.2s ease;
}
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: -1;
pointer-events: none;
}
.bg.plain {
opacity: 1;
}
&:hover:not(.disabled) {
.bg.plain {
opacity: 0;
}
.bg.hover {
opacity: 1;
}
.bg.pressed {
opacity: 0;
}
}
&:active:not(.disabled) {
.content {
opacity: .8;
}
.bg.plain {
opacity: 0;
}
.bg.hover {
opacity: 0;
}
.bg.pressed {
opacity: 1;
}
}
&.disabled {
cursor: not-allowed;
filter: grayscale(40%) brightness(80%);
.content {
opacity: 0.6;
}
.bg.plain {
opacity: 1;
}
.bg.hover,
.bg.pressed {
opacity: 0;
}
}
}
</style>