<template>
  <div
    id="background-canvas-wrapper"
    class="w100 no-scroll overflow-hidden bg-base position-relative"
    style="height: 100vh;"
    >
    <canvas id="canvas" class="absolute-top"/>
  </div>
</template>

<script setup lang="ts">
  import { onMounted, onUnmounted } from 'vue'

  onMounted(() => {
    const canvas = document.getElementById("canvas") as HTMLCanvasElement
    const ctx = canvas.getContext("2d")!
    const opts = {
      pColor: "rgb(200,200,200)",
      lRGB: "200,200,200",
      amt: 20,
      defS: 0.1,
      varS: 1,
      defR: 2,
      varR: 2,
      linkR2: 200 ** 2
    }

    let w: number, h: number, aid: number
    const particles: Particle[] = []

    const resize = () => {
      w = canvas.width = window.innerWidth
      h = canvas.height = window.innerHeight
    }

    class Particle {
      x = Math.random() * w
      y = Math.random() * h
      s = opts.defS + Math.random() * opts.varS
      a = Math.random() * Math.PI * 2
      vx = Math.cos(this.a) * this.s
      vy = Math.sin(this.a) * this.s
      r = opts.defR + Math.random() * opts.varR

      update() {
        if (this.x + this.vx > w || this.x + this.vx < 0) this.vx *= -1
        if (this.y + this.vy > h || this.y + this.vy < 0) this.vy *= -1
        this.x += this.vx
        this.y += this.vy
        ctx.beginPath()
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2)
        ctx.fillStyle = opts.pColor
        ctx.fill()
      }
    }

    resize()
    for (let i = 0; i < opts.amt; i++) particles.push(new Particle())

    const loop = () => {
      ctx.clearRect(0, 0, w, h)
      particles.forEach(p => p.update())

      for (let i = 0; i < particles.length; i++) {
        const p1 = particles[i]
        for (let j = i + 1; j < particles.length; j++) {
          const p2 = particles[j]
          if (!p1 || !p2) continue
          
          const dx = p1.x - p2.x
          const dy = p1.y - p2.y
          const d2 = dx * dx + dy * dy
          if (d2 < opts.linkR2) {
            ctx.strokeStyle = `rgba(${opts.lRGB}, ${1 - d2 / opts.linkR2})`
            ctx.lineWidth = 0.5
            ctx.beginPath()
            ctx.moveTo(p1.x, p1.y)
            ctx.lineTo(p2.x, p2.y)
            ctx.stroke()
          }
        }
      }
      aid = requestAnimationFrame(loop)
    }

    window.addEventListener("resize", resize)
    loop()

    onUnmounted(() => {
      window.removeEventListener("resize", resize)
      cancelAnimationFrame(aid)
    })
  })
</script>

<style>
  #background-canvas-wrapper {
    position: absolute !important;
    display: block;
    top: 0;
    left: 0;
    z-index: -1;
    margin: 0;
    height: 100vh !important;
  }
</style>
