A pointer lock movement manager for customizing your own creative UI.

Overview

Pointer Lock Movement

NPM

publish workflow pages workflow npm version

A pointer lock movement manager for customizing your own creative UI. Inspired by Figma's number input element: Dragging on an input label moves a virtual cursor continuously in an infinite looping area and slides the input's figure value.

pointer-lock-movement

This tool toggles pointer lock state when interacting with a specific element and continually delivers MouseEvents. You can configure its behavior as you like.

🧩 Installation

yarn add pointer-lock-movement (or npm/pnpm)

👇 Usage

import { isSupportPointerLock, pointerLockMovement } from 'pointer-lock-movement'

if (isSupportPointerLock()) {
    const cleanup = pointerLockMovement(TOGGLE_ELEMENT, OPTIONS);

    REQUEST_TO_DISPOSE_THE_LISTENED_EVENTS_CALLBACK(() => {
      cleanup()
    })
}

📎 Example

Enhance your input-number component:

const [value, setValue] = useState(0);

const pointerLockerRef = useRef<HTMLDivElement>(null)

useEffect(
  () => {
    if (!pointerLockerRef.current) {
      return
    }

    return pointerLockMovement(
      pointerLockerRef.current,
      {
          onMove: evt => setValue(val => val + evt.movementX),
          cursor: '⟺',
      }
    )
  },
  [],
)

return (
  <label>
    <div ref={resizeElRef}></div>
    <input value={value} onChange={e => setValue(e.currentTarget.value)} />
  </label>
)

See more examples:

  1. Input Number
  2. Magnifying Glass

👇 API

Name signature description
isSupportPointerLock () => boolean predicates pointer lock is supported
pointerLockMovement (element: Element, option?: PointerLockMovementOption) => () => void stars the pointer lock managing for a specific element and returns cleanup function

📝 Type Definition

type MoveState = {
    status: 'moving' | 'stopped',
    movementX: number,
    movementY: number,
    offsetX: number,
    offsetY: number,
}

type PointerLockMovementOption = {
    onLock?: (locked: boolean) => void,
    onMove?: (event: MouseEvent, moveState: MoveState) => void,
    cursor?: string | HTMLElement | Partial<CSSStyleDeclaration>,
    screen?: DOMRect | HTMLElement | Partial<CSSStyleDeclaration>,
    zIndex?: number,
    loopBehavior?: 'loop' | 'stop' | 'infinite',
    trigger?: 'drag' | 'toggle',
}
  • onLock registers callback to listen locking state changing
  • onMove registers callback to listen mouse movement, it carries the corresponding event and the moving state. If the loopBehavior is configured to stop and the virtual cursor reached the edge of the screen, the moveState.status will be read as stopped.
  • cursor is used as the virtual cursor. By default, the cursor is an empty DIV element:
    • if it is a string, it will be used as the cursor's text content,
    • if it is an HTMLElement, it will be used as the virtual cursor,
    • if it is an object with a snake-case property names, it will be applied as the cursor's CSS style.
  • screen is used as the virtual screen, it usually defines the edges of the virtual cursor. By default, we count the edges of the browser's viewport.
    • if it is a DOMRect, it will be assumed as the size and position information of the virtual screen,
    • if it is an HTMLElement, it will be rendered into the DOM structure,
    • if it is an object with a snake-case property name, it will be regarded as the CSS style and render a virtual screen element with this style.
  • zIndex is used as the z-index CSS property of the virtual cursor/screen with the default value 99999, it is useful when there are other elements over it.
  • loopBehavior is used to control the behavior of the virtual cursor when it reaches the edge of the screen. By default, it is loop.
    • loop: the virtual cursor will be moved to the other side of the screen
    • stop: the virtual cursor will be stopped at the edge of the screen
    • infinite: the virtual cursor will be moved out of the screen
  • trigger is used to control the triggering way of the virtual cursor. By default, it is drag.
    • drag: the virtual cursor movement will be toggled by pointer-down and pointer-up events.
    • toggle: the virtual cursor movement will be toggled by pointer events.
You might also like...

Vesting contract with multiple beneficiaries, tokens, and lock schedules.

⚠️ This code has not been audited, use at your own risk Vesting Contract This contract handles the vesting of ERC20 tokens for multiple beneficiaries.

Mar 14, 2022

Provides Lock and RwLock synchronization primitives.

