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