Skip to content

Commit 0d0d074

Browse files
committed
feat: polish api and name
1 parent a257842 commit 0d0d074

24 files changed

+313
-382
lines changed

CONTRIBUTING.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ The [example app](/example/) demonstrates usage of the library. You need to run
4040

4141
It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app.
4242

43-
If you want to use Android Studio or Xcode to edit the native code, you can open the `example/android` or `example/ios` directories respectively in those editors. To edit the Objective-C or Swift files, open `example/ios/AhapExample.xcworkspace` in Xcode and find the source files at `Pods > Development Pods > react-native-ahap`.
43+
If you want to use Android Studio or Xcode to edit the native code, you can open the `example/android` or `example/ios` directories respectively in those editors. To edit the Objective-C or Swift files, open `example/ios/HaptixStudio.xcworkspace` in Xcode and find the source files at `Pods > Development Pods > react-native-ahaps`.
4444

45-
To edit the Java or Kotlin files, open `example/android` in Android studio and find the source files at `react-native-ahap` under `Android`.
45+
To edit the Java or Kotlin files, open `example/android` in Android studio and find the source files at `react-native-ahaps` under `Android`.
4646

4747
You can use various commands from the root directory to work with the project.
4848

@@ -67,7 +67,7 @@ yarn example ios
6767
To confirm that the app is running with the new architecture, you can check the Metro logs for a message like this:
6868

6969
```sh
70-
Running "AhapExample" with {"fabric":true,"initialProps":{"concurrentRoot":true},"rootTag":1}
70+
Running "Haptix Studio" with {"fabric":true,"initialProps":{"concurrentRoot":true},"rootTag":1}
7171
```
7272

7373
Note the `"fabric":true` and `"concurrentRoot":true` properties.
@@ -96,7 +96,6 @@ Remember to add tests for your change if possible. Run the unit tests by:
9696
yarn test
9797
```
9898

99-
10099
### Commit message convention
101100

102101
We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages:
@@ -110,7 +109,6 @@ We follow the [conventional commits specification](https://www.conventionalcommi
110109

111110
Our pre-commit hooks verify that your commit message matches this format when committing.
112111

113-
114112
### Publishing to npm
115113

116114
We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc.
@@ -121,7 +119,6 @@ To publish new versions, run the following:
121119
yarn release
122120
```
123121

124-
125122
### Scripts
126123

127124
The `package.json` file contains various scripts for common tasks:

README.md

Lines changed: 200 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,219 @@
1-
# react-native-ahap
1+
# react-native-ahaps
22

3-
ahap
3+
AHAP-style haptics (transient + continuous) on top of [Nitro Modules](https://nitro.margelo.com/) — the core functions are **UI-thread friendly** (`'worklet'`).
44

5-
## Installation
5+
> iOS only (Core Haptics). Android support could be added in the future, but it’s currently unplanned.
66
7+
## Installation
78

89
```sh
9-
npm install react-native-ahap react-native-nitro-modules
10-
11-
> `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/).
10+
npm i react-native-ahaps react-native-nitro-modules
1211
```
1312

13+
## Concepts (what to use when)
14+
15+
- **Transient**: Instant “click/tap” events. No duration — you trigger them at a point in time.
16+
- **Continuous (pattern)**: Time-based patterns you _can_ define ahead of time. You provide **events** (with `duration`) and optionally **curves** (automation over time).
17+
- **Continuous player (real-time)**: For _unpredictable_ input (gesture position, scroll velocity, real-time data). You create a player once, then **start → update (many times) → stop**.
18+
19+
### Why `events[]` and `curves[]` are separate
20+
21+
On iOS Core Haptics, a pattern is made of two different building blocks:
22+
23+
- **Events**: things that happen (transient “ticks” or continuous segments) at a `relativeTime`, with base `intensity`/`sharpness`.
24+
- **Curves**: how parameters (intensity/sharpness) evolve over time via control points, independent of “what event” is currently playing.
25+
26+
They’re separate because they’re different object types in Core Haptics (events vs parameter curves) and they serve different jobs: **events define the structure**, **curves define the modulation**. You often combine both in one pattern.
1427

1528
## Usage
1629

30+
### Haptic “provider” (recommended)
31+
32+
Wrap your app inside `HapticsProvider`. This initializes the engine, creates the continuous player, and automatically destroys the engine when the app goes to background.
1733

18-
```js
19-
import { multiply } from 'react-native-ahap';
34+
```tsx
35+
import { HapticsProvider } from 'react-native-ahaps';
36+
37+
export function App() {
38+
return <HapticsProvider>{/* {Rest of your app} */}</HapticsProvider>;
39+
}
40+
```
2041

