Как реализовать плагин Chrome с эффектами щелчка мыши

внешний интерфейс JavaScript Chrome Vue.js React.js HTML Canvas

Как реализовать плагин Chrome с эффектами щелчка мыши

Использованная литература:plugin.baidu.com/developer/oh…

Эффект предварительного просмотра:Бойня 123.GitHub.IO/cursor_spec…

В наши дни стыдно говорить, что вы программируете без использования Chrome. Особенно интерфейс, хром — это просто инструмент отладки для интерфейса, и он незаменим. Я должен сказать, что функции Chrome чрезвычайно мощные, и самая ослепительная функция — это扩展程序(плагины для браузера), крупные отечественные бренды браузеров также последовали их примеру.Сегодня я расскажу вам о практике разработки плагинов для Chrome.

Готов к работе

  • Создать папкуcursor_special_effects

  • создать в папкеmanifest.jsonфайл, содержание файла следующее

{
  "manifest_version": 2,
  "name": "爆炸吧,小鼠标!",
  "version": "0.0.1",
  "description": "小鼠标在线爆炸",
  "author": "田某人",
  "content_scripts": [{
    "matches": ["*://*/*"], // 匹配所有的网站
    "js": ["index.js"] // 插件的主要代码
  }]
}

Официально начать

созданныйindex.jsфайл, вы можете начать увлекательное программирование.

Написанный нами плагин может получить DOM-элемент исходной страницы, а плагин устанавливается только на хром, так что про чертову совместимость можно не думать, а некоторые новые фичи ES можно использовать как угодно. Конечно, плагин Chrome также можно установить в браузерах 360 и Baidu.

Прежде всего, нам нужно проанализировать требования. Нам нужно реализовать эффект клика мыши. Какие функции нуждаются в наших плагинах?

  • Переопределить с помощью Canvas на исходной странице
  • Canvas не может повлиять на время отклика исходной веб-страницы, поэтому добавьтеpointer-events: none;

Поскольку требуется только один холст, он создается напрямую с помощью js:

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')
    }
    // 初始化
    init() {
        // 设置canvas样式
        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)
    }
}
const cursorSpecialEffects = new CursorSpecialEffects()
cursorSpecialEffects.init()

Здесь используется внеэкранный рендеринг, то есть один холст используется для расчета и один холст используется для рендеринга.

Теперь сцена выложена, и теперь вам нужно добавить событие щелчка мыши, и каждый щелчок будет запускать специальный эффект.

class CursorSpecialEffects {
    constructor() {
        ...
        this.runing = false // 标识特效是否在运行
        this.booms = [] // 可以同时存在多个特效,所以使用数组来保存
    }
    
	init() {
      	...
   		window.addEventListener('mousedown', this.handleMouseDown.bind(this))

    }
    // 鼠标点击事件
    handleMouseDown() {
        const boom = new Boom({
          // 爆炸的原点
          origin: { x: e.clientX, y: e.clientY }, 
          // canvas上下文
          context: this.computerContext,
          // 场景区域,当特效超出场景范围时,就应该停止了
          area: {
            width: this.globalWidth,
            height: this.globalHeight
          }
        })
        boom.init()
        this.booms.push(boom)
        // 如果特效已经在运行,则不重复开始
        this.running || this.run()
    }
    
    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()
        })
        // 一帧绘制完毕,将计算使用的canvas绘制到页面的canvas上
        this.renderContext.drawImage(this.computerCanvas, 0, 0, this.globalWidth, this.globalHeight)
    }
}

ВотBoomclass, каждый щелчок мыши создаетBoomПример, пока этот экземпляр не завершит воспроизведение, будет удален. Этот класс Boom может иметь множество реализаций, разные реализации могут достигать разных эффектов, при условии, что этот класс должен обеспечивать перемещение Boom, функцию рисования и атрибуты остановки. двигаться, чтобы продвигать спецэффекты, рисовать каждый кадр, стоп используется, чтобы указать, остановлен ли эффект.

Далее вводится реализация стрелы:

class Boom {
  constructor ({ origin, context, circleCount = 20, area }) {
    // 爆炸的原点
    this.origin = origin
    // canvas上下文
    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 = ['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()
    })
    // 如果所有的小球都被删除,就把这个boom标记为停止,等待下一帧被删除
    if (this.circles.length == 0) {
      this.stop = true
    }
  }
  
  draw() {
    // 循环绘制每个小球
    this.circles.forEach(circle => circle.draw())
  }
}

такBoomКласс реализован, но я до сих пор не знаю, как выглядит спецэффект. ВотCircleКласс, задача реализации спецэффектов ложится наCircleв классе. БудуCircleабстракция классаBoomКласс, который помогает разобраться в логике кода.

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++
  }
}

Здесь нужно пояснить правила движения мяча, по углу и скорости рассчитывается абсцисса движения мяча в каждом кадре.Math.sin(this.angle) * this.speed,ось YMath.cos(this.angle) * this.speed, плюс исходные координаты. Чтобы добиться универсальной гравитации, установите ускорение свободного падения на 0,3.

ты закончил

Далее просто перейдите на страницу расширения chrome и нажмите打包扩展程序(без этой кнопки нужно открыть режим разработчика), выбираемcursor_special_effectsПапки могут быть упакованы.

После успешной упаковки мы можемcursor_special_effectsВидно в каталоге того же уровня папкиcursor_special_effects.pem,cursor_special_effects.crxДва файла, первый — секретный ключ, а последний — упакованный файл. двойной щелчок или.crxПеретащите файл на страницу расширения, чтобы установить его. Если хром не может быть установлен, это потому, что он не выпущен, и его можно установить с помощью браузера 360.

Обновите страницу после установки, эффект следующий:

Выглядит неплохо, но так как релиз требует затрат на разработку в 5 долларов, так что забудьте, это всего лишь гаджет, написанный от праздной скуки, и он должен сделать еще несколько интересных спецэффектов позже.

github: GitHub.com/Slaughterhouse123/curs…