1 // A few configuration settings
2 var CROSSHAIRS_LOCATION = 'static/fusion/raptor/images/crosshairs.png';
3 var HUE_SLIDER_LOCATION = 'static/fusion/raptor/images/h.png';
4 var HUE_SLIDER_ARROWS_LOCATION = 'static/fusion/raptor/images/position.png';
5 var SAT_VAL_SQUARE_LOCATION = 'static/fusion/raptor/images/sv.png';
7 // Here are some boring utility functions. The real code comes later.
9 function hexToRgb(hex_string, default_)
11 if (default_ == undefined)
16 if (hex_string.substr(0, 1) == '#')
18 hex_string = hex_string.substr(1);
24 if (hex_string.length == 3)
26 r = hex_string.substr(0, 1);
28 g = hex_string.substr(1, 1);
30 b = hex_string.substr(2, 1);
33 else if (hex_string.length == 6)
35 r = hex_string.substr(0, 2);
36 g = hex_string.substr(2, 2);
37 b = hex_string.substr(4, 2);
47 if (isNaN(r) || isNaN(g) || isNaN(b))
53 return {r: r / 255, g: g / 255, b: b / 255};
57 function rgbToHex(r, g, b, includeHash)
59 r = Math.round(r * 255);
60 g = Math.round(g * 255);
61 b = Math.round(b * 255);
62 if (includeHash == undefined)
82 return ((includeHash ? '#' : '') + r + g + b).toUpperCase();
85 var arVersion = navigator.appVersion.split("MSIE");
86 var version = parseFloat(arVersion[1]);
88 function fixPNG(myImage)
90 if ((version >= 5.5) && (version < 7) && (document.body.filters))
92 var node = document.createElement('span');
94 node.className = myImage.className;
95 node.title = myImage.title;
96 node.style.cssText = myImage.style.cssText;
97 node.style.setAttribute('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader"
98 + "(src=\'" + myImage.src + "\', sizingMethod='scale')");
99 node.style.fontSize = '0';
100 node.style.width = myImage.width.toString() + 'px';
101 node.style.height = myImage.height.toString() + 'px';
102 node.style.display = 'inline-block';
107 return myImage.cloneNode(false);
111 function trackDrag(node, handler)
113 function fixCoords(x, y)
115 var nodePageCoords = pageCoords(node);
116 x = (x - nodePageCoords.x) + document.documentElement.scrollLeft;
117 y = (y - nodePageCoords.y) + document.documentElement.scrollTop;
120 if (x > node.offsetWidth - 1) x = node.offsetWidth - 1;
121 if (y > node.offsetHeight - 1) y = node.offsetHeight - 1;
124 function mouseDown(ev)
126 var coords = fixCoords(ev.clientX, ev.clientY);
127 var lastX = coords.x;
128 var lastY = coords.y;
129 handler(coords.x, coords.y);
131 function moveHandler(ev)
133 var coords = fixCoords(ev.clientX, ev.clientY);
134 if (coords.x != lastX || coords.y != lastY)
138 handler(coords.x, coords.y);
141 function upHandler(ev)
143 myRemoveEventListener(document, 'mouseup', upHandler);
144 myRemoveEventListener(document, 'mousemove', moveHandler);
145 myAddEventListener(node, 'mousedown', mouseDown);
147 myAddEventListener(document, 'mouseup', upHandler);
148 myAddEventListener(document, 'mousemove', moveHandler);
149 myRemoveEventListener(node, 'mousedown', mouseDown);
150 if (ev.preventDefault) ev.preventDefault();
152 myAddEventListener(node, 'mousedown', mouseDown);
153 node.onmousedown = function(e) { return false; };
154 node.onselectstart = function(e) { return false; };
155 node.ondragstart = function(e) { return false; };
158 var eventListeners = [];
160 function findEventListener(node, event, handler)
163 for (i in eventListeners)
165 if (eventListeners[i].node == node && eventListeners[i].event == event
166 && eventListeners[i].handler == handler)
173 function myAddEventListener(node, event, handler)
175 if (findEventListener(node, event, handler) != null)
180 if (!node.addEventListener)
182 node.attachEvent('on' + event, handler);
186 node.addEventListener(event, handler, false);
189 eventListeners.push({node: node, event: event, handler: handler});
192 function removeEventListenerIndex(index)
194 var eventListener = eventListeners[index];
195 delete eventListeners[index];
197 if (!eventListener.node.removeEventListener)
199 eventListener.node.detachEvent('on' + eventListener.event,
200 eventListener.handler);
204 eventListener.node.removeEventListener(eventListener.event,
205 eventListener.handler, false);
209 function myRemoveEventListener(node, event, handler)
211 removeEventListenerIndex(findEventListener(node, event, handler));
214 function cleanupEventListeners()
217 for (i = eventListeners.length; i > 0; i--)
219 if (eventListeners[i] != undefined)
221 removeEventListenerIndex(i);
225 myAddEventListener(window, 'unload', cleanupEventListeners);
227 // This copyright statement applies to the following two functions,
228 // which are taken from MochiKit.
230 // Copyright 2005 Bob Ippolito <bob@redivi.com>
232 // Permission is hereby granted, free of charge, to any person obtaining
233 // a copy of this software and associated documentation files (the
234 // "Software"), to deal in the Software without restriction, including
235 // without limitation the rights to use, copy, modify, merge, publish,
236 // distribute, sublicense, and/or sell copies of the Software, and to
237 // permit persons to whom the Software is furnished to do so, subject
238 // to the following conditions:
240 // The above copyright notice and this permission notice shall be
241 // included in all copies or substantial portions of the Software.
243 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
244 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
245 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
246 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
247 // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
248 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
249 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
251 function hsvToRgb(hue, saturation, value)
264 var i = Math.floor(hue * 6);
265 var f = (hue * 6) - i;
266 var p = value * (1 - saturation);
267 var q = value * (1 - (saturation * f));
268 var t = value * (1 - (saturation * (1 - f)));
271 case 1: red = q; green = value; blue = p; break;
272 case 2: red = p; green = value; blue = t; break;
273 case 3: red = p; green = q; blue = value; break;
274 case 4: red = t; green = p; blue = value; break;
275 case 5: red = value; green = p; blue = q; break;
276 case 6: // fall through
277 case 0: red = value; green = t; blue = p; break;
280 return {r: red, g: green, b: blue};
283 function rgbToHsv(red, green, blue)
285 var max = Math.max(Math.max(red, green), blue);
286 var min = Math.min(Math.min(red, green), blue);
297 var delta = (max - min);
298 saturation = delta / max;
301 hue = (green - blue) / delta;
303 else if (green == max)
305 hue = 2 + ((blue - red) / delta);
309 hue = 4 + ((red - green) / delta);
328 function pageCoords(node)
330 var x = node.offsetLeft;
331 var y = node.offsetTop;
332 var parent = node.offsetParent;
333 while (parent != null)
335 x += parent.offsetLeft;
336 y += parent.offsetTop;
337 parent = parent.offsetParent;
342 // The real code begins here.
343 var huePositionImg = document.createElement('img');
344 huePositionImg.galleryImg = false;
345 huePositionImg.width = 35;
346 huePositionImg.height = 11;
347 huePositionImg.src = HUE_SLIDER_ARROWS_LOCATION;
348 huePositionImg.style.position = 'absolute';
350 var hueSelectorImg = document.createElement('img');
351 hueSelectorImg.galleryImg = false;
352 hueSelectorImg.width = 35;
353 hueSelectorImg.height = 200;
354 hueSelectorImg.src = HUE_SLIDER_LOCATION;
355 hueSelectorImg.style.display = 'block';
357 var satValImg = document.createElement('img');
358 satValImg.galleryImg = false;
359 satValImg.width = 200;
360 satValImg.height = 200;
361 satValImg.src = SAT_VAL_SQUARE_LOCATION;
362 satValImg.style.display = 'block';
364 var crossHairsImg = document.createElement('img');
365 crossHairsImg.galleryImg = false;
366 crossHairsImg.width = 21;
367 crossHairsImg.height = 21;
368 crossHairsImg.src = CROSSHAIRS_LOCATION;
369 crossHairsImg.style.position = 'absolute';
371 function makeColorSelector(inputBox)
375 function colorChanged()
377 var hex = rgbToHex(rgb.r, rgb.g, rgb.b);
378 var hueRgb = hsvToRgb(hsv.h, 1, 1);
379 var hueHex = rgbToHex(hueRgb.r, hueRgb.g, hueRgb.b);
380 previewDiv.style.background = hex;
381 inputBox.value = hex;
382 satValDiv.style.background = hueHex;
383 crossHairs.style.left = ((hsv.v*199)-10).toString() + 'px';
384 crossHairs.style.top = (((1-hsv.s)*199)-10).toString() + 'px';
385 huePos.style.top = ((hsv.h*199)-5).toString() + 'px';
387 function rgbChanged()
389 hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
392 function hsvChanged()
394 rgb = hsvToRgb(hsv.h, hsv.s, hsv.v);
398 var colorSelectorDiv = document.createElement('div');
399 colorSelectorDiv.style.padding = '15px';
400 colorSelectorDiv.style.position = 'relative';
401 colorSelectorDiv.style.height = '275px';
402 colorSelectorDiv.style.width = '250px';
404 var satValDiv = document.createElement('div');
405 satValDiv.style.position = 'relative';
406 satValDiv.style.width = '200px';
407 satValDiv.style.height = '200px';
408 var newSatValImg = fixPNG(satValImg);
409 satValDiv.appendChild(newSatValImg);
410 var crossHairs = crossHairsImg.cloneNode(false);
411 satValDiv.appendChild(crossHairs);
412 function satValDragged(x, y)
418 trackDrag(satValDiv, satValDragged)
419 colorSelectorDiv.appendChild(satValDiv);
421 var hueDiv = document.createElement('div');
422 hueDiv.style.position = 'absolute';
423 hueDiv.style.left = '230px';
424 hueDiv.style.top = '15px';
425 hueDiv.style.width = '35px';
426 hueDiv.style.height = '200px';
427 var huePos = fixPNG(huePositionImg);
428 hueDiv.appendChild(hueSelectorImg.cloneNode(false));
429 hueDiv.appendChild(huePos);
430 function hueDragged(x, y)
435 trackDrag(hueDiv, hueDragged);
436 colorSelectorDiv.appendChild(hueDiv);
438 var previewDiv = document.createElement('div');
439 previewDiv.style.height = '50px'
440 previewDiv.style.width = '50px';
441 previewDiv.style.position = 'absolute';
442 previewDiv.style.top = '225px';
443 previewDiv.style.left = '15px';
444 previewDiv.style.border = '1px solid black';
445 colorSelectorDiv.appendChild(previewDiv);
447 function inputBoxChanged()
449 rgb = hexToRgb(inputBox.value, {r: 0, g: 0, b: 0});
452 myAddEventListener(inputBox, 'change', inputBoxChanged);
454 inputBox.style.position = 'absolute';
455 inputBox.style.right = '15px';
456 inputBox.style.top = (225 + (25 - (inputBox.offsetHeight/2))).toString() + 'px';
457 colorSelectorDiv.appendChild(inputBox);
461 return colorSelectorDiv;
464 function makeColorSelectors(ev)
466 var inputNodes = document.getElementsByTagName('input');
468 for (i = 0; i < inputNodes.length; i++)
470 var node = inputNodes[i];
471 if (node.className != 'color')
475 var parent = node.parentNode;
476 var prevNode = node.previousSibling;
477 var selector = makeColorSelector(node);
478 parent.insertBefore(selector, (prevNode ? prevNode.nextSibling : null));
482 myAddEventListener(window, 'load', makeColorSelectors);