ui: wip: ratio selector
This commit is contained in:
68
components/aigc/RatioSelector.vue
Normal file
68
components/aigc/RatioSelector.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import type {PropType} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
ratios: {
|
||||
type: Array as PropType<{
|
||||
ratio: string,
|
||||
label?: string,
|
||||
value: string | number
|
||||
}[]>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const selected = ref<string | number>('')
|
||||
|
||||
const handle_select = (value: string | number) => {
|
||||
selected.value = value
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
|
||||
const getRatio = (ratio: string) => {
|
||||
const [w, h] = ratio.split(/[:\/]/).map(Number)
|
||||
return {
|
||||
w: w,
|
||||
h: h
|
||||
}
|
||||
}
|
||||
|
||||
const getShapeSize = (r: { w: number, h: number }, size: number) => {
|
||||
const ratio = r.w / r.h
|
||||
if (r.w > r.h) {
|
||||
return {
|
||||
w: size,
|
||||
h: size / ratio
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
w: size * ratio,
|
||||
h: size
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-4 gap-2">
|
||||
<div v-for="(ratio, k) in ratios" :key="ratio.value" @click="handle_select(ratio.value)"
|
||||
class="w-full aspect-square bg-neutral-200/50 rounded-lg flex flex-col justify-around items-center cursor-pointer"
|
||||
:class="[ratio.value === selected && 'bg-sky-200/50']">
|
||||
<div class="bg-neutral-300/50 text-neutral-900 rounded flex justify-center items-center"
|
||||
:class="[ratio.value === selected && 'bg-sky-300/50']" :style="{
|
||||
width: getShapeSize(getRatio(ratio.ratio), 30).w * 2 + '%',
|
||||
height: getShapeSize(getRatio(ratio.ratio), 30).h * 2 + '%'
|
||||
}">
|
||||
<span class="text-xs font-thin">{{ ratio.ratio }}</span>
|
||||
</div>
|
||||
<span class="text-[10px]">
|
||||
{{ ratio?.label || getRatio(ratio.ratio).w > getRatio(ratio.ratio).h ? '横向' : '纵向' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -22,7 +22,7 @@ const props = defineProps({
|
||||
<UIcon v-if="icon" :name="icon" class="text-base inline-block"/>
|
||||
<div class="flex-1 flex items-center truncate whitespace-nowrap overflow-hidden">
|
||||
<span>{{ label }}</span>
|
||||
<UTooltip v-if="comment" :popper="{ arrow: true, placement: 'top' }" :text="comment">
|
||||
<UTooltip v-if="comment" :popper="{ arrow: true, placement: 'right' }" :text="comment">
|
||||
<UIcon class="text-base" name="i-tabler-help"/>
|
||||
</UTooltip>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user