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

dotmote

v0.3.3

Published

Brand-agnostic dotted-matrix glow background. Framework-agnostic Canvas core with thin React and Vue wrappers.

Readme

dotmote

在线演示 — dotmote.imryan.dev。

框架无关的点阵发光背景,支持 React 与 Vue。把几个字母、emoji 或形状撒在一片无边的点阵上——它们四处漂移、彼此碰撞,然后从网格里透出光来,像一场小小的灯展。

  • React 18+ · TypeScript · Canvas 2D · SSR 安全
  • 零运行时依赖 —— 只需 react(peer)
  • 纯 Canvas 2D,不用任何粒子或点阵库

安装

npm install dotmote

需要 react >= 18。提供 ESM + TypeScript 类型声明。

快速开始

import { Dotmote } from 'dotmote';

export function Page() {
  return (
    <div style={{ position: 'relative', minHeight: '100vh' }}>
      <Dotmote theme="gradient" />

      <main style={{ position: 'relative', zIndex: 1, padding: 24 }}>
        <h1>My page</h1>
      </main>
    </div>
  );
}

外层包裹的 <div> 是绝对定位、垫在所有内容后面——把你的内容放进一个 z-index 更高的兄弟节点即可。

Vue

Canvas 核心与框架无关——React 与 Vue 都只是同一套 createDotMatrixCore 的薄封装。Vue 3 用 dotmote/vue 入口:

<script setup>
import { Dotmote } from 'dotmote/vue';
</script>

<template>
  <div style="position: relative; min-height: 40vh">
    <Dotmote values="👋dotmote!" theme="auto" motion="ticker-right" />
  </div>
</template>

class / style 会透传到外层 <div>。

属性

| Prop | Type | Default | Description | | --- | --- | --- | --- | | values | string | — | 用一个字符串填充内容——每个字符成为一个主体(空白会被跳过)。items 的简写。 | | items | (ContentItem \| string)[] | ['A','B','C','D','E'] | 要漂移的主体。字符串会变成字母;见 内容。 | | theme | ThemePreset \| ThemeConfig | 'mono' | 预设名,或内联配置(dotColor、activeDotColor、glow、background)。 | | motion | MotionMode | 'drift' | 主体的运动方式——见 动效。 | | speed | number | 1 | 全局速度倍率。 | | glowStrength | number | 1 | 发光强度:<1 变淡,>1 更亮。(glowAlpha 是已废弃的别名。) | | dotRadius | number | spacing <= 9 ? 0.82 : 1 | 点的大小(px)。越大越"颗粒感"。 | | fontFamily | string | "Trebuchet MS", ui-rounded, sans-serif | 字体栈(字重/字号会自动前置:900 ${fontSize}px …)。 | | fontSizeOverride | number \| ((w)=>number) | — | 覆盖自动字号。 | | fontSizeMin / fontSizeMax | number | 207 / 270 | 自动字号钳制的上下界。 | | breakpoints | Partial<Breakpoints> | {small:372, medium:640, …} | 响应式几何。 | | spacingScale | number | 1 | 点阵密度——<1 更密,>1 更疏。 | | introDurationMs | number | 520 | 停留 + 淡入时长。 | | className / style | string / CSSProperties | — | 传给包裹 <div>。 | | ariaHidden | boolean | true | 包裹 <div> 的 aria-hidden。 |

主题

选一个中性预设,或换成你自己的配色:

<Dotmote theme="mono" />   // 默认
<Dotmote theme="dark" />
<Dotmote theme="gradient" />

<Dotmote
  theme={{
    dotColor: 'rgba(96, 165, 250, 0.6)',
    glow: ['rgba(56, 189, 248, 0.9)', 'rgba(99, 102, 241, 0.9)', 'rgba(236, 72, 153, 0.9)'],
    background: '#0b1020',
  }}
/>

预设:light、dark、mono、gradient、rainbow。

interface ThemeConfig {
  dotColor?: string;       // 点阵颜色
  activeDotColor?: string; // 纯色发光(3 个 stop 同色);不填则用 `glow`
  glow: [string, string, string];
  background?: string;
}

切换主题会原地热更新——主体保持当前位置和运动不变。

内容

values 是最快的填充方式——每个字符成为一个主体:

<Dotmote values="dotmote" />
<Dotmote values="🌊🔥⭐🌙" />

想逐个控制,就用 items:

<Dotmote items={['A', 'B', 'C', 'D', 'E']} />
<Dotmote items={[{ kind: 'shape', value: 'circle', radius: 60 }, { kind: 'emoji', value: '🌊' }]} />
type ContentItem =
  | { kind: 'text'; value: string }
  | { kind: 'emoji'; value: string }
  | { kind: 'shape'; value: 'circle' | 'square' | 'triangle' | 'star' | 'diamond'; radius?: number }
  | { kind: 'path'; value: string }; // SVG 路径

动效

| Mode | 行为 | | --- | --- | | drift | 漂移 + 碰壁反弹 + 两两碰撞 | | roam | 漂移 + 反弹,主体彼此穿过 | | static | 淡入后静止 | | ticker-left / ticker-right | 跑马灯:主体排成一行循环滚动 |

开发

npm install
npm run dev       # playground 在 http://localhost:5199/examples/index.html
npm test          # vitest(物理 + 内容归一化)
npm run lint
npm run typecheck
npm run build     # tsc → dist/

playground 在任何现代浏览器都能跑——把窗口跨过 372 / 640px 看断点变化,并在 DevTools → Console 里确认刷新无报错。

架构

薄薄一层 React 包装,下面是框架无关的 Canvas 核心。四个画布:点阵、它的白色 alpha 遮罩、被渐变照亮的主体、以及合成层。点阵和遮罩只在尺寸变化时重绘;发光层每帧合成。

说明 / 限制

  • 仅 ESM —— 没有 CommonJS 构建;请用支持 ESM 的打包器。
  • emoji 保持自身颜色 —— 它们不跟随发光渐变(文本和形状会变色)。
  • path 只支持基础用法 —— 传入一条已大致以原点为中心、缩放到约 ±100 单位的路径。
  • 碰撞是简化的动量交换,不是完整的物理冲量。

许可证

MIT