Skip to content

usePointer

ts
usePointer(): Service<PointerProps>
usePointer(target: Element): Service<ElementPointerProps>

The pointer, in the viewport or in a box.

Props

ts
interface PointerProps {
  readonly event: PointerEvent | null;
  readonly isDown: boolean;
  readonly x: number;
  readonly y: number;
  readonly deltaX: number;
  readonly deltaY: number;
  readonly maxX: number;
  readonly maxY: number;
  readonly progressX: number;
  readonly progressY: number;
}

interface ElementPointerProps extends PointerProps {
  readonly relativeX: number;
  readonly relativeY: number;
  readonly relativeProgressX: number;
  readonly relativeProgressY: number;
}

isGrabbing is removed. usePointer() uses pointer events only and follows one pointerId at a time.

Usage

js
import { 
Base
,
usePointer
} from '@studiometa/js-toolkit';
class
Cursor
extends
Base
{
static
config
= {
name
: 'Cursor' };
mounted
() {
return
usePointer
().
subscribe
(({
x
,
y
}) => {
this.
$el
.
style
.
transform
= `translate(${
x
}px, ${
y
}px)`;
}); } }

The pointer in a box

usePointer(el) is one lazy service per target, and its props add the four relative* fields beside the viewport ones:

js
import { 
Base
,
usePointer
} from '@studiometa/js-toolkit';
class
Tilt
extends
Base
{
static
config
= {
name
: 'Tilt' };
mounted
() {
return
usePointer
(this.
$el
).
subscribe
(({
relativeProgressX
,
relativeProgressY
}) => {
this.
$el
.
style
.
setProperty
('--tilt-x',
String
(
relativeProgressX
* 2 - 1));
this.
$el
.
style
.
setProperty
('--tilt-y',
String
(
relativeProgressY
* 2 - 1));
}); } }

The targeted service subscribes to the singleton, so one set of document listeners serves every target however many boxes are being watched.

When the box is measured

On demand, and kept until a scroll (captured at the document), a resize, or the target's ResizeObserver can have moved it.

The layout box is the frame of reference, so a transform the consumer applies from its own callback does not invalidate it — which is exactly what a tilt or a parallax needs.

{ immediate: true }

Does nothing before the pointer has been seen: there is no current value to deliver, which is what hasProps() says.

Mixin

js
class Tilt extends withPointer(Base) {
  moved({ relativeProgressX }) {}
}

withPointer defaults its target to $el.

MIT Licensed