Fix Issue 33: Gradient picker for fill/stroke. Also start to optimize suspendRedraw/unsuspend. Added vector image of logo.

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@346 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Jeff Schiller 2009-07-30 22:45:59 +00:00
parent f987b37526
commit 05ff4be18f
20 changed files with 1452 additions and 92 deletions

66
editor/images/logo.svg Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs id="defs14280">
<linearGradient gradientUnits="userSpaceOnUse" id="XMLID_16_" x1="67.8452" x2="144.5898" y1="115.5361" y2="115.5361">
<stop id="stop780" offset="0" stop-color="#7D7D99"/>
<stop id="stop781" offset="0.1798" stop-color="#B1B1C5"/>
<stop id="stop782" offset="0.3727" stop-color="#BCBCC8"/>
<stop id="stop783" offset="0.6825" stop-color="#C8C8CB"/>
<stop id="stop784" offset="1" stop-color="#CCC"/>
</linearGradient>
<linearGradient gradientTransform="matrix(-0.999,4.35e-2,4.35e-2,0.999,-1277.01,-496.517)" gradientUnits="userSpaceOnUse" id="XMLID_15_" x1="-1401.459" x2="-1354.6851" y1="595.63092" y2="699.47632">
<stop id="stop770" offset="0" stop-color="#FFA700"/>
<stop id="stop771" offset="0.7753" stop-color="#FFD700"/>
<stop id="stop772" offset="1" stop-color="#FF9200"/>
</linearGradient>
<linearGradient gradientTransform="matrix(-0.999,4.35e-2,4.35e-2,0.999,-1277.01,-496.517)" gradientUnits="userSpaceOnUse" id="XMLID_14_" x1="-1336.4497" x2="-1325.3219" y1="635.79492" y2="622.53333">
<stop id="stop763" offset="0" stop-color="#FFC957"/>
<stop id="stop764" offset="1" stop-color="#FF6D00"/>
</linearGradient>
<linearGradient gradientUnits="userSpaceOnUse" id="XMLID_13_" x1="65.094704" x2="137.6021" y1="-0.79540002" y2="160.1823">
<stop id="stop750" offset="0" stop-color="#FFA700"/>
<stop id="stop751" offset="0.7753" stop-color="#FFD700"/>
<stop id="stop752" offset="1" stop-color="#FF794B"/>
</linearGradient>
<linearGradient gradientTransform="matrix(-0.999,4.35e-2,4.35e-2,0.999,-1277.01,-496.517)" gradientUnits="userSpaceOnUse" id="XMLID_12_" x1="-1375.9844" x2="-1355.0455" y1="685.38092" y2="706.32172">
<stop id="stop743" offset="0" stop-color="#F8F1DC"/>
<stop id="stop744" offset="1" stop-color="#D6A84A"/>
</linearGradient>
<linearGradient gradientTransform="matrix(0.1991,0.98,-0.98,0.1991,91.6944,573.565)" gradientUnits="userSpaceOnUse" id="XMLID_11_" x1="-481.70071" x2="-360.24561" y1="-94.419403" y2="-164.22141">
<stop id="stop736" offset="0" stop-color="#900"/>
<stop id="stop737" offset="1" stop-color="#7C0000"/>
</linearGradient>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath4418">
<rect fill="none" height="79.958374" id="rect4420" stroke="#000" stroke-miterlimit="4" stroke-width="0.14421287" style="stroke-dasharray:none;" transform="scale(-1,1)" width="73.952118" x="-196.68831" y="126.58712"/>
</clipPath>
</defs>
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
</cc:Work>
</rdf:RDF>
</metadata>
<a xlink:href="http://svg-edit.googlecode.com/" xlink:title="SVG-edit, an in-browser vector graphics editor" target="_blank">
<path d="M257.74,558.2c24.94-7.02,41.7-25.17,45.56-49.34l1.3-8.12,5.49,3.91c32.51,23.15,75.86,12.04,91.83-23.54,8.82-19.67,4.96-51.37-7.53-61.73-4.87-4.04-3.66-5.35,6.15-6.67,63.27-8.51,65.48-104.18,2.72-117.72-13.73-2.97-13.19-2.25-7.45-9.82,39.41-52.03-27.83-121.53-82.22-84.99l-8.5,5.71-2.95-12.03c-15.47-63.09-108.77-60.34-117.52,3.47-1.4,10.22-1.08,10.09-9.17,3.92-29.91-22.81-79.426-7.73-91.221,27.79-6.608,19.89-2.39,47.48,8.807,57.62,5.357,4.84,4.664,5.97-4.54,7.4-66.03,10.23-66.493,109.67-0.553,118.71l8.629,1.18-5.385,7.99c-27.709,41.08,0.153,94.95,49.063,94.85,14.69-0.03,30.72-5.41,37.08-12.43,4.66-5.14,6.62-4.62,6.62,1.77,0,32.42,40.95,61.32,73.79,52.07zm-32.77-32.12c-13.84-9.85-17.94-31.87-8.34-44.84,3.86-5.23,4.15-7.92,4.15-39.1v-33.48l-24.23,24.17c-18.68,18.64-24.23,25.33-24.23,29.24,0,19.85-32.96,34.46-49.64,22-22.942-17.13-17.18-51.92,9.72-58.77,6.4-1.63,12.47-6.56,31.17-25.35l23.23-23.33-31.95,0.01c-30.22,0.01-32.47,0.27-41.49,4.84-36.551,18.55-67.269-29.82-34.708-54.66,9.535-7.27,27.368-7.79,36.798-1.07,5.75,4.11,8,4.36,38.73,4.36h32.62l-23.01-23.06c-16.39-16.43-24.74-23.42-29.01-24.27-28.64-5.73-36.095-42.37-12.22-60.06,16.84-12.48,49.88,2.08,49.72,21.92-0.03,3.94,5.16,10.04,23.74,27.91l23.79,22.87,0.53-32.09c0.5-30.31,0.3-32.41-3.67-37.77-14.37-19.44-0.44-48.03,24.42-50.09,26.09-2.17,43.22,23.68,31.2,47.08-4.75,9.25-4.98,11.14-4.99,41.64l-0.01,31.95,23.07-23.01c16.03-15.98,23.43-24.79,24.23-28.82,5.96-29.77,46.54-36.03,60.61-9.35,10.42,19.75,0.51,41.32-21.52,46.87-6.79,1.71-12.35,6.18-31.3,25.18l-23.05,23.1h33.59c30.28,0,34.12-0.37,38.94-3.8,12.83-9.14,30.26-6.74,41.53,5.73,25.04,27.73-11.22,69.98-41.53,48.4-4.82-3.43-8.66-3.81-38.94-3.81h-33.59l23.05,23.1c18.95,19.01,24.51,23.48,31.3,25.19,36.61,9.22,33.19,60.64-4.24,63.74-16.99,1.41-35.63-13.68-35.63-28.85,0-1.54-10.47-13.24-23.26-26l-23.26-23.2,0.01,31.95c0.01,30.22,0.27,32.47,4.85,41.48,15.51,30.58-19.49,61.77-47.18,42.05z" fill="#000"/>
<g clip-path="url(#clipPath4418)" transform="matrix(-4.6717475,0,0,4.6717475,1143.4575,-562.74962)">
<path d="M191.92,195.98c-11.61-36.12-13.71-42.67-14.86-44.06,0.12,0.08,0.29,0.18,0.29,0.18l-78.546-87.457c-4.195-4.65-14.005,0.356-21.355,6.976-7.283,6.542-13.32,15.773-9.37,20.564l78.941,87.547,0.54,0.09,37.76,17.6,7.69,2.37-1.09-3.81z" opacity="0.2"/>
<path d="M193.56,193.52c-11.61-36.13-13.72-42.67-14.86-44.07,0.12,0.07,0.29,0.18,0.29,0.18l-78.55-87.455c-4.195-4.651-14.011,0.355-21.357,6.975-7.281,6.545-13.32,15.773-9.368,20.566l78.945,87.544,0.53,0.1,37.77,17.59,7.68,2.37-1.08-3.8z" opacity="0.2"/>
<path d="M186.77,191.05c-11.61-36.13-13.71-42.67-14.86-44.07,0.12,0.08,0.29,0.18,0.29,0.18l-78.547-87.456c-4.192-4.65-14.009,0.359-21.354,6.978-7.283,6.542-13.321,15.771-9.369,20.565l78.94,87.543,0.54,0.09,37.77,17.6,7.68,2.37-1.09-3.8z" opacity="0.2"/>
<path d="M186.43,189.36c-11.61-36.13-13.71-42.67-14.86-44.07,0.12,0.08,0.29,0.18,0.29,0.18l-78.546-87.454c-4.199-4.651-14.015,0.357-21.359,6.977-7.283,6.543-13.322,15.774-9.37,20.566l78.945,87.541,0.53,0.1,37.77,17.6,7.69,2.36-1.09-3.8z" fill="#FFF"/>
<path d="M186.43,189.36c-11.61-36.13-13.71-42.67-14.86-44.07,0.12,0.08,0.29,0.18,0.29,0.18l-78.546-87.454c-4.199-4.651-14.015,0.357-21.359,6.977-7.283,6.543-13.322,15.774-9.37,20.566l78.945,87.541,0.53,0.1,37.77,17.6,7.69,2.36-1.09-3.8z" fill="url(#XMLID_11_)"/>
<path d="M166.97,147.76l13.72,38.13-36.37-17.9,0.17-0.15c-0.25-0.08-0.5-0.18-0.7-0.32l-0.13,0.12-75.3-83.568,0.123-0.104c-2.246-2.49,1.032-9.094,7.308-14.752,6.28-5.652,13.18-8.219,15.425-5.733l75.294,83.567,0.46,0.71z" fill="url(#XMLID_12_)"/>
<path d="M148.65,170.12c2.08-0.37,4.64-1.48,7.25-3.14,1.62-1.02,3.28-2.28,4.9-3.74,1.46-1.3,2.74-2.67,3.84-4.01,2.08-2.53,3.32-5.21,3.78-7.43l-1.45-4.04-0.47-0.71-74.793-83.022c0.608,2.24-0.962,5.938-4.063,9.74-1.134,1.389-2.441,2.789-3.945,4.141-1.574,1.419-3.195,2.652-4.767,3.654-4.493,2.871-8.628,3.928-10.548,2.486l-0.025,0.021,75.301,83.57,0.13-0.12c0.2,0.14,0.45,0.24,0.7,0.32l-0.17,0.15,4.33,2.13z" fill="url(#XMLID_13_)"/>
<path d="M68.083,83.41c1.732,1.772,5.994,0.776,10.643-2.194,1.541-0.982,3.132-2.193,4.677-3.586,1.476-1.325,2.759-2.701,3.872-4.063,3.578-4.388,5.091-8.642,3.477-10.584l0.023-0.024,75.815,84.121c0.64,2.26-0.59,6.5-3.75,10.36-1.08,1.31-2.34,2.65-3.77,3.93-1.59,1.43-3.22,2.67-4.81,3.67-4.74,3.01-9.3,4.2-11.02,2.31-0.39-0.44-2.09-2.34-2.14-2.41l-73.255-81.314,0.238-0.216z" fill="#FFF"/>
<path d="M75.79,69.215c6.28-5.652,13.18-8.219,15.425-5.733l16.965,18.828,1.15,26.49-17.975,0.78-22.996-25.509,0.123-0.104c-2.246-2.49,1.032-9.093,7.308-14.752z" fill="#FFF"/>
<path d="M68.083,83.41c1.732,1.772,5.994,0.776,10.643-2.194,1.541-0.982,3.132-2.193,4.677-3.586,1.476-1.325,2.759-2.701,3.872-4.063,3.578-4.388,5.091-8.642,3.477-10.584l0.023-0.024,75.815,84.121c0.64,2.26-0.59,6.5-3.75,10.36-1.08,1.31-2.34,2.65-3.77,3.93-1.59,1.43-3.22,2.67-4.81,3.67-4.74,3.01-9.3,4.2-11.02,2.31-0.39-0.44-2.09-2.34-2.14-2.41l-73.255-81.314,0.238-0.216z" fill="#FFF"/>
<path d="M75.79,69.215c6.28-5.652,13.18-8.219,15.425-5.733l16.965,18.828,1.15,26.49-17.975,0.78-22.996-25.509,0.123-0.104c-2.246-2.49,1.032-9.093,7.308-14.752z" fill="url(#XMLID_14_)"/>
<path d="M68.083,83.41c1.732,1.772,5.994,0.776,10.643-2.194,1.541-0.982,3.132-2.193,4.677-3.586,1.476-1.325,2.759-2.701,3.872-4.063,3.578-4.388,5.091-8.642,3.477-10.584l0.023-0.024,75.815,84.121c0.64,2.26-0.59,6.5-3.75,10.36-1.08,1.31-2.34,2.65-3.77,3.93-1.59,1.43-3.22,2.67-4.81,3.67-4.74,3.01-9.3,4.2-11.02,2.31-0.39-0.44-2.09-2.34-2.14-2.41l-73.255-81.314,0.238-0.216z" fill="url(#XMLID_15_)"/>
<path d="M74.357,90.713c0,0,6.036-0.212,10.685-3.182,1.542-0.983,3.132-2.193,4.677-3.586,1.477-1.326,2.76-2.701,3.873-4.064,2.928-3.589,4.469-7.088,4.049-9.307l-6.865-7.617-0.023,0.024c1.614,1.942,0.102,6.196-3.477,10.584-1.113,1.362-2.396,2.738-3.872,4.063-1.545,1.393-3.136,2.604-4.677,3.586-4.648,2.971-8.91,3.967-10.643,2.194l-0.238,0.217,73.254,81.315c0.05,0.07,1.75,1.96,2.15,2.4,0.34,0.38,0.8,0.63,1.34,0.77l-70.233-77.397z" fill="url(#XMLID_16_)"/>
<path d="M172.04,175.35c-1.64,1.48-3.31,2.77-4.95,3.84l13.6,6.7-5.09-14.15c-1.06,1.21-2.25,2.44-3.56,3.61z" fill="#033"/>
<path d="M163.12,157.05l-76.152-83.12c0.1-0.12,0.213-0.242,0.307-0.364,1.428-1.752,2.52-3.49,3.225-5.058l75.77,82.712c-0.55,1.82-1.6,3.86-3.15,5.83z" fill="#FFF" opacity="0.5"/>
<path d="M87.275,73.566c0.634-0.774,1.189-1.548,1.694-2.3l76.011,82.974c-0.57,1.06-1.28,2.15-2.14,3.19-0.75,0.9-1.57,1.81-2.47,2.7l-76.218-83.198c1.164-1.108,2.209-2.24,3.123-3.366z" fill="#FFF" opacity="0.5"/>
</g>
</a>
</svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

