💬 Commit message: Update 2026-02-14 05:02:03, 19 files, 158 lines
📁 Files changed: 19 📝 Lines changed: 158 • tensors-3rows.png • tensors-all-sizes.png • tensors-final.png • tensors-fixed-align.png • tensors-fresh.png • tensors-labeled-rows.png • tensors-left-align.png • tensors-ratio-buttons.png • tensors-ratio-updated.png • tensors-ratio-v3.png • tensors-table-align.png • index-BPC1k--a.js • index-BvuF0jag.css • index-CP6ArsWF.css • index-CX4x_bxc.js • index.html • GenerateView.vue • app.ts • index.ts
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -5,8 +5,8 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Tensors</title>
|
||||
<script type="module" crossorigin src="/assets/index-CX4x_bxc.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-BvuF0jag.css">
|
||||
<script type="module" crossorigin src="/assets/index-BPC1k--a.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-CP6ArsWF.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -28,17 +28,6 @@ const loraItems = computed(() => [
|
||||
...store.loras.map(l => ({ title: l.name, value: l.path }))
|
||||
])
|
||||
|
||||
const baseSizes = [
|
||||
{ title: '512', value: 512 },
|
||||
{ title: '768', value: 768 },
|
||||
{ title: '1024', value: 1024 },
|
||||
] as const
|
||||
|
||||
const aspectRatios = [
|
||||
{ title: '3:4', value: '3:4' as const },
|
||||
{ title: '1:1', value: '1:1' as const },
|
||||
{ title: '4:3', value: '4:3' as const },
|
||||
]
|
||||
|
||||
async function handleModelChange(model: string) {
|
||||
if (model && model !== store.activeModel) {
|
||||
@@ -187,22 +176,25 @@ async function generate() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-center ga-2">
|
||||
<span class="text-caption text-grey text-uppercase">Size</span>
|
||||
<v-btn-toggle v-model="store.baseSize" mandatory density="compact" :disabled="generating">
|
||||
<v-btn v-for="s in baseSizes" :key="s.value" :value="s.value" size="small">
|
||||
{{ s.title }}
|
||||
</v-btn>
|
||||
</v-btn-toggle>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-center ga-2">
|
||||
<span class="text-caption text-grey text-uppercase">Ratio</span>
|
||||
<v-btn-toggle v-model="store.aspectRatio" mandatory density="compact" :disabled="generating">
|
||||
<v-btn v-for="r in aspectRatios" :key="r.value" :value="r.value" size="small">
|
||||
{{ r.title }}
|
||||
</v-btn>
|
||||
</v-btn-toggle>
|
||||
<div class="resolution-grid rounded border pa-2">
|
||||
<div
|
||||
v-for="group in store.presetGroups"
|
||||
:key="group.label"
|
||||
class="d-flex align-center ga-2"
|
||||
>
|
||||
<span class="text-caption text-grey text-uppercase resolution-label">{{ group.label }}</span>
|
||||
<v-btn-toggle
|
||||
v-model="store.selectedPreset"
|
||||
mandatory
|
||||
density="compact"
|
||||
:disabled="generating"
|
||||
class="resolution-row"
|
||||
>
|
||||
<v-btn v-for="p in group.presets" :key="p.id" :value="p.id" size="small" class="resolution-btn">
|
||||
{{ p.label }}
|
||||
</v-btn>
|
||||
</v-btn-toggle>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-center ga-2">
|
||||
@@ -262,4 +254,29 @@ async function generate() {
|
||||
.border-t {
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.resolution-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
border-color: rgba(255, 255, 255, 0.12) !important;
|
||||
}
|
||||
|
||||
.resolution-label {
|
||||
width: 36px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.resolution-row {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(3, 100px);
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.resolution-btn {
|
||||
width: 100px !important;
|
||||
min-width: 100px !important;
|
||||
max-width: 100px !important;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import type { Model, LoRA, AspectRatio, BaseSize } from '@/types'
|
||||
import type { Model, LoRA, ResolutionPreset } from '@/types'
|
||||
import * as api from '@/api/client'
|
||||
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
@@ -16,23 +16,38 @@ export const useAppStore = defineStore('app', () => {
|
||||
const loraWeight = ref(0.8)
|
||||
|
||||
// Generation settings
|
||||
const baseSize = ref<BaseSize>(768)
|
||||
const aspectRatio = ref<AspectRatio>('1:1')
|
||||
const selectedPreset = ref('768-3:4')
|
||||
const steps = ref(20)
|
||||
const batchSize = ref(1)
|
||||
|
||||
// Resolution computation
|
||||
const resolutions: Record<BaseSize, Record<AspectRatio, [number, number]>> = {
|
||||
512: { '1:1': [512, 512], '4:3': [512, 384], '3:4': [384, 512] },
|
||||
768: { '1:1': [768, 768], '4:3': [768, 576], '3:4': [576, 768] },
|
||||
1024: { '1:1': [1024, 1024], '4:3': [1024, 768], '3:4': [768, 1024] },
|
||||
}
|
||||
// All resolution presets (base size × aspect ratio)
|
||||
const resolutionPresets: ResolutionPreset[] = [
|
||||
// 512 base
|
||||
{ id: '512-3:4', ratio: '3:4', width: 384, height: 512, label: '384×512' },
|
||||
{ id: '512-1:1', ratio: '1:1', width: 512, height: 512, label: '512×512' },
|
||||
{ id: '512-4:3', ratio: '4:3', width: 512, height: 384, label: '512×384' },
|
||||
// 768 base
|
||||
{ id: '768-3:4', ratio: '3:4', width: 576, height: 768, label: '576×768' },
|
||||
{ id: '768-1:1', ratio: '1:1', width: 768, height: 768, label: '768×768' },
|
||||
{ id: '768-4:3', ratio: '4:3', width: 768, height: 576, label: '768×576' },
|
||||
// 1024 base
|
||||
{ id: '1024-3:4', ratio: '3:4', width: 768, height: 1024, label: '768×1024' },
|
||||
{ id: '1024-1:1', ratio: '1:1', width: 1024, height: 1024, label: '1024×1024' },
|
||||
{ id: '1024-4:3', ratio: '4:3', width: 1024, height: 768, label: '1024×768' },
|
||||
]
|
||||
|
||||
const resolution = computed(() => {
|
||||
const [width, height] = resolutions[baseSize.value][aspectRatio.value]
|
||||
return { width, height }
|
||||
const preset = resolutionPresets.find(p => p.id === selectedPreset.value)
|
||||
return preset ? { width: preset.width, height: preset.height } : { width: 768, height: 1024 }
|
||||
})
|
||||
|
||||
// Presets grouped by base size for 3-row display
|
||||
const presetGroups = [
|
||||
{ label: 'low', presets: resolutionPresets.filter(p => p.id.startsWith('512-')) },
|
||||
{ label: 'mid', presets: resolutionPresets.filter(p => p.id.startsWith('768-')) },
|
||||
{ label: 'high', presets: resolutionPresets.filter(p => p.id.startsWith('1024-')) },
|
||||
]
|
||||
|
||||
// Loading states
|
||||
const loadingModels = ref(false)
|
||||
const switchingModel = ref(false)
|
||||
@@ -88,8 +103,9 @@ export const useAppStore = defineStore('app', () => {
|
||||
loraWeight,
|
||||
|
||||
// Generation settings
|
||||
baseSize,
|
||||
aspectRatio,
|
||||
selectedPreset,
|
||||
resolutionPresets,
|
||||
presetGroups,
|
||||
steps,
|
||||
batchSize,
|
||||
resolution,
|
||||
|
||||
@@ -77,5 +77,10 @@ export interface Resolution {
|
||||
label: string
|
||||
}
|
||||
|
||||
export type AspectRatio = '3:4' | '1:1' | '4:3'
|
||||
export type BaseSize = 512 | 768 | 1024
|
||||
export interface ResolutionPreset {
|
||||
id: string
|
||||
ratio: string
|
||||
width: number
|
||||
height: number
|
||||
label: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user