Files
anyame-frontend-vue/app/components/ui/anime-card/AnimeCard.vue
2025-07-20 19:19:26 +00:00

73 lines
2.9 KiB
Vue

<script setup lang="ts">
import type { Result } from '~/openapi/search';
import { Vibrant } from "node-vibrant/browser";
import { HoverCard, HoverCardContent, HoverCardTrigger } from '../hover-card';
import { Icon } from '@iconify/vue'
interface AnimeItemProp {
item: Result
}
const props = withDefaults(defineProps<AnimeItemProp>(), {
})
const vibrantColor = ref<string | null>(null);
onMounted(async () => {
const posterUrl = props.item.material_data?.anime_poster_url;
if (!posterUrl) return;
try {
const proxiedPosterUrl = `/api/proxy-image?url=${encodeURIComponent(posterUrl)}`
const palette = await Vibrant.from(proxiedPosterUrl).getPalette();
const rgbColor = palette.LightVibrant?.rgb ?? [0, 0, 0]
vibrantColor.value = rgbColor.join(',') || null;
console.log(vibrantColor.value)
} catch (error) {
console.error("Failed to extract vibrant color:", error);
}
});
</script>
<template>
<HoverCard>
<HoverCardTrigger as-child>
<NuxtLink :to="`/anime/${props.item.id}`" class="w-full group">
<div v-if="props.item.material_data?.anime_poster_url"
:style="{ 'background-image': 'url(' + props.item.material_data.anime_poster_url + ')', '--tw-shadow-color': 'rgb(' + vibrantColor + ')' }"
:alt="item.title"
class="flex items-end justify-end p-2 rounded-md bg-cover bg-center bg-no-repeat h-96 group-hover:shadow transition-shadow">
<div
class="flex items-center px-2 py-0.5 backdrop-blur-none bg-primary/75 text-background/80 rounded-sm text-xs ">
<Icon icon="gg:play-list" />
{{ props.item.material_data?.episodes_total }}
episode
</div>
</div>
<div>
<h3 className="text-xl font-semibold tracking-tight">
{{ props.item.title }}
</h3>
</div>
</NuxtLink>
</HoverCardTrigger>
<HoverCardContent>
<div class="flex justify-between space-x-4">
<div class="space-y-1">
<h3 class="text-2xl font-semibold tracking-tight">
{{ props.item.title }}
</h3>
<p class="text-sm">
{{ props.item.material_data?.description }}
</p>
<div class="flex items-center pt-2">
<Icon icon="lucide:calendar" class="mr-2 h-4 w-4 opacity-70" />
<span class="text-xs text-muted-foreground">
{{ props.item.material_data?.aired_at }}
</span>
</div>
</div>
</div>
</HoverCardContent>
</HoverCard>
</template>