A 2017 moon calendar. Click to show today.
Uses the "Simple" moon plase calculation from Moon Phase Calculators. Built with blockbuilder.org. Forked from curran's block: Moon
| license: mit | |
| border: no | |
| height: 380 |
A 2017 moon calendar. Click to show today.
Uses the "Simple" moon plase calculation from Moon Phase Calculators. Built with blockbuilder.org. Forked from curran's block: Moon
| <!DOCTYPE html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <script src="https://d3js.org/d3.v4.min.js"></script> | |
| <style> | |
| body { | |
| margin: 0;position: fixed;top: 0;right: 0;bottom: 0;left: 0; | |
| } | |
| text { | |
| font-size: 1rem; | |
| } | |
| .axis .domain, .axis line { | |
| display: none; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <svg width="960" height="380"></svg> | |
| <script> | |
| var svg = d3.select("svg"), | |
| width = svg.attr("width"), | |
| height = svg.attr("height"), | |
| margin = { left: 100, right: 15, top: 35, bottom: 35 }, | |
| moonSize = 12, | |
| moonStroke = 0.5, | |
| axisPadding = moonSize - 2, | |
| startDate = new Date(2017, 0, 1), | |
| endDate = new Date(2017, 11, 31); | |
| var g = svg.append("g") | |
| .attr("transform", "translate(" + [margin.left, margin.top] + ")"), | |
| innerWidth = width - margin.right - margin.left, | |
| innerHeight = height - margin.bottom - margin.top, | |
| formatMonth = d3.timeFormat("%B"), | |
| formatDay = d3.timeFormat("%d"), | |
| newMoon = (new Date(1970, 0, 7, 20, 35, 0)).getTime(), | |
| lunarPeriod = 2551443000, | |
| data = d3.timeDays(startDate, endDate).map(type); | |
| function type (date){ | |
| return { | |
| month: formatMonth(date), | |
| day: formatDay(date), | |
| phase: -((date.getTime() - newMoon)) / lunarPeriod * 360 + 180 | |
| }; | |
| } | |
| var xScale = d3.scaleLinear() | |
| .domain(d3.extent(data, function (d){ return d.day; })) | |
| .range([0, innerWidth]), | |
| yScale = d3.scalePoint() | |
| .domain(data.map(function (d){ return d.month; })) | |
| .range([0, innerHeight]); | |
| var circle = d3.geoCircle(), | |
| projection = d3.geoOrthographic() | |
| .scale(moonSize) | |
| .translate([0, 0]), | |
| path = d3.geoPath() | |
| .projection(projection); | |
| g.append("g") | |
| .attr("class", "y axis") | |
| .attr("transform", "translate(-" + axisPadding + ")") | |
| .call(d3.axisLeft().scale(yScale)); | |
| g.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0,-" + axisPadding + ")") | |
| .call(d3.axisTop().scale(xScale).ticks(30)); | |
| g.append("g") | |
| .attr("class", "x axis") | |
| .attr("transform", "translate(0," + (innerHeight + axisPadding) + ")") | |
| .call(d3.axisBottom().scale(xScale).ticks(30)); | |
| var moons = g.selectAll(".moon").data(data) | |
| .enter().append("g") | |
| .attr("class", "moon") | |
| .attr("transform", function (d){ | |
| return "translate(" + [xScale(d.day), yScale(d.month)] + ")"; | |
| }); | |
| moons.append("circle") | |
| .attr("fill", "#2b281b") | |
| .attr("r", moonSize + moonStroke); | |
| moons.append("path") | |
| .attr("fill", "#f7f6f2") | |
| .attr("d", function (d){ | |
| return path(circle.center([d.phase, 0])()); | |
| }); | |
| svg.on("click", function (){ | |
| var d = type(new Date()); | |
| g.append("circle") | |
| .attr("cx", function (){ return xScale(d.day); }) | |
| .attr("cy", function (){ return yScale(d.month); }) | |
| .attr("stroke", "red") | |
| .attr("stroke-width", "50px") | |
| .attr("stroke-opacity", 0) | |
| .attr("fill", "none") | |
| .attr("r", 500) | |
| .transition().duration(1000) | |
| .attr("stroke-width", "3px") | |
| .attr("stroke-opacity", 1) | |
| .attr("r", moonSize + 5); | |
| }); | |
| </script> | |
| </body> |