@enigmax/primitives

中文文档
0.28.0发布于 2026/09/29Apache-2.0TypeScriptES Module零依赖构建来源已验证近 30 天下载 2086

无头组件:行为,时间和无障碍,没有自己的风格. 框架不可知核外加薄适配器.

中文使用文档
文档目录6 节
  1. 安装
  2. 用这个
  3. 选项
  4. 为何明显执行错误
  5. 样式
  6. 测试

@enigmax/ 原始内容

无头互动原始:行为,时机和可取性,没有自己的风格.

马克以像素每秒的速度取出,从不持续. 环行的一圈和它的内容一样长,所以持续的时间可以使速度 content / duration 而每增加一个项目,该行运行得更快. 从奇长阵列分出两行,相同 --duration: 20s,测量了53.2 px/s和66.5 px/s,并意在看起来像一对. 固定50年代的提供铁路在10个、15个和20个物品上测得45个、67个和87个px/s,因为没有人在增加一个提供商时编辑时间。 取出一个速度并得出持续时间:同一条铁路随后在所有三个计数中测出67.0px/s.

安装

npm install @enigmax/primitives
# or, to copy the source in and own it:
enigma add marquee --copy

用这个

反应 :

import { useMarquee } from "@enigmax/primitives/react";

function LogoWall({ logos }) {
    const { laneRef, trackRef, copies, dragging } = useMarquee({ speed: 80, hoverScale: 0.15 });

    return (
        <div ref={laneRef} style={{ cursor: dragging ? "grabbing" : "grab" }}>
            <div ref={trackRef} style={{ display: "flex" }}>
                {Array.from({ length: copies }, (_, copy) => (
                    <div key={copy} aria-hidden={copy > 0} style={{ display: "flex", gap: 32 }}>
                        {logos.map(logo => <a key={logo.id} href={logo.href}>{logo.name}</a>)}
                    </div>
                ))}
            </div>
        </div>
    );
}

香草, Astro, 或其他任何能给你两个元素的东西:

import { createMarquee } from "@enigmax/primitives";

const marquee = createMarquee(document.querySelector("[data-lane]"), document.querySelector("[data-track]"), {
    speed: 80,
    hoverScale: 0.15
});

核心克隆了赛道上第一个灌道的孩子. 在反应中,钩子报告 copies 倒数取而代之,因此React保留了DOM的所有权.

选项

选项默认含义
speed60以像素为每秒. 没有时间.
reversefalse向起起入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入.
verticalfalse在Y轴上滚动.
draggabletrue抓住并抛出行.
hoverScale1速度乘以 a 鼠标 卧倒在一行. 0 暂停.
decay0.12一秒后剩下的速度差距的分数. 0.35 有点拖累.
manageStylestrue应用行为需要的样式。 永远不要主题风格.

为何明显执行错误

其中3个每只要一个生产错误。 这些是这一一揽子方案存在的原因,而不是片段.

setPointerCapture 默然地打破了行中的每一个链接. 一个指针捕获重瞄准兼容鼠标事件,所以 click 平面媒体在车道上而不是按住的卡片上到达,卡片的链接从不打开. 一条九条道的旋转木马悄悄地停止了九条链路 而源头里什么也没有看错 此套件绑定 pointermove 编号 : pointerup 编号 : pointercancel 改为 window,这是所有抓取的 - 鼠标下拉已经在 OS 级别上抓取了鼠标,所以浏览器窗口外的放出仍然到达.

