如何制作一个简单的浏览器用户扩展程序

437 阅读9分钟
  • 桌面新建文件夹:cromePointerEffect-plugin
  • 新建:manifest.json
  • 粘贴以下代码:
{
  "name": "custom-cursor",
  "version": "2.1",
  "description": "cool pointer.",
  "permissions": [
    "storage"
  ],
  "icons": {

  },
  "content_scripts": [
    {
      "matches": [
        "*://*/*"
      ],
      "js": [
        "cursorSpecialEffects.js"
      ],
      "css": ["custom-cursor.css"]
    }
  ],
  "manifest_version": 3
}

html, body, body select, body .custom-cursor-default-hover { cursor: url(data:image/png;base64,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) 0 2, auto !important; }

body button, body [type='button'], body input[type='reset'], body input[type='submit'], body [role="button"], ::-webkit-search-cancel-button, ::-webkit-search-decoration, ::-webkit-scrollbar-button, ::-webkit-file-upload-button, [role^=button], .cc_pointer, [type="search"]::-webkit-search-cancel-button, a, select, [type="search"]::-webkit-search-decoration, .paper-button, .ytp-progress-bar-container, input[type=submit], :link, :visited, a > *, img, .ogdlpmhglpejoiomcodnpjnfgcpmgale_pointer, ::-webkit-file-upload-button, .ytp-volume-panel, #myogdlpmhglpejoiomcodnpjnfgcpmgale .icon, body .custom-cursor-on-hover { cursor: url(data:image/png;base64,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) 1 2, pointer !important; }

- 新建:custom-cursor.css
- 粘贴以下代码:
```js

- 新建:cursorSpecialEffects.js
- 粘贴以下代码:
```js
class Circle {
  constructor({ origin, speed, color, angle, context }) {
    this.origin = origin
    this.position = { ...this.origin }
    this.color = color
    this.speed = speed
    this.angle = angle
    this.context = context
    this.renderCount = 0
  }

  draw() {
    this.context.fillStyle = this.color
    this.context.beginPath()
    this.context.arc(this.position.x, this.position.y, 2, 0, Math.PI * 2)
    this.context.fill()
  }

  move() {
    this.position.x = (Math.sin(this.angle) * this.speed) + this.position.x
    this.position.y = (Math.cos(this.angle) * this.speed) + this.position.y + (this.renderCount * 0.3)
    this.renderCount++
  }
}

class Boom {
  constructor({ origin, context, circleCount = 10, area }) {
    this.origin = origin
    this.context = context
    this.circleCount = circleCount
    this.area = area
    this.stop = false
    this.circles = []
  }

  randomArray(range) {
    const length = range.length
    const randomIndex = Math.floor(length * Math.random())
    return range[randomIndex]
  }

  randomColor() {
    const range = ['1','2', '3', '4', '5', '6', '7','8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
    return '#' + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range) + this.randomArray(range)
  }

  randomRange(start, end) {
    return (end - start) * Math.random() + start
  }

  init() {
    for (let i = 0; i < this.circleCount; i++) {
      const circle = new Circle({
        context: this.context,
        origin: this.origin,
        color: this.randomColor(),
        angle: this.randomRange(Math.PI - 1, Math.PI + 1),
        speed: this.randomRange(1, 6)
      })
      this.circles.push(circle)
    }
  }

  move() {
    this.circles.forEach((circle, index) => {
      if (circle.position.x > this.area.width || circle.position.y > this.area.height) {
        return this.circles.splice(index, 1)
      }
      circle.move()
    })
    if (this.circles.length == 0) {
      this.stop = true
    }
  }

  draw() {
    this.circles.forEach(circle => circle.draw())
  }
}

class CursorSpecialEffects {
  constructor() {
    this.computerCanvas = document.createElement('canvas')
    this.renderCanvas = document.createElement('canvas')

    this.computerContext = this.computerCanvas.getContext('2d')
    this.renderContext = this.renderCanvas.getContext('2d')

    this.globalWidth = window.innerWidth
    this.globalHeight = window.innerHeight

    this.booms = []
    this.running = false
  }

  handleMouseDown(e) {
    const boom = new Boom({
      origin: { x: e.clientX, y: e.clientY },
      context: this.computerContext,
      area: {
        width: this.globalWidth,
        height: this.globalHeight
      }
    })
    boom.init()
    this.booms.push(boom)
    this.running || this.run()
  }

  handlePageHide() {
    this.booms = []
    this.running = false
  }

