Flutter三维几何体创建插件three_js_geometry的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter三维几何体创建插件three_js_geometry的使用

three_js_geometry 是一个基于 Dart 的插件,允许用户在他们的项目中创建三维几何体。

该插件是 three.jsthree_dart 的 Dart 转换版本,最初由 @mrdoob 创建,并且有一个由 @wasabia 维护的 Dart 分支。

使用方法

此插件允许用户向他们的 three_js 项目中添加几何体。

示例

以下是在你的 Flutter 应用程序中使用 three_js_geometry 插件的完整示例代码。

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_geometry/three_js_geometry.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 WebglGeometries(),
    );
  }
}

class WebglGeometries extends StatefulWidget {
  const WebglGeometries({super.key});

  [@override](/user/override)
  createState() => _State();
}

class _State extends State<WebglGeometries> {
  late three.ThreeJS threeJs;

  [@override](/user/override)
  void initState() {
    threeJs = three.ThreeJS(
      onSetupComplete: (){setState(() {});},
      setup: setup,
      settings: three.Settings(
        localClippingEnabled: true,
      )
    );
    super.initState();
  }

  [@override](/user/override)
  void dispose() {
    threeJs.dispose();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return threeJs.build();
  }

  int startTime = 0;

  Future<void> setup() async {
    threeJs.camera = three.PerspectiveCamera(45, threeJs.width / threeJs.height, 1, 2000);
    threeJs.camera.position.y = 400;

    threeJs.scene = three.Scene();

    three.Mesh object;

    final ambientLight = three.AmbientLight(0xcccccc, 0.4);
    threeJs.scene.add(ambientLight);

    final pointLight = three.PointLight(0xffffff, 0.8);
    threeJs.camera.add(pointLight);
    threeJs.scene.add(threeJs.camera);

    final material = three.MeshPhongMaterial.fromMap({"side": tmath.DoubleSide});

    // 添加球体几何体
    object = three.Mesh(three.SphereGeometry(75, 20, 10), material);
    object.position.setValues(-300, 0, 200);
    threeJs.scene.add(object);

    // 添加二十面体几何体
    object = three.Mesh(IcosahedronGeometry(75, 1), material);
    object.position.setValues(-100, 0, 200);
    threeJs.scene.add(object);

    // 添加八面体几何体
    object = three.Mesh(OctahedronGeometry(75, 2), material);
    object.position.setValues(100, 0, 200);
    threeJs.scene.add(object);

    // 添加四面体几何体
    object = three.Mesh(TetrahedronGeometry(75, 0), material);
    object.position.setValues(300, 0, 200);
    threeJs.scene.add(object);

    // 添加平面几何体
    object = three.Mesh(three.PlaneGeometry(100, 100, 4, 4), material);
    object.position.setValues(-300, 0, 0);
    threeJs.scene.add(object);

    // 添加立方体几何体
    object = three.Mesh(three.BoxGeometry(100, 100, 100, 4, 4, 4), material);
    object.position.setValues(-100, 0, 0);
    threeJs.scene.add(object);

    // 添加圆形几何体
    object = three.Mesh(
        CircleGeometry(
            radius: 50,
            segments: 20,
            thetaStart: 0,
            thetaLength: math.pi * 2),
        material);
    object.position.setValues(100, 0, 0);
    threeJs.scene.add(object);

    // 添加环形几何体
    object = three.Mesh(RingGeometry(10, 50, 20, 5, 0, math.pi * 2), material);
    object.position.setValues(300, 0, 0);
    threeJs.scene.add(object);

    // 添加圆柱几何体
    object = three.Mesh(CylinderGeometry(25, 75, 100, 40, 5), material);
    object.position.setValues(-300, 0, -200);
    threeJs.scene.add(object);

    List<tmath.Vector2> points = [];

    for (int i = 0; i < 50; i++) {
      points.add(tmath.Vector2(
          math.sin(i * 0.2) * math.sin(i * 0.1) * 15 + 50,
          (i - 5) * 2));
    }

    // 添加旋转几何体
    object = three.Mesh(LatheGeometry(points, segments: 20), material);
    object.position.setValues(-100, 0, -200);
    threeJs.scene.add(object);

    // 添加环面几何体
    object = three.Mesh(TorusGeometry(50, 20, 20, 20), material);
    object.position.setValues(100, 0, -200);
    threeJs.scene.add(object);

    // 添加环面结几何体
    object = three.Mesh(TorusKnotGeometry(50, 10, 50, 20), material);
    object.position.setValues(300, 0, -200);
    threeJs.scene.add(object);

    startTime = DateTime.now().millisecondsSinceEpoch;

    threeJs.addAnimationEvent((dt){
      final timer = DateTime.now().millisecondsSinceEpoch * 0.0001;

      threeJs.camera.position.x = math.cos(timer) * 800;
      threeJs.camera.position.z = math.sin(timer) * 800;
      threeJs.camera.lookAt(threeJs.scene.position);

      threeJs.scene.traverse((object) {
        if (object is three.Mesh) {
          object.rotation.x = timer * 5;
          object.rotation.y = timer * 2.5;
        }
      });
    });
  }
}

