Files
xianyan/lib/editor/models/editor_models.dart
Developer 3a38c69521 chore: 完成v1.2.3版本迭代更新
主要变更:
1. 移除摇一摇相关功能代码与依赖
2. 新增自定义频道导入与管理功能
3. 优化iOS/macOS平台配置与适配
4. 重构路由转场逻辑为原生Cupertino风格
5. 修复设备发现与文件传输相关bug
6. 调整深色模式默认值为纯黑AMOLED
7. 新增运行模式标签与Spotlight搜索优化
8. 清理废弃的本地化字符串与设置项
2026-06-10 07:57:58 +08:00

983 lines
25 KiB
Dart

// ============================================================
// 闲言APP — 编辑器数据模型 (freezed)
// 创建时间: 2026-04-20
// 更新时间: 2026-05-04
// 作用: 定义卡片/壁纸编辑器的不可变数据结构
// 上次更新: 新增 DragBorderStyle 枚举
// ============================================================
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:xianyan/core/theme/app_colors.dart';
part 'editor_models.freezed.dart';
// ============================================================
// 标注相关模型 (从 annotation_layer.dart 迁移)
// ============================================================
enum AnnotationType {
line('划线'),
circle('圈选'),
arrow('箭头'),
text('文字');
const AnnotationType(this.label);
final String label;
}
@immutable
class AnnotationPoint {
const AnnotationPoint({required this.x, required this.y});
final double x;
final double y;
Offset toOffset() => Offset(x, y);
}
@immutable
class AnnotationLayer {
const AnnotationLayer({
required this.id,
required this.type,
required this.points,
this.strokeWidth = 3.0,
this.color = Colors.red,
this.opacity = 1.0,
this.visible = true,
this.locked = false,
this.name = '',
});
final String id;
final AnnotationType type;
final List<AnnotationPoint> points;
final double strokeWidth;
final Color color;
final double opacity;
final bool visible;
final bool locked;
final String name;
AnnotationLayer copyWith({
String? id,
AnnotationType? type,
List<AnnotationPoint>? points,
double? strokeWidth,
Color? color,
double? opacity,
bool? visible,
bool? locked,
String? name,
}) {
return AnnotationLayer(
id: id ?? this.id,
type: type ?? this.type,
points: points ?? this.points,
strokeWidth: strokeWidth ?? this.strokeWidth,
color: color ?? this.color,
opacity: opacity ?? this.opacity,
visible: visible ?? this.visible,
locked: locked ?? this.locked,
name: name ?? this.name,
);
}
}
// ============================================================
// 文字对齐方式
// ============================================================
/// 文字对齐方式
enum TextAlignMode { left, center, right }
/// 画布宽高比预设
enum CanvasAspectRatio {
ratio1_2('1:2', 720.0, 1440.0),
ratio9_16('9:16', 864.0, 1536.0),
ratio2_3('2:3', 720.0, 1080.0),
ratio3_4('3:4', 864.0, 1152.0),
ratio1_1('1:1', 960.0, 960.0),
ratio4_3('4:3', 1152.0, 864.0),
ratio3_2('3:2', 1152.0, 768.0),
ratio16_9('16:9', 1536.0, 864.0),
ratio21_9('21:9', 2016.0, 864.0);
// 优化 需要tips
/// 画布宽高比预设
// enum CanvasAspectRatio {
// ratio1_2('1:2', 900.0, 1800.0),
// ratio9_16('9:16', 1080.0, 1920.0),
// ratio2_3('2:3', 900.0, 1350.0),
// ratio3_4('3:4', 1080.0, 1440.0),
// ratio1_1('1:1', 1200.0, 1200.0),
// ratio4_3('4:3', 1440.0, 1080.0),
// ratio3_2('3:2', 1440.0, 960.0),
// ratio16_9('16:9', 1920.0, 1080.0),
// ratio21_9('21:9', 2520.0, 1080.0);
const CanvasAspectRatio(this.label, this.width, this.height);
final String label;
final double width;
final double height;
double get aspectRatio => width / height;
}
// ============================================================
// 文字层
// ============================================================
/// 文字层模型 — freezed 不可变
@freezed
sealed class TextLayer with _$TextLayer {
const factory TextLayer({
required String id,
required String text,
@Default(24.0) double fontSize,
@Default(FontWeight.normal) FontWeight fontWeight,
@Default('Inter') String fontFamily,
@Default(Color(0xFF1A1A2E)) Color color,
@Default(TextAlignMode.center) TextAlignMode textAlign,
@Default(0.0) double offsetX,
@Default(0.0) double offsetY,
@Default(0.0) double rotation,
@Default(1.0) double scale,
@Default(0.0) double letterSpacing,
@Default(1.5) double lineHeight,
@Default(false) bool italic,
@Default(false) bool underline,
@Default(false) bool strikethrough,
Color? strokeColor,
@Default(0.0) double strokeWidth,
Color? shadowColor,
@Default(0.0) double shadowBlur,
@Default(0.0) double shadowOffsetX,
@Default(0.0) double shadowOffsetY,
@Default(true) bool visible,
@Default(false) bool locked,
@Default(0) int zIndex,
@Default(1.0) double opacity,
@Default('') String name,
}) = _TextLayer;
const TextLayer._();
}
// ============================================================
// 背景类型
// ============================================================
/// 背景类型
enum BackgroundType { solid, gradient, image, imageBlur }
// ============================================================
// 背景层
// ============================================================
/// 背景层模型 — freezed 不可变
@freezed
sealed class BackgroundLayer with _$BackgroundLayer {
const factory BackgroundLayer({
@Default(BackgroundType.solid) BackgroundType type,
@Default(LightColors.primary) Color solidColor,
@Default([Color(0xFF6C63FF), Color(0xFF4ECDC4)]) List<Color> gradientColors,
@Default([0.0, 1.0]) List<double> gradientStops,
@Default(135.0) double gradientAngle,
@Default(Alignment.topCenter) Alignment gradientBegin,
@Default(Alignment.bottomCenter) Alignment gradientEnd,
String? imagePath,
@Default(0.0) double blurSigma,
@Default(1.0) double imageOpacity,
}) = _BackgroundLayer;
const BackgroundLayer._();
Alignment _angleToBegin(double angle) {
final rad = angle * pi / 180;
return Alignment(sin(rad), -cos(rad));
}
Alignment _angleToEnd(double angle) {
return _angleToBegin(angle + 180);
}
LinearGradient get effectiveGradient => LinearGradient(
colors: gradientColors,
stops: gradientStops.length == gradientColors.length ? gradientStops : null,
begin: _angleToBegin(gradientAngle),
end: _angleToEnd(gradientAngle),
);
}
// ============================================================
// 拖拽描边风格
// ============================================================
enum DragBorderStyle {
dashed('虚线边框', 'square_dashed'),
glow('发光边框', 'lightbulb');
const DragBorderStyle(this.label, this.iconName);
final String label;
final String iconName;
}
// ============================================================
// 水印样式
// ============================================================
/// 水印样式
enum WatermarkStyle { none, logo, info, custom }
// ============================================================
// 液态玻璃 (Liquid Glass) 设计系统
// ============================================================
/// 玻璃卡片样式枚举
enum GlassStyle {
crystal('水晶', 'clear'),
aurora('极光', 'iridescent'),
lava('熔岩', 'warm'),
ocean('深海', 'cool'),
frost('霜冻', 'icy'),
neon('霓虹', 'vibrant'),
pearl('珍珠', 'soft'),
cosmic('宇宙', 'dark');
const GlassStyle(this.label, this.category);
final String label;
final String category;
}
/// 液态玻璃卡片层模型 — freezed 不可变
@freezed
sealed class GlassCardLayer with _$GlassCardLayer {
const factory GlassCardLayer({
required String id,
@Default(GlassStyle.crystal) GlassStyle style,
@Default(0.0) double offsetX,
@Default(0.0) double offsetY,
@Default(200.0) double width,
@Default(150.0) double height,
@Default(0.0) double rotation,
@Default(1.0) double scale,
@Default(20.0) double borderRadius,
@Default(25.0) double blurIntensity,
@Default(0.65) double opacity,
@Default(0.15) double borderOpacity,
@Default(0.4) double highlightStrength,
@Default(true) bool showHighlight,
@Default(true) bool showInnerShadow,
@Default(Colors.white) Color tintColor,
@Default(true) bool visible,
@Default(false) bool locked,
@Default(10) int zIndex,
@Default(<String>[]) List<String> containedTextIds,
@Default(<String>[]) List<String> containedStickerIds,
@Default('') String name,
}) = _GlassCardLayer;
const GlassCardLayer._();
}
// ============================================================
// 贴纸层
// ============================================================
/// 贴纸类型
enum StickerType { emoji, shape, icon, widget, spritesheet }
/// 贴纸层模型 — freezed 不可变
@freezed
sealed class StickerLayer with _$StickerLayer {
const factory StickerLayer({
required String id,
@Default(StickerType.emoji) StickerType type,
required String assetPath,
@Default(80.0) double size,
@Default(0.0) double offsetX,
@Default(0.0) double offsetY,
@Default(0.0) double rotation,
@Default(1.0) double scale,
@Default(1.0) double opacity,
@Default(true) bool visible,
@Default(false) bool locked,
@Default(0) int zIndex,
@Default('') String name,
}) = _StickerLayer;
const StickerLayer._();
}
// ============================================================
// Shader 效果类型 (flutter_shaders_ui)
// ============================================================
enum ShaderEffectType {
wave('🌊', '波浪', '流动波浪渐变背景'),
aurora('🌌', '极光', '北极光幕帘效果'),
fire('🔥', '火焰', '上升火焰+余烬'),
water('💧', '水面', '水下焦散+泡沫'),
glass('🪟', '毛玻璃', '玻璃拟态效果'),
shimmer('', '闪光', '扫光高亮效果'),
snow('❄️', '飘雪', '视差雪花飘落'),
pulse('💫', '脉冲', '呼吸光环效果'),
ripple('🌊', '涟漪', '同心圆波纹'),
glowOrb('🔮', '光球', '可拖拽发光球体');
const ShaderEffectType(this.emoji, this.label, this.description);
final String emoji;
final String label;
final String description;
bool get isBackground =>
this == ShaderEffectType.wave ||
this == ShaderEffectType.aurora ||
this == ShaderEffectType.fire ||
this == ShaderEffectType.water;
bool get isOverlay =>
this == ShaderEffectType.glass ||
this == ShaderEffectType.shimmer ||
this == ShaderEffectType.snow ||
this == ShaderEffectType.pulse ||
this == ShaderEffectType.ripple ||
this == ShaderEffectType.glowOrb;
}
// ============================================================
// 画布模型
// ============================================================
/// 画布模型 — freezed 不可变
@freezed
sealed class QuoteCanvasModel with _$QuoteCanvasModel {
const factory QuoteCanvasModel({
@Default(CanvasAspectRatio.ratio4_3) CanvasAspectRatio aspectRatio,
@Default(false) bool showGrid,
@Default(40.0) double gridSize,
@Default(BackgroundLayer()) BackgroundLayer background,
@Default([]) List<TextLayer> textLayers,
@Default([]) List<StickerLayer> stickerLayers,
@Default([]) List<GlassCardLayer> glassCardLayers,
@Default(WatermarkStyle.none) WatermarkStyle watermarkStyle,
String? watermarkText,
String? selectedLayerId,
@Default(false) bool isLiquidGlassMode,
@Default([]) List<AnnotationLayer> annotationLayers,
}) = _QuoteCanvasModel;
const QuoteCanvasModel._();
double get canvasWidth => aspectRatio.width;
double get canvasHeight => aspectRatio.height;
/// 获取选中的文字层
TextLayer? get selectedLayer {
if (selectedLayerId == null) return null;
try {
return textLayers.firstWhere((l) => l.id == selectedLayerId);
} catch (_) {
return null;
}
}
/// 画布宽高比
double get aspectRatioValue => aspectRatio.aspectRatio;
}
// ============================================================
// 编辑器模板
// ============================================================
/// 预设模板
class EditorTemplate {
const EditorTemplate({
required this.id,
required this.name,
required this.emoji,
required this.background,
required this.textLayers,
});
final String id;
final String name;
final String emoji;
final BackgroundLayer background;
final List<TextLayer> textLayers;
/// 创建画布实例
QuoteCanvasModel toCanvas() {
return QuoteCanvasModel(background: background, textLayers: textLayers);
}
}
// ============================================================
// 内置模板集合
// ============================================================
/// 内置模板
class BuiltInTemplates {
BuiltInTemplates._();
static List<EditorTemplate> get all => [
_purpleGradient,
_darkMinimal,
_warmSunset,
_oceanBreeze,
_forestGreen,
_rosePink,
];
static const _purpleGradient = EditorTemplate(
id: 'purple_gradient',
name: '紫色梦境',
emoji: '💜',
background: BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [LightColors.primary, LightColors.primaryDark],
gradientBegin: Alignment.topLeft,
gradientEnd: Alignment.bottomRight,
),
textLayers: [
TextLayer(
id: 'title',
text: '在此输入文字',
fontSize: 32.0,
fontWeight: FontWeight.bold,
color: Colors.white,
offsetY: -40.0,
),
TextLayer(
id: 'author',
text: '—— 作者',
fontSize: 16.0,
color: Color(0xCCFFFFFF),
offsetY: 40.0,
),
],
);
static const _darkMinimal = EditorTemplate(
id: 'dark_minimal',
name: '暗黑极简',
emoji: '🌑',
background: BackgroundLayer(solidColor: Color(0xFF1A1A2E)),
textLayers: [
TextLayer(
id: 'title',
text: '在此输入文字',
fontSize: 28.0,
fontWeight: FontWeight.w300,
color: Color(0xFFE5E5E5),
offsetY: -30.0,
),
TextLayer(
id: 'author',
text: '—— 作者',
fontSize: 14.0,
color: LightColors.textHint,
offsetY: 30.0,
),
],
);
static const _warmSunset = EditorTemplate(
id: 'warm_sunset',
name: '暖色日落',
emoji: '🌅',
background: BackgroundLayer(
gradientColors: [Color(0xFFFF6B6B), Color(0xFFFFA07A)],
),
textLayers: [
TextLayer(
id: 'title',
text: '在此输入文字',
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.white,
offsetY: -40.0,
shadowColor: Color(0x40000000),
shadowBlur: 8.0,
shadowOffsetY: 2.0,
),
TextLayer(
id: 'author',
text: '—— 作者',
fontSize: 15.0,
color: Color(0xDDFFFFFF),
offsetY: 40.0,
),
],
);
static const _oceanBreeze = EditorTemplate(
id: 'ocean_breeze',
name: '海洋微风',
emoji: '🌊',
background: BackgroundLayer(
gradientColors: [LightColors.accent, Color(0xFF3B82F6)],
),
textLayers: [
TextLayer(
id: 'title',
text: '在此输入文字',
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Colors.white,
offsetY: -40.0,
),
TextLayer(
id: 'author',
text: '—— 作者',
fontSize: 15.0,
color: Color(0xCCFFFFFF),
offsetY: 40.0,
),
],
);
static const _forestGreen = EditorTemplate(
id: 'forest_green',
name: '森林绿意',
emoji: '🌿',
background: BackgroundLayer(
gradientColors: [Color(0xFF10B981), Color(0xFF059669)],
),
textLayers: [
TextLayer(
id: 'title',
text: '在此输入文字',
fontSize: 28.0,
fontWeight: FontWeight.bold,
color: Colors.white,
offsetY: -30.0,
),
TextLayer(
id: 'author',
text: '—— 作者',
fontSize: 14.0,
color: Color(0xBBFFFFFF),
offsetY: 30.0,
),
],
);
static const _rosePink = EditorTemplate(
id: 'rose_pink',
name: '玫瑰粉色',
emoji: '🌹',
background: BackgroundLayer(
gradientColors: [Color(0xFFF472B6), Color(0xFFEC4899)],
),
textLayers: [
TextLayer(
id: 'title',
text: '在此输入文字',
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Colors.white,
offsetY: -40.0,
shadowColor: Color(0x40000000),
shadowBlur: 6.0,
shadowOffsetY: 2.0,
),
TextLayer(
id: 'author',
text: '—— 作者',
fontSize: 15.0,
color: Color(0xDDFFFFFF),
offsetY: 40.0,
),
],
);
}
// ============================================================
// 液态玻璃 (Liquid Glass) 预设模板
// ============================================================
/// 氢设计预设模板
class GlassPreset {
const GlassPreset({
required this.id,
required this.name,
required this.emoji,
required this.style,
required this.background,
required this.glassCards,
required this.textLayers,
});
final String id;
final String name;
final String emoji;
final GlassStyle style;
final BackgroundLayer background;
final List<GlassCardLayer> glassCards;
final List<TextLayer> textLayers;
}
/// 内置氢设计预设 (8款)
class BuiltInGlassPresets {
BuiltInGlassPresets._();
static List<GlassPreset> get all => [
_crystalPure,
_auroraDream,
_lavaGlow,
_oceanDeep,
_frostIce,
_neonCyber,
_pearlSoft,
_cosmicStar,
];
static const _crystalPure = GlassPreset(
id: 'glass_crystal',
name: '纯净水晶',
emoji: '💎',
style: GlassStyle.crystal,
background: BackgroundLayer(
gradientColors: [Color(0xFFE8E8F0), Color(0xFFD0D0E8), Color(0xFFE0E0F5)],
gradientStops: [0.0, 0.5, 1.0],
),
glassCards: [
GlassCardLayer(
id: 'card_main',
offsetX: 140.0,
offsetY: 260.0,
width: 520.0,
height: 280.0,
borderRadius: 24.0,
opacity: 0.72,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 30.0,
fontWeight: FontWeight.w600,
color: Color(0xCC1A1A2E),
offsetY: -20.0,
),
TextLayer(
id: 'glass_sub',
text: '—— 副标题',
fontSize: 15.0,
color: Color(0x994A4A6A),
offsetY: 35.0,
),
],
);
static const _auroraDream = GlassPreset(
id: 'glass_aurora',
name: '极光幻梦',
emoji: '🌌',
style: GlassStyle.aurora,
background: BackgroundLayer(
gradientColors: [Color(0xFF1A0533), Color(0xFF2D1B69), Color(0xFF0D0D2B)],
gradientStops: [0.0, 0.6, 1.0],
gradientAngle: 180,
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.aurora,
offsetX: 100.0,
offsetY: 200.0,
width: 600.0,
height: 340.0,
borderRadius: 28.0,
blurIntensity: 32.0,
opacity: 0.60,
highlightStrength: 0.50,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 32.0,
fontWeight: FontWeight.w700,
color: Color(0xEEDDEEFF),
offsetY: -25.0,
),
TextLayer(
id: 'glass_sub',
text: '✨ Aurora Dream ✨',
fontSize: 14.0,
color: Color(0xBFAABFFF),
offsetY: 40.0,
),
],
);
static const _lavaGlow = GlassPreset(
id: 'glass_lava',
name: '熔岩流光',
emoji: '🔥',
style: GlassStyle.lava,
background: BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [Color(0xFF1A0A00), Color(0xFF3D1500), Color(0xFF1A0500)],
gradientStops: [0.0, 0.5, 1.0],
gradientAngle: 160,
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.lava,
offsetX: 120.0,
offsetY: 240.0,
width: 560.0,
height: 300.0,
borderRadius: 22.0,
blurIntensity: 26.0,
opacity: 0.58,
highlightStrength: 0.45,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Color(0xFFFFF0E0),
offsetY: -20.0,
),
TextLayer(
id: 'glass_sub',
text: '🔥 Lava Glow 🔥',
fontSize: 14.0,
color: Color(0xCCFFCC80),
offsetY: 38.0,
),
],
);
static const _oceanDeep = GlassPreset(
id: 'glass_ocean',
name: '深海幽蓝',
emoji: '🌊',
style: GlassStyle.ocean,
background: BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [Color(0xFF001D3D), Color(0xFF003566), Color(0xFF002B5C)],
gradientStops: [0.0, 0.5, 1.0],
gradientAngle: 170,
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.ocean,
offsetX: 110.0,
offsetY: 220.0,
width: 580.0,
height: 320.0,
borderRadius: 26.0,
blurIntensity: 30.0,
opacity: 0.55,
highlightStrength: 0.42,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 29.0,
fontWeight: FontWeight.w600,
color: Color(0xDDE0F4FF),
offsetY: -18.0,
),
TextLayer(
id: 'glass_sub',
text: '🌊 Ocean Deep 🌊',
fontSize: 14.0,
color: Color(0xAF90CAF0),
offsetY: 36.0,
),
],
);
static const _frostIce = GlassPreset(
id: 'glass_frost',
name: '霜冻冰晶',
emoji: '❄️',
style: GlassStyle.frost,
background: BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [Color(0xFFE8F4FC), Color(0xFFCCE8F7), Color(0xFFDFF0FA)],
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.frost,
offsetX: 130.0,
offsetY: 250.0,
width: 540.0,
height: 290.0,
borderRadius: 24.0,
blurIntensity: 30.0,
opacity: 0.70,
highlightStrength: 0.65,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 28.0,
fontWeight: FontWeight.w500,
color: Color(0xDD1A3A5C),
offsetY: -16.0,
),
TextLayer(
id: 'glass_sub',
text: '❄️ Frost Ice ❄️',
fontSize: 14.0,
color: Color(0x994A6A8C),
offsetY: 34.0,
),
],
);
static const _neonCyber = GlassPreset(
id: 'glass_neon',
name: '霓虹赛博',
emoji: '💜',
style: GlassStyle.neon,
background: BackgroundLayer(
gradientColors: [Color(0xFF0D001A), Color(0xFF1A002E), Color(0xFF0A0014)],
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.neon,
offsetX: 100.0,
offsetY: 210.0,
width: 600.0,
height: 340.0,
blurIntensity: 24.0,
opacity: 0.50,
highlightStrength: 0.55,
borderOpacity: 0.25,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 31.0,
fontWeight: FontWeight.bold,
color: Color(0xEEFF88CC),
offsetY: -22.0,
),
TextLayer(
id: 'glass_sub',
text: '⚡ Neon Cyber ⚡',
fontSize: 14.0,
color: Color(0xCCEE88FF),
offsetY: 38.0,
),
],
);
static const _pearlSoft = GlassPreset(
id: 'glass_pearl',
name: '珍珠柔光',
emoji: '🤍',
style: GlassStyle.pearl,
background: BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [Color(0xFFFDF2F8), Color(0xFFFCE7F3), Color(0xFFFDF4F9)],
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.pearl,
offsetX: 140.0,
offsetY: 260.0,
width: 520.0,
height: 280.0,
borderRadius: 26.0,
blurIntensity: 28.0,
opacity: 0.75,
highlightStrength: 0.50,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 27.0,
fontWeight: FontWeight.w500,
color: Color(0xDD5C3A4A),
offsetY: -15.0,
),
TextLayer(
id: 'glass_sub',
text: '🤍 Pearl Soft 🤍',
fontSize: 14.0,
color: Color(0xAA8C5A6A),
offsetY: 33.0,
),
],
);
static const _cosmicStar = GlassPreset(
id: 'glass_cosmic',
name: '宇宙星辰',
emoji: '🌟',
style: GlassStyle.cosmic,
background: BackgroundLayer(
type: BackgroundType.gradient,
gradientColors: [Color(0xFF0A0A1A), Color(0xFF141432), Color(0xFF08081A)],
),
glassCards: [
GlassCardLayer(
id: 'card_main',
style: GlassStyle.cosmic,
offsetX: 105.0,
offsetY: 215.0,
width: 590.0,
height: 330.0,
borderRadius: 24.0,
blurIntensity: 34.0,
opacity: 0.48,
highlightStrength: 0.35,
borderOpacity: 0.18,
),
],
textLayers: [
TextLayer(
id: 'glass_title',
text: '在此输入文字',
fontSize: 30.0,
fontWeight: FontWeight.w700,
color: Color(0xDDC4B5FD),
offsetY: -20.0,
),
TextLayer(
id: 'glass_sub',
text: '🌟 Cosmic Star 🌟',
fontSize: 14.0,
color: Color(0xBFA78BF8),
offsetY: 37.0,
),
],
);
}