Flutter 3D文本渲染插件three_js_text的使用
Flutter 3D 文本渲染插件 three_js_text 的使用
three_js_text
这是一个允许用户在其项目中添加视觉文本的 three_js API。
这是由 @mrdoob 创建的 three.js 和 three_dart 的 Dart 转换版本,并且有一个由 @wasabia 维护的 Dart 分支。
使用
此 API 允许用户向其 three_js 项目中添加文本。
贡献
欢迎贡献。 如果遇到任何问题,请查看 现有问题,如果没有找到与您的问题相关的,请打开一个新问题。 在进行非简单修复之前,请先创建一个问题。 对于简单的修复,可以直接提交拉取请求。
示例代码
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:three_js_core/three_js_core.dart' as three;
import 'package:three_js_math/three_js_math.dart' as tmath;
import 'package:three_js_text/three_js_text.dart';
import 'dart:math' as math;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// 这个小部件是你的应用程序的根。
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const WebglGeometryText(),
);
}
}
class WebglGeometryText extends StatefulWidget {
const WebglGeometryText({super.key});
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<WebglGeometryText> {
late three.ThreeJS threeJs;
[@override](/user/override)
void initState() {
threeJs = three.ThreeJS(
onSetupComplete: () { setState(() {}); },
setup: setup,
settings: three.Settings(
renderOptions: {
"minFilter": tmath.LinearFilter,
"magFilter": tmath.LinearFilter,
"format": tmath.RGBAFormat,
"samples": 4
}
),
);
super.initState();
}
[@override](/user/override)
void dispose() {
threeJs.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return threeJs.build();
}
late three.Group group;
late three.GroupMaterial materials;
Future<void> setup() async {
// 摄像机
threeJs.camera = three.PerspectiveCamera(30, threeJs.width / threeJs.height, 1, 1500);
threeJs.camera.position.setValues(0, 400, 700);
final cameraTarget = tmath.Vector3(0, 50, 0);
threeJs.camera.lookAt(cameraTarget);
// 场景
threeJs.scene = three.Scene();
threeJs.scene.background = tmath.Color.fromHex32(0x000000);
threeJs.scene.fog = three.Fog(0x000000, 250, 1400);
// 灯光
final dirLight = three.DirectionalLight(0xffffff, 0.125);
dirLight.position.setValues(0, 0, 1).normalize();
threeJs.scene.add(dirLight);
final pointLight = three.PointLight(0xffffff, 1.5);
pointLight.position.setValues(0, 100, 90);
threeJs.scene.add(pointLight);
// 加载字体
final font = await loadFont();
createText(font);
// 添加平面
final plane = three.Mesh(
three.PlaneGeometry(10000, 10000),
three.MeshBasicMaterial.fromMap({"color": 0xffffff, "opacity": 0.5, "transparent": true})
);
plane.position.y = -100;
plane.rotation.x = -math.pi / 2;
threeJs.scene.add(plane);
}
Future<TYPRFont> loadFont() async {
final loader = TYPRLoader();
final font = await loader.fromAsset("assets/pingfang.ttf");
loader.dispose();
return font!;
}
void createText(font) {
String text = "Three_JS";
double fontHeight = 20,
size = 70,
hover = 30,
bevelThickness = 2,
bevelSize = 1.5;
int curveSegments = 4;
bool bevelEnabled = true;
bool mirror = true;
final textGeo = TextGeometry(text, TextGeometryOptions(
font: font,
size: size,
depth: fontHeight,
curveSegments: curveSegments,
bevelThickness: bevelThickness,
bevelSize: bevelSize,
bevelEnabled: bevelEnabled
));
textGeo.computeBoundingBox();
final centerOffset =
-0.5 * (textGeo.boundingBox!.max.x - textGeo.boundingBox!.min.x);
final textMesh1 = three.Mesh(textGeo, materials);
textMesh1.position.x = centerOffset;
textMesh1.position.y = hover;
textMesh1.position.z = 0;
textMesh1.rotation.x = 0;
textMesh1.rotation.y = math.pi * 2;
group.add(textMesh1);
if (mirror) {
final textMesh2 = three.Mesh(textGeo, materials);
textMesh2.position.x = centerOffset;
textMesh2.position.y = -hover;
textMesh2.position.z = threeJs.height;
textMesh2.rotation.x = math.pi;
textMesh2.rotation.y = math.pi * 2;
group.add(textMesh2);
}
}
}
更多关于Flutter 3D文本渲染插件three_js_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter 3D文本渲染插件three_js_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中实现3D文本渲染可以通过结合使用three_js_text
插件和Three.js库来完成。虽然Flutter本身不直接支持Three.js,但你可以通过平台通道(Platform Channels)或者通过Webview来嵌入Three.js的功能。不过,请注意,three_js_text
并不是官方或广泛认可的Flutter插件名称,因此这里我将展示如何使用Three.js在Flutter的Web平台上渲染3D文本的一个基本示例。
首先,你需要确保你的Flutter项目支持Web平台。如果还没有设置,可以通过以下命令添加Web支持:
flutter config --enable-web
然后,在pubspec.yaml
文件中确保添加了flutter_web_plugins
依赖(尽管Flutter Web现在通常自动处理这些依赖,但检查一下总是好的):
dependencies:
flutter:
sdk: flutter
flutter_web_plugins:
sdk: flutter
接下来,我们将使用flutter_webview_plugin
(或类似的Webview插件)来加载包含Three.js和3D文本渲染代码的HTML页面。以下是一个简化的步骤:
- 添加
flutter_webview_plugin
依赖:
在pubspec.yaml
中添加:
dependencies:
flutter_webview_plugin: ^0.4.0 # 请检查最新版本号
- 创建一个包含Three.js和3D文本渲染代码的HTML文件:
创建一个名为assets/threejs_text.html
的文件,内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js Text Rendering</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/loaders/FontLoader.js"></script>
<script>
let scene, camera, renderer, controls;
let textMesh;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
const loader = new THREE.FontLoader();
loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function (font) {
const geometry = new THREE.TextGeometry('Hello, Three.js!', {
font: font,
size: 1,
height: 0.1,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 0.1,
bevelSize: 0.05,
bevelSegments: 5
});
const material = new THREE.MeshStandardMaterial({ color: 0x0077ff });
textMesh = new THREE.Mesh(geometry, material);
scene.add(textMesh);
animate();
});
window.addEventListener('resize', onWindowResize, false);
}
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
init();
</script>
</body>
</html>
- 在Flutter中加载这个HTML文件:
修改你的main.dart
文件,使用flutter_webview_plugin
来加载HTML文件:
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Three.js Text Rendering'),
),
body: WebViewExample(),
),
);
}
}
class WebViewExample extends StatefulWidget {
@override
_WebViewExampleState createState() => _WebViewExampleState();
}
class _WebViewExampleState extends State<WebViewExample> {
final flutterWebviewPlugin = FlutterWebviewPlugin();
@override
Widget build(BuildContext context) {
return WebviewScaffold(
url: 'assets/threejs_text.html', // 这里加载你的HTML文件
appBar: AppBar(
title: Text('Three.js Text Example'),
),
withJavascript: true,
);
}
@override
void initState() {
super.initState();
flutterWebviewPlugin.onUrlChanged.listen((String url) {
print("URL changed: $url");
});
}
@override
void dispose() {
flutterWebviewPlugin.dispose();
super.dispose();
}
}
- 确保HTML文件被包含在assets中:
在pubspec.yaml
的flutter
部分添加assets:
flutter:
assets:
- assets/threejs_text.html
- 运行你的Flutter应用:
flutter run -d chrome
这将启动你的Flutter应用,并在Chrome浏览器中打开,展示一个包含3D渲染文本的页面。
请注意,这只是一个基本的示例,实际项目中你可能需要处理更多的细节,比如错误处理、资源加载优化等。此外,如果你希望在不支持Webview的原生平台上使用Three.js,你可能需要探索更复杂的平台通道实现或者使用其他支持3D渲染的Flutter插件(如sceneform
或arkit_flutter_plugin
,但这些通常针对特定的原生平台)。