Pixel push the Done/back button.
[rgbconverter.git] / RGB Converter.wdgt / Widget.js
1 /*=====================================================================*\
2 || ###################################################################
3 || # RGB Converter
4 || # Copyright (c)2002-2010 Blue Static
5 || #
6 || # This program is free software; you can redistribute it and/or modify
7 || # it under the terms of the GNU General Public License as published by
8 || # the Free Software Foundation; version 2 of the License.
9 || #
10 || # This program is distributed in the hope that it will be useful, but
11 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 || # more details.
14 || #
15 || # You should have received a copy of the GNU General Public License along
16 || # with this program; if not, write to the Free Software Foundation, Inc.,
17 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 || ###################################################################
19 \*=====================================================================*/
20
21 var colors_ = {
22 red : 60,
23 green : 60,
24 blue : 60,
25 hex : '3C3C3C'
26 };
27
28 var backShowing_ = false;
29
30 // ###################################################################
31 // widget init
32 function Setup()
33 {
34 Draw();
35 createGenericButton(document.getElementById("backbutton"), "Done", hide_back, 0);
36 }
37
38 // ###################################################################
39 // watches the three RGB fields to make sure they don't go over the limites
40 function rgbwatcher(color)
41 {
42 field = document.getElementById(color + "input");
43
44 // handle RGB triads
45 if (triad = field.value.match(/(rgb)?\(?([0-9]{1,3}),\s?([0-9]{1,3}),\s?([0-9]{1,3})\)?/))
46 {
47 document.getElementById("redinput").value = triad[2];
48 document.getElementById("greeninput").value = triad[3];
49 document.getElementById("blueinput").value = triad[4];
50
51 rgbwatcher("red");
52 rgbwatcher("green");
53 rgbwatcher("blue");
54 return;
55 }
56
57 // sanitize the number
58 var newval = field.value.replace(/[^0-9\-\.]*/g, "");
59 newval = Math.floor(newval);
60
61 // make sure we don't go over 255
62 if (newval > 255)
63 {
64 newval = 255;
65 }
66 else if (newval < 0)
67 {
68 newval = 0;
69 }
70
71 // update the text field
72 field.value = newval;
73
74 // set fields[]
75 colors_[color] = newval;
76
77 // set hex
78 update_hex();
79
80 // redraw the swatch
81 Draw();
82 }
83
84 // ###################################################################
85 function Draw()
86 {
87 var canvas = document.getElementById('wheel');
88 var context = canvas.getContext('2d');
89 var radius = canvas.width / 2 - 3;
90 var center = [canvas.width / 2, canvas.height / 2];
91 context.strokeStyle = 'black';
92
93 context.clearRect(0, 0, canvas.width, canvas.height);
94
95 if (backShowing_) {
96 // Draw the sheen gradient.
97 context.beginPath();
98 context.arc(center[0], center[1], radius, 0, Math.PI * 2, true);
99 var gradient = context.createLinearGradient(0, 0, 0, canvas.height);
100 gradient.addColorStop(0, 'rgb(200, 200, 200)');
101 gradient.addColorStop(1, 'rgb(0, 0, 0)');
102 context.fillStyle = gradient;
103 context.fill();
104 context.closePath();
105 return;
106 }
107
108 // Draw the individual components. Start with red.
109 context.beginPath();
110 context.moveTo(center[0], center[1]);
111 context.arc(canvas.width / 2,
112 canvas.height / 2,
113 radius,
114 Math.PI * 4/3,
115 Math.PI * 6/3,
116 false);
117 context.lineTo(center[0], center[1]);
118 context.fillStyle = _GetComponentColorString('red');
119 context.fill();
120 context.stroke();
121
122 // Green component.
123 context.beginPath();
124 context.moveTo(center[0], center[1]);
125 context.arc(canvas.width / 2,
126 canvas.height / 2,
127 radius,
128 Math.PI * 0,
129 Math.PI * 2/3,
130 false);
131 context.lineTo(center[0], center[1]);
132 context.fillStyle = _GetComponentColorString('green');
133 context.fill();
134 context.stroke();
135
136 // Blue component.
137 context.beginPath();
138 context.moveTo(center[0], center[1]);
139 context.arc(canvas.width / 2,
140 canvas.height / 2,
141 radius,
142 Math.PI * 2/3,
143 Math.PI * 4/3,
144 false);
145 context.lineTo(center[0], center[1]);
146 context.fillStyle = _GetComponentColorString('blue');
147 context.fill();
148 context.stroke();
149
150 // Draw the sheen gradient.
151 context.beginPath();
152 context.arc(center[0], center[1], radius, 0, Math.PI * 2, true);
153 var gradient = context.createLinearGradient(0, 0, 0, canvas.height);
154 gradient.addColorStop(0, 'rgba(255,255,255,.5)');
155 gradient.addColorStop(1, 'rgba(0,0,0,0)');
156 context.fillStyle = gradient;
157 context.fill();
158 context.closePath();
159
160 // Draw the inner wheel.
161 context.beginPath();
162 context.arc(center[0], center[1], canvas.width / 4.75, 0, Math.PI * 2, true);
163 context.fillStyle = _GetRGBColorString();
164 context.fill();
165 context.strokeStyle = 'black';
166 context.stroke();
167 context.closePath();
168 }
169
170 // ###################################################################
171 // Returns the rgb(,,,) color string.
172
173 function _GetRGBColorString()
174 {
175 return 'rgb(' + colors_.red + ',' + colors_.green + ',' + colors_.blue + ')';
176 }
177
178 // ###################################################################
179 // Returns an individual color component's color string.
180
181 function _GetComponentColorString(color)
182 {
183 if (color == 'red') {
184 return 'rgb(' + colors_.red + ',0,0)';
185 } else if (color == 'green') {
186 return 'rgb(0,' + colors_.green + ',0)';
187 } else if (color == 'blue') {
188 return 'rgb(0,0,' + colors_.blue + ')';
189 }
190 alert('Invalid color ' + color);
191 }
192
193 // ###################################################################
194 // watches the hex field for updates
195 function hexwatcher()
196 {
197 field = document.getElementById("hexinput");
198
199 // sanitize the hex
200 var newval = field.value.replace(/[^0-9a-f]*/gi, "");
201
202 // get the length
203 var length = newval.length;
204
205 // make sure we're always 6
206 if (length > 6)
207 {
208 newval = newval.substr(0, 6);
209 }
210 else if (length == 3)
211 {
212 newval = newval.substr(0, 1) + newval.substr(0, 1) + newval.substr(1, 1) + newval.substr(1, 1) + newval.substr(2, 1) + newval.substr(2, 1);
213 }
214 else if (length < 6)
215 {
216 for (var i = length; i <= 6; i++)
217 {
218 newval = "" + newval + "0";
219 }
220 }
221
222 // update the field
223 field.value = newval;
224
225 // update fields[]
226 colors_.hex = newval;
227
228 // set RGB
229 update_rgb();
230
231 // redraw the swatch
232 Draw();
233 }
234
235 // ###################################################################
236 // update the hex value
237 function update_hex()
238 {
239 var hexstr = dec2hex(colors_.red) + dec2hex(colors_.green) + dec2hex(colors_.blue);
240 colors_.hex = hexstr;
241 document.getElementById("hexinput").value = hexstr;
242 }
243
244 // ###################################################################
245 // update the RGB values
246 function update_rgb()
247 {
248 // regex match the bits
249 var bits = colors_.hex.match(/(..)(..)(..)/);
250
251 colors_.red = hex2dec(bits[1]);
252 colors_.green = hex2dec(bits[2]);
253 colors_.blue = hex2dec(bits[3]);
254
255 // construct the hex values
256 document.getElementById("redinput").value = colors_.red;
257 document.getElementById("greeninput").value = colors_.green;
258 document.getElementById("blueinput").value = colors_.blue;
259 }
260
261 // ###################################################################
262 // convert a decimal to a hexidecimal
263 function dec2hex(dec)
264 {
265 var hexstr = "0123456789ABCDEF";
266 var low = dec % 16;
267 var high = (dec - low) / 16;
268 hex = "" + hexstr.charAt(high) + hexstr.charAt(low);
269
270 return hex.toString();
271 }
272
273 // ###################################################################
274 // converts a hexidecimal to a decimal
275 function hex2dec(hex)
276 {
277 return parseInt(hex, 16);
278 }
279
280 // ###################################################################
281 // ###################################################################
282 // ###################################################################
283
284 // flip data
285
286 function show_back()
287 {
288 backShowing_ = true;
289
290 var front = document.getElementById("front");
291 var back = document.getElementById("back");
292
293 if (window.widget)
294 {
295 widget.prepareForTransition("ToBack");
296 }
297
298 front.style.display = "none";
299 back.style.display = "block";
300
301 if (window.widget)
302 {
303 setTimeout("widget.performTransition();", 0);
304 }
305
306 document.getElementById("fliprollie").style.display = "none";
307
308 Draw();
309 }
310
311 function hide_back()
312 {
313 backShowing_ = false;
314
315 var front = document.getElementById("front");
316 var back = document.getElementById("back");
317
318 if (window.widget)
319 {
320 widget.prepareForTransition("ToFront");
321 }
322
323 back.style.display = "none";
324 front.style.display = "block";
325
326 if (window.widget)
327 {
328 setTimeout("widget.performTransition();", 0);
329 }
330
331 Draw();
332 }
333
334 var flipShown = false;
335
336 var animation = {
337 duration : 0,
338 starttime : 0,
339 to : 1.0,
340 now : 0.0,
341 from : 0.0,
342 firstElement : null,
343 timer : null
344 };
345
346 function mousemove(event)
347 {
348 if (backShowing_)
349 return;
350
351 if (!flipShown)
352 {
353 if (animation.timer != null)
354 {
355 clearInterval(animation.timer);
356 animation.timer = null;
357 }
358
359 var starttime = (new Date).getTime() - 13;
360
361 animation.duration = 500;
362 animation.starttime = starttime;
363 animation.firstElement = document.getElementById("flip");
364 animation.timer = setInterval("animate();", 13);
365 animation.from = animation.now;
366 animation.to = 1.0;
367 animate();
368 flipShown = true;
369 }
370 }
371
372 function mouseexit(event)
373 {
374 if (backShowing_)
375 return;
376
377 if (flipShown)
378 {
379 // fade in the flip widget
380 if (animation.timer != null)
381 {
382 clearInterval (animation.timer);
383 animation.timer = null;
384 }
385
386 var starttime = (new Date).getTime() - 13;
387
388 animation.duration = 500;
389 animation.starttime = starttime;
390 animation.firstElement = document.getElementById("flip");
391 animation.timer = setInterval("animate();", 13);
392 animation.from = animation.now;
393 animation.to = 0.0;
394 animate();
395 flipShown = false;
396 }
397 }
398
399
400 function animate()
401 {
402 var T;
403 var ease;
404 var time = (new Date).getTime();
405
406 T = limit_3(time - animation.starttime, 0, animation.duration);
407
408 if (T >= animation.duration)
409 {
410 clearInterval(animation.timer);
411 animation.timer = null;
412 animation.now = animation.to;
413 }
414 else
415 {
416 ease = 0.5 - (0.5 * Math.cos(Math.PI * T / animation.duration));
417 animation.now = compute_next_float(animation.from, animation.to, ease);
418 }
419
420 animation.firstElement.style.opacity = animation.now;
421 }
422
423 function limit_3 (a, b, c)
424 {
425 return a < b ? b : (a > c ? c : a);
426 }
427
428 function compute_next_float(from, to, ease)
429 {
430 return from + (to - from) * ease;
431 }
432
433 function enterflip(event)
434 {
435 document.getElementById("fliprollie").style.display = "block";
436 }
437
438 function exitflip(event)
439 {
440 document.getElementById("fliprollie").style.display = "none";
441 }