Files
drawing/pages/index.vue
2023-02-13 23:35:05 +08:00

338 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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 尝试可以应用于您的图像的不同风格样式 {{ imageCreate.models_show }}
div.flex.flex-wrap.gap-2.items-center.pt-2
div.cursor-pointer.select-none(v-for="(item, index) in filters" :key="item.name" class="w-5/16 h-20 bg-gray-500 rounded-lg")
div.flex.justify-center.items-center.h-full(v-if="!item.name" @click="ModelsShow(index)")
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;`" @click="ModelsShow(index)")
p(class="p-1") {{item.name}}
// 风格滤镜列表(弹出/悬浮)
div(v-show="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 &amp; 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 [&amp;>span]:bg-[#39324E] [&amp;>span[data-checked]]:bg-[#76ADFF] [&amp;>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 },
])
const ModelsShow = (index) => {
console.log(index)
imageCreate.value.filter_ctive = index
imageCreate.value.models_show = !imageCreate.value.models_show
}
</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>