Skip to content

Commit bb68a75

Browse files
committed
initial release 0.1.0
0 parents  commit bb68a75

29 files changed

+11453
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
dist/

.npmignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.*
2+
/src
3+
/other
4+
/examples

API.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
## Classes
2+
<dl>
3+
<dt><a href="#Taps">Taps</a></dt>
4+
<dt><a href="#Tap">Tap</a></dt>
5+
</dl>
6+
<a name="Taps"></a>
7+
8+
## Taps
9+
#### Properties:
10+
11+
| Name | Type | Description |
12+
| --- | --- | --- |
13+
| dragDistance | <code>number</code> | Distance in pixels for tap to move from start position to enter drag state, default: 20 pixels. |
14+
| dragDelay | <code>number</code> | Time in milliseconds for tap to enter drag state if held for that long, default: 200 milliseconds. |
15+
16+
17+
[new Taps([element])](#new_Taps_new) (constructor)<br />
18+
[.start](#Taps+start) : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)<br />
19+
[.up](#Taps+up) : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)<br />
20+
[.click](#Taps+click) : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)<br />
21+
[.dragstart](#Taps+dragstart) : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)<br />
22+
[.drag](#Taps+drag) : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)<br />
23+
[.dragend](#Taps+dragend) : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)<br />
24+
[.update()](#Taps+update)<br />
25+
26+
<a name="new_Taps_new"></a>
27+
28+
### new Taps([element])
29+
Taps provide source agnostic sync access to input. Either it comes from mouse and/or touch, it is the same API. It assumes multiple instances of taps making your code multi-touch by design. Providing sync access instead of event based, for best usage in real-time applications. Class itself is an iterator for easy access to taps.
30+
31+
32+
| Param | Type | Description |
33+
| --- | --- | --- |
34+
| [element] | <code>object</code> | Element to which mouse and touch events to be attached, by default `window`. |
35+
36+
**Example**
37+
```js
38+
// create taps interfaceconst taps = new Taps();function update() { requestAnimationFrame(update); // update taps on each frame taps.update(); // access all taps for(const tap of taps) { // iterate through all taps }}requestAnimationFrame(update);
39+
```
40+
<a name="Taps+start"></a>
41+
42+
### .start : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)
43+
Iterator of taps that just've been created. Tap can be only once in `start` state during its life.
44+
45+
**Example**
46+
```js
47+
for(const tap of taps.start) { // same as touchstart or mousedown}
48+
```
49+
<a name="Taps+up"></a>
50+
51+
### .up : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)
52+
Iterator of taps that been released. Tap can be only once in `up` state during its life and will be removed after.
53+
54+
**Example**
55+
```js
56+
for(const tap of taps.up) { // same as touchend, touchcancel or mouseup}
57+
```
58+
<a name="Taps+click"></a>
59+
60+
### .click : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)
61+
Iterator of taps that are consider clicks. Tap can be only once in `click` state, and will be removed after.
62+
63+
**Example**
64+
```js
65+
for(const tap of taps.click) { // same as click, happens on mouseup or touchend // if tap been short lived and/or didn't move too far from initial position}
66+
```
67+
<a name="Taps+dragstart"></a>
68+
69+
### .dragstart : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)
70+
Iterator of taps that started a drag. Tap can be only once in `dragstart` state. It is guaranteed to trigger `dragend` instead of `click` as a last state.
71+
72+
**Example**
73+
```js
74+
for(const tap of taps.dragstart) { // held touch/mousedown for long enough or moved far enough from initial tap position}
75+
```
76+
<a name="Taps+drag"></a>
77+
78+
### .drag : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)
79+
Iterator of taps that are in drag state. This state will persist from and during `dragstart` and until/during `dragend` states.
80+
81+
**Example**
82+
```js
83+
for(const tap of taps.drag) { // tap is dragging}
84+
```
85+
<a name="Taps+dragend"></a>
86+
87+
### .dragend : [<code>Iterable.&lt;Tap&gt;</code>](#Tap)
88+
Iterator of taps that ended a drag. Tap can be only once in `dragend` state, and will be removed after.
89+
90+
**Example**
91+
```js
92+
for(const tap of taps.dragend) { // drag is finished}
93+
```
94+
<a name="Taps+update"></a>
95+
96+
### .update()
97+
Update taps states, should be executed in the beginning of an application every update loop.
98+
99+
**Example**
100+
```js
101+
function update() { requestAnimationFrame(update); // update taps on each frame taps.update(); // access all taps}requestAnimationFrame(update);
102+
```
103+
<a name="Tap"></a>
104+
105+
## Tap
106+
#### Properties:
107+
108+
| Name | Type | Description |
109+
| --- | --- | --- |
110+
| start | <code>boolean</code> | True when tap been just created, equivalent to mousedown and touchstart. |
111+
| up | <code>boolean</code> | True when tap is ended, equivalent to mouseup, touchend, touchcancel. It can be in that state only once, and will be removed after. |
112+
| click | <code>boolean</code> | True when tap is considered a click. It can be in that state only once, and will be removed after. |
113+
| dragstart | <code>boolean</code> | True when tap is started dragging, which happens when either: tap duration is long enough and/or it is moved away from initial position enough. It will be in that state once, and guarantees to have `dragend` state instead of `click` state. |
114+
| drag | <code>boolean</code> | True when tap is dragging. It will be in that state from `dragstart` till the end of a tap. |
115+
| dragend | <code>boolean</code> | True when tap is ended dragging. It will be in that state only if previously was in `dragstart`, and tap will be removed after. |
116+
| timestamp | <code>boolean</code> | Milliseconds timestamp of when tap has started. |
117+
| x | <code>number</code> | X current coordinate of a tap, where 0 - is left. |
118+
| y | <code>number</code> | Y current coordinate of a tap, where 0 - is top. |
119+
| sx | <code>number</code> | X coordinate of where tap started. |
120+
| sy | <code>number</code> | Y coordinate of where tap started. |
121+
| dx | <code>number</code> | X distance of a tap traveled since previous update. |
122+
| dy | <code>number</code> | Y distance of a tap traveled since previous update. |
123+
124+
<a name="new_Tap_new"></a>
125+
126+
### new Tap()
127+
Tap is instintiated by [Taps](#Taps), and provides information about the input, its state and coordinates. It is source agnostic, and behaves identical between mouse and touch.
128+
129+
**Example**
130+
```js
131+
// clickingfor(const tap of taps.click) { // pick an object based on tap coordinates const object = pickObject(tap.x, tap.y); if (! object) continue; object.interact();}
132+
```
133+
**Example**
134+
```js
135+
// dragging// grab an object for dragstart tapsfor(const tap of taps.dragstart) { // pick an object based on tap start coordinates const object = pickObject(tap.sx, tap.sy); // remember that object against a tap tap.object = object;}// move an objects for drag tapsfor(const tap of taps.drag) { // ensure we have an object if (! tap.object) continue; // set position of a dragged object to tap coordinates tap.object.setPosition(tap.x, tap.y);}// throw an object for dragend tapsfor(const tap of taps.dragend) { // ensure we have an object if (! tap.object) continue; // dt - delta time, to correct for a variable FPS tap.object.setLinearVelocity(tap.dx * dt, tap.dy * dt);}
136+
```

README.md

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# mr-Taps
2+
3+
Taps provide source agnostic sync access to input. Either it comes from mouse and/or touch, it is the same API. It assumes multiple instances of taps making your code multi-touch by design.
4+
5+
Providing sync access instead of event based, for best usage in real-time applications.
6+
7+
[![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](LICENSE)
8+
9+
10+
## :rocket: Install
11+
12+
13+
```html
14+
<script type='module' src='mr-tap.module.min.js'></script>
15+
<script nomodule src='mr-tap.min.js'></script>
16+
```
17+
Use built files from `dist` directory for browser. It will load ES8+ version if it is supported ([~94%](https://caniuse.com/?search=ES8)). There are two versions: `nomodule` (global scope) and `module` (for `import`).
18+
19+
```js
20+
// create taps interface
21+
const taps = new Taps();
22+
23+
function update() {
24+
requestAnimationFrame(update);
25+
26+
// update taps on each frame
27+
taps.update();
28+
29+
// access all taps
30+
for(const tap of taps) {
31+
// iterate through all taps
32+
}
33+
}
34+
requestAnimationFrame(update);
35+
```
36+
37+
## :scroll: [API Documentation](API.md)
38+
39+
## Usage
40+
41+
42+
#### Creating:
43+
44+
```js
45+
const taps = new Taps();
46+
```
47+
48+
#### Updating:
49+
```js
50+
function update() {
51+
requestAnimationFrame(update);
52+
53+
// update taps on each frame
54+
taps.update();
55+
56+
// application logic
57+
}
58+
requestAnimationFrame(update);
59+
```
60+
61+
62+
#### Accessing:
63+
64+
All taps:
65+
```js
66+
// Taps - is an iterator
67+
for(const tap in taps) {
68+
// all taps
69+
}
70+
```
71+
72+
Specific state taps, e.g. clicks:
73+
74+
```js
75+
for(const tap in taps.click) {
76+
// taps that are only clicks
77+
}
78+
```
79+
80+
81+
## Examples
82+
83+
Examples are multi-touch by design.
84+
85+
Clicking on objects:
86+
```js
87+
for(const tap of taps.click) {
88+
const object = pickObject(tap.x, tap.y);
89+
if (! object) continue;
90+
object.interact();
91+
}
92+
```
93+
94+
Rendering taps:
95+
```js
96+
// drawCircle(x, y, radius)
97+
98+
for(const tap of taps) {
99+
drawCircle(tap.x, tap.y, 32);
100+
}
101+
```
102+
103+
Selecting multiple objects using rect (RTS style):
104+
```js
105+
// drawRect(left, top, right, bottom)
106+
107+
// draw selection rect
108+
for(const tap of taps.drag) {
109+
drawRect(tap.sx, tap.sy, tap.x, tap.y);
110+
}
111+
112+
// select objects on dragend
113+
for(const tap of taps.dragend) {
114+
const objects = objectsInRect(tap.sx, tap.sy, tap.x, tap.y);
115+
// selected some objects
116+
}
117+
```
118+
119+
Dragging objects:
120+
```js
121+
// pick an object from tap start position
122+
// and remember against tap object
123+
for(const tap of taps.dragstart) {
124+
const object = pickObject(tap.sx, tap.sy);
125+
if (! object) continue;
126+
127+
tap.object = object;
128+
// remember difference of position between tap and object center
129+
tap.offsetX = object.x - tap.sx;
130+
tap.offsetY = object.y - tap.sy;
131+
}
132+
133+
// position objects
134+
for(const tap of taps.drag) {
135+
// tap might have no object associated
136+
if (! tap.object) continue;
137+
// position with offset to prevent object snapping
138+
tap.object.setPosition(tap.x + tap.offsetX, tap.y + tap.offsetY);
139+
}
140+
```
141+
142+
Throwing objects:
143+
```js
144+
// pick objects
145+
// position objects
146+
147+
// throw an object
148+
for(const tap of taps.dragend) {
149+
// tap might have no object associated
150+
if (! tap.object) continue;
151+
// set linear velocity
152+
// multiply speed by deltaTime
153+
tap.object.setLinearVelocity(tap.dx * dt, tap.dy * dt);
154+
}
155+
```
156+
157+
## Tap
158+
159+
Each tap is instantiated by the Taps interface, and provided through iterators. Tap is agnostic to the input source: mouse or touch. And behaves identical. Also, due to iterator pattern, it provides sync access instead of event driven, and is multi-touch by design.
160+
161+
Tap has states with two branching scenarios:
162+
163+
Click: `start` > `click + up`
164+
Drag: `start` > `dragstart + drag` > `drag` > `dragend + drag + up`
165+
166+
167+
#### States:
168+
169+
`start` - every tap starts with a start state.
170+
171+
`click` - some taps if not moved from initial position and have not been held for too long, on `up` state, will be considered `click`.
172+
173+
`dragstart` - some taps if moved from initial position or have been held for some time, will enter `drag` state, and once be in `dragstart` state.
174+
`drag` - once tap is in `dragstart` state, it will be in `drag` state till the end of a tap.
175+
`dragend` - if tap is in `drag` state, on `up` state instead of `click` it will be in `dragend` state.
176+
177+
`up` - every tap ends with `up` state.
178+
179+
180+
#### Drag State
181+
182+
Tap enters `drag` state if moved far from start position, or held for long enough. It is possible to change default settings of 20 pixels and 200 millisecsonds:
183+
184+
```js
185+
taps.dragDistance = 20; // pixels
186+
taps.dragDelay = 200; // milliseconds
187+
```
188+
189+
190+
## Building
191+
192+
Builds library into two versions (normal and module) using Rollup, Babel and Terser.
193+
Source file: `src/index.js`
194+
Built versions normal (`dist/mr-tap.min.js`) and module (`dist/mr-tap.module.min.js`):
195+
196+
```bash
197+
npm install
198+
npm run build
199+
```

examples/click.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { pickCircle } from './lib/circle.js';
2+
import circles from './lib/circles.js';
3+
4+
// click on circles
5+
function handleClicks(taps) {
6+
for(const tap of taps.click) {
7+
const circle = pickCircle(circles, tap.x, tap.y);
8+
if (! circle) continue;
9+
// make circle bounce
10+
circle.radius = 48;
11+
// randomize circle color
12+
circle.color = '#' + (Math.random() * 0xfffff * 1000000).toString(16).slice(0, 6);
13+
}
14+
}
15+
16+
export default handleClicks;

0 commit comments

Comments
 (0)