333 lines
20 KiB
Vue
333 lines
20 KiB
Vue
<template lang="pug">
|
||
div(class="mt-[60px] grid grid-cols-1 lg:grid-cols-4 xl:grid-cols-5 text-white bg-[#05020E] h-[calc(100vh-62px)] border-t border-white/10 2xl:border-t-0 mx-auto 2xl:border-x")
|
||
// 左侧信息
|
||
aside.p-4(class="flex flex-col divide-y divide-white/10 pt-6 space-y-6 lg:overflow-y-auto scrollbar-hide")
|
||
div
|
||
p.font-bold Filter
|
||
p.text-gray-400 尝试可以应用于您的图像的不同风格样式
|
||
div.flex.flex-wrap.gap-2.items-center.pt-2
|
||
div(v-for="item in filters" class="w-5/16 h-20 bg-gray-500 rounded-lg")
|
||
div.flex.justify-center.items-center.h-full(v-if="!item.name" :click="imageCreate.models_show = !imageCreate.models_show")
|
||
img.w-6.h-6(:src="IconPlusCircle" alt="PlusCircle")
|
||
div.flex.items-end.h-full(v-else :style="`background-image: url(${item.image}); background-size: cover; background-position: center;`")
|
||
p(class="p-1") {{item.name}}
|
||
// 风格滤镜列表(弹出/悬浮)
|
||
div(v-if="imageCreate.models_show" class="absolute w-screen lg:w-[400px] bottom-2 flex flex-col" style="max-height: 80vh; left: 394px; top: 6vh;")
|
||
div(class="overflow-auto scrollbar-hide transition-[transform,opacity] duration-[50ms] z-50 pai-border rounded-lg bg-gray-900 shadow-2xl opacity-100")
|
||
div(class="space-y-2 items-center absolute overflow-hidden w-[calc(100%-2px)] px-4 pb-2 pt-4 lg:pt-2 z-50 bg-inherit rounded-t-lg border-b border-low border-white border-opacity-10")
|
||
div(class="flex justify-between")
|
||
h3(class="text-white font-bold") Filter
|
||
button(class="text-gray-600 pb-1 lg:hidden")
|
||
<svg viewBox="0 0 24 24" focusable="false" class="chakra-icon css-onkibi"><path fill="currentColor" d="M.439,21.44a1.5,1.5,0,0,0,2.122,2.121L11.823,14.3a.25.25,0,0,1,.354,0l9.262,9.263a1.5,1.5,0,1,0,2.122-2.121L14.3,12.177a.25.25,0,0,1,0-.354l9.263-9.262A1.5,1.5,0,0,0,21.439.44L12.177,9.7a.25.25,0,0,1-.354,0L2.561.44A1.5,1.5,0,0,0,.439,2.561L9.7,11.823a.25.25,0,0,1,0,.354Z"></path></svg>
|
||
div(class="relative")
|
||
input(type="text" placeholder="Search" class="input pai-border bg-gray-900 rounded-md mb-2 outline-none w-full p-2 pl-8" value="")
|
||
span(class="absolute left-2 top-2.5 text-gray-500")
|
||
<svg fill="none" height="20" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" width="20"><path d="M11 17.25a6.25 6.25 0 110-12.5 6.25 6.25 0 010 12.5z"></path><path d="M16 16l4.5 4.5"></path></svg>
|
||
div(class="h-32 lg:h-28")
|
||
div(class="grid grid-cols-3 sm:grid-cols-4 lg:grid-cols-3 gap-2 p-2 pt-0")
|
||
template(v-for="item in models" :key="item.name")
|
||
button.h-24(class="transition-[transform,opacity] origin-center filter-button relative aspect-[6/5] duration-200 border-2 rounded-lg overflow-hidden active:border-blue-300/50 border-transparent hover:border-high" aria-label="Select filter style: Colorpop" style="transition-delay: 10ms;")
|
||
span( style="box-sizing: border-box; display: block; overflow: hidden; width: initial; height: initial; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; position: absolute; inset: 0px;")
|
||
img( alt="Colorpop" :src="item.image" decoding="async" data-nimg="fill" style="position: absolute; inset: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%; object-fit: cover;" sizes="100vw" srcset="https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 640w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 750w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 828w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 1080w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 1200w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 1920w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 2048w, https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png 3840w")
|
||
div( class="absolute inset-0 bg-gradient-to-t from-black/90 via-black/40 flex flex-col justify-end text-gray-100 text-left text-sm p-1") {{ item.name }}
|
||
div
|
||
p.font-bold Prompt
|
||
p.text-gray-400 あなたのアイデアを素早く実現するためのフレームワークです。
|
||
textarea.mt-4.rounded-lg.h-32.w-full.px-4.py-2.bg-gray-500.bg-opacity-5.border.border-gray-500.border-opacity-20.text-gray-500(
|
||
v-model="imageCreate.prompt" type="text" class="focus:outline-none"
|
||
)
|
||
div
|
||
div.flex.items-center.justify-between
|
||
span.font-bold 从图像中删除特征
|
||
label.switch
|
||
input(type="checkbox" :checked="imageCreate.exclude_on" @change="imageCreate.exclude_on=!imageCreate.exclude_on")
|
||
div.slider.round
|
||
div(v-show="imageCreate.exclude_on")
|
||
textarea.mt-4.rounded-lg.h-32.w-full.px-4.py-2.bg-gray-500.bg-opacity-5.border.border-gray-500.border-opacity-20.text-gray-400(
|
||
v-model="imageCreate.exclude" type="text" class="focus:outline-none"
|
||
)
|
||
p.pt-2.text-gray-400 描述您不希望出现在图像中的细节, 例如颜色, 物体或是风景
|
||
div
|
||
p.font-bold 通过图像生成图像
|
||
p.text-gray-400 上传或绘制图像以用作灵感
|
||
input.mt-4.rounded-lg.h-9.w-full.px-4.py-2.bg-gray-500.bg-opacity-5.border.border-gray-500.border-opacity-20.text-gray-500(value="Search" type="text" class="focus:outline-none")
|
||
div.overflow-hidden.flex.gap-2.items-center
|
||
img.relative.right-6.w-4(:src="IconEdit" style="filter: drop-shadow(#ffffff 24px 0);")
|
||
span 画点什么
|
||
div
|
||
button.mt-4.rounded-lg.h-9.w-full.px-4.py-2.bg-gray-500.bg-opacity-5.border.border-gray-500.border-opacity-20.text-gray-500(value="Search" type="text" class="focus:outline-none") 开始绘制
|
||
// 中间输出
|
||
main(class="xl:col-span-3 lg:col-span-2 lg:overflow-y-auto lg:overflow-x-hidden border-x border-white/10 relative scrollbar-hide")
|
||
div.flex.gap-2.pb-8
|
||
button.rounded-full.w-14.h-14.flex.justify-center.items-center(
|
||
:class="{ 'bg-gray-800': views.cardMode }"
|
||
@click="views.cardMode = !views.cardMode"
|
||
)
|
||
img(:src="IconGrid")
|
||
button.rounded-full.w-14.h-14.flex.justify-center.items-center(
|
||
:class="{ 'bg-gray-800': !views.cardMode }"
|
||
@click="views.cardMode = !views.cardMode"
|
||
)
|
||
img(:src="IconStack")
|
||
div.flex(:class="{'justify-center': !views.cardMode, 'flex-col':views.cardMode }")
|
||
div.bg-red-500.relative(style="max-width: min(512px, 100%);")
|
||
img(:src="ImageDemo" class="rounded-md object-contain")
|
||
div.rounded-md.absolute.inset-0.flex.flex-col.items-center.justify-center.transition-opacity.bg-gradient-to-t.to-transparent.opacity-0(
|
||
class="hover:cursor-pointer hover:opacity-100 from-black/90"
|
||
)
|
||
// 右侧参数
|
||
aside(class="lg:overflow-y-auto relative z-20 transition-all scrollbar-hide")
|
||
div(class="px-6 divide-y divide-white/10")
|
||
<fieldset class="create-fieldset py-8">
|
||
<label for="model-type">Model</label>
|
||
<p>Different AI models can produce different or better results so feel free to experiment.</p>
|
||
<div class="select">
|
||
<select name="model-type" id="model-type">
|
||
<option value="stable-diffusion" data-version="1.5" selected="">Stable Diffusion 1.5</option>
|
||
<option value="stable-diffusion-2" data-version="2.0">Stable Diffusion 2.1</option>
|
||
<option value="dalle-2" data-version="2.0">DALL·E 2</option>
|
||
</select>
|
||
<svg data-testid="geist-icon" fill="none" height="16" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" width="24"><path d="M6 9l6 6 6-6"></path></svg>
|
||
</div>
|
||
</fieldset>
|
||
div(class="flex flex-col gap-y-8 py-8")
|
||
// 选择生成尺寸
|
||
fieldset(class="create-fieldset")
|
||
label 图像尺寸
|
||
p 完成图像的宽度×高度.
|
||
div(class="flex flex-row flex-wrap gap-x-2 gap-y-2")
|
||
div(class="flex flex-row flex-wrap" v-for="item in sizes" :key="item.id")
|
||
input.hidden.radio-input(type="radio" :id="item.id" checked="")
|
||
label.border.border-2.border-gray-500.rounded-md.px-4.py-1.whitespace-nowrap.text-center(:for="item.id" class="!text-[11px]" style="width:98px") {{ item.width }} x {{ item.height }}
|
||
div(class="text-sm grey-100 mt-1")
|
||
p Buy a <a target="_blank" style="color:rgb(118 173 255)" href="/pricing">paid plan</a> for any width or height up to 1536px
|
||
fieldset(class="create-fieldset")
|
||
label Prompt Guidance
|
||
p Higher guidance will make your image closer to your prompt.
|
||
SliderUndefined
|
||
//div(id="slider-undefined" class="flex items-center gap-x-4 slider-container")
|
||
// div(tabindex="-1" style="position: relative; touch-action: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); user-select: none; outline: 0px; padding-top: 8px; padding-bottom: 8px;" class="chakra-slider css-1t1xvy7")
|
||
// div(id="slider-track-:R5mnqmqulm:" style="position:absolute;top:50%;transform:translateY(-50%);width:100%" class="chakra-slider__track css-8v2r68")
|
||
// div(class="css-11z5obk")
|
||
// div(aria-valuenow="6" class="chakra-slider__filled-track css-19vmo6h" style="position: absolute; top: 50%; transform: translateY(-50%); width: 20%; left: 0%;")
|
||
// div(role="slider" tabindex="0" id="slider-thumb-:R5mnqmqulm:" aria-valuemin="0" aria-valuemax="30" aria-valuenow="6" aria-orientation="horizontal" style="position: absolute; user-select: none; touch-action: none; left: calc(20% - 8px);" class="chakra-slider__thumb css-12qisgv")
|
||
// input(type="hidden" value="6")
|
||
// input(type="text" class="w-12 rounded-full bg-gray-900 text-xs text-center py-1 text-gray-200" value="6")
|
||
fieldset(class="create-fieldset")
|
||
label Quality & Details
|
||
p More steps will result in a high quality image but will take longer.
|
||
div(id="slider-undefined" class="flex items-center gap-x-4 slider-container")
|
||
div(tabindex="-1" style="position: relative; touch-action: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); user-select: none; outline: 0px; padding-top: 8px; padding-bottom: 8px;" class="chakra-slider css-1t1xvy7")
|
||
div(id="slider-track-:R9onqmqulm:" style="position:absolute;top:50%;transform:translateY(-50%);width:100%" class="chakra-slider__track css-8v2r68")
|
||
div(class="css-11z5obk")
|
||
div(aria-valuenow="50" class="chakra-slider__filled-track css-19vmo6h" style="position: absolute; top: 50%; transform: translateY(-50%); width: 28.5714%; left: 0%;")
|
||
div(role="slider" tabindex="0" id="slider-thumb-:R9onqmqulm:" aria-valuemin="10" aria-valuemax="150" aria-valuenow="25" aria-orientation="horizontal" style="position: absolute; user-select: none; touch-action: none; left: calc(28.5714% - 8px);" class="chakra-slider__thumb css-12qisgv")
|
||
input(type="hidden" value="50")
|
||
input(type="text" class="w-12 rounded-full bg-gray-900 text-xs text-center py-1 text-gray-200" value="50")
|
||
div(class="flex flex-col gap-y-4 py-8")
|
||
<fieldset class="create-fieldset">
|
||
<label for="seed-input">Seed</label>
|
||
<p>Different numbers result in new variations of your image.</p>
|
||
<input id="seed-input" class="text-input" type="number" value="" disabled="">
|
||
<div class="flex items-center gap-x-2">
|
||
<label class="chakra-checkbox css-192puf7" data-checked="">
|
||
<input class="chakra-checkbox__input" type="checkbox" id="randomize-seed" style="border:0px;clip:rect(0px, 0px, 0px, 0px);height:1px;width:1px;margin:-1px;padding:0px;overflow:hidden;white-space:nowrap;position:absolute" checked="" value="">
|
||
<span class="chakra-checkbox__control css-19ag05x" aria-hidden="true" data-checked="">
|
||
<div style="display: flex; align-items: center; justify-content: center; height: 100%; transform: none;">
|
||
<svg viewBox="0 0 12 10" class="css-1x1o9fj" opacity="1" stroke-dashoffset="0" style="fill: none; stroke-width: 2; stroke: currentcolor; stroke-dasharray: 16;"><polyline points="1.5 6 4.5 9 10.5 1"></polyline></svg>
|
||
</div>
|
||
</span>
|
||
</label>
|
||
<label for="randomize-seed" class="text-sm text-gray-300 mt-1">Randomize each number to get new variations</label>
|
||
</div>
|
||
</fieldset>
|
||
<div class="flex flex-col gap-y-4" style="border-color:transparent">
|
||
<fieldset class="create-fieldset">
|
||
<button aria-label="Toggle advanced options" id="advanced-options-toggle"><div class="flex flex-row justify-center"><p class="advanced-options-toggle">Hide <!-- -->Advanced Options</p></div></button>
|
||
<div class="advanced-options-container transition-all overflow-hidden opacity-100 max-h-[99rem] pb-8">
|
||
<label>Sampler</label>
|
||
<p>The diffusion sampling method.</p>
|
||
<div class="select">
|
||
<select name="advanced-options" id="advanced-options">
|
||
<option value="1" selected="">pndm (plms)</option>
|
||
<option value="0">ddim</option>
|
||
<option value="2">k_euler</option>
|
||
<option value="3">k_euler_ancestral</option>
|
||
<option value="4">k_heun</option>
|
||
<option value="5">k_dpm_2</option>
|
||
<option value="6">k_dpm_2_ancestral</option>
|
||
<option value="7">k_lms</option>
|
||
</select>
|
||
<svg data-testid="geist-icon" fill="none" height="16" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" width="24"><path d="M6 9l6 6 6-6"></path></svg>
|
||
</div>
|
||
</div>
|
||
</fieldset>
|
||
</div>
|
||
<fieldset class="create-fieldset py-8">
|
||
<label>Number of Images</label>
|
||
<p>Select the number of images you would like to generate.</p>
|
||
<div class="flex gap-x-2">
|
||
<input type="radio" class="radio-input" id="num-images-1" checked="">
|
||
<label for="num-images-1">1</label><input type="radio" class="radio-input" id="num-images-2">
|
||
<label for="num-images-2">2</label><input type="radio" class="radio-input" id="num-images-3">
|
||
<label for="num-images-3">3</label><input type="radio" class="radio-input" id="num-images-4">
|
||
<label for="num-images-4">4</label>
|
||
</div>
|
||
</fieldset>
|
||
div(class="flex flex-col gap-y-4 py-8")
|
||
fieldset(class="create-fieldset")
|
||
<label>Private Session</label>
|
||
<p>Images will only be visible to you until you're ready to share them. <span> Buy a <a target="_blank" href="/pricing" style="color: rgb(118, 173, 255);">paid plan</a> to persist this setting across sessions.</span></p>
|
||
<div class="flex gap-x-3 w-44 items-center">
|
||
<label class="chakra-switch [&>span]:bg-[#39324E] [&>span[data-checked]]:bg-[#76ADFF] [&>span]:p-1 css-ghot30" data-checked="">
|
||
<input class="chakra-switch__input" type="checkbox" value="" style="border: 0px; clip: rect(0px, 0px, 0px, 0px); height: 1px; width: 1px; margin: -1px; padding: 0px; overflow: hidden; white-space: nowrap; position: absolute;">
|
||
<span aria-hidden="true" class="chakra-switch__track css-j1l0qk" data-checked="">
|
||
<span class="chakra-switch__thumb css-7roig" data-checked=""></span>
|
||
</span>
|
||
</label>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import IconEdit from 'assets/icon/edit-2.svg'
|
||
import IconGrid from 'assets/icon/grid.svg'
|
||
import IconStack from 'assets/icon/stack.svg'
|
||
import ImageDemo from 'assets/image/demo.png'
|
||
import IconPlusCircle from 'assets/icon/plus-circle.svg'
|
||
|
||
const views = ref({
|
||
cardMode: true,
|
||
active: true,
|
||
})
|
||
|
||
const imageCreate = ref({
|
||
filter_ctive: 0,
|
||
filter_list: [0, 1, 2, 3, 4, 5, 6],
|
||
prompt: '渲染提示', // 渲染提示
|
||
exclude: '排除', // 排除词汇
|
||
exclude_on: false, // 排除开关
|
||
models_show: false, // 模型列表开关
|
||
// 输入:
|
||
// 输入关键词
|
||
// 排除关键词
|
||
// 预训练风格
|
||
// 图片生成图片
|
||
// 图像强度
|
||
|
||
// 输出:
|
||
// model
|
||
// 图片尺寸
|
||
// 图像指导
|
||
// 质量与细节
|
||
// 随机数种子
|
||
// 采样器
|
||
// 图片数量
|
||
// 私有会话
|
||
})
|
||
|
||
|
||
const filters = ref([
|
||
{ name:'None', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop1', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop2', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
])
|
||
|
||
const models = ref([
|
||
{ name:'None', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop1', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop2', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
{ name:'Colorpop3', image:'https://storage.googleapis.com/pai-marketing/filters/elizaport_style.png' },
|
||
])
|
||
|
||
const tasks = ref([
|
||
// 以图生成图, 正面描述词, 反面描述词, 生成数量, 生成质量, 生成尺寸, 生成模型, 生成图片, 随机种子, 生成指导
|
||
{ tid:'sjaksjka0', model:'Colorpop0', image:'', width:768, height:768, number:1, seed:1, quality:1, prompt:'prompt0' },
|
||
{ tid:'sjaksjka1', model:'Colorpop1', image:'', width:768, height:768, number:1, seed:1, quality:1, prompt:'prompt1' },
|
||
{ tid:'sjaksjka2', model:'Colorpop2', image:'', width:768, height:768, number:1, seed:1, quality:1, prompt:'prompt2' },
|
||
{ tid:'sjaksjka3', model:'Colorpop3', image:'', width:768, height:768, number:1, seed:1, quality:1, prompt:'prompt3' },
|
||
])
|
||
|
||
const sizes = ref([
|
||
{ id:'image-dim-1', width:512, height:512 },
|
||
{ id:'image-dim-2', width:768, height:768 },
|
||
{ id:'image-dim-3', width:1024, height:1024 },
|
||
{ id:'image-dim-4', width:640, height:384 },
|
||
{ id:'image-dim-5', width:384, height:640 },
|
||
{ id:'image-dim-6', width:768, height:512 },
|
||
])
|
||
|
||
|
||
</script>
|
||
|
||
<style>
|
||
.pai-border {
|
||
border-width: 1px;
|
||
border-style: solid;
|
||
border-color: rgba(255, 255, 255, 0.08);
|
||
border-image: initial;
|
||
}
|
||
|
||
.switch {
|
||
position: relative;
|
||
display: inline-block;
|
||
width: 38px;
|
||
height: 24px;
|
||
}
|
||
|
||
.switch input {display:none;}
|
||
|
||
.slider {
|
||
position: absolute;
|
||
cursor: pointer;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: #ccc;
|
||
-webkit-transition: .4s;
|
||
transition: .4s;
|
||
}
|
||
|
||
.slider:before {
|
||
position: absolute;
|
||
content: "";
|
||
height: 16px;
|
||
width: 16px;
|
||
left: 4px;
|
||
bottom: 4px;
|
||
background-color: white;
|
||
-webkit-transition: .4s;
|
||
transition: .4s;
|
||
}
|
||
|
||
input:checked + .slider {
|
||
background-color: #2196F3;
|
||
}
|
||
|
||
input:focus + .slider {
|
||
box-shadow: 0 0 1px #2196F3;
|
||
}
|
||
|
||
input:checked + .slider:before {
|
||
-webkit-transform: translateX(14px);
|
||
-ms-transform: translateX(14px);
|
||
transform: translateX(14px);
|
||
}
|
||
|
||
/* Rounded sliders */
|
||
.slider.round {
|
||
border-radius: 17px;
|
||
}
|
||
|
||
.slider.round:before {
|
||
border-radius: 50%;
|
||
}
|
||
</style>
|