Skip to content

Commit 2d6703a

Browse files
authored
Merge pull request #1 from TheProfs/v2
fix/oop-motions
2 parents aa10620 + 79f38e1 commit 2d6703a

47 files changed

Lines changed: 156006 additions & 2334 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ npm-debug.log*
55
# llm
66
AGENTS.md
77
.claude/
8+
9+
# artifacts
10+
docs/spec/*.zip

README.md

Lines changed: 137 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,168 @@
1-
[![test][test-badge]][test]
1+
[![test][test-badge]][test]
22

3-
# pointerdriver
3+
# pointerdriver
44

5-
> Synthesizes and dispatches events.
6-
> Mimics the event stream as if it were executed
7-
> by an actual human driving the interaction.
5+
Synthesize pointer, touch, and gesture events on any page.
86

9-
```sh
10-
npm i github:TheProfs/pointerdriver
7+
```bash
8+
npx github:TheProfs/pointerdriver
119
```
1210

13-
## Usage
11+
> [!NOTE]
12+
> LLM Agents **must** read the `pointerdriver` skill first.
13+
> Ask your LLM to run: `pointerdriver --skill` and study it carefully.
14+
15+
## How it works:
16+
17+
1. Run your project however you want.
18+
We're assuming it's running on `localhost:3000`
19+
2. Run a pointerdriver server with `npx github:TheProfs/pointerdriver`
20+
3. Go in your browser console and run:
1421

1522
```js
16-
import { PointerDriver } from 'pointerdriver'
23+
const {
24+
DragMotion, GlideMotion, StrokeMotion,
25+
PinchMotion, TwistMotion, SwipeMotion
26+
} = await import('http://127.0.0.1:5619/pointerdriver.js')
27+
```
28+
29+
This loads `pointerdriver` and allows executing any of the following motions:
30+
31+
## Motions
32+
33+
Create a motion by running: `new Motion(arguments).perform()`.
34+
35+
A motion is a *human-maneuver*;
36+
Regardless of the arguments you use for it, a motion eventually
37+
generates the exact sequence of events that would be generated
38+
from a real device.
39+
1740

18-
const driver = new PointerDriver('#el')
41+
### `DragMotion(el, points)`
1942

20-
// Pencil
21-
await driver.stroke([[30, 50, 0], [60, 80, 16]]) // pen drag
43+
Mouse drag across a surface.
2244

23-
// Mouse
24-
await driver.drag([[30, 50, 0], [60, 80, 16]]) // mouse drag
45+
| Param | Description |
46+
|----------|--------------------------------------------|
47+
| `el` | target element |
48+
| `points` | `[x, y, ms][]`; `ms` monotonic and `>= 0` |
2549

26-
// Touch
27-
await driver.glide([[
28-
30, 50, 0], [60, 80, 16]
29-
]]) // one-finger drag
30-
await driver.pinch(2) // two-finger pinch
31-
await driver.swipe(80, 0) // two-finger swipe
32-
await driver.twist() // two-finger twist
50+
```js
51+
await new DragMotion(document.querySelector('#el'), [
52+
[30, 50, 0],
53+
[60, 80, 16],
54+
]).perform()
3355
```
3456

35-
### Text strokes
57+
### `GlideMotion(el, points)`
58+
59+
Finger draw on a surface.
3660

37-
`stroke()` accepts a string,
38-
but you must provide an SVG font URL in the constructor.
61+
| Param | Description |
62+
|----------|--------------------------------------------|
63+
| `el` | target element |
64+
| `points` | `[x, y, ms][]`; `ms` monotonic and `>= 0` |
3965

4066
```js
41-
const driver = new PointerDriver('#el', {
42-
font: 'http://127.0.0.1:5619/fonts/EMS_Elfin_Smooth.svg',
43-
})
67+
await new GlideMotion(document.querySelector('#el'), [
68+
[30, 50, 0],
69+
[60, 80, 16],
70+
]).perform()
71+
```
72+
73+
### `StrokeMotion(el, points)`
74+
75+
Pen stylus stroke on a surface.
4476

45-
await driver.stroke('Hello', { fontSize: 48 })
77+
| Param | Description |
78+
|----------|--------------------------------------------|
79+
| `el` | target element |
80+
| `points` | `[x, y, ms][]`; `ms` monotonic and `>= 0` |
81+
82+
```js
83+
await new StrokeMotion(document.querySelector('#el'), [
84+
[30, 50, 0],
85+
[60, 80, 16],
86+
]).perform()
4687
```
4788

48-
## Server
89+
### `PinchMotion(el, scale, { x, y, distance, steps })`
4990

50-
Run a local static server:
91+
Two-finger pinch together or apart.
5192

52-
```bash
53-
npx github:TheProfs/pointerdriver
93+
| Param | Default | Description |
94+
|------------|---------|--------------------------|
95+
| `el` | | target element |
96+
| `scale` | | target scale factor |
97+
| `x`, `y` | | gesture center |
98+
| `distance` | `100` | initial finger gap in px |
99+
| `steps` | `20` | interpolation frames |
100+
101+
```js
102+
await new PinchMotion(document.querySelector('#el'), 2, {
103+
x: 60, y: 80
104+
}).perform()
105+
```
106+
107+
### `TwistMotion(el, degrees, { x, y, radius, steps })`
108+
109+
Two-finger rotation around a center point.
110+
111+
| Param | Default | Description |
112+
|-----------|---------|-----------------------------|
113+
| `el` | | target element |
114+
| `degrees` | `45` | rotation angle |
115+
| `x`, `y` | | gesture center |
116+
| `radius` | `80` | finger distance from center |
117+
| `steps` | `20` | interpolation frames |
118+
119+
```js
120+
await new TwistMotion(document.querySelector('#el'), 45, {
121+
x: 60, y: 80
122+
}).perform()
123+
```
124+
125+
### `SwipeMotion(el, distance, { x, y, angle, separation, steps })`
126+
127+
Two-finger parallel drag.
128+
129+
| Param | Default | Description |
130+
|--------------|---------|---------------------------|
131+
| `el` | | target element |
132+
| `distance` | | travel distance in px |
133+
| `x`, `y` | | gesture center |
134+
| `angle` | `0` | direction in degrees |
135+
| `separation` | `40` | gap between fingers in px |
136+
| `steps` | `20` | interpolation frames |
137+
138+
```js
139+
await new SwipeMotion(document.querySelector('#el'), 200, {
140+
x: 60, y: 80
141+
}).perform()
54142
```
55143

56-
Open `http://127.0.0.1:5619/`.
144+
## Notes:
145+
146+
- The module server only serves `/pointerdriver.js` and `/src/*/index.js`.
147+
- It sets permissive CORS headers so you can import it from any page.
148+
149+
## HTTPS pages
150+
151+
If the target page is HTTPS,
152+
importing pointerdriver from HTTP is blocked as mixed content.
153+
Serve pointerdriver over HTTPS (see `bin/skill.md` for one approach).
154+
57155

58-
## Test
156+
## Run tests
59157

60158
```bash
61159
npm test
62160
```
63161

64-
## License
162+
## License
65163

66-
MIT
164+
[MIT][license]
67165

68-
[test-badge]: https://github.com/TheProfs/pointerdriver/actions/workflows/test.yml/badge.svg
69-
[test]: https://github.com/TheProfs/pointerdriver/actions/workflows/test.yml
166+
[test-badge]: https://github.com/TheProfs/pointerdriver/actions/workflows/test.yml/badge.svg
167+
[test]: https://github.com/TheProfs/pointerdriver/actions/workflows/test.yml
168+
[license]: https://opensource.org/licenses/MIT

0 commit comments

Comments
 (0)