A modification on my starfield pen
A Pen by Nick Sheffield on CodePen.
<canvas id="c"></canvas> |
var holeSize = 100; // size of the black hole. | |
var rotationDistance = 200; // distance of black hole from canvas center. | |
var rotationSpeed = 1; // speed of black hole rotation. | |
var spawnCount = 20; // the amount of stars to spawn every frame. | |
var rotationStep = 37; | |
// --------------------------------------------- | |
var canvas = document.getElementById('c'), | |
ctx = canvas.getContext('2d'), | |
stars = [], | |
m = {}, | |
r = 0, | |
accel = 1.01, | |
accel2 = 0.001, | |
ratio = window.devicePixelRatio || 1, | |
spawnPos = 0, | |
randomize = true | |
canvas.width = window.innerWidth * ratio; | |
canvas.height = window.innerHeight * ratio; | |
m.x = null; | |
m.y = null; | |
ctx.strokeStyle = '#fff'; | |
ctx.translate(0.5, 0.5); | |
// create stars | |
function createStars(n){ | |
if(m.x === null) return; | |
for(var i=0;i<n;i++){ | |
var shape = { | |
x: m.x, | |
y: m.y, | |
r: 1, | |
speed: 1, | |
accel: accel, | |
accel2: accel2, | |
angle: randomize ? Math.random() * 360 : spawnPos | |
} | |
if(!randomize) spawnPos += rotationStep; | |
var vel = { | |
x: holeSize * Math.cos(shape.angle * Math.PI / 180), | |
y: holeSize * Math.sin(shape.angle * Math.PI / 180) | |
}; | |
shape.x += vel.x; | |
shape.y += vel.y; | |
stars.push(shape); | |
} | |
} | |
function render(){ | |
createStars(spawnCount); | |
var bench = []; | |
// ctx.save(); | |
// ctx.fillStyle = 'rgba(0,0,0,0.5)'; | |
// ctx.fillRect(0, 0, canvas.width, canvas.height); | |
// ctx.restore(); | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
r+=rotationSpeed; | |
if(r < 360){ | |
m = { x: canvas.width / 2, y: canvas.height / 2, angle: r } | |
var targetAngle = m.angle * Math.PI / 180; | |
m.x += rotationDistance * Math.cos(targetAngle); | |
m.y += rotationDistance * Math.sin(targetAngle); | |
}else{ | |
r = 0; | |
} | |
while(stars.length){ | |
var star = stars.pop(); | |
var vel = { | |
x: star.speed * Math.cos(star.angle * Math.PI / 180), | |
y: star.speed * Math.sin(star.angle * Math.PI / 180) | |
}; | |
ctx.beginPath(); | |
ctx.moveTo(star.x, star.y); | |
ctx.lineTo(star.x + vel.x, star.y + vel.y); | |
ctx.closePath(); | |
ctx.stroke(); | |
star.x += vel.x; | |
star.y += vel.y; | |
star.speed *= star.accel; | |
star.accel += star.accel2; | |
if(star.x < canvas.width && star.x > 0 && star.y < canvas.height && star.y > 0){ | |
bench.push(star); | |
} | |
} | |
stars = bench.slice(0).reverse(); | |
} | |
window.requestAnimFrame = (function(){ | |
return window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
function(callback){ | |
window.setTimeout(callback, 1000 / 60); | |
}; | |
})(); | |
(function animloop(){ | |
requestAnimFrame(animloop); | |
render(); | |
})(); | |
if(ratio == 2){ | |
canvas.style.width='100%'; | |
canvas.style.height='100%'; | |
} | |
var GUIControls = { | |
holeSize: holeSize, | |
rotationDistance: rotationDistance, | |
rotationSpeed: rotationSpeed, | |
spawnCount: spawnCount, | |
rotationStep: rotationStep, | |
randomize: randomize, | |
reset: function() { | |
holeSize = 100 | |
rotationDistance = 200 | |
rotationSpeed = 1 | |
spawnCount = 20 | |
rotationStep = 37 | |
randomize = true | |
} | |
} | |
var datGUI = new dat.GUI() | |
datGUI.add(GUIControls, 'holeSize').min(0).max(1000).step(1).name('Hole Size').listen().onChange(function(val){ holeSize = val }) | |
datGUI.add(GUIControls, 'rotationDistance').min(0).max(500).step(1).name('Rotation Distance').listen().onChange(function(val){ rotationDistance = val }) | |
datGUI.add(GUIControls, 'rotationSpeed').min(0).max(5).name('Rotation Speed').listen().onChange(function(val){ rotationSpeed = val }) | |
datGUI.add(GUIControls, 'rotationStep').min(-100).max(100).name('Rotation Step').listen().onChange(function(val){ rotationStep = val }) | |
datGUI.add(GUIControls, 'spawnCount').min(1).max(100).name('Spawn Count').listen().onChange(function(val){ spawnCount = val }) | |
datGUI.add(GUIControls, 'randomize', true, false).name('Randomize').onChange(function(val){ randomize = val }) | |
datGUI.add(GUIControls, 'reset').name('Reset') | |
datGUI.domElement.querySelector('ul').classList.toggle('closed') |
body{ margin: 0; overflow: hidden; } | |
#c{ background: #000; } |
A modification on my starfield pen
A Pen by Nick Sheffield on CodePen.