炫酷渐变色背景粒子线条折线连接canvas动画

效果图:
在这里插入图片描述
1.新建canvas.js


// 炫酷渐变色背景粒子线条折线连接canvas动画
export const canvas = (val) => {
  var requestAnimationFrame = window.requestAnimationFrame || function (callback) {
    window.setTimeout(callback, 1000 / 60)
  }

  // var canvas = document.getElementsByTagName("canvas")[0];
  let canvas = val
  let ctx = canvas.getContext('2d')
  let maximumPossibleDistance
  let mousePositionX
  let mousePositionY
  let mouseElement
  let lines = 0
  let objects = []
  var initAnimation = function () {
    canvas.width = window.innerWidth
    canvas.height = window.innerHeight
    maximumPossibleDistance = Math.round(Math.sqrt((canvas.width * canvas.width) + (canvas.height * canvas.height)))
    Math.floor(canvas.width / 2)
    Math.floor(canvas.height / 2)
    objects.length = 0
    clearCanvas()
    createParticles()
  }
  window.addEventListener('resize', function () { initAnimation() }, false)
  // 线条参数配置
  var options = {
    // 初始线条数量
    particlesNumber: 80,
    // 圆点大小
    initialSize: 3,
    moveLimit: 50,
    durationMin: 50,
    durationMax: 300,
    drawConnections: true,
    mouseInteractionDistance: 150,
    mouseGravity: true,
    drawMouseConnections: true,
    // 图标色彩
    red: 25,
    green: 200,
    blue: 255,
    opacity: 1,
    // 已连接线条
    connectionRed: 255,
    connectionGreen: 255,
    connectionBlue: 255,
    connectionOpacity: 0.2,
    // 鼠标移动线条
    mouseConnectionRed: 255,
    mouseConnectionGreen: 255,
    mouseConnectionBlue: 255,
    mouseConnectionOpacity: 0.2

  }
  var getRandomBetween = function (a, b) {
    return Math.floor(Math.random() * b) + a
  }
  var getDistance = function (element1, element2) {
    var difX = Math.round(Math.abs(element1.positionX - element2.positionX))
    var difY = Math.round(Math.abs(element1.positionY - element2.positionY))

    return Math.round(Math.sqrt((difX * difX) + (difY * difY)))
  }
  function Particle (positionX, positionY, size, red, green, blue, opacity) {
    this.positionX = positionX
    this.positionY = positionY
    this.size = size

    this.duration = getRandomBetween(options.durationMin, options.durationMax)
    this.limit = options.moveLimit
    this.timer = 0

    this.red = red
    this.green = green
    this.blue = blue
    this.opacity = opacity

    this.color = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',+' + this.opacity + ')'
  }
  function MouseParticle (positionX, positionY, size, red, green, blue, opacity) {
    this.positionX = mousePositionX
    this.positionY = mousePositionY
    this.size = size

    this.red = red
    this.green = green
    this.blue = blue
    this.opacity = opacity

    this.color = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',+' + this.opacity + ')'
  }
  Particle.prototype.animateTo = function (newX, newY) {
    var duration = this.duration

    var animatePosition = function (newPosition, currentPosition) {
      if (newPosition > currentPosition) {
        var step = (newPosition - currentPosition) / duration
        newPosition = currentPosition + step
      } else {
        step = (currentPosition - newPosition) / duration
        newPosition = currentPosition - step
      }

      return newPosition
    }

    this.positionX = animatePosition(newX, this.positionX)
    this.positionY = animatePosition(newY, this.positionY)

    // generate new vector

    if (this.timer === this.duration) {
      this.calculateVector()
      this.timer = 0
    } else {
      this.timer++
    }
  }
  Particle.prototype.updateColor = function () {
    this.color = 'rgba(' + this.red + ',' + this.green + ',' + this.blue + ',+' + this.opacity + ')'
  }
  Particle.prototype.calculateVector = function () {
    var distance
    var newPosition = {}
    var particle = this

    var getCoordinates = function () {
      newPosition.positionX = getRandomBetween(0, window.innerWidth)
      newPosition.positionY = getRandomBetween(0, window.innerHeight)

      distance = getDistance(particle, newPosition)
    }

    // eslint-disable-next-line no-unmodified-loop-condition
    while ((typeof distance === 'undefined') || (distance > this.limit)) {
      getCoordinates()
    }

    this.vectorX = newPosition.positionX
    this.vectorY = newPosition.positionY
  }
  Particle.prototype.testInteraction = function () {
    if (!options.drawConnections) return
    var closestElement
    var distanceToClosestElement = maximumPossibleDistance
    for (var x = 0; x < objects.length; x++) {
      var testedObject = objects[x]
      var distance = getDistance(this, testedObject)
      if ((distance < distanceToClosestElement) && (testedObject !== this)) {
        distanceToClosestElement = distance
        closestElement = testedObject
      }
    }
    if (closestElement) {
      ctx.beginPath()
      ctx.moveTo(this.positionX + this.size / 2, this.positionY + this.size / 2)
      ctx.lineTo(closestElement.positionX + closestElement.size * 0.5, closestElement.positionY + closestElement.size * 0.5)
      ctx.strokeStyle = 'rgba(' + options.connectionRed + ',' + options.connectionGreen + ',' + options.connectionBlue + ',' + options.connectionOpacity + ')'
      ctx.stroke()
      lines++
    }
  }
  MouseParticle.prototype.testInteraction = function () {
    if (options.mouseInteractionDistance === 0) return

    var closestElements = []
    // var distanceToClosestElement = maximumPossibleDistance;

    for (var x = 0; x < objects.length; x++) {
      var testedObject = objects[x]
      var distance = getDistance(this, testedObject)

      if ((distance < options.mouseInteractionDistance) && (testedObject !== this)) {
        closestElements.push(objects[x])
      }
    }

    for (var i = 0; i < closestElements.length; i++) {
      if (options.drawMouseConnections) {
        var element = closestElements[i]
        ctx.beginPath()
        ctx.moveTo(this.positionX, this.positionY)
        ctx.lineTo(element.positionX + element.size * 0.5, element.positionY + element.size * 0.5)
        ctx.strokeStyle = 'rgba(' + options.mouseConnectionRed + ',' + options.mouseConnectionGreen + ',' + options.mouseConnectionBlue + ',' + options.mouseConnectionOpacity + ')'
        ctx.stroke()
        lines++
      }
      if (options.mouseGravity) {
        closestElements[i].vectorX = this.positionX
        closestElements[i].vectorY = this.positionY
      }
    }
  }
  Particle.prototype.updateAnimation = function () {
    this.animateTo(this.vectorX, this.vectorY)
    this.testInteraction()
    ctx.fillStyle = this.color
    ctx.fillRect(this.positionX, this.positionY, this.size, this.size)
  }
  MouseParticle.prototype.updateAnimation = function () {
    this.positionX = mousePositionX
    this.positionY = mousePositionY
    this.testInteraction()
  }
  var createParticles = function () {
    // create mouse particle
    mouseElement = new MouseParticle(0, 0, options.initialSize, 255, 255, 255)
    for (var x = 0; x < options.particlesNumber; x++) {
      var randomX = Math.floor((Math.random() * window.innerWidth) + 1)
      var randomY = Math.floor((Math.random() * window.innerHeight) + 1)
      var particle = new Particle(randomX, randomY, options.initialSize, options.red, options.green, options.blue, options.opacity)
      particle.calculateVector()
      objects.push(particle)
    }
  }
  var updatePosition = function () {
    for (var x = 0; x < objects.length; x++) {
      objects[x].updateAnimation()
    }
    // handle mouse
    mouseElement.updateAnimation()
  }
  window.onmousemove = function (e) {
    mousePositionX = e.clientX
    mousePositionY = e.clientY
  }
  var clearCanvas = function () {
    ctx.clearRect(0, 0, window.innerWidth, window.innerHeight)
  }
  var lastCalledTime
  var fps
  var averageFps
  var averageFpsTemp = 0
  var averageFpsCounter = 0

  function requestFps () {
    if (!lastCalledTime) {
      lastCalledTime = Date.now()
      fps = 0
      return
    }
    var delta = (new Date().getTime() - lastCalledTime) / 1000
    lastCalledTime = Date.now()
    fps = Math.floor(1 / delta)

    averageFpsTemp = averageFpsTemp + fps
    averageFpsCounter++
    if (averageFpsCounter === 5) {
      averageFps = Math.floor(averageFpsTemp / 5)
      averageFpsCounter = 0
      averageFpsTemp = 0
    }
    if (!averageFps) {

    } else if (averageFps < 10) {

    }
  }
  var loop = function () {
    clearCanvas()
    updatePosition()
    ctx.fillStyle = '#fff'
    // ctx.fillText("FPS: " + fps + " lines: " + lines + " Average FPS: " + averageFps , 10, 20);
    lines = 0
    requestAnimationFrame(loop)
    requestFps()
  }
  initAnimation()
  loop()
  return lines
}

2.引入canvas.js,实现效果

<template>
  <div class="canvas-page">
    <canvas></canvas>
  </div>
</template>
<script>
import { canvas } from '../plugins/canvas'
export default {
  name: 'CanvasPage',
  mounted () {
    canvas(document.getElementsByTagName('canvas')[0])
  }
}
</script>
<style lang="less" scoped>
.canvas-page {
  height: 100vh;
  width: 100vw;
  background-size: cover;
  position: relative;
  background-color: #474747;
  background-image: radial-gradient(circle at 2% 60%, #27278f, transparent 100%),
    radial-gradient(circle at 98% 70%, #000c91, transparent 100%),
    radial-gradient(circle at 50% 50%, #ed68ed, transparent 100%);
  canvas {
    position: absolute;
    left: 0;
    top: 0;
    background: transparent;
    z-index: 15;
  }
}
</style>

附:canvas速查表 http://canvas.migong.org/html5-canvas

发布了25 篇原创文章 · 获赞 4 · 访问量 123万+

猜你喜欢

转载自blog.csdn.net/weixin_45266125/article/details/103296555