You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.4 KiB

import Vector from "./Vector"
import util from "./util"
export default class Particle {
constructor({add, sphereRad, fLen, dotImageList}) {
this.distPos = {
theta: add === true ? Math.PI / 2 : Math.random() * Math.PI,
phi: 2 * Math.random() * Math.PI
}
this.distPos.x = sphereRad * Math.sin(this.distPos.theta) * Math.cos(this.distPos.phi)
this.distPos.y = sphereRad * Math.sin(this.distPos.theta) * Math.sin(this.distPos.phi)
this.distPos.z = sphereRad * Math.cos(this.distPos.theta)
this.distVec = new Vector(this.distPos.x, this.distPos.y, this.distPos.z)
this.unitVec = this.distVec.unit()
this.startVec = this.distVec.multiply(1 + Math.random() * 2)
this.x = this.startVec.x
this.y = this.startVec.y
this.z = this.startVec.z
this.veloRate = 1 + Math.random()
this.velo = this.unitVec.negative().multiply(this.veloRate)
this.finalVelo = 0
this.m = fLen / (fLen - this.z)
this.age = this.life = 50 + Math.floor(Math.random() * 500)
this.turnAngle = 0
this.wanderTime = 200
this.radius = 1 + Math.random() * 3
let colorRandom = Math.floor(Math.random() * 4)
switch (colorRandom) {
case 0:
this.img = dotImageList[0]
this.color = "rgba(70,255,140,"
break
case 1:
this.img = dotImageList[1]
this.color = "rgba(90,90,90,"
break
case 2:
this.img = dotImageList[2]
break
case 3:
this.img = dotImageList[3]
break
}
}
update({sphereRad, fLen, turnSpeed}) {
this.nowPos = new Vector(this.x, this.y, this.z)
this.nowPosUnit = this.nowPos.unit()
if (this.wanderTime > 0 && this.nowPos.length() > (sphereRad * 1.2)) {
this.wanderTime--
this.velo.x += 0.1 * (Math.random() * 2 - 1)
this.velo.y += 0.1 * (Math.random() * 2 - 1)
this.velo.z += 0.1 * (Math.random() * 2 - 1)
this.x = this.x + this.velo.x
this.y = this.y + this.velo.y
this.z = this.z + this.velo.z
this.op = util.map(this.nowPos.length(), sphereRad, this.startVec.length(), 1, 0)
}
else if (this.nowPos.length() > sphereRad) {
if (this.finalPos === 0) {
this.finalPos = this.nowPosUnit.multiply(sphereRad)
}
if (this.finalVelo === 0) {
this.finalVelo = this.nowPosUnit.negative().multiply(this.veloRate)
}
this.x = this.x + this.finalVelo.x
this.y = this.y + this.finalVelo.y
this.z = this.z + this.finalVelo.z
this.op = util.map(this.nowPos.length(), sphereRad, this.startVec.length(), 1, 0)
}
else {
this.op = this.life / (this.age / 2)
this.turnAngle = (this.turnAngle + turnSpeed) % (Math.PI * 2)
let cosAngle = Math.cos(turnSpeed)
let sinAngle = Math.sin(turnSpeed)
this.x = cosAngle * this.nowPos.x + sinAngle * this.nowPos.z
this.z = -sinAngle * this.nowPos.x + cosAngle * this.nowPos.z
this.y = this.nowPos.y
this.life--
}
this.m = fLen / (fLen - this.z)
}
}