- commercial_page:形象会员订阅占位 + 合作门店列表(造型/服装筛选,佣金政策展示) - avatar_viewer 精简为 MVP 占位实现(移除 three_dart/flutter_gl 依赖:flutter_gl 0.0.21 在 Flutter 3.44 下无法编译,v2 接入 GLB 时引入,接入方式注释保留) - 全链路冒烟验证通过:注册→照片→衣橱→身形→化身(172cm→体型模板4)→生成(LLM 预筛→全低分触发兜底→3 套方案)→选定主方案→3 视角效果图→收藏→门店列表
64 lines
2.0 KiB
Dart
64 lines
2.0 KiB
Dart
import 'package:flutter/material.dart';
|
||
|
||
/// 3D 化身查看组件(MVP 占位实现)
|
||
///
|
||
/// v2 接入真实 3D 渲染的方式:
|
||
/// 1. 服务端提供预烘焙 GLB 资产(/workspace/templates/avatar_f{face}_b{body}_s{skin}.glb)
|
||
/// 2. pubspec 引入 three_dart ^0.0.16 + three_dart_jsm ^0.0.10 + flutter_gl ^0.0.20
|
||
/// (注意 flutter_gl 0.0.21 在 Flutter 3.44 下无法编译,需锁 0.0.20)
|
||
/// 3. 用 flutter_gl 初始化 GL 上下文 + GLTFLoader 加载 GLB + 自动旋转渲染,
|
||
/// 参考 three_dart 0.0.16 的 example/lib/webgl_loader_glb.dart
|
||
class AvatarViewer extends StatelessWidget {
|
||
final String? glbUrl;
|
||
final String title;
|
||
final String subtitle;
|
||
final double height;
|
||
|
||
const AvatarViewer({
|
||
super.key,
|
||
required this.glbUrl,
|
||
required this.title,
|
||
required this.subtitle,
|
||
this.height = 360,
|
||
});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final scheme = Theme.of(context).colorScheme;
|
||
return Container(
|
||
height: height,
|
||
width: double.infinity,
|
||
decoration: BoxDecoration(
|
||
gradient: LinearGradient(
|
||
begin: Alignment.topCenter,
|
||
end: Alignment.bottomCenter,
|
||
colors: [
|
||
scheme.primaryContainer,
|
||
scheme.primary.withValues(alpha: 0.3),
|
||
],
|
||
),
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
child: Column(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
Icon(Icons.accessibility_new, size: 72, color: scheme.primary),
|
||
const SizedBox(height: 12),
|
||
Text(title,
|
||
style:
|
||
const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||
const SizedBox(height: 4),
|
||
Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||
child: Text(
|
||
subtitle.isEmpty ? '3D 渲染接入中(v2)' : subtitle,
|
||
textAlign: TextAlign.center,
|
||
style: const TextStyle(color: Colors.grey, fontSize: 12),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|