202
editor/jgraduate/LICENSE Normal file
View File

@ -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.

3
editor/jgraduate/README Normal file
View File

@ -0,0 +1,3 @@
jGraduate - A jQuery plugin for picking gradients
Licensed under the Apache License 2. See LICENSE for more information.

View File

@ -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;
}

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 B

1
editor/jgraduate/jpicker-1.0.9.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -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('<ul class="jGraduate_tabs">' +
'<li class="jGraduate_tab_color jGraduate_tab_current">Solid Color</li>' +
'<li class="jGraduate_tab_lingrad">Linear Gradient</li>' +
'</ul>' +
'<div class="jGraduate_colPick"></div>' +
'<div class="jGraduate_lgPick"></div>');
var colPicker = $(idref + '> .jGraduate_colPick');
var lgPicker = $(idref + '> .jGraduate_lgPick');
lgPicker.html(
'<div id="' + id + '_jGraduate_Swatch" class="jGraduate_Swatch">' +
'<h2 class="jGraduate_Title">' + $settings.window.pickerTitle + '</h2>' +
'<div id="' + id + '_jGraduate_GradContainer" class="jGraduate_GradContainer"></div>' +
'<div id="' + id + '_jGraduate_Opacity" class="jGraduate_Opacity" title="Click to set overall opacity of the gradient paint">' +
'<img id="' + id + '_jGraduate_AlphaArrows" class="jGraduate_AlphaArrows" src="' + $settings.images.clientPath + 'rangearrows2.gif"></img>' +
'</div>' +
'</div>' +
'<div class="jGraduate_Form">' +
'<div class="jGraduate_StopSection">' +
'<label class="jGraduate_Form_Heading">Begin Stop</label>' +
'<div class="jGraduate_Form_Section">' +
'<label>x:</label>' +
'<input type="text" id="' + id + '_jGraduate_x1" size="3" title="Enter starting x value between 0.0 and 1.0"/>' +
'<label> y:</label>' +
'<input type="text" id="' + id + '_jGraduate_y1" size="3" title="Enter starting y value between 0.0 and 1.0"/>' +
'<div id="' + id + '_jGraduate_colorBoxBegin" class="colorBox"></div>' +
'<label id="' + id + '_jGraduate_beginOpacity"> 100%</label>' +
'</div>' +
'</div>' +
'<div class="jGraduate_StopSection">' +
'<label class="jGraduate_Form_Heading">End Stop</label>' +
'<div class="jGraduate_Form_Section">' +
'<label>x:</label>' +
'<input type="text" id="' + id + '_jGraduate_x2" size="3" title="Enter ending x value between 0.0 and 1.0"/>' +
'<label> y:</label>' +
'<input type="text" id="' + id + '_jGraduate_y2" size="3" title="Enter ending y value between 0.0 and 1.0"/>' +
'<div id="' + id + '_jGraduate_colorBoxEnd" class="colorBox"></div>' +
'<label id="' + id + '_jGraduate_endOpacity">100%</label>' +
'</div>' +
'</div>' +
'<div class="jGraduate_OpacityField">' +
'<label class="jGraduate_OpacityLabel">A: </label>' +
'<input type="text" id="' + id + '_jGraduate_OpacityInput" class="jGraduate_OpacityInput" size="3" value="100"/>%' +
'</div>' +
'</div>' +
'<div class="jGraduate_OkCancel">' +
'<input type="button" id="' + id + '_jGraduate_Ok" class="jGraduate_Ok" value="OK"/>' +
'<input type="button" id="' + id + '_jGraduate_Cancel" class="jGraduate_Cancel" value="Cancel"/>' +
'</div>' +
'<div class="jGraduate_LightBox"></div>' +
'<div id="' + id + '_jGraduate_stopPicker" class="jGraduate_stopPicker"></div>');
// --------------
// 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();
});
};

