多主题支持架构
1. 概述
多主题支持是AI UI生成系统的核心设计特性,通过统一的主题配置系统,实现一套代码支持多种视觉风格。本章详细介绍主题系统的架构设计、配置结构、实现机制和扩展开发,包括三大内置主题(obsidian-gold、silver-white、minimal)的详细解析和自定义主题开发指南。
2. 主题系统架构
2.1 整体架构图
主题配置 -> 主题解析器 -> 渲染引擎 -> 多格式输出
↓ ↓ ↓ ↓
ui_tokens.json ThemeParser Renderer PNG/Vue/HTML
2.2 主题系统组件
class ThemeSystem:
"""主题系统核心类"""
def __init__(self, tokens_path: str = "config/ui_tokens.json"):
"""初始化主题系统"""
self.tokens_path = tokens_path
self.tokens = self._load_tokens()
self.themes = self.tokens.get("themes", {})
self.components = self.tokens.get("components", {})
def _load_tokens(self) -> Dict:
"""加载UI令牌配置"""
with open(self.tokens_path, 'r', encoding='utf-8') as f:
return json.load(f)
def get_theme(self, theme_name: str) -> Dict:
"""获取指定主题配置"""
return self.themes.get(theme_name, self.themes["obsidian-gold"])
def get_component_config(self, component_name: str) -> Dict:
"""获取组件配置"""
return self.components.get(component_name, {})
3. 主题配置结构
3.1 UI令牌配置文件结构
{
"themes": {
"obsidian-gold": {
"colors": {
"primary": "#FFD700",
"secondary": "#B8860B",
"background": "#0E0E0E",
"surface": "#1A1A1A",
"text": "#FFFFFF",
"text_secondary": "#CCCCCC",
"border": "#333333",
"accent": "#FF6B35",
"success": "#4CAF50",
"warning": "#FF9800",
"error": "#F44336"
},
"typography": {
"font_family": "PingFang SC, -apple-system, BlinkMacSystemFont, sans-serif",
"font_size_base": "16px",
"font_size_small": "14px",
"font_size_large": "18px",
"font_weight_normal": "400",
"font_weight_bold": "600"
},
"spacing": {
"xs": "4px",
"sm": "8px",
"md": "16px",
"lg": "24px",
"xl": "32px",
"xxl": "48px"
},
"border_radius": {
"small": "4px",
"medium": "8px",
"large": "12px",
"round": "50%"
},
"shadows": {
"small": "0 1px 3px rgba(0, 0, 0, 0.12)",
"medium": "0 4px 6px rgba(0, 0, 0, 0.1)",
"large": "0 10px 15px rgba(0, 0, 0, 0.1)"
}
},
"silver-white": {
"colors": {
"primary": "#6B7280",
"secondary": "#9CA3AF",
"background": "#FFFFFF",
"surface": "#F9FAFB",
"text": "#111827",
"text_secondary": "#6B7280",
"border": "#E5E7EB",
"accent": "#3B82F6",
"success": "#10B981",
"warning": "#F59E0B",
"error": "#EF4444"
},
"typography": {
"font_family": "Inter, -apple-system, BlinkMacSystemFont, sans-serif",
"font_size_base": "16px",
"font_size_small": "14px",
"font_size_large": "18px",
"font_weight_normal": "400",
"font_weight_bold": "600"
},
"spacing": {
"xs": "4px",
"sm": "8px",
"md": "16px",
"lg": "24px",
"xl": "32px",
"xxl": "48px"
},
"border_radius": {
"small": "4px",
"medium": "8px",
"large": "12px",
"round": "50%"
},
"shadows": {
"small": "0 1px 3px rgba(0, 0, 0, 0.1)",
"medium": "0 4px 6px rgba(0, 0, 0, 0.05)",
"large": "0 10px 15px rgba(0, 0, 0, 0.1)"
}
},
"minimal": {
"colors": {
"primary": "#000000",
"secondary": "#666666",
"background": "#FFFFFF",
"surface": "#FFFFFF",
"text": "#000000",
"text_secondary": "#666666",
"border": "#E0E0E0",
"accent": "#007AFF",
"success": "#34C759",
"warning": "#FF9500",
"error": "#FF3B30"
},
"typography": {
"font_family": "SF Pro Display, -apple-system, BlinkMacSystemFont, sans-serif",
"font_size_base": "16px",
"font_size_small": "14px",
"font_size_large": "18px",
"font_weight_normal": "400",
"font_weight_bold": "600"
},
"spacing": {
"xs": "4px",
"sm": "8px",
"md": "16px",
"lg": "24px",
"xl": "32px",
"xxl": "48px"
},
"border_radius": {
"small": "2px",
"medium": "4px",
"large": "8px",
"round": "50%"
},
"shadows": {
"small": "0 1px 2px rgba(0, 0, 0, 0.05)",
"medium": "0 2px 4px rgba(0, 0, 0, 0.05)",
"large": "0 4px 8px rgba(0, 0, 0, 0.1)"
}
}
},
"components": {
"button": {
"height": "44px",
"padding": "0 16px",
"border_radius": "8px",
"font_weight": "500",
"transition": "all 0.2s ease"
},
"card": {
"padding": "16px",
"border_radius": "8px",
"shadow": "medium",
"background": "surface"
},
"input": {
"height": "44px",
"padding": "0 16px",
"border_radius": "8px",
"border": "1px solid",
"background": "surface"
},
"topbar": {
"height": "44px",
"padding": "0 16px",
"background": "surface",
"border_bottom": "1px solid"
},
"tabbar": {
"height": "60px",
"background": "surface",
"border_top": "1px solid",
"position": "fixed",
"bottom": "0"
}
}
}
3.2 主题配置解析器
class ThemeParser:
"""主题配置解析器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化解析器"""
self.theme_system = theme_system
def parse_theme_colors(self, theme_name: str) -> Dict[str, str]:
"""解析主题颜色"""
theme = self.theme_system.get_theme(theme_name)
colors = theme.get("colors", {})
# 转换为CSS变量格式
css_variables = {}
for color_name, color_value in colors.items():
css_variables[f"--{color_name.replace('_', '-')}"] = color_value
return css_variables
def parse_typography(self, theme_name: str) -> Dict[str, str]:
"""解析字体配置"""
theme = self.theme_system.get_theme(theme_name)
typography = theme.get("typography", {})
css_variables = {}
for prop_name, prop_value in typography.items():
css_variables[f"--font-{prop_name.replace('_', '-')}"] = prop_value
return css_variables
def parse_spacing(self, theme_name: str) -> Dict[str, str]:
"""解析间距配置"""
theme = self.theme_system.get_theme(theme_name)
spacing = theme.get("spacing", {})
css_variables = {}
for size_name, size_value in spacing.items():
css_variables[f"--spacing-{size_name}"] = size_value
return css_variables
def parse_border_radius(self, theme_name: str) -> Dict[str, str]:
"""解析圆角配置"""
theme = self.theme_system.get_theme(theme_name)
border_radius = theme.get("border_radius", {})
css_variables = {}
for radius_name, radius_value in border_radius.items():
css_variables[f"--border-radius-{radius_name}"] = radius_value
return css_variables
def parse_shadows(self, theme_name: str) -> Dict[str, str]:
"""解析阴影配置"""
theme = self.theme_system.get_theme(theme_name)
shadows = theme.get("shadows", {})
css_variables = {}
for shadow_name, shadow_value in shadows.items():
css_variables[f"--shadow-{shadow_name}"] = shadow_value
return css_variables
4. 三大内置主题详解
4.1 Obsidian Gold主题
4.1.1 设计理念
Obsidian Gold主题采用深色背景配金色点缀的设计风格,营造高端、神秘的视觉体验:
obsidian_gold_theme = {
"design_concept": "高端神秘",
"color_scheme": "深色背景 + 金色点缀",
"target_audience": "高端用户、奢侈品、科技产品",
"visual_style": "现代、奢华、专业"
}
4.1.2 颜色系统
obsidian_gold_colors = {
"primary": "#FFD700", # 主色调:金色
"secondary": "#B8860B", # 辅助色:深金色
"background": "#0E0E0E", # 背景色:深黑色
"surface": "#1A1A1A", # 表面色:深灰色
"text": "#FFFFFF", # 主文本:白色
"text_secondary": "#CCCCCC", # 次要文本:浅灰色
"border": "#333333", # 边框色:中灰色
"accent": "#FF6B35", # 强调色:橙红色
"success": "#4CAF50", # 成功色:绿色
"warning": "#FF9800", # 警告色:橙色
"error": "#F44336" # 错误色:红色
}
4.1.3 组件样式
def render_obsidian_gold_component(component_type: str, props: Dict) -> str:
"""渲染Obsidian Gold主题组件"""
if component_type == "button":
return f"""
.button {{
background-color: var(--primary-color);
color: var(--background-color);
border: 1px solid var(--primary-color);
box-shadow: 0 2px 4px rgba(255, 215, 0, 0.3);
}}
.button:hover {{
background-color: var(--secondary-color);
box-shadow: 0 4px 8px rgba(255, 215, 0, 0.4);
}}"""
elif component_type == "card":
return f"""
.card {{
background-color: var(--surface-color);
border: 1px solid var(--border-color);
box-shadow: var(--shadow-medium);
}}
.card:hover {{
border-color: var(--primary-color);
box-shadow: 0 4px 12px rgba(255, 215, 0, 0.2);
}}"""
4.2 Silver White主题
4.2.1 设计理念
Silver White主题采用简洁的银白色调,体现现代、专业、可信赖的设计风格:
silver_white_theme = {
"design_concept": "现代专业",
"color_scheme": "银白色调 + 蓝色点缀",
"target_audience": "企业用户、商务应用、专业服务",
"visual_style": "简洁、专业、可信赖"
}
4.2.2 颜色系统
silver_white_colors = {
"primary": "#6B7280", # 主色调:银灰色
"secondary": "#9CA3AF", # 辅助色:浅灰色
"background": "#FFFFFF", # 背景色:纯白色
"surface": "#F9FAFB", # 表面色:浅灰色
"text": "#111827", # 主文本:深灰色
"text_secondary": "#6B7280", # 次要文本:中灰色
"border": "#E5E7EB", # 边框色:浅灰色
"accent": "#3B82F6", # 强调色:蓝色
"success": "#10B981", # 成功色:绿色
"warning": "#F59E0B", # 警告色:橙色
"error": "#EF4444" # 错误色:红色
}
4.2.3 组件样式
def render_silver_white_component(component_type: str, props: Dict) -> str:
"""渲染Silver White主题组件"""
if component_type == "button":
return f"""
.button {{
background-color: var(--primary-color);
color: var(--background-color);
border: 1px solid var(--primary-color);
box-shadow: 0 1px 3px rgba(107, 114, 128, 0.1);
}}
.button:hover {{
background-color: var(--secondary-color);
box-shadow: 0 2px 4px rgba(107, 114, 128, 0.15);
}}"""
elif component_type == "card":
return f"""
.card {{
background-color: var(--surface-color);
border: 1px solid var(--border-color);
box-shadow: var(--shadow-small);
}}
.card:hover {{
border-color: var(--accent-color);
box-shadow: var(--shadow-medium);
}}"""
4.3 Minimal主题
4.3.1 设计理念
Minimal主题采用极简的黑白设计,追求简洁、清晰、高效的视觉体验:
minimal_theme = {
"design_concept": "极简主义",
"color_scheme": "黑白配色 + 蓝色点缀",
"target_audience": "追求简洁的用户、内容应用、工具类应用",
"visual_style": "极简、清晰、高效"
}
4.3.2 颜色系统
minimal_colors = {
"primary": "#000000", # 主色调:纯黑色
"secondary": "#666666", # 辅助色:中灰色
"background": "#FFFFFF", # 背景色:纯白色
"surface": "#FFFFFF", # 表面色:纯白色
"text": "#000000", # 主文本:纯黑色
"text_secondary": "#666666", # 次要文本:中灰色
"border": "#E0E0E0", # 边框色:浅灰色
"accent": "#007AFF", # 强调色:蓝色
"success": "#34C759", # 成功色:绿色
"warning": "#FF9500", # 警告色:橙色
"error": "#FF3B30" # 错误色:红色
}
4.3.3 组件样式
def render_minimal_component(component_type: str, props: Dict) -> str:
"""渲染Minimal主题组件"""
if component_type == "button":
return f"""
.button {{
background-color: var(--primary-color);
color: var(--background-color);
border: 1px solid var(--primary-color);
box-shadow: none;
}}
.button:hover {{
background-color: var(--secondary-color);
border-color: var(--secondary-color);
}}"""
elif component_type == "card":
return f"""
.card {{
background-color: var(--surface-color);
border: 1px solid var(--border-color);
box-shadow: none;
}}
.card:hover {{
border-color: var(--primary-color);
}}"""
5. 主题应用机制
5.1 主题选择器
class ThemeSelector:
"""主题选择器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化主题选择器"""
self.theme_system = theme_system
self.available_themes = list(theme_system.themes.keys())
self.current_theme = "obsidian-gold"
def select_theme(self, theme_name: str) -> bool:
"""选择主题"""
if theme_name in self.available_themes:
self.current_theme = theme_name
return True
return False
def get_current_theme(self) -> str:
"""获取当前主题"""
return self.current_theme
def get_theme_preview(self, theme_name: str) -> Dict:
"""获取主题预览"""
theme = self.theme_system.get_theme(theme_name)
return {
"name": theme_name,
"colors": theme.get("colors", {}),
"preview_image": f"/static/themes/{theme_name}_preview.png"
}
5.2 主题渲染器
class ThemeRenderer:
"""主题渲染器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化主题渲染器"""
self.theme_system = theme_system
self.parser = ThemeParser(theme_system)
def render_theme_css(self, theme_name: str) -> str:
"""渲染主题CSS"""
theme = self.theme_system.get_theme(theme_name)
# 解析各种配置
colors = self.parser.parse_theme_colors(theme_name)
typography = self.parser.parse_typography(theme_name)
spacing = self.parser.parse_spacing(theme_name)
border_radius = self.parser.parse_border_radius(theme_name)
shadows = self.parser.parse_shadows(theme_name)
# 生成CSS变量
css_variables = []
css_variables.extend([f" {var}: {value};" for var, value in colors.items()])
css_variables.extend([f" {var}: {value};" for var, value in typography.items()])
css_variables.extend([f" {var}: {value};" for var, value in spacing.items()])
css_variables.extend([f" {var}: {value};" for var, value in border_radius.items()])
css_variables.extend([f" {var}: {value};" for var, value in shadows.items()])
css_variables_str = "\n".join(css_variables)
return f"""
.theme-{theme_name} {{
{css_variables_str}
}}"""
def render_component_styles(self, theme_name: str, component_type: str) -> str:
"""渲染组件样式"""
theme = self.theme_system.get_theme(theme_name)
component_config = self.theme_system.get_component_config(component_type)
# 根据组件类型生成样式
if component_type == "button":
return self._render_button_styles(theme, component_config)
elif component_type == "card":
return self._render_card_styles(theme, component_config)
elif component_type == "input":
return self._render_input_styles(theme, component_config)
# ... 其他组件类型
def _render_button_styles(self, theme: Dict, config: Dict) -> str:
"""渲染按钮样式"""
return f"""
.theme-{theme.get('name', 'default')} .button {{
height: {config.get('height', '44px')};
padding: {config.get('padding', '0 16px')};
border-radius: {config.get('border_radius', '8px')};
font-weight: {config.get('font_weight', '500')};
transition: {config.get('transition', 'all 0.2s ease')};
background-color: var(--primary-color);
color: var(--background-color);
border: 1px solid var(--primary-color);
}}
.theme-{theme.get('name', 'default')} .button:hover {{
background-color: var(--secondary-color);
border-color: var(--secondary-color);
}}"""
6. 主题切换系统
6.1 动态主题切换
class DynamicThemeSwitcher:
"""动态主题切换器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化动态主题切换器"""
self.theme_system = theme_system
self.current_theme = "obsidian-gold"
self.theme_cache = {}
def switch_theme(self, theme_name: str) -> bool:
"""切换主题"""
if theme_name not in self.theme_system.themes:
return False
# 缓存当前主题
self.theme_cache[self.current_theme] = self._get_current_theme_state()
# 切换到新主题
self.current_theme = theme_name
self._apply_theme(theme_name)
return True
def _get_current_theme_state(self) -> Dict:
"""获取当前主题状态"""
# 获取当前页面的主题状态
return {
"theme_name": self.current_theme,
"applied_at": time.time()
}
def _apply_theme(self, theme_name: str) -> None:
"""应用主题"""
# 生成主题CSS
theme_css = self._generate_theme_css(theme_name)
# 应用到页面
self._inject_theme_css(theme_css)
# 触发主题切换事件
self._trigger_theme_change_event(theme_name)
def _generate_theme_css(self, theme_name: str) -> str:
"""生成主题CSS"""
renderer = ThemeRenderer(self.theme_system)
return renderer.render_theme_css(theme_name)
def _inject_theme_css(self, css: str) -> None:
"""注入主题CSS"""
# 移除旧的主题样式
self._remove_old_theme_styles()
# 注入新的主题样式
style_element = f"<style id='dynamic-theme'>{css}</style>"
# 这里需要根据具体的渲染环境来实现CSS注入
def _remove_old_theme_styles(self) -> None:
"""移除旧的主题样式"""
# 移除旧的主题样式元素
pass
def _trigger_theme_change_event(self, theme_name: str) -> None:
"""触发主题切换事件"""
# 触发主题切换事件,通知其他组件
pass
6.2 主题持久化
class ThemePersistence:
"""主题持久化"""
def __init__(self, storage_key: str = "selected_theme"):
"""初始化主题持久化"""
self.storage_key = storage_key
def save_theme(self, theme_name: str) -> None:
"""保存主题选择"""
# 保存到本地存储
if hasattr(self, '_save_to_local_storage'):
self._save_to_local_storage(theme_name)
# 保存到服务器
if hasattr(self, '_save_to_server'):
self._save_to_server(theme_name)
def load_theme(self) -> str:
"""加载主题选择"""
# 从本地存储加载
if hasattr(self, '_load_from_local_storage'):
theme = self._load_from_local_storage()
if theme:
return theme
# 从服务器加载
if hasattr(self, '_load_from_server'):
theme = self._load_from_server()
if theme:
return theme
# 返回默认主题
return "obsidian-gold"
def _save_to_local_storage(self, theme_name: str) -> None:
"""保存到本地存储"""
# 实现本地存储逻辑
pass
def _load_from_local_storage(self) -> str:
"""从本地存储加载"""
# 实现本地存储加载逻辑
return None
def _save_to_server(self, theme_name: str) -> None:
"""保存到服务器"""
# 实现服务器保存逻辑
pass
def _load_from_server(self) -> str:
"""从服务器加载"""
# 实现服务器加载逻辑
return None
7. 自定义主题开发
7.1 主题开发指南
class CustomThemeBuilder:
"""自定义主题构建器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化自定义主题构建器"""
self.theme_system = theme_system
self.theme_template = self._load_theme_template()
def _load_theme_template(self) -> Dict:
"""加载主题模板"""
return {
"colors": {
"primary": "#000000",
"secondary": "#000000",
"background": "#FFFFFF",
"surface": "#FFFFFF",
"text": "#000000",
"text_secondary": "#000000",
"border": "#000000",
"accent": "#000000",
"success": "#000000",
"warning": "#000000",
"error": "#000000"
},
"typography": {
"font_family": "Arial, sans-serif",
"font_size_base": "16px",
"font_size_small": "14px",
"font_size_large": "18px",
"font_weight_normal": "400",
"font_weight_bold": "600"
},
"spacing": {
"xs": "4px",
"sm": "8px",
"md": "16px",
"lg": "24px",
"xl": "32px",
"xxl": "48px"
},
"border_radius": {
"small": "4px",
"medium": "8px",
"large": "12px",
"round": "50%"
},
"shadows": {
"small": "0 1px 3px rgba(0, 0, 0, 0.12)",
"medium": "0 4px 6px rgba(0, 0, 0, 0.1)",
"large": "0 10px 15px rgba(0, 0, 0, 0.1)"
}
}
def create_theme(self, theme_name: str, theme_config: Dict) -> bool:
"""创建自定义主题"""
# 验证主题配置
if not self._validate_theme_config(theme_config):
return False
# 合并主题配置
full_theme_config = self._merge_theme_config(theme_config)
# 保存主题配置
self._save_theme_config(theme_name, full_theme_config)
return True
def _validate_theme_config(self, config: Dict) -> bool:
"""验证主题配置"""
required_sections = ["colors", "typography", "spacing", "border_radius", "shadows"]
for section in required_sections:
if section not in config:
return False
# 验证颜色配置
required_colors = ["primary", "secondary", "background", "surface", "text", "text_secondary", "border", "accent", "success", "warning", "error"]
for color in required_colors:
if color not in config["colors"]:
return False
return True
def _merge_theme_config(self, config: Dict) -> Dict:
"""合并主题配置"""
merged_config = self.theme_template.copy()
for section, values in config.items():
if section in merged_config:
merged_config[section].update(values)
return merged_config
def _save_theme_config(self, theme_name: str, config: Dict) -> None:
"""保存主题配置"""
# 加载现有配置
with open(self.theme_system.tokens_path, 'r', encoding='utf-8') as f:
tokens = json.load(f)
# 添加新主题
tokens["themes"][theme_name] = config
# 保存配置
with open(self.theme_system.tokens_path, 'w', encoding='utf-8') as f:
json.dump(tokens, f, indent=2, ensure_ascii=False)
7.2 主题预览系统
class ThemePreviewGenerator:
"""主题预览生成器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化主题预览生成器"""
self.theme_system = theme_system
self.preview_components = [
"button", "card", "input", "topbar", "tabbar"
]
def generate_theme_preview(self, theme_name: str) -> str:
"""生成主题预览"""
theme = self.theme_system.get_theme(theme_name)
renderer = ThemeRenderer(self.theme_system)
# 生成主题CSS
theme_css = renderer.render_theme_css(theme_name)
# 生成预览HTML
preview_html = self._generate_preview_html(theme_name, theme_css)
return preview_html
def _generate_preview_html(self, theme_name: str, theme_css: str) -> str:
"""生成预览HTML"""
return f"""
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{theme_name} 主题预览</title>
<style>
{theme_css}
.preview-container {{
padding: 20px;
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family);
}}
.preview-section {{
margin-bottom: 30px;
}}
.preview-title {{
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
color: var(--text-color);
}}
.preview-grid {{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}}
.preview-item {{
padding: 15px;
background-color: var(--surface-color);
border: 1px solid var(--border-color);
border-radius: var(--border-radius-medium);
}}
.preview-item h3 {{
margin: 0 0 10px 0;
font-size: 14px;
color: var(--text-secondary-color);
}}
.button {{
height: 44px;
padding: 0 16px;
border-radius: 8px;
font-weight: 500;
border: none;
cursor: pointer;
background-color: var(--primary-color);
color: var(--background-color);
}}
.button:hover {{
background-color: var(--secondary-color);
}}
.card {{
padding: 16px;
border-radius: 8px;
background-color: var(--surface-color);
border: 1px solid var(--border-color);
}}
.input {{
height: 44px;
padding: 0 16px;
border-radius: 8px;
border: 1px solid var(--border-color);
background-color: var(--surface-color);
color: var(--text-color);
}}
.topbar {{
height: 44px;
padding: 0 16px;
background-color: var(--surface-color);
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-between;
}}
.tabbar {{
height: 60px;
background-color: var(--surface-color);
border-top: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: space-around;
}}
</style>
</head>
<body class="theme-{theme_name}">
<div class="preview-container">
<h1>{theme_name} 主题预览</h1>
<div class="preview-section">
<h2 class="preview-title">按钮组件</h2>
<div class="preview-grid">
<div class="preview-item">
<h3>主要按钮</h3>
<button class="button">主要按钮</button>
</div>
<div class="preview-item">
<h3>次要按钮</h3>
<button class="button" style="background-color: var(--secondary-color);">次要按钮</button>
</div>
</div>
</div>
<div class="preview-section">
<h2 class="preview-title">卡片组件</h2>
<div class="preview-grid">
<div class="preview-item">
<h3>基础卡片</h3>
<div class="card">
<h4>卡片标题</h4>
<p>这是卡片内容,展示主题的视觉效果。</p>
</div>
</div>
</div>
</div>
<div class="preview-section">
<h2 class="preview-title">输入框组件</h2>
<div class="preview-grid">
<div class="preview-item">
<h3>文本输入</h3>
<input type="text" class="input" placeholder="请输入内容">
</div>
</div>
</div>
<div class="preview-section">
<h2 class="preview-title">导航组件</h2>
<div class="preview-grid">
<div class="preview-item">
<h3>顶部栏</h3>
<div class="topbar">
<span>标题</span>
<span>操作</span>
</div>
</div>
<div class="preview-item">
<h3>底部导航</h3>
<div class="tabbar">
<span>首页</span>
<span>分类</span>
<span>购物车</span>
<span>我的</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
"""
8. 主题系统集成
8.1 渲染引擎集成
class ThemeIntegratedRenderer:
"""主题集成渲染器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化主题集成渲染器"""
self.theme_system = theme_system
self.theme_renderer = ThemeRenderer(theme_system)
def render_with_theme(self, dsl: Dict, theme_name: str) -> Dict[str, str]:
"""使用指定主题渲染UI"""
# 获取主题配置
theme = self.theme_system.get_theme(theme_name)
# 渲染PNG图片
png_renderer = UIRenderer()
png_renderer.set_theme(theme)
png_image = png_renderer.render(dsl)
# 渲染Vue页面
vue_renderer = VueRenderer()
vue_renderer.set_theme(theme)
vue_page = vue_renderer.render(dsl)
return {
"theme": theme_name,
"png": png_image,
"vue": vue_page
}
def render_all_themes(self, dsl: Dict) -> Dict[str, Dict[str, str]]:
"""使用所有主题渲染UI"""
results = {}
for theme_name in self.theme_system.themes.keys():
results[theme_name] = self.render_with_theme(dsl, theme_name)
return results
8.2 API集成
# 在FastAPI中集成主题系统
@app.get("/themes")
async def get_available_themes():
"""获取可用主题列表"""
theme_system = ThemeSystem()
themes = []
for theme_name in theme_system.themes.keys():
theme = theme_system.get_theme(theme_name)
themes.append({
"name": theme_name,
"display_name": theme.get("display_name", theme_name),
"description": theme.get("description", ""),
"preview_url": f"/themes/{theme_name}/preview"
})
return {"themes": themes}
@app.get("/themes/{theme_name}/preview")
async def get_theme_preview(theme_name: str):
"""获取主题预览"""
theme_system = ThemeSystem()
if theme_name not in theme_system.themes:
raise HTTPException(status_code=404, detail="主题不存在")
preview_generator = ThemePreviewGenerator(theme_system)
preview_html = preview_generator.generate_theme_preview(theme_name)
return HTMLResponse(content=preview_html)
@app.post("/themes/{theme_name}/apply")
async def apply_theme(theme_name: str, dsl: Dict):
"""应用主题到UI设计"""
theme_system = ThemeSystem()
if theme_name not in theme_system.themes:
raise HTTPException(status_code=404, detail="主题不存在")
integrated_renderer = ThemeIntegratedRenderer(theme_system)
result = integrated_renderer.render_with_theme(dsl, theme_name)
return result
9. 主题系统最佳实践
9.1 主题设计原则
theme_design_principles = {
"color_contrast": {
"description": "确保足够的颜色对比度",
"min_contrast_ratio": 4.5,
"recommended_ratio": 7.0
},
"accessibility": {
"description": "支持无障碍访问",
"color_blind_support": True,
"high_contrast_mode": True
},
"consistency": {
"description": "保持视觉一致性",
"color_harmony": True,
"spacing_consistency": True
},
"performance": {
"description": "优化性能",
"css_optimization": True,
"lazy_loading": True
}
}
9.2 主题测试策略
class ThemeTester:
"""主题测试器"""
def __init__(self, theme_system: ThemeSystem):
"""初始化主题测试器"""
self.theme_system = theme_system
def test_theme_accessibility(self, theme_name: str) -> Dict[str, bool]:
"""测试主题无障碍性"""
theme = self.theme_system.get_theme(theme_name)
colors = theme.get("colors", {})
results = {
"color_contrast": self._test_color_contrast(colors),
"color_blind_support": self._test_color_blind_support(colors),
"text_readability": self._test_text_readability(colors)
}
return results
def _test_color_contrast(self, colors: Dict) -> bool:
"""测试颜色对比度"""
# 实现颜色对比度测试
return True
def _test_color_blind_support(self, colors: Dict) -> bool:
"""测试色盲支持"""
# 实现色盲支持测试
return True
def _test_text_readability(self, colors: Dict) -> bool:
"""测试文本可读性"""
# 实现文本可读性测试
return True
def test_theme_consistency(self, theme_name: str) -> Dict[str, bool]:
"""测试主题一致性"""
theme = self.theme_system.get_theme(theme_name)
results = {
"color_harmony": self._test_color_harmony(theme),
"spacing_consistency": self._test_spacing_consistency(theme),
"typography_consistency": self._test_typography_consistency(theme)
}
return results
def _test_color_harmony(self, theme: Dict) -> bool:
"""测试颜色和谐性"""
# 实现颜色和谐性测试
return True
def _test_spacing_consistency(self, theme: Dict) -> bool:
"""测试间距一致性"""
# 实现间距一致性测试
return True
def _test_typography_consistency(self, theme: Dict) -> bool:
"""测试字体一致性"""
# 实现字体一致性测试
return True
通过掌握这些多主题支持技术,您可以构建一个灵活、可扩展、用户友好的主题系统。主题系统是UI生成系统的重要组成部分,需要精心设计和持续优化,以提供最佳的用户体验。