UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

161 lines (137 loc) 3.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useAnimatedSensor = useAnimatedSensor; var _react = require("react"); var _core = require("../core"); var _commonTypes = require("../commonTypes"); var _threads = require("../threads"); function initSensorData(sensorType) { if (sensorType === _commonTypes.SensorType.ROTATION) { return (0, _core.makeMutable)({ qw: 0, qx: 0, qy: 0, qz: 0, yaw: 0, pitch: 0, roll: 0, interfaceOrientation: 0 }); } else { return (0, _core.makeMutable)({ x: 0, y: 0, z: 0, interfaceOrientation: 0 }); } } // euler angles are in order ZXY, z = yaw, x = pitch, y = roll // https://github.com/mrdoob/three.js/blob/dev/src/math/Quaternion.js#L237 function eulerToQuaternion(pitch, roll, yaw) { 'worklet'; const c1 = Math.cos(pitch / 2); const s1 = Math.sin(pitch / 2); const c2 = Math.cos(roll / 2); const s2 = Math.sin(roll / 2); const c3 = Math.cos(yaw / 2); const s3 = Math.sin(yaw / 2); return [s1 * c2 * c3 - c1 * s2 * s3, c1 * s2 * c3 + s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3, c1 * c2 * c3 - s1 * s2 * s3]; } function adjustRotationToInterfaceOrientation(data) { 'worklet'; const { interfaceOrientation, pitch, roll, yaw } = data; if (interfaceOrientation === 90) { data.pitch = roll; data.roll = -pitch; data.yaw = yaw - Math.PI / 2; } else if (interfaceOrientation === 270) { data.pitch = -roll; data.roll = pitch; data.yaw = yaw + Math.PI / 2; } else if (interfaceOrientation === 180) { data.pitch *= -1; data.roll *= -1; data.yaw *= -1; } const q = eulerToQuaternion(data.pitch, data.roll, data.yaw); data.qx = q[0]; data.qy = q[1]; data.qz = q[2]; data.qw = q[3]; return data; } function adjustVectorToInterfaceOrientation(data) { 'worklet'; const { interfaceOrientation, x, y } = data; if (interfaceOrientation === 90) { data.x = -y; data.y = x; } else if (interfaceOrientation === 270) { data.x = y; data.y = -x; } else if (interfaceOrientation === 180) { data.x *= -1; data.y *= -1; } return data; } function useAnimatedSensor(sensorType, userConfig) { const ref = (0, _react.useRef)({ sensor: initSensorData(sensorType), unregister: () => {// NOOP }, isAvailable: false, config: { interval: 0, adjustToInterfaceOrientation: true, iosReferenceFrame: _commonTypes.IOSReferenceFrame.Auto } }); (0, _react.useEffect)(() => { ref.current.config = { interval: 'auto', adjustToInterfaceOrientation: true, iosReferenceFrame: _commonTypes.IOSReferenceFrame.Auto, ...userConfig }; const sensorData = ref.current.sensor; const id = (0, _core.registerSensor)(sensorType, ref.current.config.interval === 'auto' ? -1 : ref.current.config.interval, ref.current.config.iosReferenceFrame, data => { 'worklet'; if (ref.current.config.adjustToInterfaceOrientation) { if (sensorType === _commonTypes.SensorType.ROTATION) { data = adjustRotationToInterfaceOrientation(data); } else { data = adjustVectorToInterfaceOrientation(data); } } sensorData.value = data; (0, _threads.flushImmediates)(); }); if (id !== -1) { // if sensor is available ref.current.unregister = () => (0, _core.unregisterSensor)(id); ref.current.isAvailable = true; } else { // if sensor is unavailable ref.current.unregister = () => {// NOOP }; ref.current.isAvailable = false; } return () => { ref.current.unregister(); }; }, [sensorType, userConfig]); return ref.current; } //# sourceMappingURL=useAnimatedSensor.js.map