ui: drawing design

This commit is contained in:
2024-02-28 23:34:35 +08:00
parent 79d45d1781
commit ea2d53bb44
10 changed files with 199 additions and 6 deletions

BIN
assets/example/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

BIN
assets/example/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
assets/example/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
const props = defineProps({
gradient: {
type: String,
default: '90deg, #FFC0CB 0%, #FFC0CB 100%'
},
aspect: {
type: String,
default: '16/9'
}
})
const elem = ref<HTMLElement>()
const size = computed(() => {
return {
width: elem.value?.getBoundingClientRect().width.toFixed(0),
height: elem.value?.getBoundingClientRect().height.toFixed(0)
}
})
</script>
<template>
<div ref="elem" class="gradient-background flex justify-center items-center"
:style="`aspect-ratio: ${aspect};`">
<ClientOnly>
<h1 class="text-white/80 drop-shadow-2xl text-sm font-bold">
{{ size.width }} x {{ size.height }}
</h1>
</ClientOnly>
</div>
</template>
<style scoped>
.gradient-background {
@apply rounded-lg;
@apply bg-gradient-to-r from-indigo-800 to-purple-600;
}
</style>

View File

@@ -56,7 +56,7 @@ const obtainSmsCode = () => {
<template #header> <template #header>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white"> <h3 class="text-base font-semibold leading-6 text-gray-900 dark:text-white">
Modals 登录眩生花 AI 助手
</h3> </h3>
<UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="modal.close()"/> <UButton color="gray" variant="ghost" icon="i-heroicons-x-mark-20-solid" class="-my-1" @click="modal.close()"/>
</div> </div>

View File

@@ -109,6 +109,20 @@ body {
@apply bg-neutral-50 dark:bg-neutral-950 bg-fixed; @apply bg-neutral-50 dark:bg-neutral-950 bg-fixed;
@apply bg-[url('~/assets/background-pattern.svg')] dark:bg-[url('~/assets/background-pattern-dark.svg')]; @apply bg-[url('~/assets/background-pattern.svg')] dark:bg-[url('~/assets/background-pattern-dark.svg')];
} }
*::-webkit-scrollbar {
@apply w-1.5 h-1.5;
}
*::-webkit-scrollbar-track {
@apply bg-neutral-300/20 dark:bg-neutral-700/20;
}
*::-webkit-scrollbar-thumb {
@apply rounded;
@apply bg-neutral-300 dark:bg-neutral-700;
@apply hover:bg-neutral-400 hover:dark:bg-neutral-600;
}
</style> </style>
<style scoped> <style scoped>
@@ -120,11 +134,11 @@ header {
} }
main { main {
@apply min-h-[calc(100vh-4rem)] pt-16; @apply h-screen pt-16;
} }
footer { footer {
@apply h-16 bg-white border-t; @apply h-16 bg-white border-t z-30;
@apply dark:bg-neutral-900 dark:border-neutral-800; @apply dark:bg-neutral-900 dark:border-neutral-800;
@apply flex flex-row items-center justify-between px-4; @apply flex flex-row items-center justify-between px-4;
} }

View File

