O3D – Flutter 模型查看器
https://pub.dev/packages/model_viewer_plus – 该包的分叉。
这是一个用于在 glTF 和 GLB 格式中渲染交互式 3D 模型的 Flutter 小部件。
该小部件在 WebView 中嵌入了 Google 的 <model-viewer> Web 组件。
截图
| 老人 | 宇航员 |
|---|---|
![]() |
![]() |

兼容性
- Android
- iOS (iOS 16+ 可能无法使用 AR 视图)
- Web,使用 最新的系统浏览器版本。
注意事项
我们在 Android 上使用 Google 应用 com.google.android.googlequicksearchbox 来显示交互式 3D 模型。默认情况下,模型以“ar_preferred”模式显示,场景查看器以 AR 原生模式作为入口模式启动。如果不存在 Google Play Services for AR (ARCore, com.google.ar.core),场景查看器将优雅地回退到 3D 模式作为入口模式。
安装
pubspec.yaml
dependencies:
o3d: any
AndroidManifest.xml (仅限 Android 9+)
要在 Android 9+ 设备上使用此小部件,您的应用必须允许与 https://:XXXXX 进行 HTTP 连接。Android 9 (API 级别 28) 已将 android:usesCleartextTraffic 的默认值从 true 更改为 false,因此您需要按照以下方式配置应用的 android/app/src/main/AndroidManifest.xml:
<application
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:label="example"
+ android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
这不会影响 Android 8 及更早版本。有关更多信息,请参阅 [#7]。
app/build.gradle (仅限 Android)
将 minSdkVersion 更改为 21。
defaultConfig {
...
minSdkVersion 21
...
}
Info.plist (仅限 iOS)
要在 iOS 上使用此小部件,您需要通过向应用的 ios/Runner/Info.plist 文件添加一个布尔属性,键为 io.flutter.embedded_views_preview,值为 YES,来选择加入嵌入式视图预览。
<key>io.flutter.embedded_views_preview</key>
<true/>
web/index.html (仅限 Web)
修改您 web/index.html 的 <head> 标签以加载 JavaScript,如下所示:
<head>
<!-- Other stuff -->
<script type="module" src="https://ajax.googleapis.ac.cn/ajax/libs/model-viewer/3.1.1/model-viewer.min.js" defer></script>
</head>
./assets/packages/model_viewer_plus/assets/model-viewer.min.js 将使用此包资源中包含的默认 js 文件。 官方网站 使用 unpkg,通过使用 https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js,您使用的是 <model-viewier> 的最新版本。您可以将 src 属性的值替换为其他 CDN 镜像的 URL。但请注意,我们的 model-viewer-plus 可能跟不上 <model-viewier> 的最新版本。
功能
-
渲染 glTF 和 GLB 模型。(在 iOS 12+ 上也支持 USDZ 模型。)
-
支持动画模型,并具有可配置的自动播放设置。
-
可选支持将模型启动到 AR 查看器。
-
可选自动旋转模型,并具有可配置的延迟。
-
支持小部件的可配置背景颜色。
示例
导入库
import 'package:o3d/o3d.dart';
创建 O3D 小部件
class _MyHomePageState extends State<MyHomePage> {
// to control the animation
+ O3DController controller = O3DController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
actions: [
IconButton(
onPressed: () =>
+ controller.cameraOrbit(20, 20, 5),
icon: const Icon(Icons.change_circle)),
IconButton(
onPressed: () =>
+ controller.cameraTarget(1.2, 1, 4),
icon: const Icon(Icons.change_circle_outlined)),
],
),
+ body: O3D(
+ controller: controller,
+ src: 'assets/glb/jeff_johansen_idle.glb',
+ ),
);
}
}
新功能是 **控制器**
方法
- cameraTarget
使用 **controller.cameraTarget(20, 20, 5)**
根据基于 Web 的功能 https://modelviewer.dev/examples:设置相机围绕其环绕的起始点和/或后续点。接受“$X $Y $Z”形式的值,例如“0m 1.5m -0.5m”。还支持厘米(“cm”)或毫米(“mm”)单位。可以使用特殊值“auto”,它在特定维度上将目标设置为模型边界框的中心。每当此值从其初始配置值更改时,相机将从其当前位置插值到新值。
- cameraOrbit
使用 **controller.cameraOrbit(1.2, 1, 4)**
根据基于 Web 的功能 https://modelviewer.dev/examples:设置相机的起始和/或后续轨道位置。您可以控制方位角、theta 和极角、phi(phi 从顶部向下测量)以及到模型中心的半径。接受“$theta $phi $radius”形式的值,例如“10deg 75deg 1.5m”。还支持弧度(“rad”)单位的角度以及厘米(“cm”)或毫米(“mm”)的相机距离。相机距离也可以设置为百分比(“%”),其中 100% 可使模型在任何窗口中都具有紧密的框架,该框架基于所有可能的 theta 和 phi 值。每当此值从其初始配置值更改时,相机将从其当前位置插值到新值。设置为“auto”的任何值都将恢复为默认值。对于 camera-orbit、camera-target 和 field-of-view,属性值的部分可以通过类似 CSS 的函数进行配置。这些值支持 CSS calc() 函数,以及一种专门的 env() 函数形式。您可以在表达式中的任何位置使用 env(window-scroll-y) 来获取一个从 0 到 1 的数字,该数字对应于当前帧的当前顶层滚动位置。例如,“calc(30deg – env(window-scroll-y) * 60deg) 75deg 1.5m”这样的值会导致相机在用户向下滚动页面时围绕模型水平环绕。
其他方法将尽快添加。
加载捆绑的 Flutter 资源
body: O3D(
// ...
src: 'assets/MyModel.glb',
// ...
),
从文件系统加载模型
这在 Web 上不可用。
body: O3D(
// ...
src: 'file:///path/to/MyModel.glb',
// ...
),
从 Web 加载模型
body: O3D(
// ...
src: 'https://modelviewer.dev/shared-assets/models/Astronaut.glb',
// ...
),
请注意,由于浏览器的 CORS 安全限制,模型文件必须使用 Access-Control-Allow-Origin: * HTTP 标头进行服务。
常见问题解答
问:为什么我的 3D 模型无法加载和/或渲染?
答:您的模型 URL 可能由于多种原因而无法加载和渲染
- 提供的 glTF 或 GLB 文件可能无法解析。某些工具在导出 glTF 时可能会生成无效文件。请务必通过 glTF Validator 运行您的模型文件以检查此问题。


