diff options
Diffstat (limited to 'packages/frontend/src/components/MkImgWithBlurhash.vue')
| -rw-r--r-- | packages/frontend/src/components/MkImgWithBlurhash.vue | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue index 9b3dbf8618..048dcc7045 100644 --- a/packages/frontend/src/components/MkImgWithBlurhash.vue +++ b/packages/frontend/src/components/MkImgWithBlurhash.vue @@ -1,12 +1,12 @@ <template> -<div :class="[$style.root, { [$style.cover]: cover }]" :title="title"> - <canvas v-if="!loaded || forceBlurhash" ref="canvas" :class="$style.canvas" :width="size" :height="size" :title="title"/> - <img v-if="src && !forceBlurhash" :class="$style.img" :src="src" :title="title" :alt="alt" @load="onLoad"/> +<div :class="[$style.root, { [$style.cover]: cover }]" :title="title ?? ''"> + <canvas v-if="!loaded || forceBlurhash" ref="canvas" :class="$style.canvas" :width="width" :height="height" :title="title ?? ''"/> + <img v-if="src && !forceBlurhash" v-show="loaded" :class="$style.img" :src="src" :title="title ?? ''" :alt="alt ?? ''" @load="onLoad"/> </div> </template> <script lang="ts" setup> -import { onMounted } from 'vue'; +import { onMounted, watch } from 'vue'; import { decode } from 'blurhash'; const props = withDefaults(defineProps<{ @@ -14,33 +14,54 @@ const props = withDefaults(defineProps<{ hash?: string; alt?: string | null; title?: string | null; - size?: number; + height?: number; + width?: number; cover?: boolean; forceBlurhash?: boolean; }>(), { src: null, alt: '', title: null, - size: 64, + height: 64, + width: 64, cover: true, forceBlurhash: false, }); const canvas = $shallowRef<HTMLCanvasElement>(); let loaded = $ref(false); +let width = $ref(props.width); +let height = $ref(props.height); + +function onLoad() { + loaded = true; +} + +watch([() => props.width, () => props.height], () => { + const ratio = props.width / props.height; + if (ratio > 1) { + width = Math.round(64 * ratio); + height = 64; + } else { + width = 64; + height = Math.round(64 / ratio); + } +}, { + immediate: true, +}); function draw() { if (props.hash == null) return; - const pixels = decode(props.hash, props.size, props.size); + const pixels = decode(props.hash, width, height); const ctx = canvas.getContext('2d'); - const imageData = ctx!.createImageData(props.size, props.size); + const imageData = ctx!.createImageData(width, height); imageData.data.set(pixels); ctx!.putImageData(imageData, 0, 0); } -function onLoad() { - loaded = true; -} +watch(() => props.hash, () => { + draw(); +}); onMounted(() => { draw(); @@ -54,6 +75,7 @@ onMounted(() => { height: 100%; &.cover { + > .canvas, > .img { object-fit: cover; } @@ -68,8 +90,7 @@ onMounted(() => { } .canvas { - position: absolute; - object-fit: cover; + object-fit: contain; } .img { |