@@ -0,0 +1,97 @@
<script setup lang="ts">
import type {ResultBlockMeta} from "~/pages/aigc/drawing/components/index";
import type {PropType} from "vue";
import dayjs from "dayjs";
const props = defineProps({
icon: {
type: String,
default: 'i-tabler-photo-filled'
},
title: {
type: String
},
prompt: {
type: String
},
images: {
type: Array,
default: (): Array<string> => []
},
meta: {
type: Object as PropType<ResultBlockMeta>
}
})
const expand_prompt = ref(false)
const show_meta = ref(false)
</script>
<template>
<div class="">
<div class="flex items-center gap-1">
<UIcon :name="icon"/>
<h1 class="text-sm font-semibold">
{{ title }}
</h1>
<UDivider class="flex-1" size="sm"/>
<UButton color="black" size="xs" icon="i-tabler-info-circle"
:variant="show_meta ? 'solid' : 'ghost'" :disabled="!meta"
@click="show_meta = !show_meta"></UButton>
<slot name="header-right"/>
</div>
<div v-if="prompt" class="flex items-start gap-2 mt-1 mb-2">
<UIcon name="i-tabler-article" class="mt-0.5"/>
<p class="text-sm flex-1 text-ellipsis cursor-pointer"
:class="{'line-clamp-1': !expand_prompt, 'line-clamp-none': expand_prompt}"
@click="expand_prompt = !expand_prompt">
{{ prompt }}
</p>
<UButton color="gray" size="xs" icon="i-tabler-copy" variant="ghost" class="-mt-1"></UButton>
</div>
<div v-if="images.length > 0" class="flex items-center overflow-x-auto h-64 gap-2 pb-2 snap-x">
<img v-for="(url, i) in images" class="result-image" :src="url" alt="" :key="i">
</div>
<Transition v-if="meta" name="meta">
<div v-if="show_meta" class="w-full flex items-center gap-2 flex-wrap whitespace-nowrap pb-2 mt-2">
<UBadge v-if="meta.modal" color="black" variant="solid" class="text-[10px] font-bold gap-0.5">
<UIcon class="text-sm" name="i-tabler-box-seam"/>
{{ meta.modal }}
</UBadge>
<UBadge v-if="meta.cost" color="amber" variant="subtle" class="text-[10px] font-bold gap-0.5">
<UIcon class="text-sm" name="i-solar-fire-bold"/>
{{ meta.cost }}
</UBadge>
<UBadge v-if="meta.ratio" color="indigo" variant="subtle" class="text-[10px] font-bold gap-0.5">
<UIcon class="text-sm" name="i-tabler-aspect-ratio"/>
{{ meta.ratio }}
</UBadge>
<UBadge v-if="meta.id" color="indigo" variant="subtle" class="text-[10px] font-bold gap-0.5">
<UIcon class="text-sm" name="i-tabler-number"/>
{{ meta.id }}
</UBadge>
<UBadge v-if="meta.datetime" color="indigo" variant="subtle" class="text-[10px] font-bold gap-0.5">
<UIcon class="text-sm" name="i-tabler-calendar-month"/>
{{ dayjs(meta.datetime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
</UBadge>
</div>
</Transition>
</div>
</template>
<style scoped>
.meta-enter-active,
.meta-leave-active {
@apply transition duration-300;
}
.meta-enter-from,
.meta-leave-to {
@apply opacity-0 -translate-y-2;
}
.result-image {
@apply snap-start;
@apply h-full aspect-auto object-cover rounded-lg shadow-md;
}
</style>

View File

@@ -0,0 +1,7 @@
export declare interface ResultBlockMeta {
modal?: string
cost?: string
ratio?: string
id?: string
datetime?: number
}

View File

@@ -1,5 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import image1 from '~/assets/example/1.jpg';
import image2 from '~/assets/example/2.jpg';
import image3 from '~/assets/example/3.jpg';
import OptionBlock from "~/pages/aigc/drawing/components/OptionBlock.vue"; import OptionBlock from "~/pages/aigc/drawing/components/OptionBlock.vue";
import ResultBlock from "~/pages/aigc/drawing/components/ResultBlock.vue";
useHead({ useHead({
title: '绘画 | XSH AI' title: '绘画 | XSH AI'
@@ -32,12 +36,25 @@ const handle_mousedown = (e: MouseEvent, min: number = 240, max: number = 400) =
window.addEventListener('mouseup', handle_mouseup) window.addEventListener('mouseup', handle_mouseup)
} }
} }
const images = [
image1,
image2,
image3,
'https://w.wallhaven.cc/full/jx/wallhaven-jxl31y.png',
'https://w.wallhaven.cc/full/6d/wallhaven-6d7xmx.jpg',
]
const images2 = [
image1,
image2,
image3,
]
</script> </script>
<template> <template>
<div class="w-full flex"> <div class="w-full flex">
<div ref="leftSection" <div ref="leftSection"
class="relative h-[calc(100vh-4rem)] overflow-hidden bg-neutral-200 dark:bg-neutral-800 transition-all" class="hidden md:block relative h-[calc(100vh-4rem)] overflow-hidden bg-neutral-200 dark:bg-neutral-800 transition-all"
style="width: 320px"> style="width: 320px">
<div ref="leftHandler" <div ref="leftHandler"
class="absolute inset-0 left-auto hidden xl:flex flex-col justify-center items-center cursor-ew-resize px-1 group" class="absolute inset-0 left-auto hidden xl:flex flex-col justify-center items-center cursor-ew-resize px-1 group"
@@ -60,8 +77,28 @@ const handle_mousedown = (e: MouseEvent, min: number = 240, max: number = 400) =
</OptionBlock> </OptionBlock>
</div> </div>
</div> </div>
<div class="flex-1"> <div class="flex-1 h-screen flex flex-col gap-4 bg-neutral-100 dark:bg-neutral-900 p-4 overflow-y-auto">
results <ResultBlock :images="images"
title="XX大模型 · 文生图" :meta="{
id: 'd166429411dfc6722e54c032cdba97a2',
aspect: '9:16',
cost: '1500',
modal: '混元大模型',
ratio: '16:9',
datetime: 1709106270
}"
prompt="这是, 一组, 测试用的, 提示词, 很长, 很长很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长, 很长">
<template #header-right>
<UButton color="gray" size="xs" icon="i-tabler-trash" variant="ghost"></UButton>
</template>
</ResultBlock>
<ResultBlock :images="images2"
title="XX大模型 · 图生图"
prompt="这是, 一组, 测试用的, 提示词">
<template #header-right>
<UButton color="gray" size="xs" icon="i-tabler-trash" variant="ghost"></UButton>
</template>
</ResultBlock>
</div> </div>
</div> </div>
</template> </template>