feat!: (web) (flutter) create canvas when createViewer is called (no longer need to manually add canvas element to web HTML)
This commit is contained in:
@@ -85,7 +85,6 @@ abstract class ThermionViewer {
|
|||||||
///
|
///
|
||||||
Future render();
|
Future render();
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Render a single frame to the viewport and copy the pixel buffer to [out].
|
/// Render a single frame to the viewport and copy the pixel buffer to [out].
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -9,10 +9,8 @@ import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dar
|
|||||||
/// surface in a Flutter application and lifecycle listeners to pause rendering
|
/// surface in a Flutter application and lifecycle listeners to pause rendering
|
||||||
/// when the app is inactive or in the background.
|
/// when the app is inactive or in the background.
|
||||||
/// Call [createViewer] to create an instance of [ThermionViewer].
|
/// Call [createViewer] to create an instance of [ThermionViewer].
|
||||||
/// This is a lightweight singleton that
|
|
||||||
///
|
///
|
||||||
class ThermionFlutterPlugin {
|
class ThermionFlutterPlugin {
|
||||||
|
|
||||||
ThermionFlutterPlugin._();
|
ThermionFlutterPlugin._();
|
||||||
|
|
||||||
static AppLifecycleListener? _appLifecycleListener;
|
static AppLifecycleListener? _appLifecycleListener;
|
||||||
@@ -92,8 +90,12 @@ class ThermionFlutterPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
static Future<ThermionFlutterTexture?> resizeTexture(ThermionFlutterTexture texture,
|
static Future<ThermionFlutterTexture?> resizeTexture(
|
||||||
int width, int height, int offsetLeft, int offsetRight) async {
|
ThermionFlutterTexture texture,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offsetLeft,
|
||||||
|
int offsetRight) async {
|
||||||
return ThermionFlutterPlatform.instance
|
return ThermionFlutterPlatform.instance
|
||||||
.resizeTexture(texture, width, height, offsetLeft, offsetRight);
|
.resizeTexture(texture, width, height, offsetLeft, offsetRight);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:thermion_flutter/thermion/widgets/thermion_widget_web.dart';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';
|
import 'package:thermion_flutter_platform_interface/thermion_flutter_texture.dart';
|
||||||
@@ -82,17 +83,27 @@ class _ThermionWidgetState extends State<ThermionWidget> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
if (kIsWeb) {
|
||||||
|
if (_texture == null || _resizing) {
|
||||||
|
return widget.initial ?? Container(color: Colors.red);
|
||||||
|
}
|
||||||
|
return ResizeObserver(
|
||||||
|
onResized: _resizeTexture, child: ThermionWidgetWeb());
|
||||||
|
}
|
||||||
|
|
||||||
if (_texture?.usesBackingWindow == true) {
|
if (_texture?.usesBackingWindow == true) {
|
||||||
return ResizeObserver(
|
return ResizeObserver(
|
||||||
onResized: _resizeTexture,
|
onResized: _resizeTexture,
|
||||||
child: Stack(children: [
|
child: Stack(children: [
|
||||||
Positioned.fill(child: CustomPaint(painter: TransparencyPainter()))
|
Positioned.fill(child: CustomPaint(painter: TransparencyPainter()))
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_texture == null || _resizing) {
|
if (_texture == null || _resizing) {
|
||||||
return widget.initial ??
|
return widget.initial ??
|
||||||
Container(color: kIsWeb ? Colors.transparent : Colors.red);
|
Container(
|
||||||
|
color:
|
||||||
|
kIsWeb ? const Color.fromARGB(0, 170, 129, 129) : Colors.red);
|
||||||
}
|
}
|
||||||
|
|
||||||
var textureWidget = Texture(
|
var textureWidget = Texture(
|
||||||
@@ -131,3 +142,4 @@ class TransparencyPainter extends CustomPainter {
|
|||||||
@override
|
@override
|
||||||
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export 'thermion_widget_web_stub.dart'
|
||||||
|
if (dart.library.js_interop) 'thermion_widget_web_impl.dart';
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import 'dart:js_util';
|
||||||
|
import 'dart:js_interop';
|
||||||
|
import 'dart:js_interop_unsafe';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
import 'dart:ui_web' as ui_web;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:web/web.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'dart:html' as html;
|
||||||
|
|
||||||
|
class ThermionWidgetWeb extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => ThermionWidgetWebState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThermionWidgetWebState extends State<ThermionWidgetWeb> {
|
||||||
|
ui.Image? _img;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
capture();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future capture() async {
|
||||||
|
try {
|
||||||
|
final ImageBitmap newSource = await promiseToFuture<ImageBitmap>(
|
||||||
|
window.createImageBitmap(
|
||||||
|
document.getElementById("canvas") as HTMLCanvasElement));
|
||||||
|
_img = await ui_web.createImageFromImageBitmap(newSource);
|
||||||
|
setState(() {});
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
capture();
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
print(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (_img == null) {
|
||||||
|
return Container(color: Colors.transparent);
|
||||||
|
}
|
||||||
|
return RawImage(image: _img!);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
class ThermionWidgetWeb extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => throw Exception();
|
||||||
|
}
|
||||||
@@ -17,6 +17,14 @@ class ThermionFlutterWebPlugin extends ThermionFlutterPlatform {
|
|||||||
@override
|
@override
|
||||||
Future<ThermionFlutterTexture?> createTexture(
|
Future<ThermionFlutterTexture?> createTexture(
|
||||||
int width, int height, int offsetLeft, int offsetRight) async {
|
int width, int height, int offsetLeft, int offsetRight) async {
|
||||||
|
await _viewer!.destroySwapChain();
|
||||||
|
await _viewer!.createSwapChain(width, height);
|
||||||
|
_viewer!.updateViewportAndCameraProjection(width, height, 1.0);
|
||||||
|
|
||||||
|
final canvas = document.getElementById("canvas") as HTMLCanvasElement;
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
|
||||||
return ThermionFlutterTexture(null, null, 0, 0, null);
|
return ThermionFlutterTexture(null, null, 0, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,15 +47,12 @@ class ThermionFlutterWebPlugin extends ThermionFlutterPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<ThermionViewer> createViewer({String? uberArchivePath}) async {
|
Future<ThermionViewer> createViewer({String? uberArchivePath}) async {
|
||||||
final canvas = document.getElementById("canvas") as HTMLCanvasElement;
|
|
||||||
canvas.width = window.innerWidth;
|
|
||||||
canvas.height = window.innerHeight;
|
|
||||||
|
|
||||||
var width = window.innerWidth;
|
|
||||||
var height = window.innerHeight;
|
|
||||||
|
|
||||||
_viewer = ThermionViewerWasm(assetPathPrefix: "/assets/");
|
_viewer = ThermionViewerWasm(assetPathPrefix: "/assets/");
|
||||||
await _viewer!.initialize(width, height, uberArchivePath: uberArchivePath);
|
final canvas = document.createElement("canvas") as HTMLCanvasElement;
|
||||||
|
canvas.id = "canvas";
|
||||||
|
document.body!.appendChild(canvas);
|
||||||
|
canvas.style.display = 'none';
|
||||||
|
await _viewer!.initialize(0, 0, uberArchivePath:uberArchivePath);
|
||||||
return _viewer!;
|
return _viewer!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user