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 ctx.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 makeRadialGradient(x, y, r, color) { var radialgradient = offCtx.createRadialGradient(x, y, 0, x, y, r) radialgradient.addColorStop(0.2, color) radialgradient.addColorStop(0.5,'rgba(0,3,19,1)') radialgradient.addColorStop(1,'rgba(0,3,19,0)') offCtx.fillStyle = radialgradient offCtx.fillRect( x - r, y - r, 2 * r, 2 * r) } function clearCtx(){ offCtx.clearRect(-width / 2, -height / 2, width, height) ctx.clearRect(0, 0, scaledWidth, scaledHeight) } function drawStar(star) { makeRadialGradient(star.projection[0], star.projection[1], star.radius, star.color) } d3.json("/erohinaelena/raw/ec635d68e8bf55586d40/starData.json", function(error, data) { 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.3, 5 - star.mag) + 1, 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') }) })