departr 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,325 @@
1
+ /**
2
+ * CoolClock 2.1.4
3
+ * Copyright 2010, Simon Baird
4
+ * Released under the BSD License.
5
+ *
6
+ * Display an analog clock using canvas.
7
+ * http://randomibis.com/coolclock/
8
+ *
9
+ */
10
+
11
+ // Constructor for CoolClock objects
12
+ window.CoolClock = function(options) {
13
+ return this.init(options);
14
+ }
15
+
16
+ // Config contains some defaults, and clock skins
17
+ CoolClock.config = {
18
+ tickDelay: 1000,
19
+ longTickDelay: 15000,
20
+ defaultRadius: 85,
21
+ renderRadius: 100,
22
+ defaultSkin: "solt",
23
+ // Should be in skin probably...
24
+ // (TODO: allow skinning of digital display)
25
+ showSecs: true,
26
+ showAmPm: true,
27
+
28
+ skins: {
29
+ solt: {
30
+ outerBorder: { lineWidth: 4, radius:97, color: "#ccc", alpha: 1 },
31
+ smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "#ccc", alpha: 1 },
32
+ largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "#ccc", alpha: 1 },
33
+ hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
34
+ minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
35
+ secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "#54ACFF", alpha: 1 },
36
+ secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "#54ACFF", color: "red", alpha: 1 }
37
+ }/*,
38
+ swissRail: {
39
+ outerBorder: { lineWidth: 2, radius:95, color: "black", alpha: 1 },
40
+ smallIndicator: { lineWidth: 2, startAt: 88, endAt: 92, color: "black", alpha: 1 },
41
+ largeIndicator: { lineWidth: 4, startAt: 79, endAt: 92, color: "black", alpha: 1 },
42
+ hourHand: { lineWidth: 8, startAt: -15, endAt: 50, color: "black", alpha: 1 },
43
+ minuteHand: { lineWidth: 7, startAt: -15, endAt: 75, color: "black", alpha: 1 },
44
+ secondHand: { lineWidth: 1, startAt: -20, endAt: 85, color: "red", alpha: 1 },
45
+ secondDecoration: { lineWidth: 1, startAt: 70, radius: 4, fillColor: "red", color: "red", alpha: 1 }
46
+ },
47
+ chunkySwiss: {
48
+ outerBorder: { lineWidth: 4, radius:97, color: "black", alpha: 1 },
49
+ smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "black", alpha: 1 },
50
+ largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "black", alpha: 1 },
51
+ hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "black", alpha: 1 },
52
+ minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "black", alpha: 1 },
53
+ secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
54
+ secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
55
+ },
56
+ chunkySwissOnBlack: {
57
+ outerBorder: { lineWidth: 4, radius:97, color: "white", alpha: 1 },
58
+ smallIndicator: { lineWidth: 4, startAt: 89, endAt: 93, color: "white", alpha: 1 },
59
+ largeIndicator: { lineWidth: 8, startAt: 80, endAt: 93, color: "white", alpha: 1 },
60
+ hourHand: { lineWidth: 12, startAt: -15, endAt: 60, color: "white", alpha: 1 },
61
+ minuteHand: { lineWidth: 10, startAt: -15, endAt: 85, color: "white", alpha: 1 },
62
+ secondHand: { lineWidth: 4, startAt: -20, endAt: 85, color: "red", alpha: 1 },
63
+ secondDecoration: { lineWidth: 2, startAt: 70, radius: 8, fillColor: "red", color: "red", alpha: 1 }
64
+ }
65
+ */
66
+ },
67
+
68
+ // Test for IE so we can nurse excanvas in a couple of places
69
+ isIE: !!document.all,
70
+
71
+ // Will store (a reference to) each clock here, indexed by the id of the canvas element
72
+ clockTracker: {},
73
+
74
+ // For giving a unique id to coolclock canvases with no id
75
+ noIdCount: 0
76
+ };
77
+
78
+ // Define the CoolClock object's methods
79
+ CoolClock.prototype = {
80
+
81
+ // Initialise using the parameters parsed from the colon delimited class
82
+ init: function(options) {
83
+ // Parse and store the options
84
+ this.canvasId = options.canvasId;
85
+ this.skinId = options.skinId || CoolClock.config.defaultSkin;
86
+ this.displayRadius = options.displayRadius || CoolClock.config.defaultRadius;
87
+ this.showSecondHand = typeof options.showSecondHand == "boolean" ? options.showSecondHand : true;
88
+ this.gmtOffset = (options.gmtOffset !== null && options.gmtOffset !== '') ? parseFloat(options.gmtOffset) : null;
89
+ this.showDigital = typeof options.showDigital == "boolean" ? options.showDigital : true;
90
+ this.logClock = typeof options.logClock == "boolean" ? options.logClock : false;
91
+ this.logClockRev = typeof options.logClock == "boolean" ? options.logClockRev : false;
92
+
93
+ this.tickDelay = CoolClock.config[ this.showSecondHand ? "tickDelay" : "longTickDelay" ];
94
+ this.label = options.label || false;
95
+ this.fontSize = options.fontSize || "15px";
96
+
97
+ // Get the canvas element
98
+ this.canvas = document.getElementById(this.canvasId);
99
+
100
+ // Make the canvas the requested size. It's always square.
101
+ this.width = this.displayRadius*2;
102
+ this.height = this.displayRadius*2 + parseInt(this.fontSize) * 2;
103
+ this.canvas.setAttribute("width",this.width);
104
+ this.canvas.setAttribute("height",this.height);
105
+ this.canvas.style.width = this.width + "px";
106
+ this.canvas.style.height = this.height + "px";
107
+
108
+ // Explain me please...?
109
+ this.renderRadius = CoolClock.config.renderRadius;
110
+ this.scale = this.displayRadius / this.renderRadius;
111
+
112
+ // Initialise canvas context
113
+ this.ctx = this.canvas.getContext("2d");
114
+ this.ctx.scale(this.scale,this.scale);
115
+
116
+ // Keep track of this object
117
+ CoolClock.config.clockTracker[this.canvasId] = this;
118
+
119
+ // should we be running the clock?
120
+ this.active = true;
121
+ this.tickTimeout = null;
122
+
123
+ // Start the clock going
124
+ this.tick();
125
+
126
+ return this;
127
+ },
128
+
129
+ // Draw a circle at point x,y with params as defined in skin
130
+ fullCircleAt: function(x,y,skin) {
131
+ this.ctx.save();
132
+ this.ctx.globalAlpha = skin.alpha;
133
+ this.ctx.lineWidth = skin.lineWidth;
134
+
135
+ if (!CoolClock.config.isIE) {
136
+ this.ctx.beginPath();
137
+ }
138
+
139
+ if (CoolClock.config.isIE) {
140
+ // excanvas doesn't scale line width so we will do it here
141
+ this.ctx.lineWidth = this.ctx.lineWidth * this.scale;
142
+ }
143
+
144
+ this.ctx.arc(x, y, skin.radius, 0, 2*Math.PI, false);
145
+
146
+ if (CoolClock.config.isIE) {
147
+ // excanvas doesn't close the circle so let's fill in the tiny gap
148
+ this.ctx.arc(x, y, skin.radius, -0.1, 0.1, false);
149
+ }
150
+
151
+ if (skin.fillColor) {
152
+ this.ctx.fillStyle = skin.fillColor
153
+ this.ctx.fill();
154
+ }
155
+ else {
156
+ // XXX why not stroke and fill
157
+ this.ctx.strokeStyle = skin.color;
158
+ this.ctx.stroke();
159
+ }
160
+ this.ctx.restore();
161
+ },
162
+
163
+ // Draw some text centered vertically and horizontally
164
+ drawTextAt: function(theText,x,y,bold) {
165
+ this.ctx.save();
166
+ this.ctx.font = (bold?'bold ':'') + this.fontSize + ' sans-serif';
167
+ var tSize = this.ctx.measureText(theText);
168
+ if (!tSize.height) tSize.height = 15; // no height in firefox.. :(
169
+ this.ctx.fillText(theText,x - tSize.width/2,y - tSize.height/2);
170
+ this.ctx.restore();
171
+ },
172
+
173
+ lpad2: function(num) {
174
+ return (num < 10 ? '0' : '') + num;
175
+ },
176
+
177
+ tickAngle: function(second) {
178
+ // Log algorithm by David Bradshaw
179
+ var tweak = 3; // If it's lower the one second mark looks wrong (?)
180
+ if (this.logClock) {
181
+ return second == 0 ? 0 : (Math.log(second*tweak) / Math.log(60*tweak));
182
+ }
183
+ else if (this.logClockRev) {
184
+ // Flip the seconds then flip the angle (trickiness)
185
+ second = (60 - second) % 60;
186
+ return 1.0 - (second == 0 ? 0 : (Math.log(second*tweak) / Math.log(60*tweak)));
187
+ }
188
+ else {
189
+ return second/60.0;
190
+ }
191
+ },
192
+
193
+ timeText: function(hour,min,sec) {
194
+ var c = CoolClock.config;
195
+ return '' +
196
+ (c.showAmPm ? ((hour%12)==0 ? 12 : (hour%12)) : hour) + ':' +
197
+ this.lpad2(min) +
198
+ (c.showSecs ? ':' + this.lpad2(sec) : '') +
199
+ (c.showAmPm ? (hour < 12 ? ' am' : ' pm') : '')
200
+ ;
201
+ },
202
+
203
+ // Draw a radial line by rotating then drawing a straight line
204
+ // Ha ha, I think I've accidentally used Taus, (see http://tauday.com/)
205
+ radialLineAtAngle: function(angleFraction,skin) {
206
+ this.ctx.save();
207
+ this.ctx.translate(this.renderRadius,this.renderRadius);
208
+ this.ctx.rotate(Math.PI * (2.0 * angleFraction - 0.5));
209
+ this.ctx.globalAlpha = skin.alpha;
210
+ this.ctx.strokeStyle = skin.color;
211
+ this.ctx.lineWidth = skin.lineWidth;
212
+
213
+ if (CoolClock.config.isIE)
214
+ // excanvas doesn't scale line width so we will do it here
215
+ this.ctx.lineWidth = this.ctx.lineWidth * this.scale;
216
+
217
+ if (skin.radius) {
218
+ this.fullCircleAt(skin.startAt,0,skin)
219
+ }
220
+ else {
221
+ this.ctx.beginPath();
222
+ this.ctx.moveTo(skin.startAt,0)
223
+ this.ctx.lineTo(skin.endAt,0);
224
+ this.ctx.stroke();
225
+ }
226
+ this.ctx.restore();
227
+ },
228
+
229
+ render: function(hour,min,sec) {
230
+ // Get the skin
231
+ var skin = CoolClock.config.skins[this.skinId];
232
+ if (!skin) skin = CoolClock.config.skins[CoolClock.config.defaultSkin];
233
+
234
+ // Clear
235
+ this.ctx.clearRect(0,0,this.renderRadius*2,this.renderRadius*2+2*(parseInt(this.fontSize)+10));
236
+
237
+ // Draw the outer edge of the clock
238
+ if (skin.outerBorder)
239
+ this.fullCircleAt(this.renderRadius,this.renderRadius,skin.outerBorder);
240
+
241
+ // Draw the tick marks. Every 5th one is a big one
242
+ for (var i=0;i<60;i++) {
243
+ (i%5) && skin.smallIndicator && this.radialLineAtAngle(this.tickAngle(i),skin.smallIndicator);
244
+ !(i%5) && skin.largeIndicator && this.radialLineAtAngle(this.tickAngle(i),skin.largeIndicator);
245
+ }
246
+
247
+ // Write the time
248
+ if (this.showDigital) {
249
+ this.drawTextAt(
250
+ this.timeText(hour,min,sec),
251
+ this.renderRadius,
252
+ this.renderRadius*2+parseInt(this.fontSize)+15
253
+ );
254
+ }
255
+
256
+ if (this.label) {
257
+ this.drawTextAt(
258
+ this.label,
259
+ this.renderRadius,
260
+ this.renderRadius*2+2*(parseInt(this.fontSize)+10),
261
+ true
262
+ );
263
+ }
264
+
265
+ // Draw the hands
266
+ if (skin.hourHand)
267
+ this.radialLineAtAngle(this.tickAngle(((hour%12)*5 + min/12.0)),skin.hourHand);
268
+
269
+ if (skin.minuteHand)
270
+ this.radialLineAtAngle(this.tickAngle((min + sec/60.0)),skin.minuteHand);
271
+
272
+ if (this.showSecondHand && skin.secondHand)
273
+ this.radialLineAtAngle(this.tickAngle(sec),skin.secondHand);
274
+
275
+ // Second hand decoration doesn't render right in IE so lets turn it off
276
+ if (!CoolClock.config.isIE && this.showSecondHand && skin.secondDecoration)
277
+ this.radialLineAtAngle(this.tickAngle(sec),skin.secondDecoration);
278
+ },
279
+
280
+ // Check the time and display the clock
281
+ refreshDisplay: function() {
282
+ var now = new Date();
283
+ if (this.gmtOffset !== null) {
284
+ // Use GMT + gmtOffset
285
+ var offsetNow = new Date(now.valueOf() + (this.gmtOffset * 1000 * 60 * 60));
286
+ this.render(offsetNow.getUTCHours(),offsetNow.getUTCMinutes(),offsetNow.getUTCSeconds());
287
+ }
288
+ else {
289
+ // Use local time
290
+ this.render(now.getHours(),now.getMinutes(),now.getSeconds());
291
+ }
292
+ },
293
+
294
+ // Set timeout to trigger a tick in the future
295
+ nextTick: function() {
296
+ this.tickTimeout = setTimeout("CoolClock.config.clockTracker['"+this.canvasId+"'].tick()",this.tickDelay);
297
+ },
298
+
299
+ // Check the canvas element hasn't been removed
300
+ stillHere: function() {
301
+ return document.getElementById(this.canvasId) != null;
302
+ },
303
+
304
+ // Stop this clock
305
+ stop: function() {
306
+ this.active = false;
307
+ clearTimeout(this.tickTimeout);
308
+ },
309
+
310
+ // Start this clock
311
+ start: function() {
312
+ if (!this.active) {
313
+ this.active = true;
314
+ this.tick();
315
+ }
316
+ },
317
+
318
+ // Main tick handler. Refresh the clock then setup the next tick
319
+ tick: function() {
320
+ if (this.stillHere() && this.active) {
321
+ this.refreshDisplay()
322
+ this.nextTick();
323
+ }
324
+ }
325
+ };
@@ -0,0 +1,144 @@
1
+ var Application = {
2
+ init: function() {
3
+ // Sign In/Out & Dedicated GUI
4
+ if (Cookie.read('user') && Cookie.read('session')) {
5
+ // Signed in
6
+
7
+ var signout = $('signout');
8
+ signout.addEvent('click', function(e) {
9
+ e.stop();
10
+ Cookie.dispose('user');
11
+ Cookie.dispose('session');
12
+ Cookie.dispose('name');
13
+ Cookie.dispose('provider');
14
+ window.location.reload();
15
+ }).setStyle('display', 'inline');
16
+
17
+ // Edit commands
18
+ $('edit').addEvent('click', Command.edit).setStyle('display', 'inline');
19
+
20
+ // Settings
21
+ $('settings').addEvent('click', Application.settings).setStyle('display', 'inline');
22
+
23
+ new Element('a', {
24
+ id: 'profile',
25
+ text: Cookie.read('name')
26
+ }).inject($('header'), 'top');
27
+ } else {
28
+ // Not signed in
29
+ var signin = $('signin');
30
+ if (signin) {
31
+ signin.addEvent('click', function(e) {
32
+ e.stop();
33
+
34
+ var modal = new SimpleModal({
35
+ draggable: false,
36
+ hideFooter: true,
37
+ width: 420,
38
+ offsetTop: 150
39
+ });
40
+ modal.show({
41
+ model: "modal",
42
+ title: "Sign in",
43
+ contents: "<iframe frameborder='0' width='400' height='240' src='" + signin.href + "'></iframe>"
44
+ });
45
+ }).setStyle('display', 'inline');
46
+ }
47
+ }
48
+
49
+ // Help
50
+ $('help').addEvent('click', Application.help);
51
+ },
52
+
53
+ // Display a notice (instead of alert)
54
+ notice: function(msg) {
55
+ var modal = new SimpleModal({
56
+ draggable: false,
57
+ hideHeader: true,
58
+ closeButton: false,
59
+ width: 300,
60
+ offsetTop: 150
61
+ });
62
+ modal.show({
63
+ model: "alert",
64
+ contents: msg
65
+ });
66
+ },
67
+
68
+ // Help
69
+ help: function() {
70
+ var modal = new SimpleModal({
71
+ draggable: false,
72
+ hideFooter: true,
73
+ width: 900
74
+ });
75
+ modal.show({
76
+ model: "modal-ajax",
77
+ title: "Help",
78
+ param: { url: "/help" }
79
+ });
80
+ },
81
+
82
+
83
+ // Edit settings
84
+ settings: function() {
85
+ var modal = new SimpleModal({
86
+ draggable: false,
87
+ offsetTop: 150,
88
+ width: 450
89
+ });
90
+ modal.addButton("Save", "btn primary", function() {
91
+ this.hide();
92
+ new Request({
93
+ url: '/settings',
94
+ urlEncoded: false,
95
+ headers: { 'Content-Type': 'application/json' },
96
+ onFailure: function() {
97
+ Application.notice('An error occured');
98
+ }
99
+ }).post(JSON.encode(Settings));
100
+ })
101
+ modal.show({
102
+ model: "modal-ajax",
103
+ title: "Settings",
104
+ param: {
105
+ url: "/settings",
106
+ onRequestComplete: function() {
107
+ $('setting_default_search').addEvent('change', function() {
108
+ Settings.default_search = this.value;
109
+ });
110
+ $('setting_default_search').value = Settings.default_search;
111
+
112
+ $('setting_open_in_new_page').addEvent('click', function() {
113
+ Settings.open_in_new_page = !Settings.open_in_new_page;
114
+ })
115
+ $('setting_open_in_new_page').checked = (Settings.open_in_new_page === true);
116
+
117
+ $('setting_github').addEvent('click', function() {
118
+ Settings.github = !Settings.github;
119
+ $(window.parent.document).getElement('#github').setStyle('display', Settings.github === true ? 'block': 'none');
120
+ })
121
+ $('setting_github').checked = (Settings.github === true);
122
+
123
+ $('setting_calendar').addEvent('click', function() {
124
+ Settings.calendar = !Settings.calendar;
125
+ $(window.parent.document).getElement('#date').setStyle('display', Settings.calendar === true ? 'block': 'none');
126
+ })
127
+ $('setting_calendar').checked = (Settings.calendar === true);
128
+
129
+ $('setting_clock1').addEvent('change', function() {
130
+ Settings.clock1 = this.value;
131
+ });
132
+
133
+ $('setting_clock2').addEvent('change', function() {
134
+ Settings.clock2 = this.value;
135
+ });
136
+
137
+ $('setting_clock3').addEvent('change', function() {
138
+ Settings.clock3 = this.value;
139
+ });
140
+ }
141
+ }
142
+ });
143
+ }
144
+ }