Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3d model working on flutter web #80

Merged
merged 4 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 16 additions & 20 deletions open_earable/lib/sensor_data_tab/earable_3d_model.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import 'package:flutter/material.dart';
import 'package:open_earable/sensor_data_tab/earable_3d_view.dart' if (dart.library.html) 'package:open_earable/sensor_data_tab/earable_3d_view_web.dart';
import 'dart:async';
import 'dart:math';
import 'package:open_earable_flutter/open_earable_flutter.dart';
import 'package:model_viewer_plus/model_viewer_plus.dart';
import 'package:webview_flutter/webview_flutter.dart';

class Earable3DModel extends StatefulWidget {
final OpenEarable openEarable;
Expand All @@ -14,15 +13,17 @@ class Earable3DModel extends StatefulWidget {
}

class _Earable3DModelState extends State<Earable3DModel> {
WebViewController? _controller;
StreamSubscription? _imuSubscription;
double _pitch = 0;
double _yaw = 0;
double _roll = 0;

final String fileName = "assets/OpenEarable.obj";
final GlobalKey<ModelViewerWidgetState> _modelViewerKey = GlobalKey();

final String fileName = 'assets/OpenEarableV1.glb';

dynamic sourceTexture;

@override
void initState() {
super.initState();
Expand Down Expand Up @@ -62,29 +63,24 @@ class _Earable3DModelState extends State<Earable3DModel> {
_pitch = data["EULER"]["PITCH"];
_roll = data["EULER"]["ROLL"];
});
_controller?.runJavaScript(
"document.querySelector('model-viewer').setAttribute('orientation', '${-_pitch} $_roll ${-_yaw}');",);
if (_modelViewerKey.currentState == null) {
print("ModelViewerKey.currentState is null");
return;
}
_modelViewerKey.currentState?.updateOrientation(_pitch, _yaw, _roll);
});
}

