Skip to content

Commit 1302a23

Browse files
committed
feat: implement this device orientation Event on the dart side
1 parent 7789f09 commit 1302a23

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

webf/lib/src/dom/event.dart

+26
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ const String EVENT_STATE_START = 'start';
6969
const String EVENT_STATE_UPDATE = 'update';
7070
const String EVENT_STATE_END = 'end';
7171
const String EVENT_STATE_CANCEL = 'cancel';
72+
const String EVENT_DEVICE_ORIENTATION = 'deviceorientation';
7273

7374
mixin ElementEventMixin on ElementBase {
7475
AppearEventType _prevAppearState = AppearEventType.none;
@@ -418,6 +419,31 @@ class DeviceOrientationEvent extends Event {
418419
}
419420
}
420421

422+
class DeviceOrientationEvent extends Event {
423+
DeviceOrientationEvent(this.alpha, this.beta, this.gamma) : super(EVENT_DEVICE_ORIENTATION);
424+
425+
final bool absolute = true;
426+
final double alpha;
427+
final double beta;
428+
final double gamma;
429+
430+
@override
431+
Pointer<NativeType> toRaw([int extraLength = 0, bool isCustomEvent = false]) {
432+
List<int> methods = [
433+
doubleToUint64(alpha),
434+
doubleToUint64(beta),
435+
doubleToUint64(gamma)
436+
];
437+
Pointer<RawEvent> rawEvent = super.toRaw(methods.length).cast<RawEvent>();
438+
int currentStructSize = rawEvent.ref.length + methods.length;
439+
Uint64List bytes = rawEvent.ref.bytes.asTypedList(currentStructSize);
440+
bytes.setAll(rawEvent.ref.length, methods);
441+
rawEvent.ref.length = currentStructSize;
442+
443+
return rawEvent;
444+
}
445+
}
446+
421447
/// reference: https://developer.mozilla.org/en-US/docs/Web/API/GestureEvent
422448
class GestureEvent extends Event {
423449
final String state;

webf/lib/src/dom/window.dart

+48
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
* Copyright (C) 2019-2022 The Kraken authors. All rights reserved.
33
* Copyright (C) 2022-present The WebF authors. All rights reserved.
44
*/
5+
import 'dart:math' as math;
6+
import 'dart:async';
57
import 'dart:ui';
68

9+
import 'package:sensors_plus/sensors_plus.dart';
710
import 'package:webf/bridge.dart';
811
import 'package:webf/dom.dart';
912
import 'package:webf/foundation.dart';
@@ -117,6 +120,9 @@ class Window extends EventTarget {
117120
// Fired at the Document or element when the viewport or element is scrolled, respectively.
118121
document.documentElement?.addEventListener(eventType, handler, addEventListenerOptions: addEventListenerOptions);
119122
break;
123+
case EVENT_DEVICE_ORIENTATION:
124+
_registerGyroscope();
125+
break;
120126
}
121127
}
122128

@@ -127,6 +133,9 @@ class Window extends EventTarget {
127133
case EVENT_SCROLL:
128134
document.documentElement?.removeEventListener(eventType, handler);
129135
break;
136+
case EVENT_DEVICE_ORIENTATION:
137+
_unRegisterGyroscope(false);
138+
break;
130139
}
131140
}
132141

@@ -135,4 +144,43 @@ class Window extends EventTarget {
135144
void focus() {
136145
// TODO
137146
}
147+
148+
StreamSubscription<GyroscopeEvent>? _gyroscopeStream;
149+
void _registerGyroscope() {
150+
_gyroscopeStream ??= gyroscopeEventStream().listen((GyroscopeEvent event) {
151+
dispatchDeviceOrientationEvent(event.x, event.y, event.z);
152+
},
153+
cancelOnError: true,
154+
);
155+
}
156+
157+
void _unRegisterGyroscope(bool dispose) {
158+
if (dispose || !hasEventListener(EVENT_DEVICE_ORIENTATION)) {
159+
_gyroscopeStream?.cancel();
160+
_gyroscopeStream = null;
161+
}
162+
}
163+
164+
/// Convert gyroscope data obtained in Flutter into rotation angle in the Web
165+
/// In the w3c standard:
166+
/// alpha: A number representing the motion of the device around the z axis, express in degrees with values ranging from 0 (inclusive) to 360 (exclusive).
167+
/// beta: A number representing the motion of the device around the x axis, expressed in degrees with values ranging from -180 (inclusive) to 180 (exclusive).
168+
/// gamma: A number representing the motion of the device around the y axis, expressed in degrees with values ranging from -90 (inclusive) to 90 (exclusive).
169+
void dispatchDeviceOrientationEvent(x, y, z) {
170+
var xAxisAngle= math.atan2(y, z) * (180 / math.pi); // Angle of rotation around the X-axis
171+
var yAxisAngle = math.atan2(-x, math.sqrt(y * y + z * z)) * (180 / math.pi); // Rotation angle around Y axis
172+
var zAxisAngle = math.atan2(y, z) * (180 / math.pi); // Rotation angle around Z axis
173+
var alpha = zAxisAngle + 180;
174+
var beta = xAxisAngle;
175+
var gamma = yAxisAngle;
176+
if (hasEventListener(EVENT_DEVICE_ORIENTATION)) {
177+
dispatchEvent(DeviceOrientationEvent(alpha, beta, gamma));
178+
}
179+
}
180+
181+
@override
182+
void dispose() async {
183+
_unRegisterGyroscope(true);
184+
super.dispose();
185+
}
138186
}

webf/pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ dependencies:
2525
shared_preferences: 2.2.0 # No AndroidX used.
2626
archive: ^3.3.7 # Pure dart module.
2727
web_socket_channel: ^2.2.0
28+
sensors_plus: ^4.0.2
2829

2930
dev_dependencies:
3031
flutter_test:

0 commit comments

Comments
 (0)