<template>
|
<div class="particle-network-animation" :style="`height:${height}px;width:${width}px`">
|
<div style="display:none">
|
<img ref="conf0" src="../assets/img/login/0.png" />
|
<img ref="conf1" src="../assets/img/login/1.png" />
|
<img ref="conf2" src="../assets/img/login/2.png" />
|
<img ref="conf3" src="../assets/img/login/3.png" />
|
<img ref="conf4" src="../assets/img/login/4.png" />
|
<img ref="conf5" src="../assets/img/login/5.png" />
|
<img ref="conf6" src="../assets/img/login/6.png" />
|
<img ref="conf7" src="../assets/img/login/7.png" />
|
<img ref="conf8" src="../assets/img/login/8.png" />
|
<img ref="conf9" src="../assets/img/login/9.png" />
|
<img ref="conf10" src="../assets/img/login/10.png" />
|
<img ref="conf11" src="../assets/img/login/11.png" />
|
<img ref="conf12" src="../assets/img/login/12.png" />
|
<img ref="conf13" src="../assets/img/login/13.png" />
|
<img ref="conf14" src="../assets/img/login/14.png" />
|
<img ref="conf15" src="../assets/img/login/15.png" />
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
name: 'particleNetwork',
|
data() {
|
return {
|
imgNumber: 0,
|
destoryed: false
|
}
|
},
|
props: {
|
height: {
|
type: Number,
|
default: 800
|
},
|
width: {
|
type: Number,
|
default: 1000
|
}
|
},
|
mounted() {
|
this.createCavas()
|
},
|
beforeDestroy() {
|
this.destoryed = true
|
},
|
methods: {
|
createCavas() {
|
let that = this
|
var ParticleNetworkAnimation, PNA
|
ParticleNetworkAnimation = PNA = function () { }
|
|
PNA.prototype.init = function (element) {
|
// this.$el = $(element);
|
|
this.container = element
|
this.canvas = document.createElement('canvas')
|
this.sizeCanvas()
|
this.container.appendChild(this.canvas)
|
this.ctx = this.canvas.getContext('2d')
|
this.particleNetwork = new ParticleNetwork(this)
|
|
return this
|
}
|
|
PNA.prototype.sizeCanvas = function () {
|
this.canvas.width = this.container.offsetWidth
|
this.canvas.height = this.container.offsetHeight
|
}
|
|
var Particle = function (parent, x, y) {
|
this.network = parent
|
this.imgNumber = that.imgNumber++
|
this.canvas = parent.canvas
|
this.ctx = parent.ctx
|
this.particleColor = returnRandomArrayitem(
|
this.network.options.particleColors
|
)
|
// 控制大小
|
this.radius = getLimitedRandom(10, 30)
|
this.opacity = 0
|
// this.x = x || Math.random() * this.canvas.width;
|
// this.y = y || Math.random() * this.canvas.height;
|
|
// 控制初始坐标,不要超出范围
|
this.x = x || getLimitedRandom(50, this.canvas.width - 50)
|
this.y = y || getLimitedRandom(50, this.canvas.height - 50)
|
|
this.velocity = {
|
x: (Math.random() - 0.5) * parent.options.velocity,
|
y: (Math.random() - 0.5) * parent.options.velocity
|
}
|
}
|
|
Particle.prototype.update = function () {
|
if (this.opacity < 0.8) {
|
this.opacity += 0.01
|
} else {
|
this.opacity = 0.8
|
}
|
// 移动到边缘时反向
|
if (this.x > this.canvas.width - 50 || this.x < 50) {
|
this.velocity.x = -this.velocity.x
|
}
|
if (this.y > this.canvas.height - 50 || this.y < 50) {
|
this.velocity.y = -this.velocity.y
|
}
|
|
// 更新坐标
|
this.x += this.velocity.x
|
this.y += this.velocity.y
|
}
|
|
Particle.prototype.draw = function () {
|
// Draw particle
|
if (that.destoryed) {
|
return
|
}
|
this.ctx.beginPath()
|
this.ctx.fillStyle = this.particleColor
|
this.ctx.globalAlpha = this.opacity
|
this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
|
this.ctx.fill()
|
var prop = this.radius
|
// let imgOdr = parseInt(Math.random() * 16, 10);
|
var img = that.$refs['conf' + this.imgNumber]
|
// img.src = "../../assets/img/login/" + imgOdr + ".png";
|
this.ctx.drawImage(
|
img,
|
this.x - this.radius * 0.8,
|
this.y - this.radius * 0.8,
|
this.radius * 1.6,
|
this.radius * 1.6
|
)
|
}
|
|
var ParticleNetwork = function (parent) {
|
this.options = {
|
velocity: 1, // the higher the faster
|
density: 1500, // the lower the denser
|
netLineDistance: 300,
|
netLineColor: '#477bec',
|
particleColors: ['#7E8BFA'] // ['#6D4E5C', '#aaa', '#FFC458' ]
|
}
|
this.canvas = parent.canvas
|
this.ctx = parent.ctx
|
|
this.init()
|
}
|
|
ParticleNetwork.prototype.init = function () {
|
// Create particle objects
|
this.createParticles(true)
|
|
// Update canvas
|
this.animationFrame = requestAnimationFrame(this.update.bind(this))
|
}
|
|
ParticleNetwork.prototype.createParticles = function (isInitial) {
|
// Initialise / reset particles
|
var me = this
|
this.particles = []
|
// var quantity = this.canvas.width * this.canvas.height / this.options.density;
|
var quantity = 17
|
|
if (isInitial) {
|
var counter = 0
|
clearInterval(this.createIntervalId)
|
this.createIntervalId = setInterval(
|
function () {
|
if (counter < quantity - 1) {
|
// Create particle object
|
this.particles.push(new Particle(this))
|
} else {
|
clearInterval(me.createIntervalId)
|
}
|
counter++
|
}.bind(this),
|
250
|
)
|
} else {
|
// Create particle objects
|
for (var i = 0; i < quantity; i++) {
|
this.particles.push(new Particle(this))
|
}
|
}
|
}
|
|
ParticleNetwork.prototype.destory = function (isInitial) {
|
clearInterval(this.createIntervalId)
|
}
|
ParticleNetwork.prototype.update = function () {
|
if (this.canvas) {
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
this.ctx.globalAlpha = 1
|
|
// Draw connections
|
for (var i = 0; i < this.particles.length; i++) {
|
for (var j = this.particles.length - 1; j > i; j--) {
|
var distance,
|
p1 = this.particles[i],
|
p2 = this.particles[j]
|
|
// check very simply if the two points are even a candidate for further measurements
|
distance = Math.min(Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y))
|
if (distance > this.options.netLineDistance) {
|
continue
|
}
|
|
// the two points seem close enough, now let's measure precisely
|
distance = Math.sqrt(
|
Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)
|
)
|
if (distance > this.options.netLineDistance) {
|
continue
|
}
|
|
this.ctx.beginPath()
|
this.ctx.strokeStyle = this.options.netLineColor
|
this.ctx.globalAlpha =
|
((this.options.netLineDistance - distance) /
|
this.options.netLineDistance) *
|
p1.opacity *
|
p2.opacity
|
this.ctx.lineWidth = 1.7
|
this.ctx.moveTo(p1.x, p1.y)
|
this.ctx.lineTo(p2.x, p2.y)
|
this.ctx.stroke()
|
}
|
}
|
|
// Draw particles
|
for (var i = 0; i < this.particles.length; i++) {
|
this.particles[i].update()
|
this.particles[i].draw()
|
}
|
|
if (this.options.velocity !== 0) {
|
this.animationFrame = requestAnimationFrame(this.update.bind(this))
|
}
|
} else {
|
cancelAnimationFrame(this.animationFrame)
|
}
|
}
|
|
var getLimitedRandom = function (min, max, roundToInteger) {
|
var number = Math.random() * (max - min) + min
|
if (roundToInteger) {
|
number = Math.round(number)
|
}
|
return number
|
}
|
|
var returnRandomArrayitem = function (array) {
|
return array[Math.floor(Math.random() * array.length)]
|
}
|
|
var elm = document.getElementsByClassName('particle-network-animation')[0]
|
|
this.pna = new ParticleNetworkAnimation()
|
this.pna.init(elm)
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.particle-network-animation {
|
position: fixed;
|
top: 20%;
|
left: 0;
|
right: 0;
|
// background-color: #171717;
|
}
|
.particle-network-animation::before {
|
z-index: -3;
|
content: '';
|
position: absolute;
|
top: 0;
|
right: 0;
|
bottom: 0;
|
left: 0;
|
background-size: cover;
|
opacity: 0.2;
|
}
|
|
.glow {
|
z-index: -2;
|
position: fixed;
|
top: 50%;
|
left: 50%;
|
background-image: radial-gradient(
|
circle closest-side,
|
rgba(255, 255, 255, 0.025),
|
transparent
|
);
|
}
|
|
.glow-1 {
|
width: 150vw;
|
height: 150vh;
|
margin-top: -75vh;
|
margin-left: -75vw;
|
animation: glow-1-move 25s linear infinite both;
|
}
|
|
@keyframes glow-1-move {
|
from {
|
transform: translate(-100%, 100%);
|
}
|
to {
|
transform: translate(100%, -100%);
|
}
|
}
|
.glow-2 {
|
width: 100vw;
|
height: 100vh;
|
margin-top: -50vh;
|
margin-left: -50vw;
|
animation: glow-2-move 25s linear 8.3333333333s infinite both;
|
}
|
|
@keyframes glow-2-move {
|
from {
|
transform: translate(-100%, 0%);
|
}
|
to {
|
transform: translate(100%, 100%);
|
}
|
}
|
.glow-3 {
|
width: 120vw;
|
height: 120vh;
|
margin-top: -60vh;
|
margin-left: -60vw;
|
animation: glow-3-move 25s linear 16.6666666667s infinite both;
|
}
|
|
@keyframes glow-3-move {
|
from {
|
transform: translate(100%, 100%);
|
}
|
to {
|
transform: translate(0%, -100%);
|
}
|
}
|
</style>
|