Skip to content

Instantly share code, notes, and snippets.

@erohinaelena
Last active February 15, 2017 13:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erohinaelena/5808245c8928b15e7dc6 to your computer and use it in GitHub Desktop.
Save erohinaelena/5808245c8928b15e7dc6 to your computer and use it in GitHub Desktop.
canvas + StackBlur-shadows + css-rotation
<html>
<head>
<meta charset="utf-8">
<link href="stars.css" rel="stylesheet">
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://www.quasimondo.com/StackBlurForCanvas/StackBlur.js"></script>
<script src="stars.js"></script>
<script>d3.select(self.frameElement).style("height", "840px")</script>
</body>
</html>
body {
margin: 0;
background: #000313;
}
canvas {
-webkit-animation: infinite-rotate 240s linear infinite;
animation: infinite-rotate 240s linear infinite;
}
@-webkit-keyframes infinite-rotate {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
@keyframes infinite-rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
var width = 960,
height = 840
var projection = d3.geo.azimuthalEquidistant()
.scale(width / 5)
.translate([0, 0])
.rotate([-18 * 15, -66.56])
var canvas = d3.select("body").append("canvas").attr("id", "canvas")
var ctx = canvas.node().getContext("2d")
var offScreenCanvas = document.createElement('canvas')
var offCtx = offScreenCanvas.getContext('2d')
function getRetinaRatio() {
var devicePixelRatio = window.devicePixelRatio || 1
var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1
return devicePixelRatio / backingStoreRatio
}
var ratio = getRetinaRatio()
var scaledWidth = width * ratio
var scaledHeight = height * ratio
canvas.node().width = scaledWidth
canvas.node().height = scaledHeight
canvas
.style("width", width + 'px')
.style("height", height + 'px')
offScreenCanvas.width = scaledWidth
offScreenCanvas.height = scaledHeight
ctx.scale(ratio, ratio)
ctx.translate(width / 2, height / 2)
function addZodiacName(data) {
var x1 = 0, y1 = -data.y / Math.sin(Math.atan2(data.y, data.x))
ctx.save()
ctx.rotate(Math.atan2(data.y, data.x) + Math.PI / 2 )
ctx.textAlign = "center"
ctx.font = "12px sans-serif"
ctx.fillStyle = "white"
ctx.fillText(data.name, x1, y1)
ctx.restore()
}
function distance(x,y) {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
}
function drawLine(line) {
ctx.strokeStyle = (line.zodiac) ? '#f2f237':'white'
ctx.lineWidth = (line.zodiac) ? 0.8 : 0.4
ctx.beginPath()
ctx.moveTo(line.line[0][0], line.line[0][1])
ctx.lineTo(line.line[1][0], line.line[1][1])
ctx.stroke()
}
function drawStar(star) {
ctx.fillStyle = star.color
ctx.beginPath()
ctx.moveTo(star.projection[0], star.projection[1])
ctx.arc(star.projection[0], star.projection[1], star.radius, 0 ,Math.PI * 2 ,true)
ctx.fill()
}
function clearCtx(){
ctx.clearRect(-width / 2, -height / 2, width, height)
}
function changeColor(imageData, color){
var px = imageData.data
var rgb = d3.rgb(color)
for (var x = 0; x < px.length; x += 4){
if (px[x + 3]) {
px[x] = rgb.r
px[x + 1] = rgb.g
px[x + 2] = rgb.b
px[x + 3] *= 15
}
}
}
function getImage(ctx){
return ctx.getImageData(0, 0, scaledWidth, scaledHeight)
}
d3.json("/erohinaelena/raw/ec635d68e8bf55586d40/starData.json", function(error, data) {
var begin = performance.now()
var constellationLines = []
var constellationStars = []
var zodiacNames = []
data.forEach(function (constellation) {
var name = constellation.name
var projections = constellation.stars.map(function (star) {
var p = projection([star.ra, star.dec])
var out = (distance(p[0], p[1]) > width / 2.5)
return {
color: star.color,
mag: star.mag,
radius: Math.pow(1.2, 3 - star.mag),
projection: p,
out: out
}
})
var x = d3.mean(projections, function (d) { return d.projection[0] = -d.projection[0] })
var y = d3.mean(projections, function (d) { return d.projection[1] })
projections = projections.filter(function (star) {
return !star.out && star.mag <= 6
})
if (distance(x, y) < width / 3 || constellation.zodiac){
var lines = constellation.lines.map(function (line) {
var p1 = projection([line.ra1, line.dec1])
var p2 = projection([line.ra2, line.dec2])
p1[0] = -p1[0]
p2[0] = -p2[0]
var out = distance(p1[0], p1[1]) > width / 3
return {line: [p1, p2], zodiac: constellation.zodiac, out: out}
})
lines = lines.filter(function (line) {
return !line.out || line.zodiac
})
constellationLines.push(lines)
}
constellationStars.push(projections)
if (constellation.zodiac)
zodiacNames.push({
name: name,
x: x,
y: y
})
})
constellationLines.forEach(function(lines){
lines.forEach(drawLine)
})
var linesLayer = getImage(ctx)
clearCtx()
constellationStars.forEach(function(projections){
projections.forEach(drawStar)
})
var starsLayer = getImage(ctx)
stackBlurCanvasRGBA('canvas', 0, 0, width, height, 1)
var bgStarsLayer = getImage(ctx)
changeColor(bgStarsLayer, '#000313')
clearCtx()
zodiacNames.forEach(addZodiacName)
var namesLayer = getImage(ctx)
stackBlurCanvasRGBA('canvas', 0, 0, width, height, 3)
var bgNamesLayer = getImage(ctx)
changeColor(bgNamesLayer, '#000313')
clearCtx()
ctx.scale(1 / ratio, 1 / ratio )
offCtx.putImageData(linesLayer, 0, 0)
ctx.drawImage(offScreenCanvas, -scaledWidth / 2, -scaledHeight / 2)
offCtx.putImageData(bgStarsLayer, 0, 0)
ctx.drawImage(offScreenCanvas, -scaledWidth / 2, -scaledHeight / 2)
offCtx.putImageData(starsLayer, 0, 0)
ctx.drawImage(offScreenCanvas, -scaledWidth / 2, -scaledHeight / 2)
offCtx.putImageData(bgNamesLayer, 0, 0)
ctx.drawImage(offScreenCanvas, -scaledWidth / 2, -scaledHeight / 2)
offCtx.putImageData(namesLayer, 0, 0)
ctx.drawImage(offScreenCanvas, -scaledWidth / 2, -scaledHeight / 2)
var fps = 'fps'
var frames = 0
function animate(){
window.requestAnimationFrame(animate)
frames++
}
animate()
setInterval(function () {
fps = frames / 10 + ' fps'
console.log(fps)
frames = 0
}, 10000)
setTimeout(function () {console.log(performance.now() - begin,'ms')})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment