Files
tgCrewAdmin/src/components/meshBackground.vue
2026-02-13 15:06:52 +03:00

107 lines
2.6 KiB
Vue

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