Skip to content

Instantly share code, notes, and snippets.

@nasitra
Last active August 29, 2015 14:14
Show Gist options
  • Save nasitra/0cdc6511c5189acc77a5 to your computer and use it in GitHub Desktop.
Save nasitra/0cdc6511c5189acc77a5 to your computer and use it in GitHub Desktop.
<!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 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