Recognizeable effects
Updated on August 22, 2024
With a few exceptions, Baleada Logic uses the factory pattern almost exclusively to create objects that can be passed to the effects
option of the Recognizeable
class.
These functions are designed to recognize common gestures. The factory functions that fall into this category are:
The rest of this guide describes shared patterns that are applied to these these factory functions.
Listenable
subclasses
All factory functions that return Recognizeable
effects also export a Listenable
subclass that makes it easier to use Listenable
to listen for custom gestures.
To appreciate this, let's look first at how you'd configure Listenable
to listen for a drag-and-drop gesture, using createMouserelease
, and without using the nice subclass:
import {
Listenable,
createMouserelease
} from '@baleada/logic'
import type {
MousereleaseType,
MousereleaseMetadata
} from '@baleada/logic'
const dragAndDrop = new Listenable(
// To get type inference working properly, we need to
// manually assert that this `recognizeable` string is a
// `MousereleaseType`. This obviously isn't true, but
// it represents the way Listenable's internal logic
// would handle the `recognizeable` string, so it's safe
// and necessary to do this.
'recognizeable' as MousereleaseType,
// Then we use a somewhat funky nested optional object
// to pass the return value of `createMouserelease` to
// the `Listenable` instance, so that `Listenable` is
// equipped to handle all the related events.
{
recognizeable: {
effects: createMouserelease(),
},
}
)
// Finally, we list for drag and drop on any given element:
dragAndDrop.listen(
() => console.log('dragged and dropped 😎'),
{ target: myElement },
)
That's not a huge amount of work, but it's kind of annoying, and it really highlights some difficult tradeoffs that Listenable
had to make in order to support common use cases, but also be as flexible as possible, letting you recognize literally any sequence of any events as your own custom gesture, all in your own userland code.
Listenable
subclasses offer a much nicer DX:
import { Mouserelease } from '@baleada/logic'
const dragAndDrop = new Mouserelease()
dragAndDrop.listen(
() => console.log('dragged and dropped 😎'),
{ target: myElement },
)
The Mouserelease
subclass does all the Listenable
configuration and type assertion for you 🎯
Its constructor also accepts all parameters that you would pass to createMouserelease
:
import { Mouserelease } from '@baleada/logic'
const dragAndDrop = new Mouserelease({
minDuration: 1000,
minDistance: 100,
...
})
Each of the factory functions listed above has a corresponding Listenable
subclass. The Listenable
subclasses are:
Pointer metadata
Pointer metadata is an object that gets stored in Recognizeable
metadata by all of Baleada Logic's Recognizeable
effects that deal with point interactions.
Pointer metadata can be separated into three categories:
Here are the properties included in a pointer metadata object, and the category those properties relate to. Read the descriptions of those categories below to get more info on each property.
points
distance
angle
direction
times
duration
velocity
Pointer start metadata
Pointer start metadata is stored under the points
property of pointer metadata. It includes the following properties:
start
{ x: number, y: number }
end
{ x: number, y: number }
Pointer move metadata
Pointer move metadata is stored under the distance
, angle
, and direction
properties of pointer metadata.
In all the tables below that describe distance
, angle
, and direction
, note that fromStart
tells you how far or in what direction the pointer has moved since the start point (as defined by pointer start metadata), and fromPrevious
tells you how far or in what direction the pointer has moved since the previous event in the Recognizeable
sequence.
Pointer move distance
distance
includes the following properties:
straight
{ fromStart: number, fromPrevious: number }
horizontal
{ fromStart: number, fromPrevious: number }
vertical
{ fromStart: number, fromPrevious: number }
Pointer move angle
angle
includes the following properties:
fromStart
Angle
(see below)fromPrevious
Angle
(see below)The Angle
type is an object with two properties:
degrees
radians
Pointer move direction
direction
includes the following properties:
fromStart
Direction
(see below)fromPrevious
Direction
(see below)The Direction
type can be one of the following strings:
up
upRight
right
downRight
down
downLeft
left
upLeft
Pointer time metadata
Pointer time metadata is stored under the times
, duration
, and velocity
properties of pointer metadata.
Time metadata is calculated using requestAnimationFrame
, and it updates continuously at 60 frames per second, even if new events are not being added to the Recognizeable
sequence.
times
includes the following properties:
start
end
duration
is the number of milliseconds that have passed since the pointer first interacted with the target.
velocity
is the number of pixels the pointer has moved per millisecond since the previous event in the Recognizeable
sequence.
Keyboard metadata
Keyboard metadata is an object that gets stored in Recognizeable
metadata by all of Baleada Logic's Recognizeable
effects that deal with keyboard interactions.
Keyboard metadata can be separated into two categories:
Keyboard keycombo metadata
Keyboard keycombo metadata is stored under the keycombo
property of keyboard metadata.
keycombo
is a string that tells you which keycombo was recognized.
Keyboard time metadata
Keyboard time metadata is stored under the times
, and duration
properties of keyboard metadata.
Time metadata is calculated using requestAnimationFrame
, and it updates continuously at 60 frames per second, even if new events are not being added to the Recognizeable
sequence.
times
includes the following properties:
start
end
duration
is the number of milliseconds that have passed since the keyboard first interacted with the target.