更多关于Flutter三维几何体创建插件three_js_geometry的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter三维几何体创建插件three_js_geometry的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个使用 three_js_geometry 插件在 Flutter 中创建三维几何体的示例代码。请注意,three_js_geometry 插件本身可能不是直接可用的 Flutter 插件,因为 Flutter 通常通过 flutter_three 或其他类似插件来与 Three.js 集成。不过,为了演示如何在 Flutter 中集成 Three.js 并创建三维几何体,我们可以使用 webview_flutter 插件来加载一个包含 Three.js 代码的网页。

首先,你需要在 pubspec.yaml 文件中添加 webview_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  webview_flutter: ^3.0.4  # 请检查最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,创建一个 Flutter 页面,并在其中使用 WebView 来加载包含 Three.js 代码的网页。以下是一个示例代码:

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Three.js Geometry Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late WebViewController _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Three.js Geometry Demo'),
      ),
      body: WebView(
        initialUrl: Uri.dataFromString(
          '''
          <!DOCTYPE html>
          <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Three.js Geometry Demo</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>
              // Basic Three.js setup
              let scene = new THREE.Scene();
              let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
              let renderer = new THREE.WebGLRenderer();
              renderer.setSize(window.innerWidth, window.innerHeight);
              document.body.appendChild(renderer.domElement);

              // Create a geometry and material, then mesh
              let geometry = new THREE.BoxGeometry();
              let material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
              let cube = new THREE.Mesh(geometry, material);
              scene.add(cube);

              camera.position.z = 5;

              // Render loop
              function animate() {
                requestAnimationFrame(animate);
                cube.rotation.x += 0.01;
                cube.rotation.y += 0.01;
                renderer.render(scene, camera);
              }
              animate();
            </script>
          </body>
          </html>
          ''',
          mimeType: 'text/html',
          encoding: Encoding.getByName('utf-8')
        ).toString(),
        javascriptMode: JavascriptMode.unrestricted,
        onWebViewCreated: (WebViewController webViewController) {
          _controller = webViewController;
        },
      ),
    );
  }
}

在这个示例中,我们创建了一个包含 Three.js 代码的 HTML 字符串,并使用 Uri.dataFromString 方法将其加载到 WebView 中。这个 HTML 页面创建了一个简单的 Three.js 场景,其中包含一个旋转的立方体。

请注意,这种方法是通过 WebView 来间接使用 Three.js 的,因为 Flutter 本身没有直接的 Three.js 插件。如果你需要更深入的集成或更高的性能,可能需要考虑使用原生平台代码(如 Swift/Kotlin)与 Flutter 通信,或者直接在原生平台上使用 Three.js。

回到顶部