function Editor(obj, i) { var x = ($(obj).offset().left * 2 + $(obj).width()) / 2; var y = ($(obj).offset().top * 2 + $(obj).height()) / 2; $("#graph_editor").css({ "left": x, "top": y }); $("#graph_editor_thickness").val(graphs[i].getThickness()); $("#graph_editor_input").val(graphs[i].getDisplayFunction()); $("#graph_editor_wrapper").show(); editing = true; this.colorPicker = new ColorPicker(this); this.colorPicker.hex = graphs[i].getColor(); this.colorPicker.updateFromHEX(null, true); this.editDone = function(){ var newFunc = $("#graph_editor_input").val(); graphs[i].setDisplayFunction(newFunc); graphs[i].setColor(this.colorPicker.getColor()); graphs[i].setThickness(parseInt($("#graph_editor_thickness").val())); $("#function_input").val(graphs[i].getFullDescription()); $("#visible_" + i).css({ "background-color": graphs[i].getColor(), "border-color": graphs[i].getColor() }); $("#graph_editor_wrapper").hide(); editing = false; updateAll(); } } function ColorPicker(editor) { this.movingObject = ""; this.updateFromHSV = function(){ this.h = 1 - $("#hue_picker").position().top / $("#hue").height(); this.s = ($("#sb_picker").position().left + 8) / $("#saturation").width(); this.v = 1 - ($("#sb_picker").position().top + 8) / $("#value").height(); this.r = HSVtoRGB(this.h, this.s, this.v).r; this.g = HSVtoRGB(this.h, this.s, this.v).g; this.b = HSVtoRGB(this.h, this.s, this.v).b; this.hex = RGBtoHEX(this.r, this.g, this.b); this.updateInterface(); } this.updateFromRGB = function(){ this.r = $($(".color_picker_rgb")[0]).val(); this.g = $($(".color_picker_rgb")[1]).val(); this.b = $($(".color_picker_rgb")[2]).val(); this.h = RGBtoHSV(this.r, this.g, this.b).h; this.s = RGBtoHSV(this.r, this.g, this.b).s; this.v = RGBtoHSV(this.r, this.g, this.b).v; this.hex = RGBtoHEX(this.r, this.g, this.b); this.updateFromHEX(null, true); this.updateInterface(); } this.updateFromHEX = function(input, otf){ if (!otf){ //Not on the fly if (isValidHEX($(input).val())) this.hex = $(input).val(); else { alert("Error!"); return; } } this.r = HEXtoRGB(this.hex).r; this.g = HEXtoRGB(this.hex).g; this.b = HEXtoRGB(this.hex).b; this.h = RGBtoHSV(this.r, this.g, this.b).h; this.s = RGBtoHSV(this.r, this.g, this.b).s; this.v = RGBtoHSV(this.r, this.g, this.b).v; this.updateInterface(); } this.updateInterface = function(){ var o = Math.round((this.r * 299 + (this.g * 587) + (this.b * 114)) / 1000); //https://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx this.fontColor = (o > 125) ? "#000" : "#FFF"; $($(".color_picker_rgb")[0]).val(this.r); $($(".color_picker_rgb")[1]).val(this.g); $($(".color_picker_rgb")[2]).val(this.b); $("#color_picker_hex").val(this.hex); $("#hue_picker").css("top", (1 - this.h) * $("#hue").height()); $("#sb_picker").css({ "left": this.s * $("#saturation").width() - 8, "top": (1 - this.v) * $("#value").height() - 8 }); var sRGB = HSVtoRGB(this.h, 1, 1); var saturationBackground = "linear-gradient(to right, #FFF 0%, rgb(" + sRGB.r + "," + sRGB.g + "," + sRGB.b + ") 100%)"; $("#saturation").css("background", saturationBackground); /*$($(".color_picker_rgb")[0]).css({ "background-color": "rgb(" + this.r + ", 0, 0)" }); $($(".color_picker_rgb")[1]).css({ "background-color": "rgb(0, " + this.g + ", 0)" }); $($(".color_picker_rgb")[2]).css({ "background-color": "rgb(0, 0, " + this.b + ")" });*/ //Fancy but overloaded $("#color_picker_hex").css({ "background-color": this.hex, "color": this.fontColor }); } this.mousePressed = function(){ var x = winMouseX - $("#saturation").offset().left; var y = winMouseY - $("#value").offset().top; if (x > 0 && x < $("#saturation").width() && y > 0 && y < $("#value").height()){ this.movingObject = "sb"; } if (x > $("#saturation").width() + 6 && x < $("#saturation").width() + 6 + $("#hue").width() && y > 0 && y < $("#hue").height()){ this.movingObject = "hue"; } this.mouseDragged(); } this.mouseDragged = function(){ if (this.movingObject == "hue"){ var objH = $("#hue"); var picker = $("#hue_picker"); var h = winMouseY - objH.offset().top; if (h > 0 && h < objH.height()){ picker.css("top", h - 1); } else if (h > objH.height()){ picker.css("top", objH.height() - 1); } else if (h < 0){ picker.css("top", -1); } } if (this.movingObject == "sb"){ var objS = $("#saturation"); var objV = $("#value"); var picker = $("#sb_picker"); var s = winMouseX - objS.offset().left; var v = winMouseY - objV.offset().top; if (s > 0 && s < objS.width()){ picker.css("left", s - 8); } else if (s < 0){ picker.css("left", -8); } else if (s < objS.width()){ picker.css("left", objS.width() - 8); } if (v > 0 && v < objV.height()){ picker.css("top", v - 8); } else if (v < 0){ picker.css("top", -8); } else if (v > objV.height()){ picker.css("top", objV.height() - 8); } } this.updateFromHSV(); } this.mouseReleased = function(){ this.movingObject = ""; } this.getColor = function(){ return this.hex; } } //www.stackoverflow.com --> function RGBtoHEX(r, g, b) { var rgb = b | (g << 8) | (r << 16); return '#' + (0x1000000 + rgb).toString(16).slice(1); } function HEXtoRGB(hex) { var shorthandRegex = /^#?([a-fA-F\d])([a-fA-F\d])([a-fA-F\d])$/i; hex = hex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; }); var result = /^#?([a-fA-F\d]{2})([a-fA-F\d]{2})([a-fA-F\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } function HSVtoRGB(h, s, v) { var r, g, b, i, f, p, q, t; if (arguments.length === 1) { s = h.s, v = h.v, h = h.h; } i = Math.floor(h * 6); f = h * 6 - i; p = v * (1 - s); q = v * (1 - f * s); t = v * (1 - (1 - f) * s); switch (i % 6) { case 0: r = v, g = t, b = p; break; case 1: r = q, g = v, b = p; break; case 2: r = p, g = v, b = t; break; case 3: r = p, g = q, b = v; break; case 4: r = t, g = p, b = v; break; case 5: r = v, g = p, b = q; break; } return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) }; } function RGBtoHSV(r, g, b) { if (arguments.length === 1) { g = r.g, b = r.b, r = r.r; } var max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min, h, s = (max === 0 ? 0 : d / max), v = max / 255; switch (max) { case min: h = 0; break; case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break; case g: h = (b - r) + d * 2; h /= 6 * d; break; case b: h = (r - g) + d * 4; h /= 6 * d; break; } return { h: h, s: s, v: v }; } function isValidHEX(hex){ return /(^#[0-9A-Fa-f]{6}$)|(^#[0-9A-Fa-f]{3}$)/i.test(hex); }