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

eyes-follow-pointer

v1.1.0

Published

Canvas eyes that smoothly follow the pointer with blinking, eyelid shadow and eyelashes. Works in any container.

Readme

eyes-follow-pointer

Canvas 眼睛组件:在任意容器中渲染两只会“看着”指针移动的眼睛,带平滑缓动、空闲巡航、同步眨眼、眼皮阴影和睫毛效果。支持浏览器直接引入和 npm 包管理。

安装

npm i eyes-follow-pointer
# 或
pnpm add eyes-follow-pointer
# 或
yarn add eyes-follow-pointer

快速开始(浏览器 UMD)

<div id="box" style="width:400px;height:240px;position:relative"></div>
<script src="https://unpkg.com/eyes-follow-pointer@1"></script>
<script>
  const inst = Eyes.create('#box', { ease: 0.14 });
  // 销毁
  // inst.destroy();
</script>

在 React 中使用

要点:容器要有尺寸;在 effect 中创建并销毁实例。

import { useEffect, useRef } from 'react';
import Eyes from 'eyes-follow-pointer';

export default function EyesBox() {
  const boxRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!boxRef.current) return;
    const inst = Eyes.create(boxRef.current, {
      ease: 0.14,
      blinkMinInterval: 2000,
      blinkMaxInterval: 5000,
      blinkDuration: 160,
      eyelashCount: 7,
      eyelashLengthRatio: 0.5,
      eyelidShadowAlpha: 0.4,
    });
    return () => inst.destroy();
  }, []);

  return (
    <div
      ref={boxRef}
      style={{ width: 400, height: 240, position: 'relative', background: '#0f172a' }}
    />
  );
}
  • Next.js/SSR 注意:仅在客户端创建
useEffect(() => {
  if (typeof window === 'undefined' || !boxRef.current) return;
  const Eyes = require('eyes-follow-pointer').default;
  const inst = Eyes.create(boxRef.current, {});
  return () => inst.destroy();
}, []);

在 Vue 3 中使用

要点:在 onMounted 创建,在 onBeforeUnmount 销毁;容器需有尺寸。

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import Eyes from 'eyes-follow-pointer';

const boxRef = ref<HTMLElement | null>(null);
let inst: ReturnType<typeof Eyes.create> | null = null;

onMounted(() => {
  if (!boxRef.value) return;
  inst = Eyes.create(boxRef.value, {
    ease: 0.14,
    blinkMinInterval: 2000,
    blinkMaxInterval: 5000,
    blinkDuration: 160,
    eyelashCount: 7,
    eyelashLengthRatio: 0.5,
    eyelidShadowAlpha: 0.4,
  });
});

onBeforeUnmount(() => {
  inst?.destroy();
});
</script>

<template>
  <div
    ref="boxRef"
    style="width: 400px; height: 240px; position: relative; background: #0f172a;"
  />
</template>

通过 UMD(CDN)在框架中使用

如果不走打包器,在 React/Vue 的挂载生命周期里也可以通过全局 window.Eyes 使用:

<script src="https://unpkg.com/eyes-follow-pointer@1"></script>
<script>
  // 在组件挂载后:
  const inst = window.Eyes.create(containerElement, { ease: 0.14 });
  // 组件卸载时:
  inst.destroy();
</script>

API

  • Eyes.create(target, options?) => { canvas, destroy() }
    • target: 选择器字符串、HTMLElement 或 HTMLCanvasElement
    • 返回:
      • canvas: HTMLCanvasElement 实例
      • destroy(): 清理监听与动画并移除内部创建的 canvas(若传入的是已有 canvas 则不会移除)

Options

  • ease: number(默认 0.12)瞳孔跟随的缓动系数
  • idleAfterMs: number(默认 1500)无交互多少毫秒后进入 idle 巡航
  • idleRadiusRatio: number(默认 0.05)idle 巡航半径占容器短边比例
  • maxDpr: number(默认 2)最高像素比上限(防止过高 DPR 影响性能)
  • gapRatio: number(默认 1.6)两眼中心间距 = gapRatio × eyeRadius
  • blinkMinInterval: number(默认 2500)两次眨眼最短间隔(毫秒)
  • blinkMaxInterval: number(默认 6000)两次眨眼最长间隔(毫秒)
  • blinkDuration: number(默认 180)一次眨眼时长(毫秒)
  • eyelidShadowAlpha: number 0-1(默认 0.35)眼皮阴影基准强度
  • eyelashCount: number(默认 6)上沿睫毛数量
  • eyelashLengthRatio: number(默认 0.45)睫毛长度相对 eyeRadius 比例

常见问题

  • 容器没有尺寸?请给父元素一个明确的 widthheight,建议 position: relative
  • 想控制颜色/尺寸?可直接修改源码中颜色常量、或在后续版本开放更多外观参数。
  • 想在 <canvas> 上使用?直接把 canvas 传入:Eyes.create(canvasEl, options)

许可

MIT