diff --git a/editor/images/logo.svg b/editor/images/logo.svg new file mode 100644 index 00000000..038d0a93 --- /dev/null +++ b/editor/images/logo.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/editor/jgraduate/LICENSE b/editor/jgraduate/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/editor/jgraduate/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/editor/jgraduate/README b/editor/jgraduate/README new file mode 100644 index 00000000..ef3e21ff --- /dev/null +++ b/editor/jgraduate/README @@ -0,0 +1,3 @@ +jGraduate - A jQuery plugin for picking gradients + +Licensed under the Apache License 2. See LICENSE for more information. diff --git a/editor/jgraduate/css/jGraduate-0.2.0.css b/editor/jgraduate/css/jGraduate-0.2.0.css new file mode 100644 index 00000000..ffa0e9aa --- /dev/null +++ b/editor/jgraduate/css/jGraduate-0.2.0.css @@ -0,0 +1,171 @@ +/* + * jGraduate Default CSS + * + * Copyright (c) 2009 Jeff Schiller + * + * Licensed under the Apache License Version 2 + */ + +h2.jGraduate_Title { + font-family: Arial, Helvetica, Sans-Serif; + font-size: 11px !important; + font-weight: bold; + margin: -13px 0px 0px 0px; + padding: 0px; + text-align: center; +} + +.jGraduate_Picker { + font-family: Arial, Helvetica, Sans-Serif; + font-size: 12px; + border-style: solid; + border-color: lightgrey black black lightgrey; + border-width: 1px; + background-color: #EFEFEF; + position: absolute; + padding: 10px; +} + +li.jGraduate_tab_color, li.jGraduate_tab_lingrad { + background-color: #ccc; + display: inline; + border: solid 1px grey; + padding: 3px; + margin: 2px; + cursor: pointer; +} + +li.jGraduate_tab_current { + background-color: #EFEFEF; + display: inline; + padding: 3px; + margin: 2px; + border: solid 1px black; + cursor: pointer; +} + +.jGraduate_colPick { + display: none; +} + +.jGraduate_lgPick { + display: none; + border: outset 1px #666; + padding: 10px 7px 5px 5px; +} + +.jGraduate_tabs { + position: relative; + background-color: #EFEFEF; + padding: 0px; + margin: 0px; + margin-bottom: 5px; +} + +div.jGraduate_Swatch { + display: inline-block; + margin: 8px; +} +div.jGraduate_GradContainer { + border: 2px inset #EEE; + background-image: url(../images/map-opacity.png); + background-position: 0px 0px; + height: 256px; +} + +.jGraduate_AlphaArrows { + position: absolute; + margin-top: -10px; + margin-left: 250.5px; +} + +div.jGraduate_Opacity { + border: 2px inset #eee; + margin-top: 14px; + background-color: black; + background-image: url(../images/Maps.png); + background-position: 0px -2816px; + height: 20px; + cursor: ew-resize; +} + +div.jGraduate_OpacityField { + margin-top: 110px; + margin-left: -10px; +} + +div.jGraduate_Form { + display: inline-block; + vertical-align: top; + width: 140px; + margin: -3px 3px 0px 4px; +} + +div.jGraduate_StopSection { + width: 120px; + text-align: center; +} + +div.jGraduate_OkCancel { + display: inline-block; + vertical-align: top; + width: 113px; +} + +input.jGraduate_Ok, input.jGraduate_Cancel { + display: block; + width: 100px; + margin-left: -4px; + margin-right: -4px; +} +input.jGraduate_Ok { + margin: 9px -4px 5px -4px; +} + +.colorBox { + display: inline-block; + height: 16px; + width: 16px; + border: 1px solid #808080; + vertical-align: -7px; + cursor: pointer; + margin: 4px; +} + +label.jGraduate_Form_Heading { + position: relative; + top: 10px; + background-color: #EFEFEF; + padding: 2px; + font-weight: bold; + font-size: 13px; +} + +div.jGraduate_Form_Section { + border-style: solid; + border-width: 1px; + border-color: grey; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + padding: 15px 5px 5px 5px; + margin: 2px; + width: 110px; + text-align: center; +} + +div.jGraduate_LightBox { + position: fixed; + top: 0px; + left: 0px; + right: 0px; + bottom: 0px; + background-color: #000; + opacity: 0.5; + display: none; +} + +div.jGraduate_stopPicker { + position: absolute; + display: none; + background: #E8E8E8; +} \ No newline at end of file diff --git a/editor/jgraduate/css/jPicker-1.0.9.css b/editor/jgraduate/css/jPicker-1.0.9.css new file mode 100755 index 00000000..c4af17a4 --- /dev/null +++ b/editor/jgraduate/css/jPicker-1.0.9.css @@ -0,0 +1,227 @@ +.jPicker_Picker { + display: inline-block; + height: 24px; /* change this value if using a different sized color picker icon */ + position: relative; /* make this element an absolute positioning container */ + text-align: left; /* make the zero width children position to the left of container */ + width: 25px; /* change this value if using a different sized color picker icon */ +} +.jPicker_Color { + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_Icon { + background-repeat: no-repeat; + cursor: pointer; + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_Container { + display: none; + z-index: 10; /* make sure container draws above color picker icon in Firefox/Safari/Chrome/Opera/etc. - + IE calculates z-index so this won't work - we will hide all color picker icons placed after the selected one in code when shown in IE */ +} +.jPicker_table { + background-color: #efefef; + border: 1px outset #666; + font-family: Arial, Helvetica, Sans-Serif; + font-size: 12px; + height: 330px; + margin: 0px; + padding: 5px; + width: 550px; +} +.jPicker_table td { + margin: 0px; + padding: 0px; + vertical-align: top; +} +.jPicker_MoveBar { + background-color: #dddddd; + border: 1px outset #aaa; + cursor: move; + height: 12px; +} +.jPicker_Title { + font-size: 11px !important; + font-weight: bold; + margin: -2px 0px 0px 0px; + padding: 0px; + text-align: center; + width: 100%; +} +.jPicker_ColorMap { + border: 2px inset #eee; + cursor: crosshair; + height: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ + margin: 0px 5px 0px 5px; + overflow: hidden; /* hide the overdraw of the Color Map icon when at edge of viewing box */ + padding: 0px; + position: relative; /* make this element an absolute positioning container */ + width: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ +} +div[class="jPicker_ColorMap"] { + height: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ + width: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ +} +.jPicker_ColorMap_l1, .jPicker_ColorMap_l2, .jPicker_ColorMap_l3, .jPicker_ColorBar_l1, .jPicker_ColorBar_l2, .jPicker_ColorBar_l3, .jPicker_ColorBar_l4, .jPicker_ColorBar_l5, .jPicker_AlphaBar_l1, .jPicker_AlphaBar_l2 { + background-repeat: no-repeat; + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_ColorMap_l1 { + background-color: #000000; + background-image: none; +} +.jPicker_ColorMap_l2 { + background-color: transparent; +} +.jPicker_ColorMap_l3 { + background-repeat: repeat; +} +.jPicker_ColorMap_Arrow { + display: block; + position: absolute; +} +.jPicker_ColorBar { + border: 2px inset #eee; + cursor: n-resize; + height: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ + margin: 12px 10px 0px 5px; + padding: 0px; + position: relative; + width: 24px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 20px later */ +} +div[class="jPicker_ColorBar"] { + height: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ + width: 20px; /* correct to 20px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ +} +.jPicker_ColorBar_l1, .jPicker_ColorBar_l2, .jPicker_ColorBar_l3 { + background-color: transparent; + background-image: none; + background-repeat: repeat-x; +} +.jPicker_ColorBar_l4 { + background-color: transparent; + background-repeat: repeat-x; +} +.jPicker_ColorBar_l5 { + background-color: transparent; + background-repeat: repeat; +} +.jPicker_ColorBar_Arrow { + display: block; + left: -10px; /* (arrow width / 2) - (element width / 2) - position arrows' center in elements' center */ + position: absolute; +} +.jPicker_AlphaBar { + border: 2px inset #eee; + cursor: e-resize; + display: none; + height: 24px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 20px later */ + margin: 10px 5px 4px 5px; + padding: 0px; + position: relative; + width: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ +} +div[class="jPicker_AlphaBar"] { + height: 20px; /* correct to 20px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ + width: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ +} +.jPicker_AlphaBar_Arrow { + display: block; + top: -10px; /* (arrow height / 2) - (element height / 2) - position arrows' center in elements' center */ + position: absolute; +} +.jPicker_EnableAlpha { + text-align: left; +} +.jPicker_Preview { + font-size: x-small; + text-align: center; +} +.jPicker_Preview div { + border: 2px inset #eee; + height: 62px; + margin: 0px auto; + padding: 0px; + width: 62px; +} +.jPicker_Preview div span { + border: 1px solid #000; + display: block; + height: 30px; + margin: 0px auto; + padding: 0px; + width: 60px; +} +.jPicker_Preview div span.jPicker_Active { + border-bottom-width: 0px; +} +.jPicker_Preview div span.jPicker_Current { + border-top-width: 0px; + cursor: pointer; +} +.jPicker_OkCancel { + text-align: center; + width: 120px; +} +.jPicker_OkCancel input { + width: 100px; +} +.jPicker_OkCancel input.jPicker_Ok { + margin: 12px 0px 5px 0px; +} +.jPicker_Spacer { + height: 10px; +} +.jPicker_HueText, .jPicker_SaturationText, .jPicker_BrightnessText, .jPicker_RedText, .jPicker_GreenText, .jPicker_BlueText, .jPicker_AlphaText { + background-color: #fff; + border: 1px inset #aaa; + margin: 0px 0px 0px 5px; + width: 30px; +} +.jPicker_EnterHex { + text-align: right; +} +.jPicker_HexText { + background-color: #fff; + border: 1px inset #aaa; + margin: 0px 19px 0px 5px; + width: 50px; +} +td.jPicker_OpacityCol { + padding-top: 12px; + text-indent: -8px; +} +td.jPicker_OpacityCol * { + display: none; +} +td.jPicker_HexCol { + text-align: left; +} +.jPicker_Grid { + text-align: center; +} +.jPicker_QuickColor { + border: 1px inset #aaa; + cursor: pointer; + display: block; + float: left; + height: 12px; + line-height: 12px; + margin: 2px 3px 1px 3px; + padding: 0px; + width: 12px; +} \ No newline at end of file diff --git a/editor/jgraduate/images/Bars.png b/editor/jgraduate/images/Bars.png new file mode 100644 index 00000000..4c1608e3 Binary files /dev/null and b/editor/jgraduate/images/Bars.png differ diff --git a/editor/jgraduate/images/Maps.png b/editor/jgraduate/images/Maps.png new file mode 100644 index 00000000..498cf3be Binary files /dev/null and b/editor/jgraduate/images/Maps.png differ diff --git a/editor/jgraduate/images/bar-opacity.png b/editor/jgraduate/images/bar-opacity.png new file mode 100644 index 00000000..e42ad081 Binary files /dev/null and b/editor/jgraduate/images/bar-opacity.png differ diff --git a/editor/jgraduate/images/map-opacity.png b/editor/jgraduate/images/map-opacity.png new file mode 100644 index 00000000..6756cee6 Binary files /dev/null and b/editor/jgraduate/images/map-opacity.png differ diff --git a/editor/jgraduate/images/mappoint.gif b/editor/jgraduate/images/mappoint.gif new file mode 100644 index 00000000..f5f85574 Binary files /dev/null and b/editor/jgraduate/images/mappoint.gif differ diff --git a/editor/jgraduate/images/picker.gif b/editor/jgraduate/images/picker.gif new file mode 100644 index 00000000..374d8910 Binary files /dev/null and b/editor/jgraduate/images/picker.gif differ diff --git a/editor/jgraduate/images/preview-opacity.png b/editor/jgraduate/images/preview-opacity.png new file mode 100644 index 00000000..0dd9a2f8 Binary files /dev/null and b/editor/jgraduate/images/preview-opacity.png differ diff --git a/editor/jgraduate/images/rangearrows.gif b/editor/jgraduate/images/rangearrows.gif new file mode 100644 index 00000000..218872cc Binary files /dev/null and b/editor/jgraduate/images/rangearrows.gif differ diff --git a/editor/jgraduate/images/rangearrows2.gif b/editor/jgraduate/images/rangearrows2.gif new file mode 100644 index 00000000..fdeb54a1 Binary files /dev/null and b/editor/jgraduate/images/rangearrows2.gif differ diff --git a/editor/jgraduate/jpicker-1.0.9.min.js b/editor/jgraduate/jpicker-1.0.9.min.js new file mode 100755 index 00000000..2627c1d1 --- /dev/null +++ b/editor/jgraduate/jpicker-1.0.9.min.js @@ -0,0 +1 @@ +(function(e,a){var d=function(n,k){var p=this,o=e("img",n),l=function(q){h(q);e(document).bind("mousemove",m).bind("mouseup",j);q.stopPropagation();q.preventDefault();return false;},m=function(q){h(q);q.stopPropagation();q.preventDefault();return false;},j=function(q){e(document).unbind("mouseup",j).unbind("mousemove",m);q.stopPropagation();q.preventDefault();return false;},h=function(u){var w=n.offset(),q=u.pageX-w.left-parseInt(n.css("border-left-width")),z=u.pageY-w.top-parseInt(n.css("border-top-width")),t=n.w,r=n.h,v,s;if(q<0){q=0;}else{if(q>t){q=t;}}if(z<0){z=0;}else{if(z>r){z=r;}}v=Math.floor(q/t*p.mxX);s=Math.floor(z/r*p.mxY);p.x=v;p.y=s;if(p.mxX==p.mnX){q=0;}if(p.mxY==p.mnY){z=0;}p.setArrowPosition(q,z);e.isFunction(p.valuesChanged)&&p.valuesChanged(p);};e.extend(true,p,{settings:k,x:0,y:0,mnX:0,mxX:0,mnY:100,mxY:100,valuesChanged:e.isFunction(arguments[2])&&arguments[2]||null,setPositioningVariables:function(r){var q=p.settings.map;n.w=q&&q.width||n.width();n.h=q&&q.height||n.height();p.MinX=0;p.MinY=0;p.MaxX=n.w;p.MaxY=n.h;},setArrowPositionFromValues:function(t){p.setPositioningVariables();var w=0,v=0,u=p.mnX,r=p.mxX,s=p.mnY,q=p.mxY,A=p.x,z=p.y;if(u!=r){if(A==u){w=0;}else{if(A==r){w=n.w;}else{if(u<1){r+=Math.abs(u)+1;}if(A<1){A+=1;}w=A/r*n.w;if(parseInt(w)==(r-1)){w=r;}else{w=parseInt(w);}if(u<1){w-=Math.abs(u)-1;}}}}if(s!=q){if(z==s){v=0;}else{if(z==q){v=n.h;}else{if(s<1){q+=Math.abs(s)+1;}if(z<1){z+=1;}v=z/q*n.h;if(parseInt(v)==(q-1)){v=q;}else{v=parseInt(v);}if(s<1){v-=Math.abs(s)-1;}}}}p.setArrowPosition(w,v);},setArrowPosition:function(q,v){var u=n.w,s=n.h,t=o.w,r=o.h;if(q<0){q=0;}else{if(q>u){q=u;}}if(v<0){v=0;}else{if(v>s){v=s;}}if(t>u){q=(u>>1)-(t>>1);}else{q-=t>>1;}if(r>s){v=(s>>1)-(r>>1);}else{v-=r>>1;}o.css({left:q+"px",top:v+"px"});},destroy:function(){e(document).unbind("mouseup",j).unbind("mousemove",m);n.unbind("mousedown",l);n=null;o=null;p.valuesChanged=null;}});o.src=p.settings.arrow&&p.settings.arrow.image;o.w=p.settings.arrow&&p.settings.arrow.width||o.width();o.h=p.settings.arrow&&p.settings.arrow.height||o.height();p.setPositioningVariables();n.bind("mousedown",l);p.setArrowPositionFromValues();e.isFunction(p.valuesChanged)&&p.valuesChanged(p);},b=function(n){var m=this,y=function(A){if(A.target.value==""){return;}t(A);m.setValuesFromHsv();e.isFunction(m.valuesChanged)&&m.valuesChanged(m);},s=function(A){if(A.target.value==""){return;}q(A);m.setValuesFromRgb();e.isFunction(m.valuesChanged)&&m.valuesChanged(m);},r=function(A){if(A.target.value==""){return;}l(A);w.a=A.target.value;e.isFunction(m.valuesChanged)&&m.valuesChanged(m);},v=function(A){if(A.target.value==""){m.setValuesFromRgb();}},k=function(A){if(A.target.value==""){m.setValuesFromHsv();}},o=function(A){if(A.target.value==""){u.alpha.val(100);}},z=function(A){if(A.target.value==""){return;}x(A);m.setValuesFromHex();e.isFunction(m.valuesChanged)&&m.valuesChanged(m);},j=function(A){if(A.target.value==""){m.setValuesFromHsv();}},q=function(A){if(!p(A)){return A;}u.red.val(h(u.red.val(),0,255));u.green.val(h(u.green.val(),0,255));u.blue.val(h(u.blue.val(),0,255));},l=function(A){if(!p(A)){return A;}u.alpha.val(h(u.alpha.val(),0,100));},t=function(A){if(!p(A)){return A;}u.hue.val(h(u.hue.val(),0,360));u.saturation.val(h(u.saturation.val(),0,100));u.value.val(h(u.value.val(),0,100));},x=function(A){if(!p(A)){return A;}u.hex.val(u.hex.val().replace(/[^a-fA-F0-9]/g,"0").toLowerCase().substring(0,6));},p=function(A){switch(A.keyCode){case 9:case 16:case 29:case 37:case 38:case 40:return false;case"c".charCodeAt():case"v".charCodeAt():if(A.ctrlKey){return false;}}return true;},h=function(C,B,A){if(C==""||isNaN(C)){return B;}C=parseInt(C);if(C>A){return A;}if(C4){k=l.substring(4,l.length);l=l.substring(0,4);}if(l.length>2){j=l.substring(2,l.length);l=l.substring(0,2);}if(l.length>0){h=l.substring(0,l.length);}}return{r:this.hexToInt(k),g:this.hexToInt(j),b:this.hexToInt(h)};},validateHex:function(h){h=h.toLowerCase().replace(/[^a-f0-9]/g,"0");if(h.length>6){h=h.substring(0,6);}return h;},rgbToHex:function(h){return this.intToHex(h.r)+this.intToHex(h.g)+this.intToHex(h.b);},intToHex:function(j){var h=parseInt(j).toString(16);if(h.length==1){h=("0"+h);}return h.toLowerCase();},hexToInt:function(h){return parseInt(h,16);},rgbToHsv:function(l){var o=l.r/255,n=l.g/255,j=l.b/255,k={h:0,s:0,v:0},m=0,h=0,p;if(o>=n&&o>=j){h=o;m=n>j?j:n;}else{if(n>=j&&n>=o){h=n;m=o>j?j:o;}else{h=j;m=n>o?o:n;}}k.v=h;k.s=h?(h-m)/h:0;if(!k.s){k.h=0;}else{p=h-m;if(o==h){k.h=(n-j)/p;}else{if(n==h){k.h=2+(j-o)/p;}else{k.h=4+(o-n)/p;}}k.h=parseInt(k.h*60);if(k.h<0){k.h+=360;}}k.s=parseInt(k.s*100);k.v=parseInt(k.v*100);return k;},hsvToRgb:function(n){var r={r:0,g:0,b:0},m=n.h,x=n.s,u=n.v;if(x==0){if(u==0){r.r=r.g=r.b=0;}else{r.r=r.g=r.b=parseInt(u*255/100);}}else{if(m==360){m=0;}m/=60;x=x/100;u=u/100;var l=parseInt(m),o=m-l,k=u*(1-x),j=u*(1-(x*o)),w=u*(1-(x*(1-o)));switch(l){case 0:r.r=u;r.g=w;r.b=k;break;case 1:r.r=j;r.g=u;r.b=k;break;case 2:r.r=k;r.g=u;r.b=w;break;case 3:r.r=k;r.g=j;r.b=u;break;case 4:r.r=w;r.g=k;r.b=u;break;case 5:r.r=u;r.g=k;r.b=j;break;}r.r=parseInt(r.r*255);r.g=parseInt(r.g*255);r.b=parseInt(r.b*255);}return r;}}};var f=e.jPicker.Color,c=e.jPicker.List,g=e.jPicker.ColorMethods;e.fn.jPicker=function(j){var h=arguments;return this.each(function(){var w=e(this),y=e.extend(true,{},e.fn.jPicker.defaults,j);if(w.get(0).nodeName.toLowerCase()=="input"){e.extend(true,y,{window:{bindToInput:true,expandable:true,input:w}});if(g.validateHex(w.val())){y.color.active=new f({hex:w.val(),a:y.color.active.a});y.color.current=new f({hex:w.val(),a:y.color.active.a});}}if(y.window.expandable){w.after('   ');}else{y.window.liveUpdate=false;}var W=parseFloat(navigator.appVersion.split("MSIE")[1])<7&&document.body.filters,ax=null,aw=null,av=null,U=null,T=null,S=null,R=null,Q=null,aC=null,V=null,au=null,J=null,I=null,X=null,ac=null,az=null,ak=null,am=null,ao=null,K=null,G=null,aa=null,L=null,ay=null,P=null,O=null,at=null,aq=null,A=null,l=null,M=null,ap=null,ad=null,ai=null,n=null,C=null,u=null,an=function(aE){N.active=ay.color;var aF=N.active,aG=p.clientPath,aD=function(aH){ae(aH,100);aH.css({backgroundColor:"",backgroundPosition:"0px 0px",filter:""});};aD(ax);aD(aw);aD(U);aD(T);aD(S);aD(R);ac.add(az).add(ak).add(am).add(ao).add(K).removeAttr("checked");switch(aE){case"h":ac.attr("checked",true);ax.css({backgroundColor:"#"+aF.hex});aw.css({backgroundColor:"transparent"});x(aw,-256);ae(aw,100);x(R,-256);G.mxX=100;G.mxY=100;aa.mxY=360;break;case"s":az.attr("checked",true);x(ax,-512);x(aw,-768);ae(aw,0);z(S,aF.hex);x(R,-512);G.mxX=360;G.mxY=100;aa.mxY=100;break;case"v":ak.attr("checked",true);z(ax,"000");x(aw,-1024);S.css({backgroundColor:"#"+aF.hex});x(R,-768);G.mxX=360;G.mxY=100;aa.mxY=100;break;case"r":am.attr("checked",true);x(aw,-1536);x(ax,-1280);x(R,-1024);x(S,-1280);x(T,-1536);x(U,-1792);break;case"g":ao.attr("checked",true);x(aw,-2048);x(ax,-1792);x(R,-2048);x(S,-2304);x(T,-2560);x(U,-2816);break;case"b":K.attr("checked",true);x(aw,-2560);x(ax,-2304);x(R,-3072);x(S,-3328);x(T,-3584);x(U,-3840);break;default:throw ("Invalid Mode");break;}switch(aE){case"h":case"s":case"v":G.mnX=1;G.mnY=1;aa.mnY=1;break;case"r":case"g":case"b":G.mnX=0;G.mnY=0;aa.mnY=0;G.mxX=255;G.mxY=255;aa.mxY=255;break;}N.mode=aE;v();ar();ab();if(aj.expandable&&aj.liveUpdate){n.css({backgroundColor:"#"+aF.hex});if(aj.bindToInput){aj.input.val(aF.hex).css({backgroundColor:"#"+aF.hex,color:aF.v>75?"#000000":"#ffffff"});}}e.isFunction(w.liveCallback)&&w.liveCallback(aF);},m=function(){v();ah();N.active=ay.color;var aD=N.active;if(aj.expandable&&aj.liveUpdate){n.css({backgroundColor:"#"+aD.hex});if(aj.bindToInput){aj.input.val(ay.fields.hex.val()).css({backgroundColor:"#"+aD.hex,color:aD.v>75?"#000000":"#ffffff"});}}e.isFunction(w.liveCallback)&&w.liveCallback(aD);},B=function(){if(!ay||!G||!aa||!L){return;}N.active=ay.color;var aD=ay.fields,aE=N.active;switch(N.mode){case"h":aD.saturation.val(G.x);aD.value.val(100-G.y);break;case"s":aD.hue.val(G.x);aD.value.val(100-G.y);break;case"v":aD.hue.val(G.x);aD.saturation.val(100-G.y);break;case"r":aD.blue.val(G.x);aD.green.val(255-G.y);break;case"g":aD.blue.val(G.x);aD.red.val(255-G.y);break;case"b":aD.red.val(G.x);aD.green.val(255-G.y);break;}switch(N.mode){case"h":case"s":case"v":ay.setValuesFromHsv();break;case"r":case"g":case"b":ay.setValuesFromRgb();break;}ah();if(aj.expandable&&aj.liveUpdate){n.css({backgroundColor:"#"+aE.hex});if(aj.bindToInput){aj.input.val(aE.hex).css({backgroundColor:"#"+aE.hex,color:aE.v>75?"#000000":"#ffffff"});}}e.isFunction(w.liveCallback)&&w.liveCallback(aE);},al=function(){if(!ay||!G||!aa||!L){return;}N.active=ay.color;var aD=ay.fields,aE=N.active;switch(N.mode){case"h":aD.hue.val(360-aa.y);break;case"s":aD.saturation.val(100-aa.y);break;case"v":aD.value.val(100-aa.y);break;case"r":aD.red.val(255-aa.y);break;case"g":aD.green.val(255-aa.y);break;case"b":aD.blue.val(255-aa.y);break;}switch(N.mode){case"h":case"s":case"v":ay.setValuesFromHsv();break;case"r":case"g":case"b":ay.setValuesFromRgb();break;}ah();if(aj.expandable&&aj.liveUpdate){n.css({backgroundColor:"#"+aE.hex});if(aj.bindToInput){aj.input.val(aE.hex).css({backgroundColor:"#"+aE.hex,color:aE.v>75?"#000000":"#ffffff"});}}e.isFunction(w.liveCallback)&&w.liveCallback(aE);},s=function(){if(!ay||!G||!aa||!L){return;}N.active=ay.color;var aD=ay.fields,aE=N.active;aD.alpha.val(L.x);ay.setAlphaFromValue();ah();e.isFunction(w.liveCallback)&&w.liveCallback(N.active);},v=function(){N.active=ay.color;var aG=0,aF=N.active;switch(w.settings.color.mode){case"h":aG=360-aF.h;break;case"s":aG=100-aF.s;break;case"v":aG=100-aF.v;break;case"r":aG=255-aF.r;break;case"g":aG=255-aF.g;break;case"b":aG=255-aF.b;break;}aa.y=aG;L.x=aF.a;aa.setArrowPositionFromValues();L.setArrowPositionFromValues();var aE=0,aD=0;switch(w.settings.color.mode){case"h":aE=aF.s;aD=100-aF.v;break;case"s":aE=aF.h;aD=100-aF.v;break;case"v":aE=aF.h;aD=100-aF.s;break;case"r":aE=aF.b;aD=256-aF.g;break;case"g":aE=aF.b;aD=256-aF.r;break;case"b":aE=aF.r;aD=256-aF.g;break;}G.x=aE;G.y=aD;G.setArrowPositionFromValues();},ah=function(){aB();ar();ab();aA();},aB=function(){try{A.css({backgroundColor:"#"+ay.color.hex});ae(A,ay.color.a);}catch(aD){}},ar=function(){if(!N||!ay){return;}N.active=ay.color;var aD=N.active;switch(N.mode){case"h":z(ax,new f({h:aD.h,s:100,v:100}).hex);break;case"s":ae(aw,100-aD.s);break;case"v":ae(aw,aD.v);break;case"r":ae(aw,aD.r/256*100);break;case"g":ae(aw,aD.g/256*100);break;case"b":ae(aw,aD.b/256*100);break;}ae(av,100-aD.a);},ab=function(){if(!N||!ay){return;}N.active=ay.color;var aH=N.active,aK=N.mode,aM=ay.fields;switch(aK){case"h":break;case"s":var aI=new f({h:aH.h,s:100,v:aH.v});z(S,aI.hex);break;case"v":var aL=new f({h:aH.h,s:aH.s,v:100});z(S,aL.hex);break;case"r":case"g":case"b":var aJ=0,aN=0;if(aK=="r"){aJ=aM.blue.val();aN=aM.green.val();}else{if(aK=="g"){aJ=aM.blue.val();aN=aM.red.val();}else{if(aK=="b"){aJ=aM.red.val();aN=aM.green.val();}}}var aD=aJ/256*100,aG=aN/256*100,aF=(256-aJ)/256*100,aE=(256-aN)/256*100;ae(R,aG>aF?aF:aG);ae(S,aG>aD?aD:aG);ae(T,aE>aD?aD:aE);ae(U,aE>aF?aF:aE);break;}ae(Q,100-aH.a);},aA=function(){z(J,ay.color.hex);},z=function(aD,aF){try{aD.css({backgroundColor:"#"+aF});}catch(aE){}},t=function(aD,aE){if(aE.indexOf("png")&&this.isLessThanIE7){aD.attr("pngSrc",aE);aD.css({backgroundImage:"none",filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+aE+"')"});}else{aD.css({backgroundImage:"url("+aE+")"});}},x=function(aD,aE){aD.css({backgroundPosition:"0px "+aE+"px"});},ae=function(aE,aD){if(aD<100){if(this.isLessThanIE7){var aF=aE.attr("pngSrc");if(aF!=null&&aF.indexOf("map-hue")==-1){aE.css({filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+aF+"') progid:DXImageTransform.Microsoft.Alpha(opacity="+aD+")"});}}else{aE.css({opacity:aD/100});}}else{if(aD==100){if(this.isLessThanIE7){var aF=aE.attr("pngSrc");if(aF!=null&&aF.indexOf("map-hue")==-1){aE.css({filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+aF+"')"});}}else{aE.css({opacity:""});}}}},E=function(){ay.fields.hex.val(N.current.hex);ay.fields.alpha.val(N.current.a);ay.setValuesFromHex();ay.setAlphaFromValue();e.isFunction(ay.valuesChanged)&&ay.valuesChanged(ay);},D=function(aD){an(aD.target.value);},af=function(){E();},r=function(){E();aj.expandable&&w.hide();e.isFunction(w.cancelCallback)&&w.cancelCallback();},Z=function(){var aD=N.active;N.current=new f({hex:aD.hex});N.current.a=aD.a;l.css({backgroundColor:"#"+aD.hex});ae(l,ay.color.a);if(aj.expandable){n.css({backgroundColor:"#"+aD.hex});if(aj.bindToInput){aj.input.val(aD.hex).css({backgroundColor:"#"+aD.hex,color:aD.v>75?"#000000":"#ffffff"});}}e.isFunction(w.commitCallback)&&w.commitCallback(aD);},o=function(){Z();aj.expandable&&w.hide();},ag=function(){w.show();},Y=function(aF){var aD=aj.element,aE=aj.page;P=parseInt(X.css("left"));O=parseInt(X.css("top"));at=aF.pageX;aq=aF.pageY;e(document).bind("mousemove",k).bind("mouseup",q);aF.stopPropagation();aF.preventDefault();return false;},k=function(aD){X.css({left:P-(at-aD.pageX)+"px",top:O-(aq-aD.pageY)+"px"});aD.stopPropagation();aD.preventDefault();return false;},q=function(aD){e(document).unbind("mousemove",k).unbind("mouseup",q);aD.stopPropagation();aD.preventDefault();return false;},F=function(aD){ay.fields.hex.val(w.settings.window.input.val());ay.bindedHexKeyUp(aD);},H=function(aD){ay.fields.hex.val(N.quickList[aD.data.i].hex);ay.fields.alpha.val(N.quickList[aD.data.i].a);ay.setValuesFromHex();ay.setAlphaFromValue();e.isFunction(ay.valuesChanged)&&ay.valuesChanged(ay);};e.extend(true,w,{id:w.attr("id"),settings:y,color:null,icon:null,commitCallback:e.isFunction(h[1])&&h[1]||null,liveCallback:e.isFunction(h[2])&&h[2]||null,cancelCallback:e.isFunction(h[3])&&h[3]||null,show:function(){if(document.all){var aD=false;for(i=0;i>1)-259)-w.next().offset().left+"px":aj.position.x,position:"absolute",top:aj.position.y=="top"?"-340px":aj.position.y=="center"?"-153px":aj.position.y=="bottom"?"25px":aj.position.y});}if((typeof(N.active)).toString().toLowerCase()=="string"){N.active=new f({hex:N.active.substring(1)});}if(!N.alphaSupport){N.active.a=100;}X.html(''+(aj.expandable?'':"")+'
 

'+(aj.title||"Drag Markers To Pick A Color")+'

   
     
new
  
current

 
°
%
%
 
  
% 
');ac=e(".jPicker_HueRadio",X);az=e(".jPicker_SaturationRadio",X);ak=e(".jPicker_BrightnessRadio",X);am=e(".jPicker_RedRadio",X);ao=e(".jPicker_GreenRadio",X);K=e(".jPicker_BlueRadio",X);ax=e(".jPicker_ColorMap_l1",X);aw=e(".jPicker_ColorMap_l2",X);av=e(".jPicker_ColorMap_l3",X);U=e(".jPicker_ColorBar_l1",X);T=e(".jPicker_ColorBar_l2",X);S=e(".jPicker_ColorBar_l3",X);R=e(".jPicker_ColorBar_l4",X);Q=e(".jPicker_ColorBar_l5",X);J=e(".jPicker_AlphaBar_l1",X);I=e(".jPicker_AlphaBar_l2",X);aC=e(".jPicker_EnableAlpha",X);V=e(".jPicker_AlphaCheckbox",X);au=e(".jPicker_AlphaBar",X);M=e(".jPicker_NewCurrent",X);A=e(".jPicker_Active",X).css({backgroundColor:"#"+N.active.hex});l=e(".jPicker_Current",X).css({backgroundColor:"#"+N.active.hex});ap=e(".jPicker_Ok",X);ad=e(".jPicker_Cancel",X);ai=e(".jPicker_Grid",X);w.color=e(".Picker_Color");w.icon=e(".jPicker_Icon");ay=new b(X,m);G=new d(e(".jPicker_ColorMap",X),{map:{width:p.colorMap.width,height:p.colorMap.height},arrow:{image:p.clientPath+p.colorMap.arrow.file,width:p.colorMap.arrow.width,height:p.colorMap.arrow.height}},B);aa=new d(e(".jPicker_ColorBar",X),{map:{width:p.colorBar.width,height:p.colorBar.height},arrow:{image:p.clientPath+p.colorBar.arrow.file,width:p.colorBar.arrow.width,height:p.colorBar.arrow.height}},al);L=new d(e(".jPicker_AlphaBar",X),{map:{width:p.alphaBar.width,height:p.alphaBar.height},arrow:{image:p.clientPath+p.alphaBar.arrow.file,width:p.alphaBar.arrow.width,height:p.alphaBar.arrow.height}},s);L.mnX=0;L.mxX=100;t(ax,p.clientPath+"Maps.png");t(aw,p.clientPath+"Maps.png");t(av,p.clientPath+"map-opacity.png");t(U,p.clientPath+"Bars.png");t(T,p.clientPath+"Bars.png");t(S,p.clientPath+"Bars.png");t(R,p.clientPath+"Bars.png");t(Q,p.clientPath+"bar-opacity.png");t(I,p.clientPath+"Maps.png");x(I,-2816);t(M,p.clientPath+"preview-opacity.png");M.css({backgroundPosition:"1px 1px"});if(N.alphaSupport){aC.hide();au.show();e("td.jPicker_OpacityCol *",X).show();}else{V.bind("click",function(){aC.hide();au.show();e("td.jPicker_OpacityCol *",X).show();});}if(aj.expandable){n=e(".jPicker_Color",w.next()).css({backgroundColor:"#"+N.active.hex});C=e(".jPicker_Icon",w.next()).css({backgroundImage:"url("+p.clientPath+p.picker.file+")"}).bind("click",ag);if(aj.bindToInput){aj.input.bind("keyup",F).bind("change",F);}}ac.add(az).add(ak).add(am).add(ao).add(K).bind("click",D);l.bind("click",af);ad.bind("click",r);ap.bind("click",o);if(aj.expandable){u=e(".jPicker_MoveBar",X).bind("mousedown",Y);}if(N.quickList&&N.quickList.length>0){ai.html("");for(i=0;i ');e(".jPicker_QuickColor",X).eq(i).css({backgroundColor:"#"+N.quickList[i].hex}).bind("click",{i:i},H);}}an(N.mode);ay.fields.hex.val(aa.hex);ay.setValuesFromHex();ay.setAlphaFromValue();v();ah();if(!aj.expandable){w.show();}c.push(w);});};e.fn.jPicker.defaults={window:{title:null,position:{x:"screenCenter",y:"top"},expandable:false,liveUpdate:true},color:{mode:"h",active:new f({hex:"ffc000"}),alphaSupport:false,quickList:[new f({h:360,s:33,v:100}),new f({h:360,s:66,v:100}),new f({h:360,s:100,v:100}),new f({h:360,s:100,v:75}),new f({h:360,s:100,v:50}),new f({h:180,s:0,v:100}),new f({h:30,s:33,v:100}),new f({h:30,s:66,v:100}),new f({h:30,s:100,v:100}),new f({h:30,s:100,v:75}),new f({h:30,s:100,v:50}),new f({h:180,s:0,v:90}),new f({h:60,s:33,v:100}),new f({h:60,s:66,v:100}),new f({h:60,s:100,v:100}),new f({h:60,s:100,v:75}),new f({h:60,s:100,v:50}),new f({h:180,s:0,v:80}),new f({h:90,s:33,v:100}),new f({h:90,s:66,v:100}),new f({h:90,s:100,v:100}),new f({h:90,s:100,v:75}),new f({h:90,s:100,v:50}),new f({h:180,s:0,v:70}),new f({h:120,s:33,v:100}),new f({h:120,s:66,v:100}),new f({h:120,s:100,v:100}),new f({h:120,s:100,v:75}),new f({h:120,s:100,v:50}),new f({h:180,s:0,v:60}),new f({h:150,s:33,v:100}),new f({h:150,s:66,v:100}),new f({h:150,s:100,v:100}),new f({h:150,s:100,v:75}),new f({h:150,s:100,v:50}),new f({h:180,s:0,v:50}),new f({h:180,s:33,v:100}),new f({h:180,s:66,v:100}),new f({h:180,s:100,v:100}),new f({h:180,s:100,v:75}),new f({h:180,s:100,v:50}),new f({h:180,s:0,v:40}),new f({h:210,s:33,v:100}),new f({h:210,s:66,v:100}),new f({h:210,s:100,v:100}),new f({h:210,s:100,v:75}),new f({h:210,s:100,v:50}),new f({h:180,s:0,v:30}),new f({h:240,s:33,v:100}),new f({h:240,s:66,v:100}),new f({h:240,s:100,v:100}),new f({h:240,s:100,v:75}),new f({h:240,s:100,v:50}),new f({h:180,s:0,v:20}),new f({h:270,s:33,v:100}),new f({h:270,s:66,v:100}),new f({h:270,s:100,v:100}),new f({h:270,s:100,v:75}),new f({h:270,s:100,v:50}),new f({h:180,s:0,v:10}),new f({h:300,s:33,v:100}),new f({h:300,s:66,v:100}),new f({h:300,s:100,v:100}),new f({h:300,s:100,v:75}),new f({h:300,s:100,v:50}),new f({h:180,s:0,v:0}),new f({h:330,s:33,v:100}),new f({h:330,s:66,v:100}),new f({h:330,s:100,v:100}),new f({h:330,s:100,v:75}),new f({h:330,s:100,v:50})]},images:{clientPath:"/jPicker/images/",colorMap:{width:256,height:256,arrow:{file:"mappoint.gif",width:15,height:15}},colorBar:{width:20,height:256,arrow:{file:"rangearrows.gif",width:40,height:9}},alphaBar:{width:256,height:20,arrow:{file:"rangearrows2.gif",width:9,height:40}},picker:{file:"picker.gif",width:25,height:24}}};})(jQuery,"1.0.9"); \ No newline at end of file diff --git a/editor/jgraduate/jquery.jgraduate.js b/editor/jgraduate/jquery.jgraduate.js new file mode 100644 index 00000000..4fe55203 --- /dev/null +++ b/editor/jgraduate/jquery.jgraduate.js @@ -0,0 +1,529 @@ +/* + * jGraduate 0.2.x + * + * jQuery Plugin for a gradient picker + * + * Copyright (c) 2009 Jeff Schiller + * http://blog.codedread.com/ + * + * Apache 2 License + +jGraduate( options, okCallback, cancelCallback ) + +where options is an object literal: + { + window: { title: "Pick the start color and opacity for the gradient" }, + images: { clientPath: "images/" }, + paint: a Paint object + } + +- the Paint object is: + { + // object describing the color picked used by jPicker + solidColor: { hex, }, + // DOM node for the linear gradient + linearGradient: { grad, a, + } +- only one of solidColor and linearGradient must be non-null + +- picker accepts the following object as input: + { + okCallback: function to call when Ok is pressed + cancelCallback: function to call when Cancel is pressed + paint: object describing the paint to display initially, if not set, then default to opaque white + } + +- okCallback receives a Paint object + + * + */ +var ns = { svg: 'http://www.w3.org/2000/svg', xlink: 'http://www.w3.org/1999/xlink' }; +if(!window.console) { + window.console = new function() { + this.log = function(str) {}; + this.dir = function(str) {}; + }; +} +$.jGraduate = { + Paint: + function(copy) { + if (copy) { + if (copy.solidColor) + this.solidColor = new $.jPicker.Color({ hex: copy.solidColor.hex, + a: copy.solidColor.a }); + + // FIXME: linearGradient can be an object, but .grad can still be null + if (copy.linearGradient) + // Opera throws NOT_SUPPORTED_ERROR if the cloneNode(null), the other browsers do not + this.linearGradient = { grad: copy.linearGradient.grad ? document.cloneNode(copy.linearGradient.grad, true) : null, + a: copy.linearGradient.a }; + } + else { + this.solidColor = new $.jPicker.Color({ hex: '000000', a: 100 }); + this.linearGradient = { grad: null, a: 100 }; + } + } +}; + +jQuery.fn.jGraduateDefaults = { + paint: new $.jGraduate.Paint(), + window: { + pickerTitle: "Drag markers to pick a paint", + }, + images: { + clientPath: "images/", + }, +}; + +jQuery.fn.jGraduate = + function(options) { + var $arguments = arguments; + return this.each( function() { + var $this = $(this), $settings = $.extend(true, {}, jQuery.fn.jGraduateDefaults, options), + id = $this.attr('id'), + idref = '#'+$this.attr('id')+' '; + + if (!idref) + { + alert('Container element must have an id attribute to maintain unique id strings for sub-elements.'); + return; + } + + var okClicked = function() { + $.isFunction($this.okCallback) && $this.okCallback($this.paint); + $this.hide(); + }, + cancelClicked = function() { + $.isFunction($this.cancelCallback) && $this.cancelCallback(); + $this.hide(); + }; + + $.extend(true, $this, // public properties, methods, and callbacks + { + paint: $settings.paint, + okCallback: $.isFunction($arguments[1]) && $arguments[1] || null, + cancelCallback: $.isFunction($arguments[2]) && $arguments[2] || null, + }); + + var mode = "solidColor", + pos = $this.position(), + color = null; + + if ($this.paint == null) { + $this.paint = { solidColor: new $.jPicker.Color({ hex: 'ffffff', a: 100 }), + linearGradient: { grad: null, a: 100 } }; + } + + if ($this.paint.linearGradient.grad != null) { + mode = "linearGradient"; + $this.paint.solidColor = new $.jPicker.Color({ hex: 'ffffff', a: 100 }); + } + else if ($this.paint.solidColor != null) { + $this.paint.linearGradient = { grad: null, a: 100 }; + } + else { + return null; + } + + $this.addClass('jGraduate_Picker'); + $this.html('
    ' + + '
  • Solid Color
  • ' + + '
  • Linear Gradient
  • ' + + '
' + + '
' + + '
'); + var colPicker = $(idref + '> .jGraduate_colPick'); + var lgPicker = $(idref + '> .jGraduate_lgPick'); + + lgPicker.html( + '
' + + '

' + $settings.window.pickerTitle + '

' + + '
' + + '
' + + '' + + '
' + + '
' + + '
' + + '
' + + '' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '' + + '
' + + '
' + + '
' + + '' + + '
' + + '' + + '' + + '' + + '' + + '
' + + '' + + '
' + + '
' + + '
' + + '' + + '%' + + '
' + + '
' + + '
' + + '' + + '' + + '
' + + '
' + + '
'); + + // -------------- + // Set up all the SVG elements (the gradient, stops and rectangle) + var MAX = 256, MARGINX = 0, MARGINY = 0, STOP_RADIUS = 15/2, + SIZEX = MAX - 2*MARGINX, SIZEY = MAX - 2*MARGINY; +// var container = document.getElementById(id+'_jGraduate_Swatch'); + var container = document.getElementById(id+'_jGraduate_GradContainer'); + var svg = container.appendChild(document.createElementNS(ns.svg, 'svg')); + svg.id = id+'_jgraduate_svg'; + svg.setAttribute('width', MAX); + svg.setAttribute('height', MAX); + svg.setAttribute("xmlns", ns.svg); + + if ($this.paint.linearGradient.grad) { + $this.paint.linearGradient.grad = svg.appendChild( document.importNode($this.paint.linearGradient.grad, true) ); + $this.paint.linearGradient.grad.id = id+'_jgraduate_grad'; + } + else { + var grad = svg.appendChild(document.createElementNS(ns.svg, 'linearGradient')); + grad.id = id+'_jgraduate_grad'; + grad.setAttribute('x1','0.0'); + grad.setAttribute('y1','0.0'); + grad.setAttribute('x2','1.0'); + grad.setAttribute('y2','1.0'); + + var begin = grad.appendChild(document.createElementNS(ns.svg, 'stop')); + begin.setAttribute('offset', '0.0'); + begin.setAttribute('stop-color', '#ff0000'); + + var end = grad.appendChild(document.createElementNS(ns.svg, 'stop')); + end.setAttribute('offset', '1.0'); + end.setAttribute('stop-color', '#ff0'); + + $this.paint.linearGradient.grad = grad; + } + + var gradalpha = $this.paint.linearGradient.a; + $('#' + id + '_jGraduate_OpacityInput').val(gradalpha); + var posx = parseInt(255*(gradalpha/100)) - 4.5; + $('#' + id + '_jGraduate_AlphaArrows').css({'margin-left':posx}); + $('#' + id + '_jgraduate_rect').attr('fill-opacity', gradalpha/100); + + var x1 = parseFloat($this.paint.linearGradient.grad.getAttribute('x1')||0.0); + var y1 = parseFloat($this.paint.linearGradient.grad.getAttribute('y1')||0.0); + var x2 = parseFloat($this.paint.linearGradient.grad.getAttribute('x2')||1.0); + var y2 = parseFloat($this.paint.linearGradient.grad.getAttribute('y2')||0.0); + + var rect = document.createElementNS(ns.svg, 'rect'); + rect.id = id + '_jgraduate_rect'; + rect.setAttribute('x', MARGINX); + rect.setAttribute('y', MARGINY); + rect.setAttribute('width', SIZEY); + rect.setAttribute('height', SIZEY); + rect.setAttribute('fill', 'url(#'+id+'_jgraduate_grad)'); + rect.setAttribute('fill-opacity', '1.0'); + rect = svg.appendChild(rect); + + // stop visuals created here + var beginStop = document.createElementNS(ns.svg, 'image'); + beginStop.id = id + "_stop1"; + beginStop.setAttribute('class', 'stop'); + beginStop.setAttributeNS(ns.xlink, 'href', $settings.images.clientPath + 'mappoint.gif'); + beginStop.setAttributeNS(ns.xlink, "title", "Begin Stop"); + beginStop.appendChild(document.createElementNS(ns.svg, 'title')).appendChild( + document.createTextNode("Begin Stop")); + beginStop.setAttribute('width', 18); + beginStop.setAttribute('height', 18); + beginStop.setAttribute('x', MARGINX + SIZEX*x1 - STOP_RADIUS); + beginStop.setAttribute('y', MARGINY + SIZEY*y1 - STOP_RADIUS); + beginStop.setAttribute('cursor', 'move'); + // must append only after setting all attributes due to Webkit Bug 27952 + // https://bugs.webkit.org/show_bug.cgi?id=27592 + beginStop = svg.appendChild(beginStop); + + var endStop = document.createElementNS(ns.svg, 'image'); + endStop.id = id + "_stop2"; + endStop.setAttribute('class', 'stop'); + endStop.setAttributeNS(ns.xlink, 'href', $settings.images.clientPath + 'mappoint.gif'); + endStop.setAttributeNS(ns.xlink, "title", "End Stop"); + endStop.appendChild(document.createElementNS(ns.svg, 'title')).appendChild( + document.createTextNode("End Stop")); + endStop.setAttribute('width', 18); + endStop.setAttribute('height', 18); + endStop.setAttribute('x', MARGINX + SIZEX*x2 - STOP_RADIUS); + endStop.setAttribute('y', MARGINY + SIZEY*y2 - STOP_RADIUS); + endStop.setAttribute('cursor', 'move'); + endStop = svg.appendChild(endStop); + + // bind GUI elements + $('#'+id+'_jGraduate_Ok').bind('click', function() { + $this.paint.solidColor = null; + okClicked(); + }); + $('#'+id+'_jGraduate_Cancel').bind('click', function(paint) { + cancelClicked(); + }); + + var x1 = $this.paint.linearGradient.grad.getAttribute('x1'); + if(!x1) x1 = "0.0"; + x1Input = $('#'+id+'_jGraduate_x1'); + x1Input.val(x1); + x1Input.change( function() { + if (isNaN(parseFloat(this.value)) || this.value < 0.0 || this.value > 1.0) { + this.value = 0.0; + } + $this.paint.linearGradient.grad.setAttribute('x1', this.value); + beginStop.setAttribute('x', MARGINX + SIZEX*this.value - STOP_RADIUS); + }); + + var y1 = $this.paint.linearGradient.grad.getAttribute('y1'); + if(!y1) y1 = "0.0"; + y1Input = $('#'+id+'_jGraduate_y1'); + y1Input.val(y1); + y1Input.change( function() { + if (isNaN(parseFloat(this.value)) || this.value < 0.0 || this.value > 1.0) { + this.value = 0.0; + } + $this.paint.linearGradient.grad.setAttribute('y1', this.value); + beginStop.setAttribute('y', MARGINY + SIZEY*this.value - STOP_RADIUS); + }); + + var x2 = $this.paint.linearGradient.grad.getAttribute('x2'); + if(!x2) x2 = "1.0"; + x2Input = $('#'+id+'_jGraduate_x2'); + x2Input.val(x2); + x2Input.change( function() { + if (isNaN(parseFloat(this.value)) || this.value < 0.0 || this.value > 1.0) { + this.value = 1.0; + } + $this.paint.linearGradient.grad.setAttribute('x2', this.value); + endStop.setAttribute('x', MARGINX + SIZEX*this.value - STOP_RADIUS); + }); + + var y2 = $this.paint.linearGradient.grad.getAttribute('y2'); + if(!y2) y2 = "0.0"; + y2Input = $('#'+id+'_jGraduate_y2'); + y2Input.val(y2); + y2Input.change( function() { + if (isNaN(parseFloat(this.value)) || this.value < 0.0 || this.value > 1.0) { + this.value = 0.0; + } + $this.paint.linearGradient.grad.setAttribute('y2', this.value); + endStop.setAttribute('y', MARGINY + SIZEY*this.value - STOP_RADIUS); + }); + + var stops = $this.paint.linearGradient.grad.getElementsByTagNameNS(ns.svg, 'stop'); + var numstops = stops.length; + // if there are not at least two stops, then + if (numstops < 2) { + while (numstops < 2) { + $this.paint.linearGradient.grad.appendChild( document.createElementNS(ns.svg, 'stop') ); + ++numstops; + } + stops = $this.paint.linearGradient.grad.getElementsByTagNameNS(ns.svg, 'stop'); + } + + var setOpacitySlider = function(e, div) { + var offset = div.offset(); + var x = (e.pageX - offset.left - parseInt(div.css('border-left-width'))); + if (x > 255) x = 255; + if (x < 0) x = 0; + var posx = x - 4.5; + x /= 255; + $('#' + id + '_jGraduate_AlphaArrows').css({'margin-left':posx}); + $('#' + id + '_jgraduate_rect').attr('fill-opacity', x); + x = parseInt(x*100); + $('#' + id + '_jGraduate_OpacityInput').val(x); + $this.paint.linearGradient.a = x; + }; + + // handle dragging on the opacity slider + var bSlidingOpacity = false; + $('.jGraduate_Opacity').mousedown(function(evt) { + setOpacitySlider(evt, $(this)); + bSlidingOpacity = true; + evt.preventDefault(); + }); + $('.jGraduate_Opacity').mousemove(function(evt) { + if (bSlidingOpacity) { + setOpacitySlider(evt, $(this)); + evt.preventDefault(); + } + }); + $('.jGraduate_Opacity').mouseup(function(evt) { + setOpacitySlider(evt, $(this)); + bSlidingOpacity = false; + evt.preventDefault(); + }); + + // handle dragging the stop around the swatch + var draggingStop = null; + var startx = -1, starty = -1; + // for whatever reason, Opera does not allow $('image.stop') here + $('.stop').mousedown(function(evt) { + draggingStop = this; + startx = evt.clientX; + starty = evt.clientY; + evt.preventDefault(); + }); + $('#'+id+'_jgraduate_svg').mousemove(function(evt) { + if (null != draggingStop) { + var dx = evt.clientX - startx; + var dy = evt.clientY - starty; + startx += dx; + starty += dy; + var x = parseFloat(draggingStop.getAttribute('x')) + dx; + var y = parseFloat(draggingStop.getAttribute('y')) + dy; + + // clamp stop to the swatch + if (x < MARGINX - STOP_RADIUS) x = MARGINX - STOP_RADIUS; + if (y < MARGINY - STOP_RADIUS) y = MARGINY - STOP_RADIUS; + if (x > MARGINX + SIZEX - STOP_RADIUS) x = MARGINX + SIZEX - STOP_RADIUS; + if (y > MARGINY + SIZEY - STOP_RADIUS) y = MARGINY + SIZEY - STOP_RADIUS; + + draggingStop.setAttribute('x', x); + draggingStop.setAttribute('y', y); + + // calculate stop offset + var fracx = (x - MARGINX + STOP_RADIUS)/SIZEX; + var fracy = (y - MARGINY + STOP_RADIUS)/SIZEY; + + if (draggingStop.id == (id+'_stop1')) { + x1Input.val(fracx); + y1Input.val(fracy); + $this.paint.linearGradient.grad.setAttribute('x1', fracx); + $this.paint.linearGradient.grad.setAttribute('y1', fracy); + } + else { + x2Input.val(fracx); + y2Input.val(fracy); + $this.paint.linearGradient.grad.setAttribute('x2', fracx); + $this.paint.linearGradient.grad.setAttribute('y2', fracy); + } + + evt.preventDefault(); + } + }); + $('#'+id+'_jgraduate_svg').mouseup(function(evt) { + draggingStop = null; + }); + + var beginColor = stops[0].getAttribute('stop-color'); + if(!beginColor) beginColor = '#000'; + beginColorBox = $('#'+id+'_jGraduate_colorBoxBegin'); + beginColorBox.css({'background-color':beginColor}); + + var beginOpacity = stops[0].getAttribute('stop-opacity'); + if(!beginOpacity) beginOpacity = '1.0'; + $('#'+id+'jGraduate_beginOpacity').html( (beginOpacity*100)+'%' ); + + var endColor = stops[stops.length-1].getAttribute('stop-color'); + if(!endColor) endColor = '#000'; + endColorBox = $('#'+id+'_jGraduate_colorBoxEnd'); + endColorBox.css({'background-color':endColor}); + + var endOpacity = stops[stops.length-1].getAttribute('stop-opacity'); + if(!endOpacity) endOpacity = '1.0'; + $('#'+id+'jGraduate_endOpacity').html( (endOpacity*100)+'%' ); + + $('#'+id+'_jGraduate_colorBoxBegin').click(function() { + $('div.jGraduate_LightBox').show(); + var colorbox = $(this); + color = new $.jPicker.Color({ hex: beginColor.substr(1), a:(parseFloat(beginOpacity)*100) }); + $('#'+id+'_jGraduate_stopPicker').css({'left': 100, 'bottom': 15}).jPicker({ + window: { title: "Pick the start color and opacity for the gradient" }, + images: { clientPath: $settings.images.clientPath }, + color: { active: color, alphaSupport: true } + }, function(color){ + beginColor = '#' + this.settings.color.active.hex; + beginOpacity = this.settings.color.active.a/100; + colorbox.css('background', beginColor); + $('#'+id+'_jGraduate_beginOpacity').html(parseInt(beginOpacity*100)+'%'); + stops[0].setAttribute('stop-color', beginColor); + stops[0].setAttribute('stop-opacity', beginOpacity); + $('div.jGraduate_LightBox').hide(); + $('#'+id+'_jGraduate_stopPicker').hide(); + }, null, function() { + $('div.jGraduate_LightBox').hide(); + $('#'+id+'_jGraduate_stopPicker').hide(); + }); + }); + $('#'+id+'_jGraduate_colorBoxEnd').click(function() { + $('div.jGraduate_LightBox').show(); + var colorbox = $(this); + color = new $.jPicker.Color({ hex: endColor.substr(1), a:(parseFloat(endOpacity)*100) }); + $('#'+id+'_jGraduate_stopPicker').css({'left': 100, 'top': 15}).jPicker({ + window: { title: "Pick the end color and opacity for the gradient" }, + images: { clientPath: $settings.images.clientPath }, + color: { active: color, alphaSupport: true } + }, function(color){ + endColor = '#' + this.settings.color.active.hex; + endOpacity = this.settings.color.active.a/100; + colorbox.css('background', endColor); + $('#'+id+'_jGraduate_endOpacity').html(parseInt(endOpacity*100)+'%'); + stops[1].setAttribute('stop-color', endColor); + stops[1].setAttribute('stop-opacity', endOpacity); + $('div.jGraduate_LightBox').hide(); + $('#'+id+'_jGraduate_stopPicker').hide(); + }, null, function() { + $('div.jGraduate_LightBox').hide(); + $('#'+id+'_jGraduate_stopPicker').hide(); + }); + }); + + // -------------- + + colPicker.jPicker( + { + window: { title: $settings.window.pickerTitle }, + images: { clientPath: $settings.images.clientPath }, + color: { active: $this.paint.solidColor, alphaSupport: true } + }, + function(color) { + $this.paint.solidColor = color; + $this.paint.linearGradient.grad = null; + okClicked(); + }, + null, + function(){ cancelClicked(); } + ); + + $(idref + ' .jGraduate_tab_color').click( function(){ + $(idref + ' .jGraduate_tab_lingrad').removeClass('jGraduate_tab_current'); + $(idref + ' .jGraduate_tab_color').addClass('jGraduate_tab_current'); + lgPicker.hide(); + colPicker.show(); + }); + $(idref + ' .jGraduate_tab_lingrad').click( function(){ + $(idref + ' .jGraduate_tab_color').removeClass('jGraduate_tab_current'); + $(idref + ' .jGraduate_tab_lingrad').addClass('jGraduate_tab_current'); + colPicker.hide(); + lgPicker.show(); + }); + + if (mode == "linearGradient") { + lgPicker.show(); + colPicker.hide(); + $(idref + ' .jGraduate_tab_color').removeClass('jGraduate_tab_current'); + $(idref + ' .jGraduate_tab_lingrad').addClass('jGraduate_tab_current'); + } + else { + colPicker.show(); + lgPicker.hide(); + $(idref + ' .jGraduate_tab_color').addClass('jGraduate_tab_current'); + $(idref + ' .jGraduate_tab_lingrad').removeClass('jGraduate_tab_current'); + } + + $this.show(); + }); + }; diff --git a/editor/svg-editor.css b/editor/svg-editor.css index ca8401ff..db98fb1d 100644 --- a/editor/svg-editor.css +++ b/editor/svg-editor.css @@ -49,14 +49,6 @@ body { cursor: pointer; } -#svg_editor #fill_color { - background: url('images/none.png'); -} - -#svg_editor #stroke_color { - background: #000000; -} - #svg_editor div#palette { float: left; width: 6848px; @@ -103,6 +95,7 @@ body { /* TODO: fix this */ div.color_block { + background-image: url('images/none.png'); display: inline-block; } @@ -191,10 +184,6 @@ div.color_block { padding: 2px; } -#svg_editor #paint_picker { - display: none; -} - #svg_editor #color_picker { position: absolute; display: none; diff --git a/editor/svg-editor.html b/editor/svg-editor.html index befd51d4..731b5fdd 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -2,17 +2,17 @@ - + + - - + + - @@ -207,9 +207,6 @@ -
-
-
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index f1dcffee..cf06845f 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -22,6 +22,9 @@ function svg_edit_setup() { var selectedElement = null; var multiselected = false; var editingsource = false; + + var fillPaint = new $.jGraduate.Paint(); + var strokePaint = new $.jGraduate.Paint(); // called when we've selected a different element var selectedChanged = function(window,elems) { @@ -81,21 +84,27 @@ function svg_edit_setup() { // update fill color var fillColor = selectedElement.getAttribute("fill"); + // TODO: get a Paint from this and store in fillPaint ? + // TODO: call setFillPaint() ? svgCanvas.setFillColor(fillColor); if (fillColor == "none") { - fillColor = 'url(\'images/none.png\')'; + fillColor = "none"; fillOpacity = "N/A"; } - $('#fill_color').css('background', fillColor); + // update the rect inside #fill_color + document.getElementById("gradbox_fill").parentNode.firstChild.setAttribute("fill", fillColor); // update stroke color var strokeColor = selectedElement.getAttribute("stroke"); + // TODO: get a Paint from this and store in strokePaint ? + // TODO: call setStrokePaint() ? svgCanvas.setStrokeColor(strokeColor); if (strokeColor == null || strokeColor == "" || strokeColor == "none") { - strokeColor = 'url(\'images/none.png\')'; strokeOpacity = "N/A"; + strokeColor = "none"; } - $('#stroke_color').css('background', strokeColor); + // update the rect inside #fill_color + document.getElementById("gradbox_stroke").parentNode.firstChild.setAttribute("fill", strokeColor); $('#fill_opacity').html(fillOpacity); $('#stroke_opacity').html(strokeOpacity); @@ -200,9 +209,9 @@ function svg_edit_setup() { svgCanvas.bind("selected", selectedChanged); svgCanvas.bind("changed", elementChanged); - var str = '
' + var str = '
' $.each(palette, function(i,item){ - str += '
'; + str += '
'; }); $('#palette').append(str); @@ -244,17 +253,19 @@ function svg_edit_setup() { }); $('.palette_item').click(function(evt){ + var picker = (evt.shiftKey ? "stroke" : "fill"); var id = (evt.shiftKey ? '#stroke_' : '#fill_'); - color = $(this).css('background-color'); + var color = $(this).attr('data-rgb'); + var rectbox = document.getElementById("gradbox_"+picker).parentNode.firstChild; + // Webkit-based browsers returned 'initial' here for no stroke if (color == 'transparent' || color == 'initial') { color = 'none'; - $(id + "color").css('background', 'url(\'images/none.png\')'); $(id + "opacity").html("N/A"); - } else { - $(id + "color").css('background', color); } - if (evt.shiftKey) { + rectbox.setAttribute("fill", color); + + if (evt.shiftKey) { svgCanvas.setStrokeColor(color); if (color != 'none' && $("#stroke_opacity").html() == 'N/A') { svgCanvas.setStrokeOpacity(1.0); @@ -550,18 +561,16 @@ function svg_edit_setup() { $(document).bind('keydown', {combi:'esc', disableInInput: false}, hideSourceEditor); var colorPicker = function(elem) { - var oldbg = elem.css('background'); - var color = elem.css('background-color'); - var oldopacity = "100 %"; - if (elem.attr('id') == 'stroke_color') { - oldopacity = $('#stroke_opacity').html(); - } - if (elem.attr('id') == 'fill_color') { - oldopacity = $('#fill_opacity').html(); - } + var picker = elem.attr('id') == 'stroke_color' ? 'stroke' : 'fill'; + var oldopacity = (picker == 'stroke' ? $('#stroke_opacity').html() : $('#fill_opacity').html()); + + var paint = (picker == 'stroke' ? strokePaint : fillPaint); + var title = (picker == 'stroke' ? 'Pick a Stroke Paint and Opacity' : 'Pick a Fill Paint and Opacity'); + var oldPaint = new $.jGraduate.Paint(paint); var was_none = false; - if (color == 'transparent' || color == 'initial') { - color = new $.jPicker.Color({ hex: 'ffffff', a: 100 }); + + if (paint.solidColor == null && paint.linearGradient == null) { + paint = new $.jGraduate.Paint(); was_none = true; } else { var alpha; @@ -570,53 +579,45 @@ function svg_edit_setup() { } else { alpha = oldopacity.split(' ')[0]; } - if (color.length == 7 && color[0] == '#') { // #hheexx notation - color = new $.jPicker.Color( { hex: color.substring(1,7) , a: alpha } ); - } else if (color.substring(0,4) == 'rgb(' && color[color.length-1] == ')') { // rgb(r,g,b) notation - var rgb = color.substring(4,color.length-1).split(','); - color = new $.jPicker.Color({ r: rgb[0], g: rgb[1], b: rgb[2], a: alpha }); - } else { - color = new $.jPicker.Color({ hex: 'ffffff', a: alpha }); - } } var pos = elem.position(); - var picker = elem.attr('id') == 'stroke_color' ? 'stroke' : 'fill'; - $('#color_picker').css({'left': pos.left - 140, 'bottom': 104 - pos.top}).jPicker({ - window: { title: "Choose the " + picker + " color and opacity"}, - images: { clientPath: "jpicker/images/" }, - color: { active: color, alphaSupport: true } - }, function(color){ - elem.css('background', '#' + this.settings.color.active.hex); - if (elem.attr('id') == 'stroke_color') { - svgCanvas.setStrokeColor('#' + this.settings.color.active.hex); - svgCanvas.setStrokeOpacity(this.settings.color.active.a/100); - $('#stroke_opacity').html(this.settings.color.active.a+" %"); - } else if (elem.attr('id') == 'fill_color') { - svgCanvas.setFillColor('#' + this.settings.color.active.hex); - svgCanvas.setFillOpacity(this.settings.color.active.a/100); - $('#fill_opacity').html(this.settings.color.active.a+" %"); - } - $('#color_picker').hide(); - } - , null - , function(){ - elem.css('background', oldbg); - if (elem.attr('id') == 'stroke_color') { - $('#stroke_opacity').html(oldopacity); - } else if (elem.attr('id') == 'fill_color') { - $('#fill_opacity').html(oldopacity); - } - if (was_none) { - if (elem.attr('id') == 'stroke_color') { - svgCanvas.setStrokeColor('none'); - $('#stroke_opacity').html('N/A'); - } else if (elem.attr('id') == 'fill_color') { - svgCanvas.setFillColor('none'); - $('#fill_opacity').html('N/A'); + $('#color_picker').css({'left': pos.left - 140, 'bottom': 124 - pos.top}).jGraduate( + { + paint: paint, + window: { pickerTitle: title }, + images: { clientPath: "jGraduate/images/" }, + }, + function(p) { + paint.solidColor = p.solidColor; + paint.linearGradient.grad = p.linearGradient.grad; + paint.linearGradient.a = p.linearGradient.a; + + var oldgrad = document.getElementById("gradbox_"+picker); + var svgbox = oldgrad.parentNode; + var rectbox = svgbox.firstChild; + + if (paint.linearGradient.grad) { + svgbox.removeChild(oldgrad); + var newgrad = svgbox.appendChild(document.importNode(paint.linearGradient.grad, true)); + newgrad.id = "gradbox_"+picker; + rectbox.setAttribute("fill", "url(#gradbox_" + picker + ")"); } - } - $('#color_picker').hide(); - }); + else { + rectbox.setAttribute("fill", "#" + paint.solidColor.hex); + } + + if (picker == 'stroke') { + svgCanvas.setStrokePaint(paint); + } + else { + svgCanvas.setFillPaint(paint); + } + + $('#color_picker').hide(); + }, + function(p) { + $('#color_picker').hide(); + }); } function updateToolButtonState() { @@ -657,6 +658,22 @@ function svg_edit_setup() { } } + // set up gradients to be used for the buttons + var svgdocbox = new DOMParser().parseFromString( + '\ + \ + \ + \ + ', 'text/xml'); + + var boxgrad = svgdocbox.getElementById('gradbox_'); + boxgrad.id = 'gradbox_fill'; + $('#fill_color').append( document.importNode(svgdocbox.documentElement,true) ); + + boxgrad.id = 'gradbox_stroke'; + $(svgdocbox.documentElement.firstChild).attr('fill', '#000'); + $('#stroke_color').append( document.importNode(svgdocbox.documentElement,true) ); + $('#fill_color').click(function(){ colorPicker($(this)); updateToolButtonState(); diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 04ac8615..87f5c554 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -14,7 +14,7 @@ var svgWhiteList = { "linearGradient": ["id", "x1", "x2", "y1", "y2"], "path": ["d", "fill", "fill-opacity", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray"], "rect": ["fill", "fill-opacity", "height", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray", "width", "x", "y"], - "stop": ["id", "stop-color", "stop-opacity"], + "stop": ["id", "offset", "stop-color", "stop-opacity"], "svg": ["id", "height", "width", "xmlns"], "text": ["font-family", "font-size", "font-style", "font-weight", "id", "x", "y"], }; @@ -239,6 +239,7 @@ function SvgCanvas(c) } this.showGrips = function(show) { + // TODO: use suspendRedraw() here for (dir in this.selectorGrips) { this.selectorGrips[dir].setAttribute("display", show ? "inline" : "none"); } @@ -258,6 +259,7 @@ function SvgCanvas(c) } var bbox = bbox || this.selectedElement.getBBox(); var l=bbox.x-offset, t=bbox.y-offset, w=bbox.width+(offset<<1), h=bbox.height+(offset<<1); + // TODO: use suspendRedraw() here selectedBox.x.baseVal.value = l; selectedBox.y.baseVal.value = t; selectedBox.width.baseVal.value = w; @@ -414,6 +416,8 @@ function SvgCanvas(c) var current_resize_mode = "none"; var current_fill = "none"; var current_stroke = "black"; + var current_stroke_paint = null; + var current_fill_paint = null; var current_stroke_width = 1; var current_stroke_style = "none"; var current_opacity = 1; @@ -464,10 +468,17 @@ function SvgCanvas(c) var nodes = svgroot.childNodes; var i = svgroot.childNodes.length; while (i--) { - if (nodes[i].id != "selectorParentGroup" && - Utils.rectsIntersect(rubberBBox, nodes[i].getBBox())) - { - resultList.push(nodes[i]); + // need to do this since the defs has no bbox and causes an exception + // to be thrown in Mozilla + try { +// if (nodes[i].tagName == "defs") continue; + if (nodes[i].id != "selectorParentGroup" && + Utils.rectsIntersect(rubberBBox, nodes[i].getBBox())) + { + resultList.push(nodes[i]); + } + } catch(e) { + // do nothing, this element did not have a bbox } } } @@ -514,14 +525,17 @@ function SvgCanvas(c) }; var assignAttributes = function(node, attrs) { + var handle = svgroot.suspendRedraw(60); for (i in attrs) { node.setAttributeNS(null, i, attrs[i]); } + svgroot.unsuspendRedraw(handle); }; // remove unneeded attributes // makes resulting SVG smaller var cleanupElement = function(element) { + var handle = svgroot.suspendRedraw(60); if (element.getAttribute('fill-opacity') == '1') element.removeAttribute('fill-opacity'); if (element.getAttribute('opacity') == '1') @@ -538,6 +552,7 @@ function SvgCanvas(c) element.removeAttribute('rx') if (element.getAttribute('ry') == '0') element.removeAttribute('ry') + svgroot.unsuspendRedraw(handle); }; var addSvgElementFromJson = function(data) { @@ -644,7 +659,7 @@ function SvgCanvas(c) indent--; if (!bOneLine) { out.push("\n"); - for (i=0; i"); } else { @@ -732,46 +747,56 @@ function SvgCanvas(c) changes["y1"] = selected.y1.baseVal.value; changes["x2"] = selected.x2.baseVal.value; changes["y2"] = selected.y2.baseVal.value; + var handle = svgroot.suspendRedraw(1000); selected.x1.baseVal.value = remapx(selected.x1.baseVal.value); selected.y1.baseVal.value = remapy(selected.y1.baseVal.value); selected.x2.baseVal.value = remapx(selected.x2.baseVal.value); selected.y2.baseVal.value = remapy(selected.y2.baseVal.value); + svgroot.unsuspendRedraw(handle); break; case "circle": changes["cx"] = selected.cx.baseVal.value; changes["cy"] = selected.cy.baseVal.value; changes["r"] = selected.r.baseVal.value; + var handle = svgroot.suspendRedraw(1000); selected.cx.baseVal.value = remapx(selected.cx.baseVal.value); selected.cy.baseVal.value = remapy(selected.cy.baseVal.value); // take the minimum of the new selected box's dimensions for the new circle radius selected.r.baseVal.value = Math.min(selectedBBox.width/2,selectedBBox.height/2); + svgroot.unsuspendRedraw(handle); break; case "ellipse": changes["cx"] = selected.cx.baseVal.value; changes["cy"] = selected.cy.baseVal.value; changes["rx"] = selected.rx.baseVal.value; changes["ry"] = selected.ry.baseVal.value; + var handle = svgroot.suspendRedraw(1000); selected.cx.baseVal.value = remapx(selected.cx.baseVal.value); selected.cy.baseVal.value = remapy(selected.cy.baseVal.value); selected.rx.baseVal.value = scalew(selected.rx.baseVal.value); selected.ry.baseVal.value = scaleh(selected.ry.baseVal.value); + svgroot.unsuspendRedraw(handle); break; case "text": // cannot use x.baseVal.value here because x is a SVGLengthList changes["x"] = selected.getAttribute("x"); changes["y"] = selected.getAttribute("y"); + var handle = svgroot.suspendRedraw(1000); selected.setAttribute("x", remapx(selected.getAttribute("x"))); selected.setAttribute("y", remapy(selected.getAttribute("y"))); + svgroot.unsuspendRedraw(handle); break; case "rect": changes["x"] = selected.x.baseVal.value; changes["y"] = selected.y.baseVal.value; changes["width"] = selected.width.baseVal.value; changes["height"] = selected.height.baseVal.value; + var handle = svgroot.suspendRedraw(1000); selected.x.baseVal.value = remapx(selected.x.baseVal.value); selected.y.baseVal.value = remapy(selected.y.baseVal.value); selected.width.baseVal.value = scalew(selected.width.baseVal.value); selected.height.baseVal.value = scaleh(selected.height.baseVal.value); + svgroot.unsuspendRedraw(handle); break; default: // rect console.log("Unknown shape type: " + selected.tagName); @@ -1143,25 +1168,33 @@ function SvgCanvas(c) selectorManager.requestSelector(selected).resize(selectedBBox); break; case "text": + var handle = svgroot.suspendRedraw(1000); shape.setAttribute("x", x); shape.setAttribute("y", y); + svgroot.unsuspendRedraw(handle); break; case "line": + var handle = svgroot.suspendRedraw(1000); shape.setAttributeNS(null, "x2", x); shape.setAttributeNS(null, "y2", y); + svgroot.unsuspendRedraw(handle); break; case "square": var size = Math.max( Math.abs(x - start_x), Math.abs(y - start_y) ); + var handle = svgroot.suspendRedraw(1000); shape.setAttributeNS(null, "width", size); shape.setAttributeNS(null, "height", size); shape.setAttributeNS(null, "x", start_x < x ? start_x : start_x - size); shape.setAttributeNS(null, "y", start_y < y ? start_y : start_y - size); + svgroot.unsuspendRedraw(handle); break; case "rect": + var handle = svgroot.suspendRedraw(1000); shape.setAttributeNS(null, "x", Math.min(start_x,x)); shape.setAttributeNS(null, "y", Math.min(start_y,y)); shape.setAttributeNS(null, "width", Math.abs(x-start_x)); shape.setAttributeNS(null, "height", Math.abs(y-start_y)); + svgroot.unsuspendRedraw(handle); break; case "circle": var cx = shape.getAttributeNS(null, "cx"); @@ -1172,8 +1205,10 @@ function SvgCanvas(c) case "ellipse": var cx = shape.getAttributeNS(null, "cx"); var cy = shape.getAttributeNS(null, "cy"); + var handle = svgroot.suspendRedraw(1000); shape.setAttributeNS(null, "rx", Math.abs(x - cx) ); shape.setAttributeNS(null, "ry", Math.abs(y - cy) ); + svgroot.unsuspendRedraw(handle); break; case "fhellipse": case "fhrect": @@ -1406,8 +1441,11 @@ function SvgCanvas(c) this.setResolution = function(x, y) { var w = svgroot.getAttribute("width"), h = svgroot.getAttribute("height"); + + var handle = svgroot.suspendRedraw(1000); svgroot.setAttribute("width", x); svgroot.setAttribute("height", y); + svgroot.unsuspendRedraw(handle); addCommandToHistory(new ChangeElementCommand(svgroot, {"width":w,"height":h}, "resolution")); call("changed", [svgroot]); }; @@ -1448,6 +1486,120 @@ function SvgCanvas(c) this.changeSelectedAttribute("fill", val, elems); }; + var findDefs = function() { + var defs = svgroot.getElementsByTagNameNS(svgns, "defs"); + if (defs.length > 0) { + defs = defs[0]; + } + else { + defs = svgroot.insertBefore( svgdoc.createElementNS(svgns, "defs" ), svgroot.firstChild); + } + return defs; + }; + + var findDuplicateGradient = function(grad) { + var defs = findDefs(); + var existing_grads = defs.getElementsByTagNameNS(svgns, "linearGradient"); + var i = existing_grads.length; + while (i--) { + var og = existing_grads.item(i); + if (grad.getAttribute('x1') != og.getAttribute('x1') || + grad.getAttribute('y1') != og.getAttribute('y1') || + grad.getAttribute('x2') != og.getAttribute('x2') || + grad.getAttribute('y2') != og.getAttribute('y2')) + { + continue; + } + + // else could be a duplicate, iterate through stops + var stops = grad.getElementsByTagNameNS(svgns, "stop"); + var ostops = og.getElementsByTagNameNS(svgns, "stop"); + + if (stops.length != ostops.length) { + continue; + } + + var j = stops.length; + while(j--) { + var stop = stops.item(j); + var ostop = ostops.item(j); + + if (stop.getAttribute('offset') != ostop.getAttribute('offset') || + stop.getAttribute('stop-opacity') != ostop.getAttribute('stop-opacity') || + stop.getAttribute('stop-color') != ostop.getAttribute('stop-color')) + { + break; + } + } + + if (j == -1) { + return og; + } + } // for each gradient in defs + + return null; + }; + + // TODO: what to do about the opacity in these functions? + + this.setStrokePaint = function(p) { + current_stroke_paint = p; + if (p.solidColor) { + this.setStrokeColor("#"+p.solidColor.hex); + } + else if(p.linearGradient.grad) { + // find out if there is a duplicate gradient already in the defs + var grad = p.linearGradient.grad; + var duplicate_grad = findDuplicateGradient(grad); + var defs = findDefs(); + + // no duplicate found, so import gradient into defs + if (!duplicate_grad) { + grad = defs.appendChild( svgdoc.importNode(grad, true) ); + + // get next id and set it on the grad + grad.id = getNextId(); + } + else { // use existing gradient + grad = duplicate_grad; + } + + this.setStrokeColor("url(#" + grad.id + ")"); + } + else { +// console.log("none!"); + } + }; + + this.setFillPaint = function(p) { + current_fill_paint = p; + if (p.solidColor) { + this.setFillColor("#"+p.solidColor.hex); + } + else if(p.linearGradient.grad) { + // find out if there is a duplicate gradient already in the defs + var grad = p.linearGradient.grad; + var duplicate_grad = findDuplicateGradient(grad); + var defs = findDefs(); + + // no duplicate found, so import gradient into defs + if (!duplicate_grad) { + grad = defs.appendChild( svgdoc.importNode(grad, true) ); + + // get next id and set it on the grad + grad.id = getNextId(); + } + else { // use existing gradient + grad = duplicate_grad; + } + + this.setFillColor("url(#" + grad.id + ")"); + } + else { +// console.log("none!"); + } + }; + this.getStrokeWidth = function() { return current_stroke_width; }; @@ -1608,6 +1760,7 @@ function SvgCanvas(c) var elems = elems || selectedElements; var batchCmd = new BatchCommand("Change " + attr); var i = elems.length; + var handle = svgroot.suspendRedraw(1000); while(i--) { var elem = elems[i]; if (elem == null) continue; @@ -1623,6 +1776,7 @@ function SvgCanvas(c) batchCmd.addSubCommand(new ChangeElementCommand(elem, changes, attr)); } } + svgroot.unsuspendRedraw(handle); if (!batchCmd.isEmpty()) { addCommandToHistory(batchCmd); call("changed", elems); @@ -1675,7 +1829,11 @@ function SvgCanvas(c) var oldParent = t.parentNode; var oldNextSibling = t.nextSibling; if (oldNextSibling == selectorManager.selectorParentGroup) oldNextSibling = null; - t = t.parentNode.insertBefore(t, t.parentNode.firstChild); + var firstChild = t.parentNode.firstChild; + if (firstChild.tagName == 'defs') { + firstChild = firstChild.nextSibling; + } + t = t.parentNode.insertBefore(t, firstChild); addCommandToHistory(new MoveElementCommand(t, oldNextSibling, oldParent, "bottom")); } };