touch-action 决定手机能否滚动页面. 没有它,浏览器就拥有了水平的刷子,拖曳处理器从不看到. 与 none,访问者无法再通过开始行上手势来滚动页面,这在手机上是屏幕宽度的大部分. 车道得到 pan-y (或 pan-x 当垂直时.

忽略的悬浮效应 pointerType 永远保持接触. 水龙头大火 pointerenter 也一样,在触摸上... ... ..... pointerleave 所以在第一次水龙头之后,"在徘徊上慢下来" 就会以15%的速度永远离开排位 这里每条徘徊道都是被锁住的 pointerType === "mouse" - 光是这个门是不够的,需要CI故障:铬跟随 兼容性 索赔的指针事件 pointerType: "mouse"它在Linux上而不是在Windows上发出它们,所以天真之门通过一台机器而失败在另一台机器上. 因此,一触也抑制了徘徊一秒钟 pointerleave 清除状态, 不论指针类型如何, 因为无法消除的悬浮是错误 .

简而言之,其余的:圈由两个拷贝之间的台阶来测量,而不是由项目宽度来计算;转换由一个驱动 requestAnimationFrame 循环而不是 CSS 键框,它在每个重写者上重新启动; 一个整数器携带了巡航,徘徊和动力,所以没有人能作为切入而来; 拖过~6px在捕获相中取消了点击; 右键从不开始拖动; 指针在放出前仍被拖出~90ms; 在拖动时会减少自動放出, 因为拖动是对指针的回答,而不是页面自己主动的动作.

样式

原始船只没有视觉风格 它只规定行为需要什么overflow, (中文(简体) ), touch-action, (中文(简体) ), user-select, (中文(简体) ), will-change, (中文(简体) ), transform)并曝光状态作为主题要钩入的数据属性:

[data-enigma-marquee]                        { cursor: grab; }
[data-enigma-marquee][data-dragging]         { cursor: grabbing; }
[data-enigma-marquee][data-hovering]         { --logo-opacity: 1; }
[data-enigma-marquee][data-reduced-motion="true"] { /* autoplay is off */ }
[data-enigma-marquee-track]                  { display: flex; }
[data-enigma-marquee-copy]                   { display: flex; gap: 2rem; }

测试

套房驱动真实的浏览器和样本 new DOMMatrixReadOnly(getComputedStyle(track).transform).m41 而不是问引擎它相信什么.

npm run test:install   # once, fetches Chromium
npm test
检查通行条件
2,9,11,20项的速度相同测量的px/s在1%以内
沿着指针拖曳200px 刷新移动行 200.0px
释放单调地在巡航上衰变, 没有显示翻转
4个视图调整大小帧不移动多于一帧
在链接上拖动结束0个导航
完全点击并点击链接每架1个导航
触动排行不坚持徘徊速度
电话垂直刷卡页面仍然滚动
prefers-reduced-motion0.00px 闲放漂移,拖放还行
别动,然后释放不飞

两种欺骗自己的方法, 这两种方法都产生了虚假的警报 当它被写: 不要测量大小 改变像之前/之后,因为 setViewportSize 需要几百毫秒 在此期间,行 合法地继续移动 - 抽样每个帧 寻找一个异常的一。 并丢弃前几个样本,因为安装了取样器后的第一个RAF三角洲接近于零并产生无意义的px/s突起.

版本与发布记录

@enigmax/primitives 共发布 33 个版本,首次发布于 2026/08/14;过去 12 个月发布了 33 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.28.0latest2026/09/291 个月前
0.27.02026/09/072 个月前
0.26.02026/09/072 个月前
0.25.02026/09/062 个月前
0.24.02026/09/052 个月前
0.23.02026/09/022 个月前

关于 @enigmax/primitives 的常见问题

@enigmax/primitives 是什么?

无头组件:行为,时间和无障碍,没有自己的风格. 框架不可知核外加薄适配器.

如何安装 @enigmax/primitives?

在项目目录运行 npm install @enigmax/primitives,或使用 pnpm add / yarn add / bun add。

@enigmax/primitives 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@enigmax/primitives 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@enigmax/primitives 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@enigmax/primitives 可以商用吗?

@enigmax/primitives 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@enigmax/primitives 的下载量有多少?

根据 npm 官方下载统计,@enigmax/primitives 在 2026/10/14 – 2026/11/12 这 30 天内被下载 2,086 次,日均约 70 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@enigmax/primitives 还在维护吗?

最新版本 0.28.0 发布于 2026/09/29(1 个月前);至今共发布 33 个版本,其中过去 12 个月发布了 33 个;首次发布于 2026/08/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。