Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.1.0 #3

Merged
merged 5 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules
docs/.vitepress/cache
docs/.vitepress/dist
*.log
*.env
*.DS_Store
4 changes: 3 additions & 1 deletion .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"printWidth": 100,
"singleQuote": true
"semi": true,
"singleQuote": true,
"tabWidth": 2
}
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# DragDoll
<h1 align="center">
<a id="dragdoll" href="#dragdoll" aria-hidden="true"><img src="https://niklasramo.github.io/dragdoll/dragdoll-logo.svg" alt="DragDoll" width="400" /></a>
</h1>

DragDoll is a modular and highly extensible drag & drop system written in TypeScript. It's originally based on [Muuri's](https://github.com/haltu/muuri) internal drag & drop system, but fully redesigned to be used as a general purpose drag & drop system.

Expand Down
273 changes: 142 additions & 131 deletions dist/dragdoll.d.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/dragdoll.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/dragdoll.umd.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
base: '/dragdoll/',
lang: 'en-US',
title: 'DragDoll',
description: 'Modular and extensible JavaScript drag & drop system.',
description: 'Modular and extensible TypeScript drag & drop system.',
appearance: true,
head: [['link', { rel: 'icon', type: 'image/svg+xml', href: '/dragdoll-icon.svg' }]],
lastUpdated: true,
Expand Down Expand Up @@ -76,10 +76,10 @@ function sidebarGuide() {
items: [
{ text: 'Sensor', link: '/docs/sensor' },
{ text: 'BaseSensor', link: '/docs/base-sensor' },
{ text: 'BaseControllerSensor', link: '/docs/base-controller-sensor' },
{ text: 'BaseMotionSensor', link: '/docs/base-motion-sensor' },
{ text: 'PointerSensor', link: '/docs/pointer-sensor' },
{ text: 'KeyboardSensor', link: '/docs/keyboard-sensor' },
{ text: 'KeyboardControllerSensor', link: '/docs/keyboard-controller-sensor' },
{ text: 'KeyboardMotionSensor', link: '/docs/keyboard-motion-sensor' },
],
},
{
Expand Down
6 changes: 2 additions & 4 deletions docs/.vitepress/theme/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
--vp-button-brand-bg: #ff5555;
}
.VPImage.logo {
height: 40px;
height: 32px;
}
.VPFeatures .VPFeature {
position: relative;
padding-left: 60px;
background-color: transparent;
border-color: var(--vp-c-divider-light);
padding-left: 34px;
}
.VPFeatures .VPFeature .icon {
position: absolute;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
[BaseSensor](/docs/base-sensor) →

# BaseControllerSensor
# BaseMotionSensor

BaseControllerSensor is a tailor-made base sensor for scenarios where you want to smoothly move an object, e.g. a car or a character in a 2D game, based on custom inputs. It extends [BaseSensor](/docs/base-sensor) and provides functionality for controlling the drag movement on every frame via speed and direction.
BaseMotionSensor is an extendable base class tailor-made for scenarios where you want to smoothly move an object, e.g. a car or a character in a 2D game, based on custom inputs. It extends [BaseSensor](/docs/base-sensor) and provides functionality for controlling the drag movement on every frame via protected `_speed` and `_direction` properties.

## Example

```ts
import { BaseControllerSensor, Draggable } from 'dragdoll';
import { BaseMotionSensor, Draggable } from 'dragdoll';

// Create a custom controller sensor which starts moving the provided
// element "virtually" in random direction with random speed when you press
// space. Stop the drag pressing space again, and cancel by pressing esc.
class CustomControllerSensor extends BaseControllerSensor {
class CustomMotionSensor extends BaseMotionSensor {
element: HTMLElement;

constructor(element: HTMLElement) {
Expand All @@ -27,12 +27,12 @@ class CustomControllerSensor extends BaseControllerSensor {
// Start/stop drag with space.
case ' ': {
// Stop.
if (this.isActive) {
if (this.drag) {
e.preventDefault();
this._end({
type: 'end',
clientX: this.clientX!,
clientY: this.clientY!,
x: this.drag.x,
y: this.drag.y,
});
}
// Start.
Expand All @@ -44,30 +44,30 @@ class CustomControllerSensor extends BaseControllerSensor {
// Compute random speed.
const maxSpeed = 1000;
const minSpeed = 100;
this.speed = Math.floor(Math.random() * (maxSpeed - minSpeed + 1) + minSpeed);
this._speed = Math.floor(Math.random() * (maxSpeed - minSpeed + 1) + minSpeed);

// Compute random direction vector.
const a = Math.random() * (2 * Math.PI);
this.direction.x = Math.cos(a);
this.direction.y = Math.sin(a);
this._direction.x = Math.cos(a);
this._direction.y = Math.sin(a);

// Start the drag.
this._start({
type: 'start',
clientX: left,
clientY: top,
x: left,
y: top,
});
}
return;
}
// Cancel on esc.
case 'Escape': {
if (this.isActive) {
if (this.drag) {
e.preventDefault();
this._cancel({
type: 'cancel',
clientX: this.clientX!,
clientY: this.clientY!,
x: this.drag.x,
y: this.drag.y,
});
}
return;
Expand All @@ -84,7 +84,7 @@ class CustomControllerSensor extends BaseControllerSensor {

// Create a custom controller sensor instance.
const dragElement = document.querySelector('.dragElement');
const customSensor = new CustomControllerSensor(dragElement);
const customSensor = new CustomMotionSensor(dragElement);

// Listen to events.
customSensor.on('start', (e) => console.log('drag started', e));
Expand All @@ -101,37 +101,41 @@ const draggable = new Draggable([customSensor], {

## Properties

### direction
### drag

```ts
type direction = { x: number; y: number };
type drag = {
// Coordinates of the drag within the viewport.
readonly x: number;
readonly y: number;
// The latest DOMHighResTimeStamp.
readonly time: number;
// Current frame's delta time (in milliseconds).
readonly deltaTime: number;
} | null;
```

2D direction vector which indicates the drag direction. This is assumed to be a unit vector (length 1) if there should be movement, otherwise x and y components should be 0. You can manually modify this anytime you want.
Current drag data or `null` when drag is inactive. Read-only.

### speed
## Protected Properties

```ts
type speed = number;
```
These protected properties are inherited by any class that extends this class and should be used to control the drag speed and direction.

The speed of the drag as pixels-per-second. You can manually modify this anytime you want.

### time
### \_direction

```ts
type time = DOMHighResTimeStamp;
type _direction = { x: number; y: number };
```

The latest [`high resolution timestamp`](https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp) in milliseconds. Note that this is only updated while drag is active. Read-only.
2D direction vector which indicates the drag direction. This is assumed to be a unit vector (length 1) if there should be movement, otherwise x and y components should be 0. You can manually modify this anytime you want.

### deltaTime
### \_speed

```ts
type time = number;
type speed = number;
```

Current frame's delta time in milliseconds. Note that this is only updated while drag is active. Read-only.
The speed of the drag as pixels-per-second. You can manually modify this anytime you want.

## Methods

Expand All @@ -145,8 +149,8 @@ type on = (
e:
| {
type: 'start' | 'move' | 'end' | 'cancel';
clientX: number;
clientY: number;
x: number;
y: number;
}
| {
type: 'tick';
Expand All @@ -161,7 +165,7 @@ type on = (
) => string | number | symbol;

// Usage
baseControllerSensor.on('start', (e) => {
baseMotionSensor.on('start', (e) => {
console.log('start', e);
});
```
Expand All @@ -178,8 +182,8 @@ type off = (
) => void;

// Usage
const id = baseControllerSensor.on('start', (e) => console.log('start', e));
baseControllerSensor.off('start', id);
const id = baseMotionSensor.on('start', (e) => console.log('start', e));
baseMotionSensor.off('start', id);
```

Removes a listener (based on listener or listener id) from a sensor event.
54 changes: 24 additions & 30 deletions docs/docs/base-sensor.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# BaseSensor

BaseSensor is an extendable base class to ease the process of creating custom sensors. It does not do anything by itself, but it does implement the Sensor API and provides you some protected helper methods for controlling the state of the drag process. It's used by [`KeyboardSensor`](/docs/keyboard-sensor) so you can check out implementation tips there.
BaseSensor is an extendable base class to ease the process of creating custom sensors. It does not do anything by itself, but it does implement the [Sensor](/docs/sensor) API and provides you some protected helper methods for controlling the state of the drag process. It's used by [`KeyboardSensor`](/docs/keyboard-sensor) so you can check out implementation tips there.

## Constructor

Expand All @@ -14,29 +14,17 @@ The constuctor accepts no arguments.

## Properties

### clientX
### drag

```ts
type clientX = number | null;
type drag = {
// Coordinates of the drag within the viewport.
readonly x: number;
readonly y: number;
} | null;
```

Current horizontal coordinate of the drag within the application's viewport, `null` when drag is inactive. Read-only.

### clientY

```ts
type clientY = number | null;
```

Current vertical coordinate of the drag within the application's viewport, `null` when drag is inactive. Read-only.

### isActive

```ts
type isActive = boolean;
```

Is dragging active or not? Read-only.
Current drag data or `null` when drag is inactive. Read-only.

### isDestroyed

Expand All @@ -46,6 +34,12 @@ type isDestroyed = boolean;

Is sensor destroyed or not? Read-only.

## Protected Properties

### \_emitter

An event emitter, instance of [Eventti Emitter](https://github.com/niklasramo/eventti#api).

## Methods

### on
Expand All @@ -58,8 +52,8 @@ type on = (
e:
| {
type: 'start' | 'move' | 'end' | 'cancel';
clientX: number;
clientY: number;
x: number;
y: number;
}
| {
type: 'destroy';
Expand Down Expand Up @@ -124,10 +118,10 @@ These protected methods are inherited by any class that extends this class and s

```ts
// Type
type _start = (data: { type: 'start'; clientX: number; clientY: number }) => void;
type _start = (data: { type: 'start'; x: number; y: number }) => void;

// Usage
baseSensor._start({ type: 'start', clientX: 100, clientY: 200 });
baseSensor._start({ type: 'start', x: 100, y: 200 });
```

Protected method, which starts the drag process and emits drag start event with the provided data.
Expand All @@ -136,10 +130,10 @@ Protected method, which starts the drag process and emits drag start event with

```ts
// Type
type _move = (data: { type: 'move'; clientX: number; clientY: number }) => void;
type _move = (data: { type: 'move'; x: number; y: number }) => void;

// Usage
baseSensor._move({ type: 'move', clientX: 100, clientY: 200 });
baseSensor._move({ type: 'move', x: 100, y: 200 });
```

Protected method, which emits drag move event with the provided data.
Expand All @@ -148,10 +142,10 @@ Protected method, which emits drag move event with the provided data.

```ts
// Type
type _end = (data: { type: 'end'; clientX: number; clientY: number }) => void;
type _end = (data: { type: 'end'; x: number; y: number }) => void;

// Usage
baseSensor._end({ type: 'end', clientX: 100, clientY: 200 });
baseSensor._end({ type: 'end', x: 100, y: 200 });
```

Protected method, which ends the drag process and emits drag end event with the provided data.
Expand All @@ -160,10 +154,10 @@ Protected method, which ends the drag process and emits drag end event with the

```ts
// Type
type _cancel = (data: { type: 'cancel'; clientX: number; clientY: number }) => void;
type _cancel = (data: { type: 'cancel'; x: number; y: number }) => void;

// Usage
baseSensor._cancel({ type: 'cancel', clientX: 100, clientY: 200 });
baseSensor._cancel({ type: 'cancel', x: 100, y: 200 });
```

Protected method, which cancels the drag process and emits drag cancel event with the provided data.
Loading