Skip to content

Instantly share code, notes, and snippets.

@av1la
Last active January 10, 2020 22:43
Show Gist options
  • Save av1la/64cc2372ea07ff4347b05b2c920e8ec9 to your computer and use it in GitHub Desktop.
Save av1la/64cc2372ea07ff4347b05b2c920e8ec9 to your computer and use it in GitHub Desktop.
/*
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