Convenient, concise, streaming interface for scale, drag & movement. A single API for mouse and touch events in 3.3k gzipped (9k minified)
npm install pointer-stream
Drop pointer-stream.min.js
in your html file.
<script src="https://github.com/JAForbes/pointer-stream/raw/master/node_modules/pointer-stream/pointer-stream.min.js"></script>
Or using browserify:
var PointerStream = require('pointer-stream')
const pointer = PointerStream({
offset: { x: 0, y: 0 }
,scale: { min: 1, max: 40 }
})
// subscribe to changes in scale
pointer.scale.map(function(scale){
container.style.transform = 'scale('+scale+')'
})
// translate your container
pointer.coords.map(function({x,y}){
container.style.transform = 'translate('+x+'px,'+y+'px)'
})
// clean up the pointer events, so they can be gc'd
pointer.end(true)
All the streams used are flyd streams. You can use any of the operators flyd supports, and you can use Fantasy land compatible libraries like Ramda to transform the streams in advanced ways.
// If any of these streams return True
// `hovering` will return false
const hovering = R.pipe(
R.always([
pointer.dragging
,pointer.pinching
,pointer.wheeling
])
,R.anyPass
,R.complement
)
There are many low level streams exposed that can be composed to create more advanced, specific streams.
coords
is a convenience stream for translating a container.
It updates whenever a drag or scale event occurs. If you find the container translation behaviour is a little off, you can try adding a transform origin rule to your element:
#container {
transform-origin: 'top left'
}
If your container is offset at all, you can pass a value to
pointer.settings.offset({ x,y })
.
Subsequent events will be translated based on coords updating.
Type signature of the PointerStream
constructor.
{ {offset:{x,y}, scale:{min,max} }} =>
{ mousedown: stream Number
, movement: stream { x: Number, y: Number }
, move: stream { x: Number, y: Number }
, dragging: stream Boolean
, pinching: stream Number
, wheeling: stream Number
, scale: stream Number
, coords: stream { x: Number, y: Number }
, end: stream Boolean?
, settings:
{ scale: { min: Number, max: Number }
, offset: { x: stream Number, y: stream Number}
}
}
Note: Unless otherwise stated, all streams respond to touch and mouse. Even streams like mousemove
.
The idea is, you can abstract away whether an event came from the mouse or
a finger, without having to learn non standard event names.
stream Number
An integer that increments on every mouse move event. Used internally to determine whether a drag is occuring.
Could potentially be used to create a long-press
stream
stream {x,y}
The amount we have moved since the previous event. Used internally
to create the coords
stream.
stream {x,y}
The current position of either the finger or the mouse.
In the case of multiple pointers, move
will be the center
of the first two fingers in the touches
array.
stream Boolean
True if the mouse is click+dragging or if a finger is panning.
stream Boolean
This stream is specific to touch.
True if two fingers are pinch/zooming.
stream Boolean
This stream is specific to the mouse.
True if the mouse wheel is moving. Used internally to dispatch to a specific scale handler.
stream Number
The current scale of the container. Increments when zooming in and decrements when zooming out.
stream Boolean?
Pass true
into this stream to clean up the pointer instance.
pointer.end(true)
All streams will cease to emit new values and will be garbage collected.
Specify the minimum and maximum scale. This will clamp the scale on subsequent events.
The current offset of your container. Allows you to inform
a pointer
instance if your container has moved.
This allows the library to calibrate coords
move
and movement