HumanBreak/src/components/boxAnimate.vue

91 lines
2.2 KiB
Vue
Raw Normal View History

2022-11-16 23:01:23 +08:00
<template>
<canvas
:width="width ?? 32"
:height="height ?? 32"
2022-11-21 20:00:34 +08:00
:id="`box-animate-${id}`"
2022-11-16 23:01:23 +08:00
></canvas>
</template>
<script lang="tsx" setup>
2022-11-21 20:00:34 +08:00
import { onMounted, onUnmounted, onUpdated, ref } from 'vue';
2022-11-16 23:01:23 +08:00
import { addAnimate, removeAnimate } from '../plugin/animateController';
import { has, requireUniqueSymbol } from '../plugin/utils';
2022-11-21 20:00:34 +08:00
const id = requireUniqueSymbol().toFixed(0);
2022-11-16 23:01:23 +08:00
const props = defineProps<{
2022-12-29 00:26:12 +08:00
id: AllIds | 'hero' | 'none';
2022-11-21 20:00:34 +08:00
noborder?: boolean;
2022-11-16 23:01:23 +08:00
width?: number;
height?: number;
2024-04-23 21:43:26 +08:00
noAnimate?: boolean;
2022-11-16 23:01:23 +08:00
}>();
2022-11-21 20:00:34 +08:00
let c: HTMLCanvasElement;
let ctx: CanvasRenderingContext2D;
let drawFn: () => void;
function draw() {
if (has(drawFn)) removeAnimate(drawFn);
2022-11-16 23:01:23 +08:00
2022-12-28 12:13:52 +08:00
const cls = core.getClsFromId(props.id as AllIds);
2022-11-16 23:01:23 +08:00
const frames = core.getAnimateFrames(cls);
2022-11-21 20:00:34 +08:00
const w = props.width ?? 32;
const h = props.height ?? 32;
if (!props.noborder) {
c.style.border = '1.5px solid #ddd';
c.style.backgroundColor = '#222';
}
2022-11-16 23:01:23 +08:00
const scale = window.devicePixelRatio;
2022-11-21 20:00:34 +08:00
c.style.width = `${w}px`;
c.style.height = `${h}px`;
c.width = scale * w;
c.height = scale * h;
2022-11-16 23:01:23 +08:00
ctx.scale(scale, scale);
2024-04-22 23:08:46 +08:00
ctx.imageSmoothingEnabled = false;
2022-11-16 23:01:23 +08:00
2022-12-29 00:26:12 +08:00
if (props.id === 'none') return;
2022-11-30 16:42:44 +08:00
if (props.id === 'hero') {
const img = core.material.images.hero;
ctx.drawImage(img, 0, 0, img.width / 4, img.height / 4, 0, 0, w, h);
} else if (frames === 1) {
2022-11-21 20:00:34 +08:00
core.drawIcon(ctx, props.id, 0, 0, props.width, props.height);
} else {
drawFn = () => {
core.clearMap(ctx);
2024-04-23 21:43:26 +08:00
const frame = props.noAnimate
? 0
: core.status.globalAnimateStatus % frames;
2022-12-29 00:26:12 +08:00
core.drawIcon(ctx, props.id as AllIds, 0, 0, w, h, frame);
2022-11-21 20:00:34 +08:00
};
2022-11-16 23:01:23 +08:00
2022-11-21 20:00:34 +08:00
drawFn();
2024-04-23 21:43:26 +08:00
if (!props.noAnimate) {
addAnimate(drawFn);
}
2022-11-21 20:00:34 +08:00
}
}
2024-02-03 16:07:47 +08:00
onUnmounted(() => {
removeAnimate(drawFn);
});
2022-11-21 20:00:34 +08:00
onMounted(() => {
c = document.getElementById(`box-animate-${id}`) as HTMLCanvasElement;
ctx = c.getContext('2d')!;
2024-04-22 23:08:46 +08:00
ctx.imageSmoothingEnabled = false;
2022-11-21 20:00:34 +08:00
draw();
});
onUpdated(() => {
draw();
2022-11-16 23:01:23 +08:00
});
</script>
2022-11-21 20:00:34 +08:00
<style lang="less" scoped></style>