44 lines
1.4 KiB
Vue
44 lines
1.4 KiB
Vue
|
|
<template>
|
||
|
|
<div class="flex flex-col gap-0.5 w-full">
|
||
|
|
<div v-if="label" class="flex justify-between items-end px-0.5">
|
||
|
|
<div class="flex items-center gap-1 text-[#8f80a0]">
|
||
|
|
<component :is="icon" v-if="icon" :size="10" />
|
||
|
|
<span class="text-[10px] uppercase font-bold leading-none">{{ label }}</span>
|
||
|
|
</div>
|
||
|
|
<span class="text-[10px] font-mono text-[#e0d8f0] leading-none">{{ current }}/{{ max }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="h-3 bg-[#0f0816] border border-[#4a3b5e] p-[1px] relative">
|
||
|
|
<div
|
||
|
|
class="h-full transition-all duration-300 relative"
|
||
|
|
:style="{ width: `${percentage}%`, backgroundColor: barColor }"
|
||
|
|
>
|
||
|
|
<!-- Shine effect -->
|
||
|
|
<div class="absolute top-0 left-0 w-full h-[1px] bg-white opacity-30" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { computed } from 'vue';
|
||
|
|
import type { Component } from 'vue';
|
||
|
|
|
||
|
|
interface Props {
|
||
|
|
current: number;
|
||
|
|
max: number;
|
||
|
|
type: 'hp' | 'energy' | 'mana';
|
||
|
|
label?: string;
|
||
|
|
icon?: Component;
|
||
|
|
}
|
||
|
|
|
||
|
|
const props = defineProps<Props>();
|
||
|
|
|
||
|
|
const percentage = computed(() => Math.min(100, Math.max(0, (props.current / props.max) * 100)));
|
||
|
|
|
||
|
|
const barColor = computed(() => {
|
||
|
|
if (props.type === 'energy') return '#f6b26b'; // Orange
|
||
|
|
if (props.type === 'mana') return '#2ce8f4'; // Cyan
|
||
|
|
return '#d95763'; // HP Red (default)
|
||
|
|
});
|
||
|
|
</script>
|