  init() {
    const style = this.renderCanvas.style
    style.position = 'fixed'
    style.top = style.left = 0
    style.zIndex = '999999999999999999999999999999999999999999'
    style.pointerEvents = 'none'

    style.width = this.renderCanvas.width = this.computerCanvas.width = this.globalWidth
    style.height = this.renderCanvas.height = this.computerCanvas.height = this.globalHeight

    document.body.append(this.renderCanvas)

    window.addEventListener('mousedown', this.handleMouseDown.bind(this))
    window.addEventListener('pagehide', this.handlePageHide.bind(this))
  }

  run() {
    this.running = true
    if (this.booms.length == 0) {
      return this.running = false
    }

    requestAnimationFrame(this.run.bind(this))

    this.computerContext.clearRect(0, 0, this.globalWidth, this.globalHeight)
    this.renderContext.clearRect(0, 0, this.globalWidth, this.globalHeight)

    this.booms.forEach((boom, index) => {
      if (boom.stop) {
        return this.booms.splice(index, 1)
      }
      boom.move()
      boom.draw()
    })
    this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
  }
}

const cursorSpecialEffects = new CursorSpecialEffects()
cursorSpecialEffects.init()

// chrome.runtime.onInstalled.addListener(details => {
//   if (details.reason === 'install') {
//     // install
//     alert("The pointer is cool");
//   }
//   if (details.reason === 'update') {
//     alert("The cool pointer has updated");
//   }
// })

function fairyDustCursor(){
  var possibleColors = ["#D61C59", "#E7D84B", "#1B8798"];
  var width = window.innerWidth;
  var height = window.innerHeight;
  var cursor = { x: width / 2, y: width / 2 };
  var particles = [];
  var particleBox = null;
  function init() {
    particleBox = document.createElement("div");
    particleBox.style.position = "fixed";
    particleBox.style.top = "0";
    particleBox.style.left = "0";
    particleBox.style.width = "100%";
    particleBox.style.height = "100%";
    particleBox.style.pointerEvents = "none";
    particleBox.classList.add("fairy-dust-cursor");
    document.body.appendChild(particleBox);
    bindEvents();
    loop()
  }
  function bindEvents() {
    document.addEventListener("mousemove", onMouseMove);
    window.addEventListener("resize", onWindowResize)
  }
  function onWindowResize(e) {
    width = window.innerWidth;
    height = window.innerHeight
  }
  function onMouseMove(e) {
    cursor.x = e.clientX; cursor.y = e.clientY;
    addParticle(cursor.x, cursor.y, possibleColors[Math.floor(Math.random() * possibleColors.length)])
  }
  function addParticle(x, y, color) {
    var particle = new Particle();
    particle.init(x, y, color);
    particles.push(particle)
  }
  function updateParticles() {
    for (var i = 0; i < particles.length; i++) {
      particles[i].update()
    }
    for (var i = particles.length - 1; i >= 0; i--) {
      if (particles[i].lifeSpan < 0) {
        particles[i].die(); particles.splice(i, 1)
      }
    }
  }
  function loop() {
    requestAnimationFrame(loop); updateParticles()
  }
  function Particle() {
    this.character = "*";
    this.lifeSpan = 120;
    this.initialStyles = {
      "position": "fixed",
      "display": "inline-block",
      "top": "0px",
      "left": "0px",
      "pointerEvents": "none",
      "touch-action": "none",
      "z-index": "10000000",
      "fontSize": "25px",
      "will-change": "transform"
    };
    this.init = function (x, y, color) {
      this.velocity = {
        x: (Math.random() < 0.5 ? -1 : 3) * (Math.random() / 2), y: 1
      };
      this.position = {
        x: x + 10,
        y: y + 10
      };
      this.initialStyles.color = color;
      this.element = document.createElement("span");
      this.element.innerHTML = this.character;
      applyProperties(this.element, this.initialStyles);
      this.update();
      particleBox.appendChild(this.element)
    };
    this.update = function () {
      this.position.x += this.velocity.x;
      this.position.y += this.velocity.y;
      this.lifeSpan-=3;
      this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px, 0) scale(" + (this.lifeSpan / 120) + ")"
    };
    this.die = function () {
      particleBox.removeChild(this.element)
    }
  }
  function applyProperties(target, properties) {
    for (var key in properties) {
      target.style[key] = properties[key]
    }
  }
  if (!("ontouchstart" in window || navigator.msMaxTouchPoints)) {
    init()
  }
}
// fairyDustCursor()
  • 谷歌浏览器地址栏贴入:chrome://extensions/ 回车
  • 右侧开启开发者模式 点击 加载已解压的扩展程序 选择 脚本文件夹 cromePointerEffect-plugin 确定即可

此时进入任何一个标签页面点击 会有惊喜哦!

至此:一个简单的浏览器用户扩展程序制作完成