|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<link href='http://fonts.googleapis.com/css?family=Exo+2:100,200,300' rel='stylesheet' type='text/css'> |
|
<title>刻 spacetime</title> |
|
<link rel="shortcut icon" href="favicon.ico" /> |
|
<style> |
|
|
|
body { |
|
background: #222; |
|
} |
|
|
|
#container { |
|
position: absolute; |
|
left: 50%; |
|
margin-left: -480px; |
|
top: 50%; |
|
margin-top: -250px; |
|
} |
|
|
|
.bigclock { |
|
font-family: "Exo 2"; |
|
font-size: 120px; |
|
font-weight: 300; |
|
} |
|
|
|
.smallclock{ |
|
font-family: "Exo 2"; |
|
font-size: 50px; |
|
font-weight: 100; |
|
} |
|
|
|
</style> |
|
<body> |
|
<div id="container"></div> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script> |
|
|
|
Number.prototype.pad = function(size) { |
|
var s = String(this); |
|
if(typeof(size) !== "number"){size = 2;} |
|
|
|
while (s.length < size) {s = "0" + s;} |
|
return s; |
|
} |
|
|
|
var now = new Date(d3.time.year.floor(new Date())); |
|
|
|
var spacetime = d3.select('#container'); |
|
var radius = 500, |
|
width = 960, |
|
height = radius; |
|
|
|
var radii = { |
|
"sun": radius / 8, |
|
"earthOrbit": radius / 2.5, |
|
"earth": radius / 32, |
|
"moonOrbit": radius / 16, |
|
"moon": radius / 96 |
|
}; |
|
|
|
// Space |
|
var svg = spacetime.append("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.append("g") |
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); |
|
|
|
// Clock |
|
var solarTime = svg.append("text") |
|
.attr("class", "smallclock") |
|
.attr("x", -315) |
|
.attr("dominant-baseline", "central") |
|
.style("text-anchor", "start") |
|
.style("fill", "rgba(255, 204, 0, 0.75)") |
|
.text("year"), |
|
lunarTime = svg.append("text") |
|
.attr("class", "smallclock") |
|
.attr("x", 365) |
|
.attr("dominant-baseline", "central") |
|
.style("font-weight", 200) |
|
.style("text-anchor", "end") |
|
.style("fill", "rgba(150, 150, 150, 0.75)") |
|
.text("month"), |
|
|
|
keTime = svg.append("text") |
|
.attr("class", "bigclock") |
|
.attr("dominant-baseline", "central") |
|
.style("text-anchor", "end") |
|
.style("fill", "rgba(85, 126, 190, 0.75)") |
|
.text("刻"), |
|
fenTime = svg.append("text") |
|
.attr("class", "bigclock") |
|
.attr("dominant-baseline", "central") |
|
.style("font-weight", 200) |
|
.style("text-anchor", "start") |
|
.style("fill", "rgba(85, 126, 190, 0.25)") |
|
.text("分"); |
|
|
|
// Earth's orbit |
|
svg.append("circle") |
|
.attr("class", "earthOrbit") |
|
.attr("r", radii.earthOrbit) |
|
.style("fill", "none") |
|
.style("stroke", "rgba(255, 204, 0, 0.25)"); |
|
|
|
// Current position of Earth in its orbit |
|
var earthOrbitPosition = d3.svg.arc() |
|
.outerRadius(radii.earthOrbit + 1) |
|
.innerRadius(radii.earthOrbit - 1) |
|
.startAngle(0) |
|
.endAngle(2*Math.PI); |
|
svg.append("path") |
|
.attr("class", "earthOrbitPosition") |
|
.attr("d", earthOrbitPosition) |
|
.style("fill", "rgba(255, 204, 0, 0.75)"); |
|
|
|
// Earth's spin |
|
svg.append("circle") |
|
.attr("class", "earth") |
|
.attr("r", radii.earth) |
|
.attr("transform", "translate(0," + -radii.earthOrbit + ")") |
|
.style("fill", "none") |
|
.style("stroke", "rgba(85, 126, 190, 0.25)"); |
|
|
|
// Current position of Earth in its spin |
|
var day = d3.svg.arc() |
|
.outerRadius(radii.earth + 2.8) |
|
.innerRadius(radii.earth - 2.8) |
|
.startAngle(0) |
|
.endAngle(2*Math.PI); |
|
svg.append("path") |
|
.attr("class", "day") |
|
.attr("d", day) |
|
.attr("transform", "translate(0," + -radii.earthOrbit + ")") |
|
.style("fill", "rgba(85, 126, 190, 0.75)"); |
|
|
|
// Moon's orbit |
|
svg.append("circle") |
|
.attr("class", "moonOrbit") |
|
.attr("r", radii.moonOrbit) |
|
.attr("transform", "translate(0," + -radii.earthOrbit + ")") |
|
.style("fill", "none") |
|
.style("stroke", "rgba(150, 150, 150, 0.25)"); |
|
|
|
// Current position of the Moon in its orbit |
|
var moonOrbitPosition = d3.svg.arc() |
|
.outerRadius(radii.moonOrbit + 1.5) |
|
.innerRadius(radii.moonOrbit - 1.5) |
|
.startAngle(0) |
|
.endAngle(2*Math.PI); |
|
svg.append("path") |
|
.attr("class", "moonOrbitPosition") |
|
.attr("d", moonOrbitPosition(now)) |
|
.attr("transform", "translate(0," + -radii.earthOrbit + ")") |
|
.style("fill", "rgba(150, 150, 150, 0.75)"); |
|
|
|
var UpdateClock = function () { |
|
now = new Date(); |
|
|
|
var solarFraction = d3.time.hours(d3.time.year.floor(now), now).length / d3.time.hours(d3.time.year.floor(now), d3.time.year.ceil(now)).length, |
|
interpolateEarthOrbitPosition = d3.interpolate(earthOrbitPosition.endAngle()(), 2*Math.PI*solarFraction); |
|
if (solarFraction === 1) solarFraction = 0 |
|
solarTime.text(Math.floor(100*solarFraction).pad(2)) |
|
|
|
var keFraction = d3.time.seconds(d3.time.day.floor(now), now).length / d3.time.seconds(d3.time.day.floor(now), d3.time.day.ceil(now)).length,interpolateDay = d3.interpolate(day.endAngle()(), 2 * Math.PI * keFraction); |
|
if (keFraction === 1) keFraction = 0 |
|
var ke = Math.floor(100*keFraction); |
|
document.title = ke.pad(2) + "刻" |
|
keTime.text(ke.pad(2)); |
|
var fen = Math.floor(100*(100*keFraction - ke)); |
|
if (fen === 100) fen = 0 |
|
fenTime.text(fen.pad(2)); |
|
|
|
var lunarFraction = d3.time.hours(d3.time.month.floor(now), now).length / d3.time.hours(d3.time.month.floor(now), d3.time.month.ceil(now)).length, |
|
interpolateMoonOrbitPosition = d3.interpolate(moonOrbitPosition.endAngle()(), 2 * Math.PI * lunarFraction); |
|
if (lunarFraction === 1) lunarFraction = 0 |
|
lunarTime.text(Math.floor(100*lunarFraction).pad(2)); |
|
lunarTime.attr("x", 315) |
|
|
|
d3.transition().tween("orbit", function () { |
|
return function (t) { |
|
// Animate Earth orbit position |
|
d3.select(".earthOrbitPosition").attr("d", earthOrbitPosition.endAngle(interpolateEarthOrbitPosition(t))); |
|
|
|
// Transition Earth |
|
d3.select(".earth") |
|
.attr("transform", "translate(" + radii.earthOrbit * Math.sin(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + "," + -radii.earthOrbit * Math.cos(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + ")"); |
|
|
|
// Animate day |
|
// Transition day |
|
d3.select(".day") |
|
.attr("d", day.endAngle(interpolateDay(t))) |
|
.attr("transform", "translate(" + radii.earthOrbit * Math.sin(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + "," + -radii.earthOrbit * Math.cos(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + ")"); |
|
|
|
// Transition Moon orbit |
|
d3.select(".moonOrbit") |
|
.attr("transform", "translate(" + radii.earthOrbit * Math.sin(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + "," + -radii.earthOrbit * Math.cos(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + ")"); |
|
|
|
// Animate Moon orbit position |
|
// Transition Moon orbit position |
|
d3.select(".moonOrbitPosition") |
|
.attr("d", moonOrbitPosition.endAngle(interpolateMoonOrbitPosition(t))) |
|
.attr("transform", "translate(" + radii.earthOrbit * Math.sin(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + "," + -radii.earthOrbit * Math.cos(interpolateEarthOrbitPosition(t) - earthOrbitPosition.startAngle()()) + ")"); |
|
|
|
}; |
|
}); |
|
} |
|
|
|
// Update the clock every 分 |
|
if (location.hash === "#nowait") UpdateClock() |
|
setInterval(UpdateClock, 8640); |
|
|
|
</script> |