chore: lazy thumbnail loading & animations

This commit is contained in:
2024-08-01 19:22:43 +02:00
parent b49517aded
commit 27b23ccc95
2 changed files with 73 additions and 10 deletions
+9 -10
View File
@@ -11,15 +11,11 @@
</div>
<span>
<img
<VehicleThumbnail
v-for="(thumbnailImage, imageIndex) in images"
:data-mouseover="vehicleName"
data-tooltip-type="VehiclePreviewTooltip"
:data-tooltip-content="vehicleName"
:src="`https://static.spythere.eu/thumbnails/v2/${thumbnailImage}.png`"
@error="onImageError($event, imagesFallbacks[imageIndex])"
@click.stop="() => {}"
height="60"
:vehicle-name="vehicleName"
:img-name="thumbnailImage"
:fallback-name="imagesFallbacks[imageIndex]"
/>
</span>
</li>
@@ -30,8 +26,11 @@
<script lang="ts">
import { PropType, defineComponent } from 'vue';
import { useApiStore } from '../../store/apiStore';
import VehicleThumbnail from './VehicleThumbnail.vue';
export default defineComponent({
components: { VehicleThumbnail },
props: {
trainStockList: {
type: Array as PropType<string[]>,
@@ -143,7 +142,7 @@ export default defineComponent({
else {
let fallbackVehicleImage = 'unknown_cargo';
if (/^(EP|EU)/.test(vehicleName)) fallbackVehicleImage = 'unknown_train';
if (/^(EP|EU|ET|201E)/.test(vehicleName)) fallbackVehicleImage = 'unknown_train';
else if (/^(SM42)/.test(vehicleName)) fallbackVehicleImage = 'unknown_SM42';
else if (/(\d{3}a|(Bau|Gor)\d{2}|304C)_/.test(vehicleName))
fallbackVehicleImage = 'unknown_passenger';
@@ -160,7 +159,7 @@ export default defineComponent({
},
methods: {
onImageError(event: Event, fallbackImage: string) {
onImageError(event: Event, fallbackImage: string) {
(event.target as HTMLImageElement).src = `/images/${fallbackImage}.png`;
}
}
@@ -0,0 +1,64 @@
<template>
<div class="vehicle-thumbnail">
<img
ref="imgRef"
:src="`https://static.spythere.eu/thumbnails/v2/${imgName}.png`"
height="60"
loading="lazy"
:data-mouseover="vehicleName"
:data-tooltip-content="vehicleName"
:data-load-status="imgStatus"
data-tooltip-type="VehiclePreviewTooltip"
@error="onImageError"
@load="onImageLoad"
/>
</div>
</template>
<script setup lang="ts">
import { onMounted, Ref, ref } from 'vue';
const props = defineProps({
vehicleName: { type: String, required: true },
imgName: { type: String, required: true },
fallbackName: { type: String, required: true },
placeholderName: String
});
const imgRef = ref(null) as Ref<HTMLElement | null>;
// const imgState = ref('loading') as Ref<'loading' | 'loaded' | 'error'>;
const imgStatus = ref('loading');
function onImageError(event: Event) {
console.log('error');
(event.target as HTMLImageElement).src = `/images/${props.fallbackName}.png`;
imgStatus.value = 'error';
// imgState.value = 'error';
}
function onImageLoad() {
if (imgStatus.value != 'error') {
imgStatus.value = 'loaded';
}
imgRef.value!.style.opacity = '1';
}
</script>
<style lang="scss" scoped>
.vehicle-thumbnail {
position: relative;
}
img {
opacity: 0;
transition: opacity 100ms ease-in-out;
&[data-load-status='loading'] {
min-height: 60px;
min-width: 150px;
}
}
</style>