View File

@ -49,14 +49,6 @@ body {
cursor: pointer; cursor: pointer;
} }
#svg_editor #fill_color {
background: url('images/none.png');
}
#svg_editor #stroke_color {
background: #000000;
}
#svg_editor div#palette { #svg_editor div#palette {
float: left; float: left;
width: 6848px; width: 6848px;
@ -103,6 +95,7 @@ body {
/* TODO: fix this */ /* TODO: fix this */
div.color_block { div.color_block {
background-image: url('images/none.png');
display: inline-block; display: inline-block;
} }
@ -191,10 +184,6 @@ div.color_block {
padding: 2px; padding: 2px;
} }
#svg_editor #paint_picker {
display: none;
}
#svg_editor #color_picker { #svg_editor #color_picker {
position: absolute; position: absolute;
display: none; display: none;

View File

@ -2,17 +2,17 @@
<html> <html>
<head> <head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<link rel="stylesheet" href="jpicker/css/jPicker-1.0.9.css" type="text/css"/> <link rel="stylesheet" href="jgraduate/css/jPicker-1.0.9.css" type="text/css"/>
<link rel="stylesheet" href="jgraduate/css/jGraduate-0.2.0.css" type="text/css"/>
<link rel="stylesheet" href="svg-editor.css" type="text/css"/> <link rel="stylesheet" href="svg-editor.css" type="text/css"/>
<link rel="stylesheet" href="spinbtn/JQuerySpinBtn.css" type="text/css"/> <link rel="stylesheet" href="spinbtn/JQuerySpinBtn.css" type="text/css"/>
<link rel="stylesheet" href="jgraduate/jgraduate.css" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.js"></script>
<!--script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script--> <!--script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script-->
<script type="text/javascript" src="js-hotkeys/jquery.hotkeys.min.js"></script> <script type="text/javascript" src="js-hotkeys/jquery.hotkeys.min.js"></script>
<script type="text/javascript" src="jpicker/jpicker-1.0.9.js"></script> <script type="text/javascript" src="jgraduate/jpicker-1.0.9.min.js"></script>
<script type="text/javascript" src="jgraduate/jquery.jgraduate.js"></script>
<script type="text/javascript" src="spinbtn/JQuerySpinBtn.js"></script> <script type="text/javascript" src="spinbtn/JQuerySpinBtn.js"></script>
<!--script type="text/javascript" src="spinbtn/JQuerySpinBtn.min.js"></script--> <!--script type="text/javascript" src="spinbtn/JQuerySpinBtn.min.js"></script-->
<script type="text/javascript" src="jgraduate/jquery.jgraduate.js"></script>
<!--script type="text/javascript" src="jgraduate/jquery.jgraduate.min.js"></script--> <!--script type="text/javascript" src="jgraduate/jquery.jgraduate.min.js"></script-->
<script type="text/javascript" src="svgcanvas.js"></script> <script type="text/javascript" src="svgcanvas.js"></script>
<!--script type="text/javascript" src="svgcanvas.min.js"></script--> <!--script type="text/javascript" src="svgcanvas.min.js"></script-->
@ -207,9 +207,6 @@
</div> </div>
<!-- hidden divs --> <!-- hidden divs -->
<div id="paint_picker">
</div>
<div id="color_picker"></div> <div id="color_picker"></div>
<div id="tools_rect" class="tools_flyout"> <div id="tools_rect" class="tools_flyout">