Lock Provides Lock and RWLock (read write lock) synchronization primitives for protecting in-memory state across multiple tasks and/or microtasks. Ins

Apr 27, 2022

Deduplication tool for pnpm-lock.yaml files

pnpm-deduplicate Remove duplicate dependencies from pnpm-lock.yaml. This project is simple and not have many features. I see it as a temporary solutio

Jan 3, 2023

A simple lock-and-release eventually-consistent DB to be consumed by multi-threaded applications in node.

worsen - a persistence store for quick prototyping A simple lock-and-release eventually-consistent DB to be consumed by multi-threaded applications in

Oct 1, 2022

🤑💰 Crowdfunding Platform backed by Ethereum Blockchain to bring your creative projects to life

🤑💰 Crowdfunding Platform backed by Ethereum Blockchain to bring your creative projects to life

Crypto Crowdfund For Creators Lacking the money to bring your Creative Venture to Life? Crypto Crowdfund Campaigns will help you turn your creative id

Oct 3, 2022

A public board for all the Computer Society and Students to display their profile. An online year-book for you to display your profile in the most creative manner

A public board for all the Computer Society and Students to display their profile. An online year-book for you to display your profile in the most creative manner

Student's Yearbook by IEEE Computer Society Student's yearbook is an open-source project which intends to dispaly the students who will be graduating

Dec 18, 2022

Meogic-tab-manager is an extensible, headless JavaScript tab manager framework.

Meogic-tab-manager is an extensible, headless JavaScript tab manager framework.

MeogicTabManager English document MeogicTabManager是一个有可拓展性的、headless的JavaScript标签页管理框架。 MeogicTabManager旨在提供可自由组装页面框架、自定义页面组件、甚至覆盖框架自带事件响应的开发体验。 Meogi

Oct 8, 2022

This project provides a React-powered web experience using the PokeAPI. It also is a creative space to hone frontend skills.

pokedex-nova This project provides a React-powered web experience using the PokeAPI. It also is a creative space to hone frontend skills. Available Sc

Feb 1, 2022

In game dev, generative art, and creative coding, sine is a ubiquitous function that is often used as a spring-like oscillator for a given parameter.

In game dev, generative art, and creative coding, sine is a ubiquitous function that is often used as a spring-like oscillator for a given parameter.

In game dev, generative art, and creative coding, sine is a ubiquitous function that is often used as a spring-like oscillator for a given parameter.

Feb 22, 2022
Releases(v0.0.5)
Owner
Zheeeng
♘ Cast a cold eye. On life, on death. Horseman, pass by! ♞
Zheeeng
An extension written for customizing skyroom

SkyroomCustomize An extension written for customizing skyroom. Installation First goto extensions page and enable developer mode. Then download latest

Seyed Danial Movahed 6 Mar 15, 2022
Small example showing how you can make game sprite animations using CSS with Javascript movement.

Hi there, I'm Björn Hjorth ?? I like combining the web and game development, if you like what you see please do not be a stranger and say "Hi" on Twit

Björn Hjorth 29 Nov 9, 2022
Deno's first lightweight, secure distributed lock manager utilizing the Redlock algorithm

Deno-Redlock Description This is an implementation of the Redlock algorithm in Deno. It is a secure, lightweight solution to control resource access i

OSLabs Beta 223 Dec 31, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
This is a boilerplate for creating your own languages for various use cases. You can even create your own programming language from scratch!

Bootstrap compiler This is a bootstrap compiler that can be used to compile to compiler written in the target language. You can write a compiler in th

Kaan 3 Nov 14, 2022
A devtool improve your pakage manager use experience no more care about what package manager is this repo use; one line, try all.

pi A devtool improve your pakage manager use experience no more care about what package manager is this repo use; one line, try all. Stargazers over t

tick 11 Nov 1, 2022
This React-Based WebPage allows the client/user system to create their own blog, where users can publish their own opinions.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Gauri Bhand 4 Jul 28, 2022
zkPoB is a mobile compatible tool that lets anyone prove they own a Bufficorn (or any NFT) without revealing which Buffi they own or the address they are verifying themselves with

zkPoB is a mobile compatible tool that lets anyone prove they own a Bufficorn (or any NFT) without revealing which Buffi they own or the address they are verifying themselves with

Marto.eth 10 Aug 25, 2022