Skip to content

Commit

Permalink
v0.1.0 (#3)
Browse files Browse the repository at this point in the history
* Refactored API (quite many breaking changes).
* Improved TS typing.
* Updated docs and dependencies.
* Updated logo.
* Added some initial tests (although tests in general are still a work in progress).
* Fixed an issue with auto-scrolling where it could not always detect the end of the scroll.
  • Loading branch information
niklasramo authored Jul 9, 2023
1 parent 23d0370 commit 64aad6e
Show file tree
Hide file tree
Showing 62 changed files with 11,123 additions and 7,614 deletions.
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

0 comments on commit 64aad6e

Please sign in to comment.