npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

glissix

v0.1.0

Published

An inertia-driven physics engine for tactile UI motion.

Downloads

170

Readme

Glissix

An inertia-driven, spring-damper physics engine for tactile UI motion. Focuses on physical simulation (momentum, weight, and drag) so that interface elements feel dragged, flicked, and released naturally, instead of executing rigid time-based bezier curves.

npm version npm downloads license


✦ Features

  • Tactile Material Presets: Load physically pre-tuned configurations like LEATHER, RUBBER, HONEY, and GHOST.
  • Dynamic Impulse Injection: Inject instantaneous speed at any time (applyImpulse) to support fluid swipe-and-flick gestures.
  • Auto-Sanitized Physics: Automatic clamping limits for mass, tension, and friction to guarantee mathematical stability and prevent spring explosion or jitter.
  • Framework Agnostic: Pure TypeScript library with zero dependencies. Runs seamlessly in React, Vue, Svelte, or vanilla JS/TS.
  • Ultra-Lightweight: Only ~2.2KB gzipped.

✦ Core Physical Parameters

Unlike duration-based animators, Glissix uses a mathematical spring-mass-damper system:

  • mass (0.1 - 10.0): Represents the inertia of the moving element. A higher mass creates a feeling of weight, taking longer to accelerate and decelerate.
  • tension (0.001 - 1.0): Represents the stiffness of the spring. High tension pulls the element toward the target aggressively, while lower tension feels loose.
  • friction (0.01 - 0.999): Represents the damping or resistance. High friction dampens oscillation quickly (critical damping), while low friction lets the element bounce.

✦ Installation

npm install glissix

✦ Quick Start

1. Basic 2D Position Tracking (e.g. Card Drag & Flick)

import { Glissix } from 'glissix';

// Instantiate with starting coordinates (0, 0)
const tracker = new Glissix(0, 0);

// Use a built-in tactile preset
tracker.useMaterial('LEATHER');

// Target a new coordinates (e.g., when the user releases a drag)
tracker.setTarget(300, 150);

// Inject an instantaneous speed (e.g. from pointer velocity tracker)
tracker.applyImpulse(25, -12);

// Physics animation loop
function animate() {
  // Step computes the next physical coordinate based on delta forces
  const { x, y, vx, vy } = tracker.step();

  // Apply positions to CSS transform
  card.style.transform = `translate3d(${x}px, ${y}px, 0)`;

  // Keep animating until the element settles
  const speed = tracker.getVelocity();
  const distToTarget = Math.hypot(tracker.getState().targetX - x, tracker.getState().targetY - y);

  if (speed > 0.001 || distToTarget > 0.01) {
    requestAnimationFrame(animate);
  }
}
animate();

2. Animating 1D Values (e.g. Drawer Swipe-to-Open)

You can use the helper updateValue() to drive single variables like sheet positions, opacity, scale, or scroll offsets:

import { Glissix } from 'glissix';

const opacityTracker = new Glissix(0, 0); // initial value 0
opacityTracker.useMaterial('RUBBER');

function fadeOut() {
  function tick() {
    opacityTracker.updateValue(1.0, (val, speed) => {
      overlay.style.opacity = val.toString();
    });

    if (Math.abs(opacityTracker.getState().x - 1.0) > 0.001) {
      requestAnimationFrame(tick);
    }
  }
  tick();
}

✦ Presets & Materials

| Material Preset | Mass | Tension | Friction | Physical Feeling | | :--- | :--- | :--- | :--- | :--- | | LEATHER | 2.0 | 0.10 | 0.85 | Heavy, draggy, premium tactile dampening | | RUBBER | 0.5 | 0.40 | 0.70 | Snappy, highly responsive, elastic spring | | HONEY | 5.0 | 0.05 | 0.95 | Slow, high-viscosity, super smooth glide | | GHOST | 0.1 | 0.20 | 0.99 | Float-like, almost frictionless motion |


✦ API Reference

Constructor

const tracker = new Glissix(initialX: number, initialY: number, config?: Partial<GlissixConfig>);

Creates a new motion controller.

  • initialX: Initial position along the X axis.
  • initialY: Initial position along the Y axis.
  • config: Optional configuration object (values are automatically clamped):
    • mass (defaults to 1.0)
    • tension (defaults to 0.15)
    • friction (defaults to 0.82)

Instance Methods

setTarget(x: number, y: number): void

Sets the new destination coordinates.

applyImpulse(vx: number, vy: number): void

Injects an instantaneous impulse velocity (adds to current velocity). Perfect for throwing/flicking cards or lists.

step(): GlissixStep

Performs a single simulation step. Returns the current physics metrics: { x: number, y: number, vx: number, vy: number }

updateValue(target: number, callback: (value: number, velocity: number) => void): void

Steps a single scalar value. Sets target-x to target and returns the output via the callback.

useMaterial(name: GlissixMaterial): void

Loads a pre-tuned configuration ('LEATHER' | 'RUBBER' | 'HONEY' | 'GHOST').

setConfig(config: Partial<GlissixConfig>): void

Modifies the active configuration fields on-the-fly.

getVelocity(): number

Returns the scalar magnitude of the current velocity vector (speed).

getState(): GlissixState

Returns the exact physics simulation state copy: { x, y, vx, vy, targetX, targetY }

reset(x?: number, y?: number): void

Resets the position, target, and sets velocities to zero.


✦ Why Glissix?

Traditional transition tools require you to specify a preset curve (like ease-out) and duration. If a user flicks an element halfway through an animation, the motion snaps awkwardly.

Glissix solves this:

  1. Preserved Momentum: If a user drags and releases at speed, the swipe velocity is fed directly into the engine, producing a seamless decelerating slide.
  2. Dynamic Redirection: Changing targets mid-flight alters the acceleration vector smoothly, preventing sudden direction snaps.
  3. Pure Math: No browser timers or complex rendering context is required, making it incredibly lightweight and deterministic.

✦ Creator

Developed and maintained by Nilanshu Kumar Singh:

✦ License

MIT