Skip to content

Instantly share code, notes, and snippets.

@erohinaelena
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erohinaelena/f7f8e07873995ff57528 to your computer and use it in GitHub Desktop.
Save erohinaelena/f7f8e07873995ff57528 to your computer and use it in GitHub Desktop.
canvas + shadows-circles + ctx.rotate
<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="stars.js"></script>
<script>d3.select(self.frameElement).style("height", "840px")</script>
</body>
</html>
body {
margin: 0;
background: #000313;
}
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")
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
offCtx.scale(ratio, ratio)
offCtx.translate(width / 2, height / 2)
function addZodiacName(data) {
var x1 = 0, y1 = -data.y / Math.sin(Math.atan2(data.y, data.x))
offCtx.save()
offCtx.rotate(Math.atan2(data.y, data.x) + Math.PI / 2 )
offCtx.textAlign = "center"
offCtx.font = "12px sans-serif"
offCtx.strokeStyle = "#000313"
offCtx.lineWidth = 3
offCtx.lineJoin = "round"
offCtx.strokeText(data.name, x1, y1)
offCtx.fillStyle = "white"
offCtx.fillText(data.name, x1, y1)
offCtx.restore()
}
function distance(x,y) {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
}
function drawLine(line) {
offCtx.strokeStyle = (line.zodiac) ? '#f2f237':'white'
offCtx.lineWidth = (line.zodiac) ? 0.8 : 0.4
offCtx.beginPath()
offCtx.moveTo(line.line[0][0], line.line[0][1])
offCtx.lineTo(line.line[1][0], line.line[1][1])
offCtx.stroke()
}
function drawStar(star) {
offCtx.fillStyle = '#000313'
offCtx.beginPath()
offCtx.moveTo(star.projection[0], star.projection[1]);
offCtx.arc(star.projection[0], star.projection[1], star.radius + 1.2, 0 ,Math.PI * 2 ,true);
offCtx.fill()
offCtx.fillStyle = star.color
offCtx.beginPath()
offCtx.moveTo(star.projection[0], star.projection[1]);
offCtx.arc(star.projection[0], star.projection[1], star.radius, 0 ,Math.PI * 2 ,true);
offCtx.fill()
}
function clearCtx(){
offCtx.clearRect(-width / 2, -height / 2, width, height)
ctx.clearRect(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
})
})
var angle = 0
var fps = 'fps'
var frames = 0
function draw () {
begin = performance.now()
frames++
clearCtx()
offCtx.fillStyle = '#fff'
offCtx.fillText(fps, -width / 2 + 10, -height / 2 + 20)
angle += 0.002
offCtx.save()
offCtx.rotate(angle)
constellationLines.forEach(function(lines){
lines.forEach(drawLine)
})
constellationStars.forEach(function(projections){
projections.forEach(drawStar)
})
zodiacNames.forEach(addZodiacName)
offCtx.restore()
ctx.drawImage(offScreenCanvas, 0, 0);
}
function animate(){
window.requestAnimationFrame(animate)
draw()
}
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