她说想要浪漫,我把浏览器鼠标换成了柴犬,点一下就有烟花(附源码)

昨天下班前,女朋友给我甩了个柴犬表情包:能不能把我的鼠标变成它?最好点一下还能"啪"一下冒烟花。她说得挺自然,我听着只想笑:这不就是我的主场吗。于是我关了外卖,开了编辑器,直接开干一个Chrome扩展,先把鼠标换成小柴犬,再加一手彩色烟花。第二天她用上了,第一句话就是:也太治愈了吧!而我更开心的是------不到一百行就搞定。

先看效果:鼠标样式变成柴犬,点击有粒子动效

需求分析:

  • 随处可用:在任何网页都生效,打开即用,无需手动注入。
  • 不打扰交互:可点击元素仍是"手形",输入框仍是"文本光标",不要因为可爱影响效率。
  • 轻量不卡顿:粒子数量适中,淡出动画自然,不能拖累页面性能。
  • 好上手:解压即装,不需要复杂配置。

项目结构

bash 复制代码
shiba-cursor
├── manifest.json      # 扩展的"身份证"
├── content.js         # 内容脚本(替换光标 + 粒子动效)
└── mouse.png          # 柴犬鼠标样式图

文件说明:

  • manifest.json:扩展身份信息
  • content.js:处理替换光标 + 粒子动效
  • mouse.png:柴犬小图标

手把手实现

第一步:创建项目文件

创建文件夹 shiba-cursor

创建manifest.json文件

json 复制代码
{
  "manifest_version": 3,
  "name": "鼠标样式",
  "version": "1.0",
  "description": "自动应用自定义鼠标样式",
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "run_at": "document_start"
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["mouse.png"],
      "matches": ["<all_urls>"]
    }
  ]
}

创建content.js文件

js 复制代码
(function () {
  const iconUrl = chrome.runtime.getURL('mouse.png');
  const body = document.body;

  // 注入样式
  const style = document.createElement('style');
  style.textContent = `
    /* 默认鼠标替换为柴犬 */
    * {
      cursor: url('${iconUrl}') 12 12, auto !important;
    }
    
    /* 可点击元素恢复原生手形指针 */
    a, button, [role="button"], [onclick], [role="link"],
    input[type="submit"], input[type="button"], input[type="reset"], input[type="image"],
    select, option, label[for],
    .btn, .button, .clickable, .link, .pointer,
    [tabindex]:not([tabindex="-1"]),
    summary, details > summary,
    [data-toggle], [data-click], [data-action] {
      cursor: pointer !important;
    }
    
    /* 文本输入恢复原生文本光标 */
    input:not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="range"]):not([type="color"]), 
    textarea, [contenteditable="true"], [contenteditable=""],
    .text-input, .input-field {
      cursor: text !important;
    }
    
    /* 特殊输入类型保持默认样式 */
    input[type="checkbox"], input[type="radio"], input[type="file"], 
    input[type="range"], input[type="color"] {
      cursor: default !important;
    }
    
    /* 禁用元素保持默认样式 */
    [disabled], .disabled {
      cursor: not-allowed !important;
    }
    
    /* 调整大小元素 */
    [resize], .resize {
      cursor: nw-resize !important;
    }
    
    /* 粒子效果 */
    .click-particle {
      position: fixed;
      border-radius: 50%;
      pointer-events: none;
      z-index: 9998;
    }
  `;

  (document.head || document.documentElement).appendChild(style);

  // 粒子效果-从光标位置发出
  const createParticles = (x, y) => {
    const particleCount = 8;
    const adjustedX = x - 12;
    const adjustedY = y - 12;

    for (let i = 0; i < particleCount; i++) {
      const particle = document.createElement('div');
      particle.className = 'click-particle';

      // 随机大小(4-8px)
      const size = 4 + Math.random() * 4;
      particle.style.width = `${size}px`;
      particle.style.height = `${size}px`;

      // 随机颜色
      const hue = Math.random() * 360;
      particle.style.backgroundColor = `hsl(${hue}, 80%, 60%)`;
      particle.style.boxShadow = `0 0 ${size / 2}px hsl(${hue}, 80%, 60%)`;

      // 从光标热点位置发出
      particle.style.left = `${adjustedX}px`;
      particle.style.top = `${adjustedY}px`;

      // 随机的飞散方向和距离
      const angle = Math.random() * Math.PI * 2;
      const distance = 20 + Math.random() * 40;
      const dx = Math.cos(angle) * distance;
      const dy = Math.sin(angle) * distance;

      body.appendChild(particle);

      const animation = particle.animate(
        [
          {
            transform: 'translate(0, 0) scale(1) rotate(0deg)',
            opacity: 1,
          },
          {
            transform: `translate(${dx}px, ${dy}px) scale(0) rotate(360deg)`,
            opacity: 0,
          },
        ],
        {
          duration: 600 + Math.random() * 400,
          easing: 'cubic-bezier(0.25, 0.1, 0.25, 1)',
        }
      );

      // 动画结束后移除元素
      animation.onfinish = () => particle.remove();
    }
  };

  // 事件监听
  document.addEventListener('click', (e) =>
    createParticles(e.clientX, e.clientY)
  );
})();

mouse.png 右键下载图标即可

第二步:安装扩展

  1. 打开Chrome浏览器
  2. 地址栏输入:chrome://extensions/
  3. 打开右上角"开发者模式"
  4. 点击"加载已解压的扩展程序"
  5. 选择刚才的文件夹,然后确定

第三步:测试效果:打开任意网站看看鼠标样式修改是否有效

总结

这小玩意儿不复杂,但治愈值拉满。一个小小的 Chrome 扩展,把"可爱"和"仪式感"塞进了每个网页。她说"太治愈了",我说"这才不到一百行"。

相关推荐
To_OC3 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC3 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic3 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy3 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志4 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble5 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长5 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯6 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜6 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司6 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能