Flutter三维绘图插件three_js_line的使用

Flutter三维绘图插件three_js_line的使用

three_js_line

Pub Version 分析 许可证: MIT

three_js_line 是一个基于 three.js 和 three_dart 的 Dart 转换版本,最初由 @mrdoob 创建。该插件允许用户在其项目中增加线几何图形的厚度。

厚彩色线条示例

使用

three_js_line 插件允许用户在他们的项目中增加线几何图形的厚度。

贡献

欢迎贡献!如果遇到任何问题,请查看现有的问题,如果没有找到与您的问题相关的,可以打开一个新的问题。对于非简单修复,请先创建一个问题,然后再提交拉取请求。对于简单修复,可以直接提交拉取请求。


以下是一个完整的示例代码,展示如何使用 three_js_line 插件来绘制三维线条:

import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'package:three_js/three_js.dart' as three;
import 'package:three_js_line/three_js_line.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late three.ThreeJS threeJs;

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          threeJs.build(),
        ],
      ),
    );
  }

  late three.OrbitControls controls;

  Future<void> setup() async {
    threeJs.scene = three.Scene();

    threeJs.camera = three.PerspectiveCamera(40, threeJs.width / threeJs.height, 1, 1000);
    threeJs.camera.position.setValues(-40, 0, 60);

    controls = three.OrbitControls(threeJs.camera, threeJs.globalKey);
    controls.minDistance = 10;
    controls.maxDistance = 500;

    final matLine = LineMaterial.fromMap({
      'linewidth': 5, // 在世界单位中(大小衰减),像素单位否则
      'vertexColors': true,
    });

    final matThresholdLine = LineMaterial.fromMap({
      'linewidth': matLine.linewidth, // 在世界单位中(大小衰减),像素单位否则
      // vertexColors: true,
      'transparent': true,
      'opacity': 0.2,
      'depthTest': false,
      'visible': false,
    });

    final List<double> positions = [];
    final List<double> colors = [];
    final List<three.Vector3> points = [];

    for (int i = -50; i < 50; i++) {
      final t = i / 3;
      points.add(three.Vector3(t * math.sin(2 * t), t, t * math.cos(2 * t)));
    }

    final spline = three.CatmullRomCurve3(points: points);
    final divisions = (3 * points.length).round();
    final point = three.Vector3();
    final color = three.Color();

    for (int i = 0, l = divisions; i < l; i++) {
      final t = i / l;

      spline.getPoint(t, point);
      positions.addAll([point.x, point.y, point.z]);

      color.setHSL(t, 1.0, 0.5, three.ColorSpace.srgb);
      colors.addAll([color.red, color.green, color.blue]);
    }

    final lineGeometry = LineGeometry();
    lineGeometry.setPositions(three.Float32Array.fromList(positions));
    lineGeometry.setColors(three.Float32Array.fromList(colors));

    final segmentsGeometry = LineSegmentsGeometry();
    segmentsGeometry.setPositions(three.Float32Array.fromList(positions));
    segmentsGeometry.setColors(three.Float32Array.fromList(colors));

    final segments = LineSegments2(segmentsGeometry, matLine);
    segments.computeLineDistances();
    segments.scale.setValues(1, 1, 1);
    threeJs.scene.add(segments);
    segments.visible = false;

    final thresholdSegments = LineSegments2(segmentsGeometry, matThresholdLine);
    thresholdSegments.computeLineDistances();
    thresholdSegments.scale.setValues(1, 1, 1);
    threeJs.scene.add(thresholdSegments);
    thresholdSegments.visible = false;

    final line = Line2(lineGeometry, matLine);
    line.computeLineDistances();
    line.scale.setValues(1, 1, 1);
    threeJs.scene.add(line);

    final thresholdLine = Line2(lineGeometry, matThresholdLine);
    thresholdLine.computeLineDistances();
    thresholdLine.scale.setValues(1, 1, 1);
    threeJs.scene.add(thresholdLine);

    final geo = three.BufferGeometry();
    geo.setAttributeFromString('position', three.Float32BufferAttribute.fromList(positions, 3));
    geo.setAttributeFromString('color', three.Float32BufferAttribute.fromList(colors, 3));

    threeJs.addAnimationEvent((dt) {
      thresholdLine.position.setFrom(line.position);
      thresholdLine.quaternion.setFrom(line.quaternion);
      thresholdSegments.position.setFrom(segments.position);
      thresholdSegments.quaternion.setFrom(segments.quaternion);
    });
  }
}

更多关于Flutter三维绘图插件three_js_line的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter三维绘图插件three_js_line的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中使用three_js_line插件进行三维绘图,首先需要了解该插件的基本用法和配置。three_js_line插件是一个用于在Flutter中集成Three.js的库,允许你在Flutter应用中渲染3D图形。

1. 安装依赖

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

dependencies:
  flutter:
    sdk: flutter
  three_js_line: ^0.0.1 # 请使用最新版本

然后运行flutter pub get来安装依赖。

2. 基本用法

下面是一个简单的示例,展示如何使用three_js_line在Flutter中渲染一个简单的3D线条。

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

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Three.js Line Example'),
        ),
        body: ThreeJsLineExample(),
      ),
    );
  }
}

class ThreeJsLineExample extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return ThreeJsLine(
      onSceneCreated: (ThreeJsLineController controller) {
        // 创建场景、相机和渲染器
        controller.createScene();
        controller.createCamera();
        controller.createRenderer();

        // 创建线条
        final points = [
          Vector3(0, 0, 0),
          Vector3(1, 1, 0),
          Vector3(2, 0, 0),
        ];
        controller.createLine(points, Colors.blue);

        // 渲染场景
        controller.render();
      },
    );
  }
}
回到顶部