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

tactile-motion

v0.1.0

Published

A headless motion engine for tactile UI controls.

Readme

tactile-motion

面向触感交互控件的无头运动引擎。

适用于标尺(Ruler)、滑块(Slider)、选择器(Picker)、旋钮(Knob)、时间轴及 Canvas 控件。

License: MIT npm version npm downloads bundle size

手势层输入 → 物理演算 → 数值输出
   drag → velocity → inertia → settle
  • 连续运动:基于指数衰减的精确物理模型,手感细腻可调。
  • 零依赖:Core 核心零运行时依赖(压缩后约 1.8 kB gzip)。
  • 无头设计(Headless):不绑定 DOM 事件与渲染层,自由配合任何 UI。
  • 框架无关:纯 TS 核心库,附带开箱即用的 React 适配器。
  • 帧率无关:在 30 / 60 / 120 / 144 Hz 下具有一致的物理落点。

English · 示例代码

安装

npm install tactile-motion

若使用 React 适配器(tactile-motion/react),需在宿主项目中安装 react(>= 16.8.0)。

核心使用(Core API)

import { createTactileMotion } from 'tactile-motion';

const motion = createTactileMotion({
  value: 0,
  min: 0,
  max: 1000,
  friction: 0.94,
  velocityMultiplier: 1,
  maxVelocity: 3,
  threshold: 0.01,
  onChange(value) {
    render(value);
  },
  onStateChange(state) {
    console.log(state); // 'idle' | 'dragging' | 'animating'
  },
  onRest(value) {
    console.log('settled', value);
  },
});

// 绑定手势生命周期:
motion.start(); // 手指按下 / 拖拽开始
motion.drag(12.5); // 移动,传入单次增量 delta
motion.release(); // 松手,启动惯性滑动

motion.stop(); // 立即停止并保持当前位置
motion.set(500); // 停止并直接定位到指定值

配置项(Options)

| 参数 | 默认值 | 说明 | | -------------------- | ------------------------ | -------------------------------------------------------------------- | | value | 0 | 初始数值(会自动受限于 [min, max])。 | | min / max | -Infinity / Infinity | 硬边界范围。 | | friction | 0.94 | 每 16.67ms 保留的速度比例(0 <= friction < 1),数值越小减速越快。 | | velocityMultiplier | 1 | 释放时的速度放大倍率。 | | maxVelocity | Infinity | 释放速度上限(单位/ms),在倍率生效后截断。 | | threshold | 0.01 | 静止速度阈值(单位/ms),低于此值触发停止。 | | scheduler | RAF / timer | 帧调度器适配层。 |

实例方法(Methods)

| 方法 | 说明 | | --------------------- | --------------------------------------------------------- | | getValue() | 获取当前数值。 | | getSnapshot() | 获取不可变的快照对象 { value, velocity, state }。 | | start(time?) | 进入 dragging 状态并重置速度采样。 | | drag(delta, time?) | 应用位移增量并更新速度估算。 | | release(time?) | 释放拖拽并进入 animating 惯性阶段(无速度时直接静止)。 | | stop() | 取消运动并在当前数值停留在 idle 状态。 | | set(value) | 取消运动,直接设置受限数值并通知变更。 | | configure(options) | 动态更新配置项。 | | subscribe(listener) | 监听快照变更,返回取消订阅函数。 |

React

import { useTactileMotion } from 'tactile-motion/react';

function Slider() {
  const motion = useTactileMotion({
    min: 0,
    max: 100,
    maxVelocity: 2,
    onChange(val) {
      // 变动回调
    },
  });

  return (
    <div>
      <span>{motion.value.toFixed(1)}</span>
      {/* 手势层可调用 motion.dragStart() / motion.dragMove(delta) / motion.dragEnd() */}
    </div>
  );
}

Hook 返回当前快照属性(value, velocity, state)、全部核心方法,以及便捷别名 dragStart、dragMove、dragEnd。原生支持 SSR 与 React StrictMode。

刻度吸附(Snapping)

引擎本身专注连续物理运动。吸附逻辑应由控件语义层在 onRest 中决定:

const step = 10;
const motion = createTactileMotion({
  onRest(position) {
    motion.set(Math.round(position / step) * step);
  },
});

本地开发

# 启动示例实验台(Ruler、Slider、Knob、Canvas)
npm install
npm run dev

# 运行全套检查与测试
npm run check

License

MIT