View File

@ -22,6 +22,9 @@ function svg_edit_setup() {
var selectedElement = null; var selectedElement = null;
var multiselected = false; var multiselected = false;
var editingsource = false; var editingsource = false;
var fillPaint = new $.jGraduate.Paint();
var strokePaint = new $.jGraduate.Paint();
// called when we've selected a different element // called when we've selected a different element
var selectedChanged = function(window,elems) { var selectedChanged = function(window,elems) {
@ -81,21 +84,27 @@ function svg_edit_setup() {
// update fill color // update fill color
var fillColor = selectedElement.getAttribute("fill"); var fillColor = selectedElement.getAttribute("fill");
// TODO: get a Paint from this and store in fillPaint ?
// TODO: call setFillPaint() ?
svgCanvas.setFillColor(fillColor); svgCanvas.setFillColor(fillColor);
if (fillColor == "none") { if (fillColor == "none") {
fillColor = 'url(\'images/none.png\')'; fillColor = "none";
fillOpacity = "N/A"; 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 // update stroke color
var strokeColor = selectedElement.getAttribute("stroke"); var strokeColor = selectedElement.getAttribute("stroke");
// TODO: get a Paint from this and store in strokePaint ?
// TODO: call setStrokePaint() ?
svgCanvas.setStrokeColor(strokeColor); svgCanvas.setStrokeColor(strokeColor);
if (strokeColor == null || strokeColor == "" || strokeColor == "none") { if (strokeColor == null || strokeColor == "" || strokeColor == "none") {
strokeColor = 'url(\'images/none.png\')';
strokeOpacity = "N/A"; 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); $('#fill_opacity').html(fillOpacity);
$('#stroke_opacity').html(strokeOpacity); $('#stroke_opacity').html(strokeOpacity);
@ -200,9 +209,9 @@ function svg_edit_setup() {
svgCanvas.bind("selected", selectedChanged); svgCanvas.bind("selected", selectedChanged);
svgCanvas.bind("changed", elementChanged); svgCanvas.bind("changed", elementChanged);
var str = '<div class="palette_item" style="background: url(\'images/none.png\');"></div>' var str = '<div class="palette_item" style="background-image: url(\'images/none.png\');" data-rgb="none"></div>'
$.each(palette, function(i,item){ $.each(palette, function(i,item){
str += '<div class="palette_item" style="background: ' + item + ';"></div>'; str += '<div class="palette_item" style="background-color: ' + item + ';" data-rgb="' + item + '"></div>';
}); });
$('#palette').append(str); $('#palette').append(str);
@ -244,17 +253,19 @@ function svg_edit_setup() {
}); });
$('.palette_item').click(function(evt){ $('.palette_item').click(function(evt){
var picker = (evt.shiftKey ? "stroke" : "fill");
var id = (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 // Webkit-based browsers returned 'initial' here for no stroke
if (color == 'transparent' || color == 'initial') { if (color == 'transparent' || color == 'initial') {
color = 'none'; color = 'none';
$(id + "color").css('background', 'url(\'images/none.png\')');
$(id + "opacity").html("N/A"); $(id + "opacity").html("N/A");
} else {
$(id + "color").css('background', color);
} }
if (evt.shiftKey) { rectbox.setAttribute("fill", color);
if (evt.shiftKey) {
svgCanvas.setStrokeColor(color); svgCanvas.setStrokeColor(color);
if (color != 'none' && $("#stroke_opacity").html() == 'N/A') { if (color != 'none' && $("#stroke_opacity").html() == 'N/A') {
svgCanvas.setStrokeOpacity(1.0); svgCanvas.setStrokeOpacity(1.0);
@ -550,18 +561,16 @@ function svg_edit_setup() {
$(document).bind('keydown', {combi:'esc', disableInInput: false}, hideSourceEditor); $(document).bind('keydown', {combi:'esc', disableInInput: false}, hideSourceEditor);
var colorPicker = function(elem) { var colorPicker = function(elem) {
var oldbg = elem.css('background'); var picker = elem.attr('id') == 'stroke_color' ? 'stroke' : 'fill';
var color = elem.css('background-color'); var oldopacity = (picker == 'stroke' ? $('#stroke_opacity').html() : $('#fill_opacity').html());
var oldopacity = "100 %";
if (elem.attr('id') == 'stroke_color') { var paint = (picker == 'stroke' ? strokePaint : fillPaint);
oldopacity = $('#stroke_opacity').html(); var title = (picker == 'stroke' ? 'Pick a Stroke Paint and Opacity' : 'Pick a Fill Paint and Opacity');
} var oldPaint = new $.jGraduate.Paint(paint);
if (elem.attr('id') == 'fill_color') {
oldopacity = $('#fill_opacity').html();
}
var was_none = false; 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; was_none = true;
} else { } else {
var alpha; var alpha;
@ -570,53 +579,45 @@ function svg_edit_setup() {
} else { } else {
alpha = oldopacity.split(' ')[0]; 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 pos = elem.position();
var picker = elem.attr('id') == 'stroke_color' ? 'stroke' : 'fill'; $('#color_picker').css({'left': pos.left - 140, 'bottom': 124 - pos.top}).jGraduate(
$('#color_picker').css({'left': pos.left - 140, 'bottom': 104 - pos.top}).jPicker({ {
window: { title: "Choose the " + picker + " color and opacity"}, paint: paint,
images: { clientPath: "jpicker/images/" }, window: { pickerTitle: title },
color: { active: color, alphaSupport: true } images: { clientPath: "jGraduate/images/" },
}, function(color){ },
elem.css('background', '#' + this.settings.color.active.hex); function(p) {
if (elem.attr('id') == 'stroke_color') { paint.solidColor = p.solidColor;
svgCanvas.setStrokeColor('#' + this.settings.color.active.hex); paint.linearGradient.grad = p.linearGradient.grad;
svgCanvas.setStrokeOpacity(this.settings.color.active.a/100); paint.linearGradient.a = p.linearGradient.a;
$('#stroke_opacity').html(this.settings.color.active.a+" %");
} else if (elem.attr('id') == 'fill_color') { var oldgrad = document.getElementById("gradbox_"+picker);
svgCanvas.setFillColor('#' + this.settings.color.active.hex); var svgbox = oldgrad.parentNode;
svgCanvas.setFillOpacity(this.settings.color.active.a/100); var rectbox = svgbox.firstChild;
$('#fill_opacity').html(this.settings.color.active.a+" %");
} if (paint.linearGradient.grad) {
$('#color_picker').hide(); svgbox.removeChild(oldgrad);
} var newgrad = svgbox.appendChild(document.importNode(paint.linearGradient.grad, true));
, null newgrad.id = "gradbox_"+picker;
, function(){ rectbox.setAttribute("fill", "url(#gradbox_" + picker + ")");
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');
} }
} else {
$('#color_picker').hide(); 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() { function updateToolButtonState() {
@ -657,6 +658,22 @@ function svg_edit_setup() {
} }
} }
// set up gradients to be used for the buttons
var svgdocbox = new DOMParser().parseFromString(
'<svg xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="none"/>\
<linearGradient id="gradbox_">\
<stop stop-color="#000" offset="0.0"/>\
<stop stop-color="#FF0000" offset="1.0"/>\
</linearGradient></svg>', '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(){ $('#fill_color').click(function(){
colorPicker($(this)); colorPicker($(this));
updateToolButtonState(); updateToolButtonState();

View File

@ -14,7 +14,7 @@ var svgWhiteList = {
"linearGradient": ["id", "x1", "x2", "y1", "y2"], "linearGradient": ["id", "x1", "x2", "y1", "y2"],
"path": ["d", "fill", "fill-opacity", "id", "stroke", "stroke-opacity", "stroke-width", "stroke-dasharray"], "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"], "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"], "svg": ["id", "height", "width", "xmlns"],
"text": ["font-family", "font-size", "font-style", "font-weight", "id", "x", "y"], "text": ["font-family", "font-size", "font-style", "font-weight", "id", "x", "y"],
}; };
@ -239,6 +239,7 @@ function SvgCanvas(c)
} }
this.showGrips = function(show) { this.showGrips = function(show) {
// TODO: use suspendRedraw() here
for (dir in this.selectorGrips) { for (dir in this.selectorGrips) {
this.selectorGrips[dir].setAttribute("display", show ? "inline" : "none"); this.selectorGrips[dir].setAttribute("display", show ? "inline" : "none");
} }
@ -258,6 +259,7 @@ function SvgCanvas(c)
} }
var bbox = bbox || this.selectedElement.getBBox(); 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); 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.x.baseVal.value = l;
selectedBox.y.baseVal.value = t; selectedBox.y.baseVal.value = t;
selectedBox.width.baseVal.value = w; selectedBox.width.baseVal.value = w;
@ -414,6 +416,8 @@ function SvgCanvas(c)
var current_resize_mode = "none"; var current_resize_mode = "none";
var current_fill = "none"; var current_fill = "none";
var current_stroke = "black"; var current_stroke = "black";
var current_stroke_paint = null;
var current_fill_paint = null;
var current_stroke_width = 1; var current_stroke_width = 1;
var current_stroke_style = "none"; var current_stroke_style = "none";
var current_opacity = 1; var current_opacity = 1;
@ -464,10 +468,17 @@ function SvgCanvas(c)
var nodes = svgroot.childNodes; var nodes = svgroot.childNodes;
var i = svgroot.childNodes.length; var i = svgroot.childNodes.length;
while (i--) { while (i--) {
if (nodes[i].id != "selectorParentGroup" && // need to do this since the defs has no bbox and causes an exception
Utils.rectsIntersect(rubberBBox, nodes[i].getBBox())) // to be thrown in Mozilla
{ try {
resultList.push(nodes[i]); // 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 assignAttributes = function(node, attrs) {
var handle = svgroot.suspendRedraw(60);
for (i in attrs) { for (i in attrs) {
node.setAttributeNS(null, i, attrs[i]); node.setAttributeNS(null, i, attrs[i]);
} }
svgroot.unsuspendRedraw(handle);
}; };
// remove unneeded attributes // remove unneeded attributes
// makes resulting SVG smaller // makes resulting SVG smaller
var cleanupElement = function(element) { var cleanupElement = function(element) {
var handle = svgroot.suspendRedraw(60);
if (element.getAttribute('fill-opacity') == '1') if (element.getAttribute('fill-opacity') == '1')
element.removeAttribute('fill-opacity'); element.removeAttribute('fill-opacity');
if (element.getAttribute('opacity') == '1') if (element.getAttribute('opacity') == '1')
@ -538,6 +552,7 @@ function SvgCanvas(c)
element.removeAttribute('rx') element.removeAttribute('rx')
if (element.getAttribute('ry') == '0') if (element.getAttribute('ry') == '0')
element.removeAttribute('ry') element.removeAttribute('ry')
svgroot.unsuspendRedraw(handle);
}; };
var addSvgElementFromJson = function(data) { var addSvgElementFromJson = function(data) {
@ -644,7 +659,7 @@ function SvgCanvas(c)
indent--; indent--;
if (!bOneLine) { if (!bOneLine) {
out.push("\n"); out.push("\n");
for (i=0; i<indent; i++) out += " "; for (i=0; i<indent; i++) out.push(" ");
} }
out.push("</"); out.push(elem.nodeName); out.push(">"); out.push("</"); out.push(elem.nodeName); out.push(">");
} else { } else {
@ -732,46 +747,56 @@ function SvgCanvas(c)
changes["y1"] = selected.y1.baseVal.value; changes["y1"] = selected.y1.baseVal.value;
changes["x2"] = selected.x2.baseVal.value; changes["x2"] = selected.x2.baseVal.value;
changes["y2"] = selected.y2.baseVal.value; changes["y2"] = selected.y2.baseVal.value;
var handle = svgroot.suspendRedraw(1000);
selected.x1.baseVal.value = remapx(selected.x1.baseVal.value); selected.x1.baseVal.value = remapx(selected.x1.baseVal.value);
selected.y1.baseVal.value = remapy(selected.y1.baseVal.value); selected.y1.baseVal.value = remapy(selected.y1.baseVal.value);
selected.x2.baseVal.value = remapx(selected.x2.baseVal.value); selected.x2.baseVal.value = remapx(selected.x2.baseVal.value);
selected.y2.baseVal.value = remapy(selected.y2.baseVal.value); selected.y2.baseVal.value = remapy(selected.y2.baseVal.value);
svgroot.unsuspendRedraw(handle);
break; break;
case "circle": case "circle":
changes["cx"] = selected.cx.baseVal.value; changes["cx"] = selected.cx.baseVal.value;
changes["cy"] = selected.cy.baseVal.value; changes["cy"] = selected.cy.baseVal.value;
changes["r"] = selected.r.baseVal.value; changes["r"] = selected.r.baseVal.value;
var handle = svgroot.suspendRedraw(1000);
selected.cx.baseVal.value = remapx(selected.cx.baseVal.value); selected.cx.baseVal.value = remapx(selected.cx.baseVal.value);
selected.cy.baseVal.value = remapy(selected.cy.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 // 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); selected.r.baseVal.value = Math.min(selectedBBox.width/2,selectedBBox.height/2);
svgroot.unsuspendRedraw(handle);
break; break;
case "ellipse": case "ellipse":
changes["cx"] = selected.cx.baseVal.value; changes["cx"] = selected.cx.baseVal.value;
changes["cy"] = selected.cy.baseVal.value; changes["cy"] = selected.cy.baseVal.value;
changes["rx"] = selected.rx.baseVal.value; changes["rx"] = selected.rx.baseVal.value;
changes["ry"] = selected.ry.baseVal.value; changes["ry"] = selected.ry.baseVal.value;
var handle = svgroot.suspendRedraw(1000);
selected.cx.baseVal.value = remapx(selected.cx.baseVal.value); selected.cx.baseVal.value = remapx(selected.cx.baseVal.value);
selected.cy.baseVal.value = remapy(selected.cy.baseVal.value); selected.cy.baseVal.value = remapy(selected.cy.baseVal.value);
selected.rx.baseVal.value = scalew(selected.rx.baseVal.value); selected.rx.baseVal.value = scalew(selected.rx.baseVal.value);
selected.ry.baseVal.value = scaleh(selected.ry.baseVal.value); selected.ry.baseVal.value = scaleh(selected.ry.baseVal.value);
svgroot.unsuspendRedraw(handle);
break; break;
case "text": case "text":
// cannot use x.baseVal.value here because x is a SVGLengthList // cannot use x.baseVal.value here because x is a SVGLengthList
changes["x"] = selected.getAttribute("x"); changes["x"] = selected.getAttribute("x");
changes["y"] = selected.getAttribute("y"); changes["y"] = selected.getAttribute("y");
var handle = svgroot.suspendRedraw(1000);
selected.setAttribute("x", remapx(selected.getAttribute("x"))); selected.setAttribute("x", remapx(selected.getAttribute("x")));
selected.setAttribute("y", remapy(selected.getAttribute("y"))); selected.setAttribute("y", remapy(selected.getAttribute("y")));
svgroot.unsuspendRedraw(handle);
break; break;
case "rect": case "rect":
changes["x"] = selected.x.baseVal.value; changes["x"] = selected.x.baseVal.value;
changes["y"] = selected.y.baseVal.value; changes["y"] = selected.y.baseVal.value;
changes["width"] = selected.width.baseVal.value; changes["width"] = selected.width.baseVal.value;
changes["height"] = selected.height.baseVal.value; changes["height"] = selected.height.baseVal.value;
var handle = svgroot.suspendRedraw(1000);
selected.x.baseVal.value = remapx(selected.x.baseVal.value); selected.x.baseVal.value = remapx(selected.x.baseVal.value);
selected.y.baseVal.value = remapy(selected.y.baseVal.value); selected.y.baseVal.value = remapy(selected.y.baseVal.value);
selected.width.baseVal.value = scalew(selected.width.baseVal.value); selected.width.baseVal.value = scalew(selected.width.baseVal.value);
selected.height.baseVal.value = scaleh(selected.height.baseVal.value); selected.height.baseVal.value = scaleh(selected.height.baseVal.value);
svgroot.unsuspendRedraw(handle);
break; break;
default: // rect default: // rect
console.log("Unknown shape type: " + selected.tagName); console.log("Unknown shape type: " + selected.tagName);
@ -1143,25 +1168,33 @@ function SvgCanvas(c)
selectorManager.requestSelector(selected).resize(selectedBBox); selectorManager.requestSelector(selected).resize(selectedBBox);
break; break;
case "text": case "text":
var handle = svgroot.suspendRedraw(1000);
shape.setAttribute("x", x); shape.setAttribute("x", x);
shape.setAttribute("y", y); shape.setAttribute("y", y);
svgroot.unsuspendRedraw(handle);
break; break;
case "line": case "line":
var handle = svgroot.suspendRedraw(1000);
shape.setAttributeNS(null, "x2", x); shape.setAttributeNS(null, "x2", x);
shape.setAttributeNS(null, "y2", y); shape.setAttributeNS(null, "y2", y);
svgroot.unsuspendRedraw(handle);
break; break;
case "square": case "square":
var size = Math.max( Math.abs(x - start_x), Math.abs(y - start_y) ); 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, "width", size);
shape.setAttributeNS(null, "height", size); shape.setAttributeNS(null, "height", size);
shape.setAttributeNS(null, "x", start_x < x ? start_x : start_x - 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); shape.setAttributeNS(null, "y", start_y < y ? start_y : start_y - size);
svgroot.unsuspendRedraw(handle);
break; break;
case "rect": case "rect":
var handle = svgroot.suspendRedraw(1000);
shape.setAttributeNS(null, "x", Math.min(start_x,x)); shape.setAttributeNS(null, "x", Math.min(start_x,x));
shape.setAttributeNS(null, "y", Math.min(start_y,y)); shape.setAttributeNS(null, "y", Math.min(start_y,y));
shape.setAttributeNS(null, "width", Math.abs(x-start_x)); shape.setAttributeNS(null, "width", Math.abs(x-start_x));
shape.setAttributeNS(null, "height", Math.abs(y-start_y)); shape.setAttributeNS(null, "height", Math.abs(y-start_y));
svgroot.unsuspendRedraw(handle);
break; break;
case "circle": case "circle":
var cx = shape.getAttributeNS(null, "cx"); var cx = shape.getAttributeNS(null, "cx");
@ -1172,8 +1205,10 @@ function SvgCanvas(c)
case "ellipse": case "ellipse":
var cx = shape.getAttributeNS(null, "cx"); var cx = shape.getAttributeNS(null, "cx");
var cy = shape.getAttributeNS(null, "cy"); var cy = shape.getAttributeNS(null, "cy");
var handle = svgroot.suspendRedraw(1000);
shape.setAttributeNS(null, "rx", Math.abs(x - cx) ); shape.setAttributeNS(null, "rx", Math.abs(x - cx) );
shape.setAttributeNS(null, "ry", Math.abs(y - cy) ); shape.setAttributeNS(null, "ry", Math.abs(y - cy) );
svgroot.unsuspendRedraw(handle);
break; break;
case "fhellipse": case "fhellipse":
case "fhrect": case "fhrect":
@ -1406,8 +1441,11 @@ function SvgCanvas(c)
this.setResolution = function(x, y) { this.setResolution = function(x, y) {
var w = svgroot.getAttribute("width"), var w = svgroot.getAttribute("width"),
h = svgroot.getAttribute("height"); h = svgroot.getAttribute("height");
var handle = svgroot.suspendRedraw(1000);
svgroot.setAttribute("width", x); svgroot.setAttribute("width", x);
svgroot.setAttribute("height", y); svgroot.setAttribute("height", y);
svgroot.unsuspendRedraw(handle);
addCommandToHistory(new ChangeElementCommand(svgroot, {"width":w,"height":h}, "resolution")); addCommandToHistory(new ChangeElementCommand(svgroot, {"width":w,"height":h}, "resolution"));
call("changed", [svgroot]); call("changed", [svgroot]);
}; };
@ -1448,6 +1486,120 @@ function SvgCanvas(c)
this.changeSelectedAttribute("fill", val, elems); 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() { this.getStrokeWidth = function() {
return current_stroke_width; return current_stroke_width;
}; };
@ -1608,6 +1760,7 @@ function SvgCanvas(c)
var elems = elems || selectedElements; var elems = elems || selectedElements;
var batchCmd = new BatchCommand("Change " + attr); var batchCmd = new BatchCommand("Change " + attr);
var i = elems.length; var i = elems.length;
var handle = svgroot.suspendRedraw(1000);
while(i--) { while(i--) {
var elem = elems[i]; var elem = elems[i];
if (elem == null) continue; if (elem == null) continue;
@ -1623,6 +1776,7 @@ function SvgCanvas(c)
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes, attr)); batchCmd.addSubCommand(new ChangeElementCommand(elem, changes, attr));
} }
} }
svgroot.unsuspendRedraw(handle);
if (!batchCmd.isEmpty()) { if (!batchCmd.isEmpty()) {
addCommandToHistory(batchCmd); addCommandToHistory(batchCmd);
call("changed", elems); call("changed", elems);
@ -1675,7 +1829,11 @@ function SvgCanvas(c)
var oldParent = t.parentNode; var oldParent = t.parentNode;
var oldNextSibling = t.nextSibling; var oldNextSibling = t.nextSibling;
if (oldNextSibling == selectorManager.selectorParentGroup) oldNextSibling = null; 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")); addCommandToHistory(new MoveElementCommand(t, oldNextSibling, oldParent, "bottom"));
} }
}; };