200 lines
4.6 KiB
Vue
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> |