78 lines
1.4 KiB
Vue
78 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|||
|
|
import { computed } from 'vue'
|
||
|
|
|
||
|
|
const props = withDefaults(defineProps<{
|
||
|
|
size?: number
|
||
|
|
flip?: boolean
|
||
|
|
}>(), {
|
||
|
|
size: 24,
|
||
|
|
flip: false,
|
||
|
|
})
|
||
|
|
|
||
|
|
// 10x11 pixel boxing glove facing right
|
||
|
|
// M=main body, H=highlight, S=shadow, C=cuff
|
||
|
|
const grid = [
|
||
|
|
'...MMMM...',
|
||
|
|
'..HMMMMM..',
|
||
|
|
'.HMMMMMM..',
|
||
|
|
'HMMMMMMS..',
|
||
|
|
'MMMMMMMMS.',
|
||
|
|
'MMMMMMMMSS',
|
||
|
|
'MMMMMMMM..',
|
||
|
|
'.MMMMMM...',
|
||
|
|
'..CCCC....',
|
||
|
|
'..CCCC....',
|
||
|
|
'...CC.....',
|
||
|
|
]
|
||
|
|
|
||
|
|
const colorMap: Record<string, string> = {
|
||
|
|
M: '#ff2d78',
|
||
|
|
H: '#ff6fa0',
|
||
|
|
S: '#cc1155',
|
||
|
|
C: '#64dfff',
|
||
|
|
}
|
||
|
|
|
||
|
|
const pixels = computed(() => {
|
||
|
|
const result: { x: number; y: number; color: string }[] = []
|
||
|
|
for (let y = 0; y < grid.length; y++) {
|
||
|
|
for (let x = 0; x < grid[y].length; x++) {
|
||
|
|
const ch = grid[y][x]
|
||
|
|
if (ch !== '.' && colorMap[ch]) {
|
||
|
|
result.push({ x, y, color: colorMap[ch] })
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return result
|
||
|
|
})
|
||
|
|
|
||
|
|
const cols = grid[0].length
|
||
|
|
const rows = grid.length
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<svg
|
||
|
|
:width="props.size"
|
||
|
|
:height="props.size * (rows / cols)"
|
||
|
|
:viewBox="`0 0 ${cols} ${rows}`"
|
||
|
|
:style="{ transform: props.flip ? 'scaleX(-1)' : undefined }"
|
||
|
|
class="pixel-glove"
|
||
|
|
>
|
||
|
|
<rect
|
||
|
|
v-for="(p, i) in pixels"
|
||
|
|
:key="i"
|
||
|
|
:x="p.x"
|
||
|
|
:y="p.y"
|
||
|
|
width="1"
|
||
|
|
height="1"
|
||
|
|
:fill="p.color"
|
||
|
|
/>
|
||
|
|
</svg>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.pixel-glove {
|
||
|
|
image-rendering: pixelated;
|
||
|
|
filter: drop-shadow(0 0 3px rgba(255, 45, 120, 0.6));
|
||
|
|
}
|
||
|
|
</style>
|