Last active
January 10, 2020 22:43
-
-
Save av1la/64cc2372ea07ff4347b05b2c920e8ec9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
links utilizados para o desenvolvimento: | |
http://www.independent-software.com/determining-coordinates-on-a-html-canvas-bezier-curve.html | |
https://repositorio.ufsc.br/bitstream/handle/123456789/96536/Roberto_Simoni.pdf?sequence=1 | |
use o html abaixo para testar | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Particles v3</title> | |
<style> | |
body { | |
padding: 0px; | |
margin: 0px; | |
width: 100%; | |
height: 100%; | |
} | |
</style> | |
</head> | |
<body> | |
<canvas id="particle-canvas"></canvas> | |
<script src="./particlesv3.js"></script> | |
</body> | |
</html> | |
v2 | |
adiciona suporte a tamanhos diferentes. | |
parametriza configuracoes do script | |
@ Diego 01/2020 | |
*/ | |
const CANVAS_IDENTIFIER = 'particle-canvas' // html id | |
const MAX_PARTICLES = 50 // quantidade de curvas que serao geradas | |
const PARTICLE_SIZE = [0.5, 1, 1.8] // use um inteiro para um tamanho fixo ou entao uma array para diversos tamanhos (gera uma certa profundidade) | |
const DRAW_SPEED = 50 // frequencia com que o canvas é atualizado em ms. | |
const DRAW_DENSITY = 0.001 // densidade da curva (quantidade de pixels) | |
const DRAW_CLEAN = true // apaga canvas no inicio de cada ciclo | |
class Particle { | |
constructor() { | |
this.size = PARTICLE_SIZE | |
this.positions = [] | |
this.maxWidth = document.body.scrollWidth | |
this.maxHeight = document.body.scrollHeight | |
this.defineSeedPositions() | |
this.defineBezierCurvePositions() | |
if (PARTICLE_SIZE instanceof Array) { | |
this.size = PARTICLE_SIZE[Math.floor(Math.random() * (PARTICLE_SIZE.length - 0) + 0)] | |
} | |
} | |
defineControlPoint = () => { | |
/* gera uma posicao aleatoria para ser utilizada como ponto de controle | |
da curva. a partir desde ponto de controle é gerada a forma da curva.*/ | |
return { | |
x: this.random(0, this.maxWidth), | |
y: this.random(0, this.maxHeight) | |
} | |
} | |
defineSeedPositions() { | |
/* | |
define as posicoes finais e iniciais da curva; | |
como a intencao é criar uma particula que nunca pare de se | |
movimentar, a posicao final deve ser reaproveitada. quando todas as | |
posicoes forem utilizadas, deve ser gerado uma nova curva, | |
utilizando a posicao final como a iniial e uma nova posicao final | |
deve ser gerada. | |
*/ | |
if (this.endX == undefined && this.endY == undefined) { | |
this.startX = Math.floor(Math.random() * this.maxWidth) | |
this.startY = Math.floor(Math.random() * this.maxHeight) | |
this.endX = Math.floor(Math.random() * this.maxWidth) | |
this.endY = Math.floor(Math.random() * this.maxHeight) | |
} else { | |
console.log('criando nova curva') | |
this.startX = this.endX | |
this.startY = this.endY | |
this.endX = Math.floor(Math.random() * this.maxWidth) | |
this.endY = Math.floor(Math.random() * this.maxHeight) | |
} | |
} | |
defineBezierCurvePositions() { | |
let ctrl1 = this.defineControlPoint() | |
let ctrl2 = this.defineControlPoint() | |
for(let t = 0; t <= 1; t+=DRAW_DENSITY) { | |
this.positions.push({ | |
x: Math.pow(1-t,3) * this.startX + 3 * t * Math.pow(1 - t, 2) * ctrl1.x + 3 * t * t * (1 - t) * ctrl2.x + t * t * t * this.endX, | |
y: Math.pow(1-t,3) * this.startY + 3 * t * Math.pow(1 - t, 2) * ctrl1.y + 3 * t * t * (1 - t) * ctrl1.y + t * t * t * this.endY | |
}) | |
} | |
} | |
getRenderPosition() { | |
let position = this.positions.shift() | |
if (position == undefined) { | |
this.defineSeedPositions() | |
this.defineBezierCurvePositions() | |
position = this.positions.shift() | |
} | |
return position | |
} | |
random = (min, max) => { | |
return Math.random() * (max - min) + min; | |
} | |
} | |
function draw(context, curves, size) { | |
/* funcao chamada pelo predeterminado intervalo de tempo definido no cabecalho | |
responsavel por realizar o desenho de cada movimento. | |
*/ | |
// remove os desenhos anteriores, assim emulando o movimento de um ponto | |
// a partir das posicoes da curva de bezier; | |
if (DRAW_CLEAN) | |
context.clearRect(0, 0, document.body.scrollWidth, document.body.scrollHeight) | |
for(let i = 0; i < curves.length; i++) { | |
let position = curves[i].getRenderPosition() | |
context.beginPath(); | |
context.arc(position.x, position.y, curves[i].size, 0, Math.PI*2); | |
context.fillStyle = '000'; | |
context.fill(); | |
context.closePath(); | |
} | |
} | |
function setup() { | |
/* inicializa processo de desenho */ | |
let particleCanvas = document.getElementById(CANVAS_IDENTIFIER) | |
let context = particleCanvas.getContext("2d"); | |
particleCanvas.width = document.body.scrollWidth; | |
particleCanvas.height = document.body.scrollHeight; | |
let curves = [] | |
for(let x = 0; x < MAX_PARTICLES; x++) { | |
curves.push(new Particle()) | |
} | |
return setInterval(draw, DRAW_SPEED, context, curves, PARTICLE_SIZE) | |
} | |
function init() { | |
/* chamado quando o script é iniciado */ | |
let interval = setup() | |
// verifica redimensionamento de pagina. | |
window.addEventListener("resize", () => { | |
clearInterval(interval) | |
interval = setup() | |
}) | |
} init() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment