Skip to content

feat: Add 3D model screenshot capture functionalityDev add animation #70

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
21 changes: 17 additions & 4 deletions lib/src/controllers/flutter_3d_controller.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_3d_controller/src/controllers/i_flutter_3d_controller.dart';
import 'package:flutter_3d_controller/src/data/repositories/i_flutter_3d_repository.dart';
import 'package:flutter_3d_controller/src/core/exception/flutter_3d_controller_exception.dart';
import 'package:flutter_3d_controller/src/data/repositories/i_flutter_3d_repository.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

class Flutter3DController extends IFlutter3DController {
IFlutter3DRepository? _repository;
InAppWebViewController? _webViewController;

Flutter3DController();

ValueNotifier<bool> onModelLoaded = ValueNotifier<bool>(false);

void init(IFlutter3DRepository repository) {
void init(IFlutter3DRepository repository, InAppWebViewController? webViewController) {
_repository = repository;
_webViewController = webViewController;
}

@override
Expand Down Expand Up @@ -99,9 +102,9 @@ class Flutter3DController extends IFlutter3DController {
}

@override
void setCameraOrbit(double theta, double phi, double radius) {
void setCameraOrbit(double theta, double phi, double radius, {bool isAnimate = true}) {
if (onModelLoaded.value) {
_repository?.setCameraOrbit(theta, phi, radius);
_repository?.setCameraOrbit(theta, phi, radius, isAnimate);
} else {
throw Flutter3dControllerLoadingException();
}
Expand All @@ -115,4 +118,14 @@ class Flutter3DController extends IFlutter3DController {
throw Flutter3dControllerLoadingException();
}
}

@override
Future<Uint8List?> takeScreenshot() async {
try {
final screenshot = await _webViewController?.takeScreenshot();
return screenshot;
} catch (e) {
return null;
}
}
}
5 changes: 5 additions & 0 deletions lib/src/controllers/i_flutter_3d_controller.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:typed_data';

abstract class IFlutter3DController {
/// Causes animations to be played, Can be use to switch animations as well.
/// If animationName is null and model has at list one animation, it will play first model's animation
Expand Down Expand Up @@ -41,4 +43,7 @@ abstract class IFlutter3DController {

/// Causes camera target reset to default value
void resetCameraOrbit();

/// It will take screenshot of 3D model as [Uint8List]
Future<Uint8List?> takeScreenshot();
}
27 changes: 19 additions & 8 deletions lib/src/data/datasources/flutter_3d_datasource_mobile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,25 @@ class Flutter3DDatasource implements IFlutter3DDatasource {
}

@override
void setCameraOrbit(double theta, double phi, double radius) {
executeCustomJsCode(
"const modelViewer = document.getElementById(\"$_viewerId\");"
"modelViewer.cameraOrbit = \"${theta}deg ${phi}deg $radius%\";",
100,
400,
_activeGestureInterceptor,
);
void setCameraOrbit(double theta, double phi, double radius, bool isAnimate) {
if (isAnimate) {
executeCustomJsCode(
"const modelViewer = document.getElementById(\"$_viewerId\");"
"modelViewer.cameraOrbit = \"${theta}deg ${phi}deg $radius%\";",
100,
400,
_activeGestureInterceptor,
);
} else {
executeCustomJsCode(
"const modelViewer = document.getElementById(\"$_viewerId\");"
"modelViewer.cameraOrbit = \"${theta}deg ${phi}deg $radius%\";"
"modelViewer.jumpCameraToGoal();",
100,
400,
_activeGestureInterceptor,
);
}
}

@override
Expand Down
18 changes: 13 additions & 5 deletions lib/src/data/datasources/flutter_3d_datasource_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,19 @@ class Flutter3DDatasource implements IFlutter3DDatasource {
}

@override
void setCameraOrbit(double theta, double phi, double radius) {
executeCustomJsCode(
"const modelViewer = document.getElementById(\"$_viewerId\");"
"modelViewer.cameraOrbit = \"${theta}deg ${phi}deg $radius%\";",
);
void setCameraOrbit(double theta, double phi, double radius, bool isAnimate) {
if (isAnimate) {
executeCustomJsCode(
"const modelViewer = document.getElementById(\"$_viewerId\");"
"modelViewer.cameraOrbit = \"${theta}deg ${phi}deg $radius%\";",
);
} else {
executeCustomJsCode(
"const modelViewer = document.getElementById(\"$_viewerId\");"
"modelViewer.cameraOrbit = \"${theta}deg ${phi}deg $radius%\";"
"modelViewer.jumpCameraToGoal();",
);
}
}

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/src/data/datasources/i_flutter_3d_datasource.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ abstract class IFlutter3DDatasource {
void resetCameraTarget();

/// It will change camera orbit
void setCameraOrbit(double theta, double phi, double radius);
void setCameraOrbit(double theta, double phi, double radius, bool isAnimate);

/// Causes camera target reset to default value
void resetCameraOrbit();
Expand Down
4 changes: 2 additions & 2 deletions lib/src/data/repositories/flutter_3d_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ class Flutter3DRepository extends IFlutter3DRepository {
}

@override
void setCameraOrbit(double theta, double phi, double radius) {
_datasource.setCameraOrbit(theta, phi, radius);
void setCameraOrbit(double theta, double phi, double radius, bool isAnimate) {
_datasource.setCameraOrbit(theta, phi, radius, isAnimate);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion lib/src/data/repositories/i_flutter_3d_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class IFlutter3DRepository {
void resetCameraTarget();

/// It will change camera orbit
void setCameraOrbit(double theta, double phi, double radius);
void setCameraOrbit(double theta, double phi, double radius, bool isAnimate);

/// Causes camera target reset to default value
void resetCameraOrbit();
Expand Down
4 changes: 2 additions & 2 deletions lib/src/widgets/flutter_3d_viewer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ class _Flutter3DViewerState extends State<Flutter3DViewer> {
_id = _utils.generateId();
_controller = widget.controller ?? Flutter3DController();
if (kIsWeb) {
_controller
.init(Flutter3DRepository(IFlutter3DDatasource(_id, null, false)));
_controller.init(Flutter3DRepository(IFlutter3DDatasource(_id, null, false)), null);
}
super.initState();
}
Expand Down Expand Up @@ -167,6 +166,7 @@ class _Flutter3DViewerState extends State<Flutter3DViewer> {
widget.activeGestureInterceptor,
),
),
value,
);
},
);
Expand Down