42+
### `startHaptic(events, curves)` (transient + continuous patterns)
43+
44+
Play a transient:
45+
46+
```ts
47+
import { startHaptic } from 'react-native-ahaps';
48+
49+
startHaptic(
50+
[
51+
{
52+
type: 'transient',
53+
relativeTime: 0,
54+
parameters: [
55+
{ type: 'intensity', value: 1 },
56+
{ type: 'sharpness', value: 0.5 },
57+
],
58+
},
59+
],
60+
[]
61+
);
62+
```
63+
64+
Play a continuous pattern (events + curves together):
65+
66+
```ts
67+
import { startHaptic } from 'react-native-ahaps';
68+
69+
startHaptic(
70+
[
71+
{
72+
type: 'continuous',
73+
relativeTime: 0,
74+
duration: 1.2,
75+
parameters: [
76+
{ type: 'intensity', value: 0.2 },
77+
{ type: 'sharpness', value: 0.5 },
78+
],
79+
},
80+
],
81+
[
82+
{
83+
type: 'intensity',
84+
relativeTime: 0,
85+
controlPoints: [
86+
{ relativeTime: 0.0, value: 0.2 },
87+
{ relativeTime: 0.6, value: 1.0 },
88+
{ relativeTime: 1.2, value: 0.2 },
89+
],
90+
},
91+
]
92+
);
93+
```
94+
95+
Combine transient + continuous in one pattern:
96+
97+
```ts
98+
import { startHaptic } from 'react-native-ahaps';
99+
100+
startHaptic(
101+
[
102+
{
103+
type: 'transient',
104+
relativeTime: 0,
105+
parameters: [
106+
{ type: 'intensity', value: 1 },
107+
{ type: 'sharpness', value: 0.8 },
108+
],
109+
},
110+
{
111+
type: 'continuous',
112+
relativeTime: 0.05,
113+
duration: 0.8,
114+
parameters: [
115+
{ type: 'intensity', value: 0.2 },
116+
{ type: 'sharpness', value: 0.4 },
117+
],
118+
},
119+
],
120+
[]
121+
);
122+
```
123+
124+
### Real-time continuous mode (continuous player)
125+
126+
Use this when you _can’t_ predefine a pattern. You start the player, update it in real time, then stop it.
127+
128+
```ts
129+
import {
130+
createContinuousPlayer,
131+
startContinuousPlayer,
132+
updateContinuousPlayer,
133+
stopContinuousPlayer,
134+
} from 'react-native-ahaps';
135+
136+
createContinuousPlayer(1.0, 0.5);
137+
startContinuousPlayer();
138+
updateContinuousPlayer(0.8, 0.1);
139+
stopContinuousPlayer();
140+
```
141+
142+
### Opt out of the provider (manual engine control)
143+
144+
If you don’t want the provider behavior:
145+
146+
```ts
147+
import { initializeEngine, destroyEngine } from 'react-native-ahaps';
148+
149+
initializeEngine();
21150
// ...
151+
destroyEngine();
152+
```
22153

23-
const result = multiply(3, 7);
154+
### Stop everything (recommended in screen cleanups)
155+
156+
Call `stopAllHaptics()` in your cleanup functions to terminate any ongoing continuous haptics. This prevents haptics from bleeding through to the next screen when navigating.
157+
158+
```ts
159+
import { stopAllHaptics } from 'react-native-ahaps';
160+
import { useEffect } from 'react';
161+
162+
export function SomeScreen() {
163+
useEffect(() => () => stopAllHaptics(), []);
164+
return null;
165+
}
24166
```
25167

168+
## API (tables)
169+
170+
| Function | Purpose |
171+
| ------------------------------------------------------------ | ------------------------------------------------------------------- |
172+
| `useHapticEngine(options?)` | Initialize engine + continuous player; destroy engine on background |
173+
| `initializeEngine()` / `destroyEngine()` | Manual engine lifecycle |
174+
| `startHaptic(events, curves)` | Play a pattern (transient + continuous events, optional curves) |
175+
| `stopAllHaptics()` | Stop any running haptics (useful on unmount/navigation) |
176+
| `createContinuousPlayer(initialIntensity, initialSharpness)` | Create the real-time continuous player |
177+
| `startContinuousPlayer()` / `stopContinuousPlayer()` | Start/stop real-time continuous playback |
178+
| `updateContinuousPlayer(intensityControl, sharpnessControl)` | Update real-time intensity/sharpness |
179+
180+
## Types (inputs)
181+
182+
| Type | Values |
183+
| --------------------- | ----------------------------- |
184+
| `HapticEventType` | `'transient' \| 'continuous'` |
185+
| `HapticParameterType` | `'intensity' \| 'sharpness'` |
186+
| `HapticCurveType` | `'intensity' \| 'sharpness'` |
187+
188+
| `HapticEventParameter` | Type |
189+
| ---------------------- | --------------------- |
190+
| `type` | `HapticParameterType` |
191+
| `value` | `number` |
192+
193+
**`HapticEvent`** (discriminated union)
194+
195+
- **Transient:**
196+
197+
- `type`: `'transient'`
198+
- `relativeTime`: `number`
199+
- `parameters`: `HapticEventParameter[]`
200+
201+
- **Continuous:**
202+
- `type`: `'continuous'`
203+
- `relativeTime`: `number`
204+
- `duration`: `number`
205+
- `parameters`: `HapticEventParameter[]`
206+
207+
| `HapticCurveControlPoint` | Type |
208+
| ------------------------- | -------- |
209+
| `relativeTime` | `number` |
210+
| `value` | `number` |
211+
212+
| `HapticCurve` | Type |
213+
| --------------- | --------------------------- |
214+
| `type` | `HapticCurveType` |
215+
| `relativeTime` | `number` |
216+
| `controlPoints` | `HapticCurveControlPoint[]` |
26217

27218
## Contributing
28219

@@ -33,7 +224,3 @@ const result = multiply(3, 7);
33224
## License
34225

35226
MIT
36-
37-
---
38-
39-
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)

0 commit comments

Comments
 (0)