react-native-nitro-compass 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -2
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -136,6 +136,7 @@ function CompassView() {
|
|
|
136
136
|
filterDegrees: 1,
|
|
137
137
|
declination: 0,
|
|
138
138
|
pauseOnBackground: true,
|
|
139
|
+
enabled: true,
|
|
139
140
|
})
|
|
140
141
|
|
|
141
142
|
if (!hasCompass) return <Text>No compass on this device.</Text>
|
|
@@ -151,10 +152,62 @@ function CompassView() {
|
|
|
151
152
|
}
|
|
152
153
|
```
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
```ts
|
|
156
|
+
function useCompass(options?: UseCompassOptions): UseCompassResult
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Options
|
|
160
|
+
|
|
161
|
+
| Option | Type | Default | Description |
|
|
162
|
+
| --- | --- | --- | --- |
|
|
163
|
+
| `filterDegrees` | `number` | `1` | Minimum change between successive samples in degrees. Pass `0` for "every event". Updated live via `NitroCompass.setFilter()` whenever the prop changes. |
|
|
164
|
+
| `declination` | `number` | `0` | Magnetic-to-true offset in signed degrees. Pull from a model like [`geomagnetism`](https://github.com/kahirokunn/geomagnetism) keyed on the user's lat/lon. When non-zero, every emitted sample is true-north. |
|
|
165
|
+
| `pauseOnBackground` | `boolean` | `true` | Pause the underlying sensor / location-manager subscription while the app is backgrounded and resume on foreground. |
|
|
166
|
+
| `enabled` | `boolean` | `true` | Toggle the heading subscription without unmounting. When `false`, `reading` stops updating but calibration and interference observation continue (so you can still show warnings). |
|
|
167
|
+
|
|
168
|
+
`filterDegrees`, `declination`, and `pauseOnBackground` map to global state on `NitroCompass` — if multiple hooks set them, last-write-wins.
|
|
169
|
+
|
|
170
|
+
#### Result
|
|
171
|
+
|
|
172
|
+
| Field | Type | Description |
|
|
173
|
+
| --- | --- | --- |
|
|
174
|
+
| `reading` | `CompassSample \| null` | Latest emitted sample (`{ heading, accuracy }`), or `null` until the first arrives. Heading is true-north when `declination` is set, magnetic otherwise. |
|
|
175
|
+
| `quality` | `AccuracyQuality \| null` | Coarse calibration bucket — `'high'`, `'medium'`, `'low'`, or `'unreliable'`. `null` until the first transition. Show your own calibration UI on `'unreliable'`. |
|
|
176
|
+
| `interfering` | `boolean` | `true` while the raw magnetic field magnitude is outside the normal Earth band (~20–70 µT) — laptops, monitors, car engines, steel structures. |
|
|
177
|
+
| `hasCompass` | `boolean` | Hardware availability — read once on first render. Render a fallback when `false`. |
|
|
178
|
+
| `diagnostics` | `SensorDiagnostics \| undefined` | Which sensor backs the readings on this device (`rotationVector`, `geomagneticRotationVector`, or `coreLocation`). Useful for explaining quality differences. |
|
|
155
179
|
|
|
156
180
|
For non-React state managers, lower-level `addHeadingListener(cb): () => void`, `addCalibrationListener(cb): () => void`, and `addInterferenceListener(cb): () => void` are also exported. They are reference-counted: the first heading listener calls `start()`, the last unsubscribe calls `stop()`. Mixing these helpers with direct `NitroCompass.start()` / `setOnCalibrationNeeded()` / `setOnInterferenceDetected()` will clobber the multiplex's internal callback slot — pick one path.
|
|
157
181
|
|
|
182
|
+
### Smooth dial animation (Reanimated)
|
|
183
|
+
|
|
184
|
+
`useCompass()` returns React state, so each sample re-renders the consumer — fine for a numeric readout, but a rotating dial driven that way will jitter on faster filter values. For 60 fps animations, subscribe with `addHeadingListener` and write directly into a Reanimated shared value on the UI thread:
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'
|
|
188
|
+
import { addHeadingListener } from 'react-native-nitro-compass'
|
|
189
|
+
|
|
190
|
+
function Dial() {
|
|
191
|
+
const angle = useSharedValue(0)
|
|
192
|
+
const last = useRef(0)
|
|
193
|
+
|
|
194
|
+
useEffect(() => addHeadingListener(({ heading }) => {
|
|
195
|
+
// unwrap so 359° → 1° animates +2°, not -358°
|
|
196
|
+
const wrapped = ((last.current % 360) + 360) % 360
|
|
197
|
+
let delta = heading - wrapped
|
|
198
|
+
if (delta > 180) delta -= 360
|
|
199
|
+
else if (delta < -180) delta += 360
|
|
200
|
+
last.current += delta
|
|
201
|
+
angle.value = withTiming(last.current, { duration: 80, easing: Easing.out(Easing.quad) })
|
|
202
|
+
}), [angle])
|
|
203
|
+
|
|
204
|
+
const style = useAnimatedStyle(() => ({ transform: [{ rotate: `${-angle.value}deg` }] }))
|
|
205
|
+
return <Animated.View style={[styles.dial, style]}>{/* ticks */}</Animated.View>
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The same pattern is used in [example/components/Compass.tsx](./example/components/Compass.tsx).
|
|
210
|
+
|
|
158
211
|
## Permissions
|
|
159
212
|
|
|
160
213
|
- **iOS**: requires `NSLocationWhenInUseUsageDescription` in `Info.plist`. `CLLocationManager` only emits headings when location permission is granted.
|
|
@@ -162,7 +215,7 @@ For non-React state managers, lower-level `addHeadingListener(cb): () => void`,
|
|
|
162
215
|
|
|
163
216
|
## Example app
|
|
164
217
|
|
|
165
|
-
A bare React Native CLI app under [example/](./example) (RN 0.
|
|
218
|
+
A bare React Native CLI app under [example/](./example) (RN 0.85.3, New Arch enabled) consumes the library via a local symlink. It demos the full surface — `useCompass()` for the readout, calibration / interference banners, and a Reanimated-driven dial that subscribes via `addHeadingListener` so the rotation runs entirely on the UI thread. Use it to test changes on a real device — the iOS Simulator has no compass and the Android emulator's magnetometer is faked.
|
|
166
219
|
|
|
167
220
|
First-time setup:
|
|
168
221
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-compass",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=18"
|
|
6
6
|
},
|
|
@@ -54,14 +54,20 @@
|
|
|
54
54
|
"*.podspec",
|
|
55
55
|
"README.md"
|
|
56
56
|
],
|
|
57
|
-
"repository":
|
|
57
|
+
"repository": {
|
|
58
|
+
"type": "git",
|
|
59
|
+
"url": "git+https://github.com/omarsdev/react-native-nitro-compass.git"
|
|
60
|
+
},
|
|
58
61
|
"author": "Omar Sukarieh",
|
|
59
62
|
"license": "MIT",
|
|
60
|
-
"bugs":
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://github.com/omarsdev/react-native-nitro-compass/issues"
|
|
65
|
+
},
|
|
61
66
|
"homepage": "https://github.com/omarsdev/react-native-nitro-compass#readme",
|
|
62
67
|
"publishConfig": {
|
|
63
68
|
"access": "public",
|
|
64
|
-
"registry": "https://registry.npmjs.org/"
|
|
69
|
+
"registry": "https://registry.npmjs.org/",
|
|
70
|
+
"provenance": true
|
|
65
71
|
},
|
|
66
72
|
"devDependencies": {
|
|
67
73
|
"@jamesacarr/eslint-formatter-github-actions": "^0.2.0",
|