feat(variant): image preview on variant creation with a real sample image
This commit is contained in:
1 parent
a1cdfce529
commit
04dc151ed7
9 files changed
+314
-40
No files matched your search
@@ -17,6 +17,8 @@ const CHIP =
|
||||
const props = defineProps<{
|
||||
name: string
|
||||
comparable: boolean
|
||||
originalSrc?: string | null
|
||||
variantSrc?: string | null
|
||||
}>()
|
||||
|
||||
const position = defineModel<number>({ default: 50 })
|
||||
@@ -64,7 +66,13 @@ function onKeydown(event: KeyboardEvent) {
|
||||
class="absolute inset-0 flex items-center justify-center bg-(--ui-color-secondary-200) text-muted dark:bg-(--ui-color-secondary-300)"
|
||||
:class="PATTERN"
|
||||
>
|
||||
<UIcon name="i-lucide-image" class="size-8 opacity-55" />
|
||||
<img
|
||||
v-if="originalSrc"
|
||||
:src="originalSrc"
|
||||
alt=""
|
||||
class="absolute inset-0 size-full object-cover"
|
||||
/>
|
||||
<UIcon v-else name="i-lucide-image" class="size-8 opacity-55" />
|
||||
</div>
|
||||
<template v-if="comparable">
|
||||
<div
|
||||
@@ -72,7 +80,14 @@ function onKeydown(event: KeyboardEvent) {
|
||||
class="absolute inset-0 bg-accented"
|
||||
:class="VARIANT_PATTERN"
|
||||
:style="{ clipPath: `inset(0 0 0 ${position}%)` }"
|
||||
/>
|
||||
>
|
||||
<img
|
||||
v-if="variantSrc"
|
||||
:src="variantSrc"
|
||||
alt=""
|
||||
class="absolute inset-0 size-full object-contain"
|
||||
/>
|
||||
</div>
|
||||
<span :class="[CHIP, 'left-2']">{{ t('Original') }}</span>
|
||||
<span :class="[CHIP, 'right-2 font-mono']">{{ shownName }}</span>
|
||||
<input
|
||||
|
||||
@@ -4,7 +4,13 @@ import { t } from '@/i18n'
|
||||
import { computed, ref } from 'vue'
|
||||
import ImageCompare from '@/components/variants/ImageCompare.vue'
|
||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||
import { SAMPLE_SOURCE, estimateLabel, estimateVariant } from '@/lib/variants/variantEstimate'
|
||||
import { useVariantRender } from '@/composables/useVariantRender'
|
||||
import {
|
||||
SAMPLE_SOURCE,
|
||||
estimateLabel,
|
||||
estimateVariant,
|
||||
type EstimateRequest,
|
||||
} from '@/lib/variants/variantEstimate'
|
||||
import { parseDimension, sliderValue, type VariantFormValues } from '@/lib/variants/variantForm'
|
||||
import { formatVariantSize } from '@/lib/variants/variantFormat'
|
||||
|
||||
@@ -25,22 +31,31 @@ const dimensionsAreValid = computed(
|
||||
(props.values.height.trim() === '' || parseDimension(props.values.height) !== null),
|
||||
)
|
||||
|
||||
const estimate = computed(() =>
|
||||
const request = computed<EstimateRequest | null>(() =>
|
||||
dimensionsAreValid.value
|
||||
? estimateVariant({
|
||||
? {
|
||||
width: parseDimension(props.values.width),
|
||||
height: parseDimension(props.values.height),
|
||||
fit: props.values.fit,
|
||||
format: props.values.format,
|
||||
quality: sliderValue(props.values.quality),
|
||||
})
|
||||
}
|
||||
: null,
|
||||
)
|
||||
|
||||
const estimate = computed(() => (request.value ? estimateVariant(request.value) : null))
|
||||
const { original, variant } = useVariantRender(request)
|
||||
|
||||
const shownName = computed(() => props.values.name || t('name'))
|
||||
const outputLine = computed(() =>
|
||||
estimate.value ? estimateLabel(estimate.value) : t('No output yet'),
|
||||
)
|
||||
const outputLine = computed(() => {
|
||||
if (!estimate.value) {
|
||||
return t('No output yet')
|
||||
}
|
||||
const bytes = variant.value
|
||||
? Math.min(SAMPLE_SOURCE.bytes, variant.value.bytes)
|
||||
: estimate.value.bytes
|
||||
return estimateLabel({ size: estimate.value.size, bytes })
|
||||
})
|
||||
const originalLine = computed(
|
||||
() =>
|
||||
`${SAMPLE_SOURCE.width} × ${SAMPLE_SOURCE.height} · ${formatVariantSize(SAMPLE_SOURCE.bytes)}`,
|
||||
@@ -67,7 +82,13 @@ async function onCopy() {
|
||||
t('Sample: {0}', [SAMPLE_SOURCE.filename])
|
||||
}}</span>
|
||||
</div>
|
||||
<ImageCompare v-model="position" :name="values.name" :comparable="estimate !== null" />
|
||||
<ImageCompare
|
||||
v-model="position"
|
||||
:name="values.name"
|
||||
:comparable="estimate !== null"
|
||||
:original-src="original"
|
||||
:variant-src="variant?.url ?? null"
|
||||
/>
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div class="flex flex-col">
|
||||
<span class="font-medium text-highlighted">{{ t('Original') }}</span>
|
||||
|
||||
Reference in new issue
Block a user