Files
test-repo/docs/.vitepress/theme/components/appendix/image-gen-intro/LatentSpaceViz.vue
T
sanbuphy 73f4788d7e feat: comprehensive documentation and demo updates
- Update READMEs and docs across multiple languages
- Enhance interactive demos for Agent, LLM, VLM, Audio, Image Gen, Terminal, and Web Basics
- Add new appendix sections for Database and IDE intros
- Update VitePress config, theme, and utility scripts
- Clean up unused assets and components
2026-01-16 19:10:51 +08:00

291 lines
6.6 KiB
Vue

<template>
<div class="latent-space-viz">
<el-card shadow="never">
<div class="viz-container">
<!-- Pixel Space -->
<div class="space-block">
<div class="space-header">
<el-icon :size="20"><Picture /></el-icon>
<span class="space-title">像素空间 (Pixel Space)</span>
</div>
<div class="grid-wrapper pixel-wrapper">
<div class="pixel-grid">
<div
v-for="n in 256"
:key="n"
class="pixel-cell"
:style="getPixelStyle(n)"
></div>
</div>
<div class="grid-overlay">
<span>HD Image</span>
<span class="res-tag">1024x1024</span>
</div>
</div>
<div class="data-stats">
<div class="stat-row">
<span class="label">维度:</span>
<span class="value">3 (RGB)</span>
</div>
<div class="stat-row">
<span class="label">数据量:</span>
<span class="value">~300</span>
</div>
</div>
</div>
<!-- Transformation -->
<div class="transform-process">
<div class="process-arrow">
<div class="vae-box">
<span class="vae-label">VAE Encoder</span>
<el-icon><Filter /></el-icon>
</div>
<el-icon :size="24" class="arrow-icon"><Right /></el-icon>
</div>
<el-tag type="danger" size="small" effect="dark" class="compress-tag"
>压缩 48x</el-tag
>
</div>
<!-- Latent Space -->
<div class="space-block highlight">
<div class="space-header">
<el-icon :size="20" color="#E6A23C"><Cpu /></el-icon>
<span class="space-title">潜空间 (Latent Space)</span>
</div>
<div class="grid-wrapper latent-wrapper">
<div class="latent-grid">
<div
v-for="n in 16"
:key="n"
class="latent-cell"
:style="getLatentStyle(n)"
></div>
</div>
<div class="grid-overlay">
<span>Latent Feature</span>
<span class="res-tag">64x64</span>
</div>
</div>
<div class="data-stats">
<div class="stat-row">
<span class="label">维度:</span>
<span class="value">4 (Channels)</span>
</div>
<div class="stat-row">
<span class="label">数据量:</span>
<span class="value">~1.6</span>
</div>
</div>
</div>
</div>
<el-divider />
<el-row :gutter="20">
<el-col :span="8">
<el-statistic title="压缩比" value="1:48">
<template #suffix>
<el-icon style="vertical-align: -0.125em"><Scissor /></el-icon>
</template>
</el-statistic>
</el-col>
<el-col :span="16">
<el-alert
title="为什么要压缩?"
type="success"
:closable="false"
description="直接处理 300 万个像素太慢了。VAE 把图像压缩成「压缩饼干」(潜变量),保留了核心特征(语义、构图),扔掉了冗余细节。AI 在这个小空间里画画,速度飞快!"
show-icon
/>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script setup>
import { Picture, Cpu, Right, Filter, Scissor } from '@element-plus/icons-vue'
const getPixelStyle = (n) => {
// Simulate a natural image with smooth color transitions
const r = 100 + Math.sin(n * 0.1) * 50
const g = 150 + Math.cos(n * 0.1) * 50
const b = 200 + Math.sin(n * 0.05) * 50
return {
backgroundColor: `rgb(${r}, ${g}, ${b})`,
opacity: 0.8 + Math.random() * 0.2
}
}
const getLatentStyle = (n) => {
// Simulate high-level features (more abstract, high contrast colors)
const hue = (n * 137) % 360
return {
backgroundColor: `hsl(${hue}, 70%, 60%)`,
boxShadow: `0 0 5px hsl(${hue}, 70%, 60%)`
}
}
</script>
<style scoped>
.latent-space-viz {
margin: 20px 0;
}
.viz-container {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 20px;
}
.space-block {
flex: 1;
min-width: 200px;
background: var(--el-fill-color-lighter);
border-radius: 8px;
padding: 15px;
border: 1px solid var(--el-border-color-lighter);
}
.space-block.highlight {
border-color: var(--el-color-warning-light-5);
background: var(--el-color-warning-light-9);
}
.space-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 15px;
font-weight: bold;
color: var(--el-text-color-primary);
}
.grid-wrapper {
position: relative;
background: #000;
border-radius: 4px;
overflow: hidden;
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: center;
}
.pixel-wrapper {
height: 160px;
}
.latent-wrapper {
height: 100px; /* Smaller representation */
width: 100px;
margin: 0 auto 15px auto;
}
.pixel-grid {
display: grid;
grid-template-columns: repeat(16, 1fr);
width: 100%;
height: 100%;
}
.pixel-cell {
width: 100%;
height: 100%;
}
.latent-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
width: 100%;
height: 100%;
gap: 2px;
padding: 5px;
}
.latent-cell {
width: 100%;
height: 100%;
border-radius: 2px;
}
.grid-overlay {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
background: rgba(0, 0, 0, 0.6);
color: #fff;
font-size: 0.75em;
padding: 4px 8px;
display: flex;
justify-content: space-between;
align-items: center;
}
.res-tag {
font-family: monospace;
opacity: 0.8;
}
.data-stats {
font-size: 0.85em;
color: var(--el-text-color-secondary);
}
.stat-row {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
}
.transform-process {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
color: var(--el-text-color-secondary);
}
.process-arrow {
display: flex;
align-items: center;
gap: 5px;
}
.vae-box {
border: 1px solid var(--el-border-color);
border-radius: 4px;
padding: 4px 8px;
font-size: 0.8em;
display: flex;
align-items: center;
gap: 4px;
background: #fff;
}
.compress-tag {
transform: scale(0.9);
}
@media (max-width: 600px) {
.viz-container {
flex-direction: column;
}
.transform-process {
transform: rotate(90deg);
margin: 10px 0;
}
.compress-tag {
display: none; /* Hide tag when rotated to avoid layout issues */
}
}
</style>