@override
Widget build(BuildContext context) {
return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
child: ModelViewer(
cameraControls: false,
backgroundColor: Theme.of(context).colorScheme.surface,
src: 'assets/OpenEarableV1.glb',
alt: 'A 3D model of an astronaut',
interactionPrompt: InteractionPrompt.none,
autoRotate: false,
disableZoom: true,
disablePan: true,
onWebViewCreated: (controller) {
_controller = controller;
controller.runJavaScript(
"document.body.style.overflow = 'hidden';document.documentElement.style.overflow = 'hidden';document.addEventListener('touchmove', function(e) { e.preventDefault(); }, { passive: false });",);
},),),
child: ModelViewerWidget(
key: _modelViewerKey,
modelSrc: fileName,
backgroundColor: Theme.of(context).colorScheme.surface,
),
),
Padding(
padding: EdgeInsets.only(bottom: 16),
child: Text(
Expand Down
58 changes: 58 additions & 0 deletions open_earable/lib/sensor_data_tab/earable_3d_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:model_viewer_plus/model_viewer_plus.dart';
import 'package:webview_flutter/webview_flutter.dart';

class ModelViewerWidget extends StatefulWidget {
final String modelSrc;
final Color backgroundColor;
final bool cameraControls;
final bool autoRotate;
final bool disableZoom;
final bool disablePan;

const ModelViewerWidget({
required this.modelSrc,
required this.backgroundColor,
this.cameraControls = false,
this.autoRotate = false,
this.disableZoom = true,
this.disablePan = true,
super.key,
});

@override
State<ModelViewerWidget> createState() => ModelViewerWidgetState();
}

class ModelViewerWidgetState extends State<ModelViewerWidget> {
WebViewController? _controller;

void updateOrientation(double pitch, double yaw, double roll) {
if (_controller != null) {
final jsCommand = "document.querySelector('model-viewer').setAttribute('orientation', '${-pitch} $roll ${-yaw}');";
_controller?.runJavaScript(jsCommand);
} else {
print("WebViewController is not initialized yet.");
}
}

@override
Widget build(BuildContext context) {
return ModelViewer(
cameraControls: widget.cameraControls,
backgroundColor: widget.backgroundColor,
src: widget.modelSrc,
alt: 'A 3D model of the OpenEarable',
interactionPrompt: InteractionPrompt.none,
autoRotate: widget.autoRotate,
disableZoom: widget.disableZoom,
disablePan: widget.disablePan,
onWebViewCreated: (controller) {
_controller = controller;
controller.runJavaScript(
"document.body.style.overflow = 'hidden';document.documentElement.style.overflow = 'hidden';document.addEventListener('touchmove', function(e) { e.preventDefault(); }, { passive: false });",
);
},
);
}
}
75 changes: 75 additions & 0 deletions open_earable/lib/sensor_data_tab/earable_3d_view_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import 'dart:ui_web';

import 'package:universal_html/html.dart' as html;
import 'package:flutter/material.dart';

class ModelViewerWidget extends StatefulWidget {
final String modelSrc;
final Color backgroundColor;
final bool cameraControls;
final bool autoRotate;
final bool disableZoom;
final bool disablePan;

const ModelViewerWidget({
required this.modelSrc,
required this.backgroundColor,
this.cameraControls = false,
this.autoRotate = false,
this.disableZoom = true,
this.disablePan = true,
super.key,
});

@override
State<ModelViewerWidget> createState() => ModelViewerWidgetState();
}

class ModelViewerWidgetState extends State<ModelViewerWidget> {
final String _viewType = 'model-viewer';

@override
void initState() {
super.initState();

platformViewRegistry.registerViewFactory(
_viewType,
(int viewId) {
final element = html.Element.tag('model-viewer')
..setAttribute('src', widget.modelSrc)
..setAttribute('alt', 'A 3D model of the OpenEarable')
..style.width = '100%'
..style.height = '100%';

if (widget.cameraControls) {
element.setAttribute('camera-controls', '');
}
if (widget.autoRotate) {
element.setAttribute('auto-rotate', '');
}
if (widget.disableZoom) {
element.setAttribute('disable-zoom', '');
}
if (widget.disablePan) {
element.setAttribute('disable-pan', '');
}

return element;
},
);
}

void updateOrientation(double pitch, double yaw, double roll) {
// Find the registered element and update its orientation
print("Updating orientation: $pitch, $yaw, $roll");
final element = html.document.querySelector(_viewType);
if (element != null) {
element.setAttribute('orientation', '${-pitch} $roll ${-yaw}');
}
}

@override
Widget build(BuildContext context) {
return HtmlElementView(viewType: _viewType);
}
}
8 changes: 2 additions & 6 deletions open_earable/lib/sensor_data_tab/sensor_html_chart.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import 'dart:convert';
// ignore: avoid_web_libraries_in_flutter
import 'dart:js' as js;
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import 'package:universal_html/html.dart' as html;
import 'package:universal_html/js.dart' as js;
import 'dart:ui_web';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:open_earable/sensor_data_tab/sensor_chart.dart';
// Conditional imports
// For web-specific code

class ChartSeries {
final String id;
Expand Down
5 changes: 3 additions & 2 deletions open_earable/lib/sensor_data_tab/sensor_html_chart_stub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ class ChartSeries {
});
}


class ChartJsWidget extends StatelessWidget {
final String chartType;
final List<ChartSeries> seriesList;

final String title;

const ChartJsWidget({
super.key,
const ChartJsWidget({super.key,
required this.chartType,
required this.seriesList,
required this.title,
Expand Down
32 changes: 26 additions & 6 deletions open_earable/macos/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
PODS:
- flutter_inappwebview_macos (0.0.1):
- FlutterMacOS
- OrderedSet (~> 5.0)
- OrderedSet (~> 6.0.3)
- FlutterMacOS (1.0.0)
- OrderedSet (5.0.0)
- open_file_mac (0.0.1):
- FlutterMacOS
- OrderedSet (6.0.3)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- universal_ble (0.0.1):
- Flutter
- FlutterMacOS
- url_launcher_macos (0.0.1):
- FlutterMacOS
- webview_flutter_wkwebview (0.0.1):
- Flutter
- FlutterMacOS

DEPENDENCIES:
- flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`)
- FlutterMacOS (from `Flutter/ephemeral`)
- open_file_mac (from `Flutter/ephemeral/.symlinks/plugins/open_file_mac/macos`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- universal_ble (from `Flutter/ephemeral/.symlinks/plugins/universal_ble/darwin`)
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
- webview_flutter_wkwebview (from `Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin`)

SPEC REPOS:
trunk:
Expand All @@ -29,21 +40,30 @@ EXTERNAL SOURCES:
:path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos
FlutterMacOS:
:path: Flutter/ephemeral
open_file_mac:
:path: Flutter/ephemeral/.symlinks/plugins/open_file_mac/macos
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
universal_ble:
:path: Flutter/ephemeral/.symlinks/plugins/universal_ble/darwin
url_launcher_macos:
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
webview_flutter_wkwebview:
:path: Flutter/ephemeral/.symlinks/plugins/webview_flutter_wkwebview/darwin

SPEC CHECKSUMS:
flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d
flutter_inappwebview_macos: bdf207b8f4ebd58e86ae06cd96b147de99a67c9b
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
open_file_mac: 0e554648e2a87ce59e9438e3e5ca3e552e90d89a
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
url_launcher_macos: 5f437abeda8c85500ceb03f5c1938a8c5a705399
universal_ble: cf52a7b3fd2e7c14d6d7262e9fdadb72ab6b88a6
url_launcher_macos: c82c93949963e55b228a30115bd219499a6fe404
webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4

PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367

COCOAPODS: 1.15.2
COCOAPODS: 1.16.2
16 changes: 16 additions & 0 deletions open_earable/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
charcode:
dependency: transitive
description:
name: charcode
sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306
url: "https://pub.dev"
source: hosted
version: "1.3.1"
checked_yaml:
dependency: transitive
description:
Expand Down Expand Up @@ -787,6 +795,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.12.0"
universal_html:
dependency: "direct main"
description:
name: universal_html
sha256: "56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971"
url: "https://pub.dev"
source: hosted
version: "2.2.4"
universal_io:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions open_earable/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ dependencies:
collection: ^1.18.0
webview_flutter: ^4.9.0
intl: ^0.18.1
universal_html: ^2.2.4

dependency_overrides:
intl: ^0.18.1
Expand Down
3 changes: 2 additions & 1 deletion open_earable/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<meta name="description" content="A new Flutter project.">

<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="open_earable">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
Expand All @@ -40,6 +40,7 @@
<link rel="stylesheet" type="text/css" href="splash/style.css">
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
<script src="splash/splash.js"></script>
<script type="module" src="./assets/packages/model_viewer_plus/assets/model-viewer.min.js" defer></script>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
Expand Down