rawEvents method
Raw sensor events. The sensor runs only while the stream is listened to.
Implementation
@override
Stream<Map<String, Object?>> rawEvents(RawSensorConfig config) {
late StreamController<Map<String, Object?>> controller;
JSFunction? absoluteListener;
JSFunction? plainListener;
double? number(JSObject event, String name) {
final value = event[name];
if (value.isUndefinedOrNull) return null;
final n = (value as JSNumber).toDartDouble;
return n.isFinite ? n : null;
}
void onEvent(web.Event raw, {required bool absoluteEvent}) {
final event = raw as JSObject;
final rotation = _screenRotation();
final webkit = number(event, 'webkitCompassHeading');
if (webkit != null) {
controller.add({
'kind': 'heading',
'heading': webkit,
'compensated': false,
'screenRotation': rotation,
// iOS Safari: webkitCompassAccuracy is degrees, negative = invalid.
'errorDegrees': number(event, 'webkitCompassAccuracy'),
});
return;
}
final alpha = number(event, 'alpha');
final beta = number(event, 'beta');
final gamma = number(event, 'gamma');
if (alpha == null || beta == null || gamma == null) return;
final flag = event['absolute'];
final absolute = absoluteEvent ||
(!flag.isUndefinedOrNull && (flag as JSBoolean).toDart);
controller.add({
'kind': 'euler',
'alpha': alpha,
'beta': beta,
'gamma': gamma,
'absolute': absolute,
'screenRotation': rotation,
});
}
controller = StreamController<Map<String, Object?>>(
onListen: () {
absoluteListener =
((web.Event e) => onEvent(e, absoluteEvent: true)).toJS;
plainListener =
((web.Event e) => onEvent(e, absoluteEvent: false)).toJS;
web.window
.addEventListener('deviceorientationabsolute', absoluteListener);
web.window.addEventListener('deviceorientation', plainListener);
},
onCancel: () {
if (absoluteListener != null) {
web.window.removeEventListener(
'deviceorientationabsolute', absoluteListener);
}
if (plainListener != null) {
web.window.removeEventListener('deviceorientation', plainListener);
}
},
);
return controller.stream;
}