|
<script lang="ts"> |
|
import type { PicletInstance } from '$lib/db/schema'; |
|
|
|
interface Props { |
|
instance: PicletInstance; |
|
size?: number; |
|
showDetails?: boolean; |
|
onClick?: () => void; |
|
} |
|
|
|
let { instance, size = 100, showDetails = true, onClick }: Props = $props(); |
|
|
|
const hpPercentage = $derived(instance.currentHp / instance.maxHp); |
|
const hpColor = $derived( |
|
hpPercentage > 0.5 ? '#34c759' : |
|
hpPercentage > 0.25 ? '#ffcc00' : |
|
'#ff3b30' |
|
); |
|
|
|
|
|
const typeColor = '#007bff'; |
|
</script> |
|
|
|
<button |
|
class="piclet-card" |
|
style="width: {size}px; height: {size + 30}px;" |
|
onclick={onClick} |
|
type="button" |
|
> |
|
<div class="image-container" style="background-color: {typeColor}10;"> |
|
<img |
|
src={instance.imageData || instance.imageUrl} |
|
alt={instance.nickname || 'Piclet'} |
|
class="piclet-image" |
|
style="width: {size * 0.9}px; height: {size * 0.9}px;" |
|
/> |
|
<div class="level-badge"> |
|
Lv.{instance.level} |
|
</div> |
|
</div> |
|
|
|
{#if showDetails} |
|
<div class="details-section"> |
|
<p class="nickname">{instance.nickname || 'Unknown'}</p> |
|
<div class="hp-bar"> |
|
<div |
|
class="hp-fill" |
|
style="width: {hpPercentage * 100}%; background-color: {hpColor};" |
|
></div> |
|
</div> |
|
</div> |
|
{/if} |
|
</button> |
|
|
|
<style> |
|
.piclet-card { |
|
display: flex; |
|
flex-direction: column; |
|
background: white; |
|
border-radius: 12px; |
|
border: 2px solid; |
|
border-color: color-mix(in srgb, var(--type-color, #007bff) 30%, transparent); |
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
|
padding: 0; |
|
cursor: pointer; |
|
transition: transform 0.2s; |
|
} |
|
|
|
.piclet-card:active { |
|
transform: scale(0.95); |
|
} |
|
|
|
.image-container { |
|
width: 100%; |
|
flex: 1; |
|
position: relative; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
border-radius: 10px 10px 0 0; |
|
overflow: hidden; |
|
} |
|
|
|
.piclet-image { |
|
object-fit: contain; |
|
} |
|
|
|
.level-badge { |
|
position: absolute; |
|
top: 4px; |
|
right: 4px; |
|
background: rgba(255, 255, 255, 0.9); |
|
padding: 2px 6px; |
|
border-radius: 8px; |
|
font-size: 10px; |
|
font-weight: bold; |
|
} |
|
|
|
.details-section { |
|
height: 40px; |
|
padding: 4px 6px; |
|
display: flex; |
|
flex-direction: column; |
|
justify-content: center; |
|
} |
|
|
|
.nickname { |
|
margin: 0; |
|
font-size: 11px; |
|
font-weight: 600; |
|
text-align: center; |
|
overflow: hidden; |
|
text-overflow: ellipsis; |
|
white-space: nowrap; |
|
} |
|
|
|
.hp-bar { |
|
height: 3px; |
|
background: #f0f0f0; |
|
border-radius: 1.5px; |
|
margin-top: 2px; |
|
overflow: hidden; |
|
} |
|
|
|
.hp-fill { |
|
height: 100%; |
|
border-radius: 1.5px; |
|
transition: width 0.3s ease; |
|
} |
|
</style> |