Last active
August 29, 2015 14:14
-
-
Save nasitra/0cdc6511c5189acc77a5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>World Time Clock</title> | |
<style> | |
* { | |
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); | |
-webkit-text-size-adjust:none; | |
-webkit-touch-callout:none; | |
} | |
html, body { | |
height: 100%; | |
overflow: hidden; | |
user-select: none; | |
} | |
#container { | |
height: 100%; | |
overflow: hidden; | |
vertical-align: text-bottom; | |
white-space: nowrap; | |
} | |
</style> | |
</head> | |
<body> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script> | |
<div id="container"></div> | |
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script> | |
<script> | |
(function() { | |
var TimeZoneList = ["America/New_York", "Europe/London", "Asia/Tokyo"]; | |
function Model() { | |
var attr = {data: [], selectedItems: []}; | |
var timer = null; | |
function getTimeZone(list, callback) { | |
callback([["America/New_York",-18000],["Europe/London",0],["Asia/Tokyo",32400]]); | |
} | |
function getTimelist(timezone) { | |
var i, len, timelist = [], date = new Date(), name; | |
for (i = 0, len = timezone.length; i < len; ++i) { | |
name = timezone[i][0].substring(timezone[i][0].lastIndexOf("/") + 1).replace(/_/g, " "); | |
timelist[i] = [name, new Date(date.getTime() + parseInt(timezone[i][1], 10) * 1000 + date.getTimezoneOffset() * 60 * 1000)]; | |
} | |
return timelist; | |
} | |
return { | |
init: function(__attr__) { for (var key in __attr__) { attr[key] = __attr__[key]; } }, | |
select: function(list) { | |
if (list === undefined) { return attr.selectedItems; } | |
else { attr.selectedItems = list; } | |
}, | |
removeSelect: function(item) { | |
var selectedItems = attr.selectedItems; | |
for(var i = selectedItems.length - 1; i >= 0; --i){ | |
if (selectedItems[i] === item){ selectedItems.splice(i, 1); } | |
} | |
}, | |
start: function() { | |
var self = this; | |
self.stop(timer); | |
getTimeZone(attr.selectedItems, function(data) { | |
$(self).trigger($.Event("update", {timelist: getTimelist(data)})); | |
timer = setInterval(function() { | |
$(self).trigger($.Event("update", {timelist: getTimelist(data)})); | |
}, 10000); | |
}); | |
}, | |
stop: function() { if (timer !== null) { clearInterval(timer); timer = null; } } | |
}; | |
} | |
function View() { | |
var attr = {element: "", timelist: []}; | |
var clock = null, center, r, pointlist = []; | |
function capitalize(str) { | |
return str.replace(/\w+/g, function(word){ | |
return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase(); | |
}); | |
} | |
function drawClock(paper, x, y, r) { | |
var viewlist = [], i, dif = Math.PI / 12, deg = 0, text, fontSize, rate; | |
viewlist.push({type: "circle", cx: x, cy: y, r: r, "stroke-width": r/30}); | |
for (i = 0; i < 24; ++i) { | |
switch (i) { | |
case 0: text = "18"; break; | |
case 3: text = "21"; break; | |
case 6: text = "0"; break; | |
case 9: text = "3"; break; | |
case 12: text = "6"; break; | |
case 15: text = "9"; break; | |
case 18: text = "12"; break; | |
case 21: text = "15"; break; | |
default: text = "・"; break; | |
} | |
if (text === "・") { fontSize = r / 12; } else { fontSize = r / 4.5; } | |
if (text === "18" || text === "15" || text === "21") { rate = 0.04; } else { rate = 0; } | |
viewlist.push({type:"text", x: x + r * (0.8 - Math.abs(rate * Math.cos(deg))) * Math.cos(deg), y: y + r * (0.8 - Math.abs(rate * Math.sin(deg))) * Math.sin(deg), text: text, "font-size": Math.max(fontSize, 18), "font-family": "serif"}); | |
deg += dif; | |
} | |
paper.add(viewlist); | |
} | |
function updateClock(paper, x, y, r, timelist) { | |
var i, len, time, deg, text, textBBox, textPoint, textList = {}; | |
for (i = 0, len = pointlist.length; i < len; ++i) { pointlist[i].remove(); } | |
pointlist = []; | |
for (i = 0, len = timelist.length; i < len; ++i) { | |
time = timelist[i][1]; | |
deg = (time.getHours() + time.getMinutes() / 60) / 24 * (Math.PI * 2) + Math.PI / 2; | |
textPoint = {x: x + r * Math.cos(deg), y: y + r * Math.sin(deg)}; | |
pointlist.push(paper.circle(x + r * Math.cos(deg), y + r * Math.sin(deg), r/20).attr({fill: "white", "stroke-width": r/90})); | |
text = textList[time.getTime()]; | |
if (text === undefined) { | |
text = paper.text(textPoint.x, textPoint.y, timelist[i][0]).attr({opacity: 1, "font-size": r/10, "font-family": "serif"}); | |
textList[time.getTime()] = text; | |
} else { text.attr({text: text.attr("text") + "," + timelist[i][0]}); } | |
textBBox = text.getBBox(); | |
textPoint.x = x + (r + textBBox.width/2 + r/8) * Math.cos(deg); | |
textPoint.y = y + (r + textBBox.height/2 + r/8) * Math.sin(deg); | |
text.attr({x: textPoint.x, y: textPoint.y}); | |
pointlist.push(text); | |
} | |
} | |
return { | |
init: function(__attr__) { | |
var self = this, key; | |
for (key in __attr__) { attr[key] = __attr__[key]; } | |
self.setTimelist = function(value) { | |
attr.timelist = value; | |
}; | |
self.setElement = function(value) { | |
attr.element = value; | |
}; | |
}, | |
update: function() { | |
var self = this; | |
if (clock === null) { | |
clock = Raphael(attr.element, "100%", "100%"); | |
var $container = $("#container"); | |
center = {x: $container.width()/2, y: $container.height()/2}, r = Math.min(center.x, center.y) * 0.6; | |
drawClock(clock, center.x, center.y, r); | |
clock.circle(center.x, center.y, r / 10).attr({"stroke-width": r / 70, "fill": "white"}); | |
} | |
updateClock(clock, center.x, center.y, r, attr.timelist); | |
$("#container").css({width: $(window).width(), height: $(window).height()}); | |
}, | |
clear: function() { | |
if (clock !== null) { clock.remove(); clock = null; } | |
} | |
}; | |
} | |
function Controller() { | |
return { | |
init: function() { | |
var model = Model(); | |
model.init({data: TimeZoneList}); | |
var view = View(); | |
$(function() { | |
view.init({element: "container"}); | |
$(model).bind("update", function(event) { | |
view.setTimelist(event.timelist); | |
view.update(); | |
}); | |
model.select(["America/New_York", "Europe/London", "Asia/Tokyo"]); | |
model.start(); | |
}); | |
} | |
}; | |
} | |
Controller().init(); | |
})(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is the world time clock user interface. | |
You can check current time at one view. | |
This UI is used for the folloing application. | |
Loclock: http://www.ionstage.org/loclock/index.html | |
2013/09/12 | |
- modify the source code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment