method_draw 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +148 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/method_draw.js +9 -0
- data/app/assets/javascripts/method_draw/base64.js +95 -0
- data/app/assets/javascripts/method_draw_embed.js +76 -0
- data/app/assets/stylesheets/sketchily.css +6 -0
- data/app/helpers/method_draw_helper.rb +35 -0
- data/app/views/method_draw/_embed.html.erb +51 -0
- data/app/views/method_draw/_method_draw.html.erb +19 -0
- data/app/views/method_draw/_method_draw_tag.html.erb +14 -0
- data/lib/method_draw.rb +16 -0
- data/lib/method_draw/engine.rb +4 -0
- data/lib/method_draw/method_draw.rb +37 -0
- data/lib/method_draw/method_draw_tag.rb +20 -0
- data/lib/method_draw/version.rb +3 -0
- data/spec/app/helpers/method_draw_helper_spec.rb +8 -0
- data/spec/dummy/README.md +3 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/drawings_controller.rb +18 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/drawing.rb +2 -0
- data/spec/dummy/app/views/drawings/method_draw.html.erb +3 -0
- data/spec/dummy/app/views/drawings/method_draw_tag.html.erb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +27 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +8 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/0_create_drawings.rb +7 -0
- data/spec/dummy/db/schema.rb +20 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +922 -0
- data/spec/dummy/log/test.log +181 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/01e63791dcd008779246d1eeeace9408 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/061f36c32f08daef6eca93b74eaf74fd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1dbfe77fba798ba3dc24571c3b6d7eed +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/1fd7477d83ec1798c2bc740be42bd6b2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/203471220004cb0cc667b886fb87dc46 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/213e12fc648032455ca0b118e987cca6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/296bbe63b0505bc5be472fc1c8a1a5fd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3239b44c026d7c1646c17a10c72905bf +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/38c8fbf05056bbe66399b6923521dc20 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/3e30c8cfdf7deeda4607e4a8298f09a5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/4bdd61ba53e8d9b7c19afea13c6e8985 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/52b0b11efea48f1fe5e46eeb4aa20193 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/5ef314d6f1af1570631d60b7f9a96d6c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6215f00c593e1789ef865a545b17fc14 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/624fdd5478edd235a86af4b6168d0f75 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6299190ac3952cf7eee042e60c9aee89 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/62a95a2d67ec78570de6d0b31436206a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/65ed942dea29700b739c2292791eb65e +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/66eb709561f77a29885af4423a3eb193 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/6f8f2c21bc49ae5ebad6e8a96cea4fe6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/85dab60ed9ec9625b7ee22d4342fe26c +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/86358bce0bfd5de6ac8afb1bfa9d675b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8b835ce894c1218dea1e7c83a9109d2d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8e177cc7106653a1e053bb2444bb43a5 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/8f41435d82ae4df55ae7dfdc1e99b0bb +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/94be0a0bca76437d0766c265a9cdecda +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/9a093e6973aa150a0a4388167364593d +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/a280ac195f56a87267d2ec5d3e22ebcd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b13cddebc9106da6cfaf949ab3856d1f +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/b29ac216cb03ce2f30655a0d9bed77d4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c39d32e3ef6cc89f9c522212e65c49e1 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/c9910a0652952be02900dc71594d4384 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cb14e22baac3ab2cc947628f283e117b +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d1475c156face9f06092c9cf89905372 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d22aa5a4d864d00cced2437352fe8fe4 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d46cc5e60d1b2a20d622cdf9bab35fad +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d7f27a7f35278e87c69668a65683360a +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e0080336bb31d78e9efab59b234e0d85 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e06104d99b055e792effca7bd66ad384 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e095df19da361d5f53d90f6749a38ea6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e5fb97d39fdd2e383e61115ef06079fd +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/e6d1ec9817258cfda7c68499a841a9d2 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/edec019e8f1d7e758eb45524a913fd47 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f37cf330dccb15bee2a195f643f3ba29 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/fc84011813992cacde5880c6b21701de +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/061f36c32f08daef6eca93b74eaf74fd +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/38c8fbf05056bbe66399b6923521dc20 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/3e30c8cfdf7deeda4607e4a8298f09a5 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/52b0b11efea48f1fe5e46eeb4aa20193 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/5ef314d6f1af1570631d60b7f9a96d6c +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/6299190ac3952cf7eee042e60c9aee89 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/62a95a2d67ec78570de6d0b31436206a +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/65ed942dea29700b739c2292791eb65e +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/85dab60ed9ec9625b7ee22d4342fe26c +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/a280ac195f56a87267d2ec5d3e22ebcd +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cb14e22baac3ab2cc947628f283e117b +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d1475c156face9f06092c9cf89905372 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/e0080336bb31d78e9efab59b234e0d85 +0 -0
- data/spec/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/features/method_draw_spec.rb +10 -0
- data/spec/features/method_draw_tag_spec.rb +11 -0
- data/spec/lib/method_draw/method_draw_spec.rb +27 -0
- data/spec/lib/method_draw/method_draw_tag_spec.rb +19 -0
- data/spec/lib/method_draw_spec.rb +11 -0
- data/spec/test_helper.rb +24 -0
- data/vendor/assets/javascripts/method-draw-js/browser-not-supported.html +27 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Anivers-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Anivers-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Anivers-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Arvo-Regular-webfont.svg +145 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Arvo-Regular-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Junction-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Junction-webfont.svg +133 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Junction-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Junction-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/League_Gothic-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/League_Gothic-webfont.svg +235 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/League_Gothic-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/League_Gothic-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Museo_Slab-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Museo_Slab-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Museo_Slab-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Museo_Slab_Italic-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Museo_Slab_Italic-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/Museo_Slab_Italic-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/arvo-bold-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/arvo-bolditalic-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/arvo-italic-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/arvo-regular-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/euphoriascript-regular-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood-webfont.svg +939 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood_italic-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood_italic-webfont.svg +682 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood_italic-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fanwood_italic-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fertigo-webfont.eot +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fertigo-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/fertigo-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/oswald-bold-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/oswald-light-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/shadowsintolight-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/simonetta-black-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/simonetta-blackitalic-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/simonetta-italic-webfont.ttf +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/simonetta-regular-webfont.woff +0 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/test.html +62 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/test.svg +15 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/test_ff.svg +16 -0
- data/vendor/assets/javascripts/method-draw-js/css/font-files/test_ffsvg.svg +13 -0
- data/vendor/assets/javascripts/method-draw-js/css/fonts.css +72 -0
- data/vendor/assets/javascripts/method-draw-js/css/method-draw.compiled.css +417 -0
- data/vendor/assets/javascripts/method-draw-js/css/method-draw.css +2083 -0
- data/vendor/assets/javascripts/method-draw-js/embedapi.html +56 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/closepath_icons.svg +41 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-arrows.js +298 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-closepath.js +92 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-connector.js +587 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-eyedropper.js +135 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-foreignobject.js +277 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-grid.js +186 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-helloworld.js +78 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-imagelib.js +444 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-imagelib.xml +14 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-markers.js +576 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-server_moinsave.js +56 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-server_opensave.js +180 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-shapes.js +358 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-shapes.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/ext-shapes.xml +8 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/eyedropper-icon.xml +17 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/eyedropper.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/eyedropper.svg +15 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/fileopen.php +31 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/filesave.php +44 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/foreignobject-icons.xml +96 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/grid-icon.xml +30 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/helloworld-icon.xml +21 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/imagelib/index.html +64 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/imagelib/smiley.svg +12 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/markers-icons.xml +115 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib.svg +10 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/arrow.json +40 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/dialog_balloon.json +14 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/flowchart.json +20 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/game.json +13 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/math.json +8 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/misc.json +6 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/music.json +21 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/nature.json +36 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/object.json +30 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/raphael.txt +12 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/raphael_1.json +7 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/social.json +21 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/symbol.json +35 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/ui.json +57 -0
- data/vendor/assets/javascripts/method-draw-js/extensions/shapelib/weather.json +26 -0
- data/vendor/assets/javascripts/method-draw-js/icons/jquery.svgicons.js +471 -0
- data/vendor/assets/javascripts/method-draw-js/images/AlphaBar.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/Bars.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/Maps.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/NoColor.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/README.txt +61 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-bottom.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-bottom.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-center.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-center.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-left.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-left.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-middle.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-middle.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-right.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-right.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-top.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/align-top.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/bar-opacity.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/bold.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/cancel.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/circle.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/clear.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/clone.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/conn.svg +29 -0
- data/vendor/assets/javascripts/method-draw-js/images/copy.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/cross.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/cut.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/delete.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/document-properties.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/drag.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/dragging.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/dropdown.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/ellipse.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/ellipse.svg +8 -0
- data/vendor/assets/javascripts/method-draw-js/images/eye.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/eye.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/eyedropper.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/eyedropper_tool.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/fhpath.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/flyouth.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/flyup.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/freehand-circle.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/freehand-square.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/go-down.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/go-up.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/image.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/image.svg +12 -0
- data/vendor/assets/javascripts/method-draw-js/images/italic.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/italic.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/line.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/link_controls.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/logo.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/map-opacity.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/mappoint.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/mappoint_c.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/mappoint_f.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/move_bottom.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/move_top.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/node_clone.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/node_delete.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/none.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/open.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/paste.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/path.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/path.svg +10 -0
- data/vendor/assets/javascripts/method-draw-js/images/pencil.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/pencil.svg +11 -0
- data/vendor/assets/javascripts/method-draw-js/images/pencil_cursor.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/picker.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/placeholder.svg +10 -0
- data/vendor/assets/javascripts/method-draw-js/images/polygon.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/polygon.svg +1 -0
- data/vendor/assets/javascripts/method-draw-js/images/preview-opacity.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/rangearrows.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/rangearrows2.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/rect.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/redo.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/reorient.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/rotate.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/save.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/select.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/select.svg +10 -0
- data/vendor/assets/javascripts/method-draw-js/images/select_node.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/sep.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/shape_group.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/shape_ungroup.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/source.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/spinbtn_updn_big.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/square.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/svg_edit_icons.svg +455 -0
- data/vendor/assets/javascripts/method-draw-js/images/svg_edit_icons.svgz +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/text.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/text.svg +10 -0
- data/vendor/assets/javascripts/method-draw-js/images/to_path.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/undo.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/view-refresh.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/wave.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/wireframe.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/zoom.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/images/zoom.svg +12 -0
- data/vendor/assets/javascripts/method-draw-js/index.html +631 -0
- data/vendor/assets/javascripts/method-draw-js/lib/canvg/canvg.js +2620 -0
- data/vendor/assets/javascripts/method-draw-js/lib/canvg/rgbcolor.js +287 -0
- data/vendor/assets/javascripts/method-draw-js/lib/contextmenu.js +68 -0
- data/vendor/assets/javascripts/method-draw-js/lib/contextmenu/jquery.contextMenu.js +223 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/LICENSE +202 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/README +3 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/css/jPicker.css +250 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/css/jgraduate.css +332 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/AlphaBar.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/Bars.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/Maps.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/NoColor.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/bar-opacity.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/eyedropper.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/map-opacity.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/mappoint.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/mappoint_c.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/mappoint_f.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/picker.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/preview-opacity.png +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/rangearrows.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/images/rangearrows2.gif +0 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/jpicker.min.js +2087 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/jquery.jgraduate.js +1175 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jgraduate/jquery.jgraduate.min.js +37 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jquery-draginput.js +181 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jquery-ui/jquery-ui-1.8.17.custom.min.js +54 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jquery-ui/jquery-ui-1.8.custom.min.js +84 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jquery.js +2 -0
- data/vendor/assets/javascripts/method-draw-js/lib/jquerybbq/jquery.bbq.min.js +18 -0
- data/vendor/assets/javascripts/method-draw-js/lib/js-hotkeys/README.md +45 -0
- data/vendor/assets/javascripts/method-draw-js/lib/js-hotkeys/jquery.hotkeys.min.js +15 -0
- data/vendor/assets/javascripts/method-draw-js/lib/mousewheel.js +84 -0
- data/vendor/assets/javascripts/method-draw-js/lib/requestanimationframe.js +24 -0
- data/vendor/assets/javascripts/method-draw-js/lib/taphold.js +136 -0
- data/vendor/assets/javascripts/method-draw-js/lib/touch.js +28 -0
- data/vendor/assets/javascripts/method-draw-js/method-draw.compiled.css +417 -0
- data/vendor/assets/javascripts/method-draw-js/method-draw.compiled.js +692 -0
- data/vendor/assets/javascripts/method-draw-js/method-draw.manifest +121 -0
- data/vendor/assets/javascripts/method-draw-js/src/browser.js +181 -0
- data/vendor/assets/javascripts/method-draw-js/src/dialog.js +49 -0
- data/vendor/assets/javascripts/method-draw-js/src/dragupload.js +11 -0
- data/vendor/assets/javascripts/method-draw-js/src/draw.js +533 -0
- data/vendor/assets/javascripts/method-draw-js/src/embedapi.js +173 -0
- data/vendor/assets/javascripts/method-draw-js/src/history.js +601 -0
- data/vendor/assets/javascripts/method-draw-js/src/math.js +247 -0
- data/vendor/assets/javascripts/method-draw-js/src/method-draw.js +4140 -0
- data/vendor/assets/javascripts/method-draw-js/src/path.js +979 -0
- data/vendor/assets/javascripts/method-draw-js/src/sanitize.js +273 -0
- data/vendor/assets/javascripts/method-draw-js/src/select.js +608 -0
- data/vendor/assets/javascripts/method-draw-js/src/svgcanvas.js +9047 -0
- data/vendor/assets/javascripts/method-draw-js/src/svgtransformlist.js +291 -0
- data/vendor/assets/javascripts/method-draw-js/src/svgutils.js +648 -0
- data/vendor/assets/javascripts/method-draw-js/src/units.js +281 -0
- data/vendor/assets/javascripts/method-draw-js/svgedit.compiled.css +417 -0
- data/vendor/assets/javascripts/method-draw-js/svgedit.compiled.js +691 -0
- data/vendor/assets/javascripts/method-draw-js/temp.css +2665 -0
- metadata +619 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package: svedit.math
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2
|
|
5
|
+
*
|
|
6
|
+
* Copyright(c) 2010 Alexis Deveria
|
|
7
|
+
* Copyright(c) 2010 Jeff Schiller
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Dependencies:
|
|
11
|
+
// None.
|
|
12
|
+
|
|
13
|
+
var svgedit = svgedit || {};
|
|
14
|
+
|
|
15
|
+
(function() {
|
|
16
|
+
|
|
17
|
+
if (!svgedit.math) {
|
|
18
|
+
svgedit.math = {};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Constants
|
|
22
|
+
var NEAR_ZERO = 1e-14;
|
|
23
|
+
|
|
24
|
+
// Throw away SVGSVGElement used for creating matrices/transforms.
|
|
25
|
+
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
26
|
+
|
|
27
|
+
// Function: svgedit.math.transformPoint
|
|
28
|
+
// A (hopefully) quicker function to transform a point by a matrix
|
|
29
|
+
// (this function avoids any DOM calls and just does the math)
|
|
30
|
+
//
|
|
31
|
+
// Parameters:
|
|
32
|
+
// x - Float representing the x coordinate
|
|
33
|
+
// y - Float representing the y coordinate
|
|
34
|
+
// m - Matrix object to transform the point with
|
|
35
|
+
// Returns a x,y object representing the transformed point
|
|
36
|
+
svgedit.math.transformPoint = function(x, y, m) {
|
|
37
|
+
return { x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
// Function: svgedit.math.isIdentity
|
|
42
|
+
// Helper function to check if the matrix performs no actual transform
|
|
43
|
+
// (i.e. exists for identity purposes)
|
|
44
|
+
//
|
|
45
|
+
// Parameters:
|
|
46
|
+
// m - The matrix object to check
|
|
47
|
+
//
|
|
48
|
+
// Returns:
|
|
49
|
+
// Boolean indicating whether or not the matrix is 1,0,0,1,0,0
|
|
50
|
+
svgedit.math.isIdentity = function(m) {
|
|
51
|
+
return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
// Function: svgedit.math.matrixMultiply
|
|
56
|
+
// This function tries to return a SVGMatrix that is the multiplication m1*m2.
|
|
57
|
+
// We also round to zero when it's near zero
|
|
58
|
+
//
|
|
59
|
+
// Parameters:
|
|
60
|
+
// >= 2 Matrix objects to multiply
|
|
61
|
+
//
|
|
62
|
+
// Returns:
|
|
63
|
+
// The matrix object resulting from the calculation
|
|
64
|
+
svgedit.math.matrixMultiply = function() {
|
|
65
|
+
var args = arguments, i = args.length, m = args[i-1];
|
|
66
|
+
|
|
67
|
+
while(i-- > 1) {
|
|
68
|
+
var m1 = args[i-1];
|
|
69
|
+
m = m1.multiply(m);
|
|
70
|
+
}
|
|
71
|
+
if (Math.abs(m.a) < NEAR_ZERO) m.a = 0;
|
|
72
|
+
if (Math.abs(m.b) < NEAR_ZERO) m.b = 0;
|
|
73
|
+
if (Math.abs(m.c) < NEAR_ZERO) m.c = 0;
|
|
74
|
+
if (Math.abs(m.d) < NEAR_ZERO) m.d = 0;
|
|
75
|
+
if (Math.abs(m.e) < NEAR_ZERO) m.e = 0;
|
|
76
|
+
if (Math.abs(m.f) < NEAR_ZERO) m.f = 0;
|
|
77
|
+
|
|
78
|
+
return m;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Function: svgedit.math.hasMatrixTransform
|
|
82
|
+
// See if the given transformlist includes a non-indentity matrix transform
|
|
83
|
+
//
|
|
84
|
+
// Parameters:
|
|
85
|
+
// tlist - The transformlist to check
|
|
86
|
+
//
|
|
87
|
+
// Returns:
|
|
88
|
+
// Boolean on whether or not a matrix transform was found
|
|
89
|
+
svgedit.math.hasMatrixTransform = function(tlist) {
|
|
90
|
+
if(!tlist) return false;
|
|
91
|
+
var num = tlist.numberOfItems;
|
|
92
|
+
while (num--) {
|
|
93
|
+
var xform = tlist.getItem(num);
|
|
94
|
+
if (xform.type == 1 && !svgedit.math.isIdentity(xform.matrix)) return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// Function: svgedit.math.transformBox
|
|
100
|
+
// Transforms a rectangle based on the given matrix
|
|
101
|
+
//
|
|
102
|
+
// Parameters:
|
|
103
|
+
// l - Float with the box's left coordinate
|
|
104
|
+
// t - Float with the box's top coordinate
|
|
105
|
+
// w - Float with the box width
|
|
106
|
+
// h - Float with the box height
|
|
107
|
+
// m - Matrix object to transform the box by
|
|
108
|
+
//
|
|
109
|
+
// Returns:
|
|
110
|
+
// An object with the following values:
|
|
111
|
+
// * tl - The top left coordinate (x,y object)
|
|
112
|
+
// * tr - The top right coordinate (x,y object)
|
|
113
|
+
// * bl - The bottom left coordinate (x,y object)
|
|
114
|
+
// * br - The bottom right coordinate (x,y object)
|
|
115
|
+
// * aabox - Object with the following values:
|
|
116
|
+
// * Float with the axis-aligned x coordinate
|
|
117
|
+
// * Float with the axis-aligned y coordinate
|
|
118
|
+
// * Float with the axis-aligned width coordinate
|
|
119
|
+
// * Float with the axis-aligned height coordinate
|
|
120
|
+
svgedit.math.transformBox = function(l, t, w, h, m) {
|
|
121
|
+
var topleft = {x:l,y:t},
|
|
122
|
+
topright = {x:(l+w),y:t},
|
|
123
|
+
botright = {x:(l+w),y:(t+h)},
|
|
124
|
+
botleft = {x:l,y:(t+h)};
|
|
125
|
+
var transformPoint = svgedit.math.transformPoint;
|
|
126
|
+
topleft = transformPoint( topleft.x, topleft.y, m );
|
|
127
|
+
var minx = topleft.x,
|
|
128
|
+
maxx = topleft.x,
|
|
129
|
+
miny = topleft.y,
|
|
130
|
+
maxy = topleft.y;
|
|
131
|
+
topright = transformPoint( topright.x, topright.y, m );
|
|
132
|
+
minx = Math.min(minx, topright.x);
|
|
133
|
+
maxx = Math.max(maxx, topright.x);
|
|
134
|
+
miny = Math.min(miny, topright.y);
|
|
135
|
+
maxy = Math.max(maxy, topright.y);
|
|
136
|
+
botleft = transformPoint( botleft.x, botleft.y, m);
|
|
137
|
+
minx = Math.min(minx, botleft.x);
|
|
138
|
+
maxx = Math.max(maxx, botleft.x);
|
|
139
|
+
miny = Math.min(miny, botleft.y);
|
|
140
|
+
maxy = Math.max(maxy, botleft.y);
|
|
141
|
+
botright = transformPoint( botright.x, botright.y, m );
|
|
142
|
+
minx = Math.min(minx, botright.x);
|
|
143
|
+
maxx = Math.max(maxx, botright.x);
|
|
144
|
+
miny = Math.min(miny, botright.y);
|
|
145
|
+
maxy = Math.max(maxy, botright.y);
|
|
146
|
+
|
|
147
|
+
return {tl:topleft, tr:topright, bl:botleft, br:botright,
|
|
148
|
+
aabox: {x:minx, y:miny, width:(maxx-minx), height:(maxy-miny)} };
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Function: svgedit.math.transformListToTransform
|
|
152
|
+
// This returns a single matrix Transform for a given Transform List
|
|
153
|
+
// (this is the equivalent of SVGTransformList.consolidate() but unlike
|
|
154
|
+
// that method, this one does not modify the actual SVGTransformList)
|
|
155
|
+
// This function is very liberal with its min,max arguments
|
|
156
|
+
//
|
|
157
|
+
// Parameters:
|
|
158
|
+
// tlist - The transformlist object
|
|
159
|
+
// min - Optional integer indicating start transform position
|
|
160
|
+
// max - Optional integer indicating end transform position
|
|
161
|
+
//
|
|
162
|
+
// Returns:
|
|
163
|
+
// A single matrix transform object
|
|
164
|
+
svgedit.math.transformListToTransform = function(tlist, min, max) {
|
|
165
|
+
if(tlist == null) {
|
|
166
|
+
// Or should tlist = null have been prevented before this?
|
|
167
|
+
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix());
|
|
168
|
+
}
|
|
169
|
+
var min = min == undefined ? 0 : min;
|
|
170
|
+
var max = max == undefined ? (tlist.numberOfItems-1) : max;
|
|
171
|
+
min = parseInt(min);
|
|
172
|
+
max = parseInt(max);
|
|
173
|
+
if (min > max) { var temp = max; max = min; min = temp; }
|
|
174
|
+
var m = svg.createSVGMatrix();
|
|
175
|
+
for (var i = min; i <= max; ++i) {
|
|
176
|
+
// if our indices are out of range, just use a harmless identity matrix
|
|
177
|
+
var mtom = (i >= 0 && i < tlist.numberOfItems ?
|
|
178
|
+
tlist.getItem(i).matrix :
|
|
179
|
+
svg.createSVGMatrix());
|
|
180
|
+
m = svgedit.math.matrixMultiply(m, mtom);
|
|
181
|
+
}
|
|
182
|
+
return svg.createSVGTransformFromMatrix(m);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
// Function: svgedit.math.getMatrix
|
|
187
|
+
// Get the matrix object for a given element
|
|
188
|
+
//
|
|
189
|
+
// Parameters:
|
|
190
|
+
// elem - The DOM element to check
|
|
191
|
+
//
|
|
192
|
+
// Returns:
|
|
193
|
+
// The matrix object associated with the element's transformlist
|
|
194
|
+
svgedit.math.getMatrix = function(elem) {
|
|
195
|
+
var tlist = svgedit.transformlist.getTransformList(elem);
|
|
196
|
+
return svgedit.math.transformListToTransform(tlist).matrix;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
// Function: svgedit.math.snapToAngle
|
|
201
|
+
// Returns a 45 degree angle coordinate associated with the two given
|
|
202
|
+
// coordinates
|
|
203
|
+
//
|
|
204
|
+
// Parameters:
|
|
205
|
+
// x1 - First coordinate's x value
|
|
206
|
+
// x2 - Second coordinate's x value
|
|
207
|
+
// y1 - First coordinate's y value
|
|
208
|
+
// y2 - Second coordinate's y value
|
|
209
|
+
//
|
|
210
|
+
// Returns:
|
|
211
|
+
// Object with the following values:
|
|
212
|
+
// x - The angle-snapped x value
|
|
213
|
+
// y - The angle-snapped y value
|
|
214
|
+
// snapangle - The angle at which to snap
|
|
215
|
+
svgedit.math.snapToAngle = function(x1,y1,x2,y2) {
|
|
216
|
+
var snap = Math.PI/4; // 45 degrees
|
|
217
|
+
var dx = x2 - x1;
|
|
218
|
+
var dy = y2 - y1;
|
|
219
|
+
var angle = Math.atan2(dy,dx);
|
|
220
|
+
var dist = Math.sqrt(dx * dx + dy * dy);
|
|
221
|
+
var snapangle= Math.round(angle/snap)*snap;
|
|
222
|
+
var x = x1 + dist*Math.cos(snapangle);
|
|
223
|
+
var y = y1 + dist*Math.sin(snapangle);
|
|
224
|
+
//console.log(x1,y1,x2,y2,x,y,angle)
|
|
225
|
+
return {x:x, y:y, a:snapangle};
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
// Function: rectsIntersect
|
|
230
|
+
// Check if two rectangles (BBoxes objects) intersect each other
|
|
231
|
+
//
|
|
232
|
+
// Paramaters:
|
|
233
|
+
// r1 - The first BBox-like object
|
|
234
|
+
// r2 - The second BBox-like object
|
|
235
|
+
//
|
|
236
|
+
// Returns:
|
|
237
|
+
// Boolean that's true if rectangles intersect
|
|
238
|
+
svgedit.math.rectsIntersect = function(r1, r2) {
|
|
239
|
+
if (!r1 || !r2) return false;
|
|
240
|
+
return r2.x < (r1.x+r1.width) &&
|
|
241
|
+
(r2.x+r2.width) > r1.x &&
|
|
242
|
+
r2.y < (r1.y+r1.height) &&
|
|
243
|
+
(r2.y+r2.height) > r1.y;
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
})();
|
|
@@ -0,0 +1,4140 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* svg-editor.js
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the MIT License
|
|
5
|
+
*
|
|
6
|
+
* Copyright(c) 2010 Alexis Deveria
|
|
7
|
+
* Copyright(c) 2010 Pavol Rusnak
|
|
8
|
+
* Copyright(c) 2010 Jeff Schiller
|
|
9
|
+
* Copyright(c) 2010 Narendra Sisodiya
|
|
10
|
+
* Copyright(c) 2012 Mark MacKay
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Dependencies:
|
|
15
|
+
// 1) units.js
|
|
16
|
+
// 2) browser.js
|
|
17
|
+
// 3) svgcanvas.js
|
|
18
|
+
|
|
19
|
+
(function() {
|
|
20
|
+
|
|
21
|
+
document.addEventListener("touchstart", touchHandler, true);
|
|
22
|
+
document.addEventListener("touchmove", touchHandler, true);
|
|
23
|
+
document.addEventListener("touchend", touchHandler, true);
|
|
24
|
+
document.addEventListener("touchcancel", touchHandler, true);
|
|
25
|
+
|
|
26
|
+
if(!window.methodDraw) window.methodDraw = function($) {
|
|
27
|
+
var svgCanvas;
|
|
28
|
+
var Editor = {};
|
|
29
|
+
var is_ready = false;
|
|
30
|
+
curConfig = {
|
|
31
|
+
canvas_expansion: 1,
|
|
32
|
+
dimensions: [580,400],
|
|
33
|
+
initFill: {color: 'fff', opacity: 1},
|
|
34
|
+
initStroke: {width: 1.5, color: '000', opacity: 1},
|
|
35
|
+
initOpacity: 1,
|
|
36
|
+
imgPath: 'images/',
|
|
37
|
+
extPath: 'extensions/',
|
|
38
|
+
jGraduatePath: 'jgraduate/images/',
|
|
39
|
+
extensions: [],
|
|
40
|
+
initTool: 'select',
|
|
41
|
+
wireframe: false,
|
|
42
|
+
colorPickerCSS: false,
|
|
43
|
+
gridSnapping: false,
|
|
44
|
+
gridColor: "#000",
|
|
45
|
+
baseUnit: 'px',
|
|
46
|
+
snappingStep: 10,
|
|
47
|
+
showRulers: (svgedit.browser.isTouch()) ? false : true,
|
|
48
|
+
show_outside_canvas: false,
|
|
49
|
+
no_save_warning: true,
|
|
50
|
+
initFont: 'Helvetica, Arial, sans-serif'
|
|
51
|
+
},
|
|
52
|
+
uiStrings = Editor.uiStrings = {
|
|
53
|
+
common: {
|
|
54
|
+
"ok":"OK",
|
|
55
|
+
"cancel":"Cancel",
|
|
56
|
+
"key_up":"Up",
|
|
57
|
+
"key_down":"Down",
|
|
58
|
+
"key_backspace":"Backspace",
|
|
59
|
+
"key_del":"Del"
|
|
60
|
+
|
|
61
|
+
},
|
|
62
|
+
// This is needed if the locale is English, since the locale strings are not read in that instance.
|
|
63
|
+
layers: {
|
|
64
|
+
"layer":"Layer"
|
|
65
|
+
},
|
|
66
|
+
notification: {
|
|
67
|
+
"invalidAttrValGiven":"Invalid value given",
|
|
68
|
+
"noContentToFitTo":"No content to fit to",
|
|
69
|
+
"dupeLayerName":"There is already a layer named that!",
|
|
70
|
+
"enterUniqueLayerName":"Please enter a unique layer name",
|
|
71
|
+
"enterNewLayerName":"Please enter the new layer name",
|
|
72
|
+
"layerHasThatName":"Layer already has that name",
|
|
73
|
+
"QmoveElemsToLayer":"Move selected elements to layer \"%s\"?",
|
|
74
|
+
"QwantToClear":"<strong>Do you want to clear the drawing?</strong>\nThis will also erase your undo history",
|
|
75
|
+
"QwantToOpen":"Do you want to open a new file?\nThis will also erase your undo history",
|
|
76
|
+
"QerrorsRevertToSource":"There were parsing errors in your SVG source.\nRevert back to original SVG source?",
|
|
77
|
+
"QignoreSourceChanges":"Ignore changes made to SVG source?",
|
|
78
|
+
"featNotSupported":"Feature not supported",
|
|
79
|
+
"enterNewImgURL":"Enter the new image URL",
|
|
80
|
+
"defsFailOnSave": "NOTE: Due to a bug in your browser, this image may appear wrong (missing gradients or elements). It will however appear correct once actually saved.",
|
|
81
|
+
"loadingImage":"Loading image, please wait...",
|
|
82
|
+
"saveFromBrowser": "Select \"Save As...\" in your browser to save this image as a %s file.",
|
|
83
|
+
"noteTheseIssues": "Also note the following issues: ",
|
|
84
|
+
"unsavedChanges": "There are unsaved changes.",
|
|
85
|
+
"enterNewLinkURL": "Enter the new hyperlink URL",
|
|
86
|
+
"errorLoadingSVG": "Error: Unable to load SVG data",
|
|
87
|
+
"URLloadFail": "Unable to load from URL",
|
|
88
|
+
"retrieving": 'Retrieving "%s" ...'
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
var curPrefs = {}; //$.extend({}, defaultPrefs);
|
|
94
|
+
var customHandlers = {};
|
|
95
|
+
Editor.curConfig = curConfig;
|
|
96
|
+
Editor.tool_scale = 1;
|
|
97
|
+
|
|
98
|
+
Editor.setConfig = function(opts) {
|
|
99
|
+
$.extend(true, curConfig, opts);
|
|
100
|
+
if(opts.extensions) {
|
|
101
|
+
curConfig.extensions = opts.extensions;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Extension mechanisms must call setCustomHandlers with two functions: opts.open and opts.save
|
|
106
|
+
// opts.open's responsibilities are:
|
|
107
|
+
// - invoke a file chooser dialog in 'open' mode
|
|
108
|
+
// - let user pick a SVG file
|
|
109
|
+
// - calls setCanvas.setSvgString() with the string contents of that file
|
|
110
|
+
// opts.save's responsibilities are:
|
|
111
|
+
// - accept the string contents of the current document
|
|
112
|
+
// - invoke a file chooser dialog in 'save' mode
|
|
113
|
+
// - save the file to location chosen by the user
|
|
114
|
+
Editor.setCustomHandlers = function(opts) {
|
|
115
|
+
Editor.ready(function() {
|
|
116
|
+
if(opts.open) {
|
|
117
|
+
$('#tool_open > input[type="file"]').remove();
|
|
118
|
+
$('#tool_open').show();
|
|
119
|
+
svgCanvas.open = opts.open;
|
|
120
|
+
}
|
|
121
|
+
if(opts.save) {
|
|
122
|
+
Editor.show_save_warning = false;
|
|
123
|
+
svgCanvas.bind("saved", opts.save);
|
|
124
|
+
}
|
|
125
|
+
if(opts.pngsave) {
|
|
126
|
+
svgCanvas.bind("exported", opts.pngsave);
|
|
127
|
+
}
|
|
128
|
+
customHandlers = opts;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
Editor.randomizeIds = function() {
|
|
133
|
+
svgCanvas.randomizeIds(arguments)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
Editor.init = function() {
|
|
137
|
+
// For external openers
|
|
138
|
+
(function() {
|
|
139
|
+
// let the opener know SVG Edit is ready
|
|
140
|
+
var w = window.opener;
|
|
141
|
+
if (w) {
|
|
142
|
+
try {
|
|
143
|
+
var methodDrawReadyEvent = w.document.createEvent("Event");
|
|
144
|
+
methodDrawReadyEvent.initEvent("methodDrawReady", true, true);
|
|
145
|
+
w.document.documentElement.dispatchEvent(methodDrawReadyEvent);
|
|
146
|
+
}
|
|
147
|
+
catch(e) {}
|
|
148
|
+
}
|
|
149
|
+
})();
|
|
150
|
+
|
|
151
|
+
(function() {
|
|
152
|
+
$("body").toggleClass("touch", svgedit.browser.isTouch());
|
|
153
|
+
// Load config/data from URL if given
|
|
154
|
+
var urldata = $.deparam.querystring(true);
|
|
155
|
+
if(!$.isEmptyObject(urldata)) {
|
|
156
|
+
if(urldata.dimensions) {
|
|
157
|
+
urldata.dimensions = urldata.dimensions.split(',');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if(urldata.extensions) {
|
|
161
|
+
urldata.extensions = urldata.extensions.split(',');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if(urldata.bkgd_color) {
|
|
165
|
+
urldata.bkgd_color = '#' + urldata.bkgd_color;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
methodDraw.setConfig(urldata);
|
|
169
|
+
|
|
170
|
+
var src = urldata.source;
|
|
171
|
+
var qstr = $.param.querystring();
|
|
172
|
+
|
|
173
|
+
if(!src) { // urldata.source may have been null if it ended with '='
|
|
174
|
+
if(qstr.indexOf('source=data:') >= 0) {
|
|
175
|
+
src = qstr.match(/source=(data:[^&]*)/)[1];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if(src) {
|
|
180
|
+
if(src.indexOf("data:") === 0) {
|
|
181
|
+
// plusses get replaced by spaces, so re-insert
|
|
182
|
+
src = src.replace(/ /g, "+");
|
|
183
|
+
Editor.loadFromDataURI(src);
|
|
184
|
+
} else {
|
|
185
|
+
Editor.loadFromString(src);
|
|
186
|
+
}
|
|
187
|
+
} else if(qstr.indexOf('paramurl=') !== -1) {
|
|
188
|
+
// Get paramater URL (use full length of remaining location.href)
|
|
189
|
+
methodDraw.loadFromURL(qstr.substr(9));
|
|
190
|
+
} else if(urldata.url) {
|
|
191
|
+
methodDraw.loadFromURL(urldata.url);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
})();
|
|
195
|
+
|
|
196
|
+
$("#canvas_width").val(curConfig.dimensions[0]);
|
|
197
|
+
$("#canvas_height").val(curConfig.dimensions[1]);
|
|
198
|
+
|
|
199
|
+
var extFunc = function() {
|
|
200
|
+
$.each(curConfig.extensions, function() {
|
|
201
|
+
var extname = this;
|
|
202
|
+
$.getScript(curConfig.extPath + extname, function(d) {
|
|
203
|
+
// Fails locally in Chrome 5
|
|
204
|
+
if(!d) {
|
|
205
|
+
var s = document.createElement('script');
|
|
206
|
+
s.src = curConfig.extPath + extname;
|
|
207
|
+
document.querySelector('head').appendChild(s);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Load extensions
|
|
214
|
+
// Bit of a hack to run extensions in local Opera/IE9
|
|
215
|
+
if(document.location.protocol === 'file:') {
|
|
216
|
+
setTimeout(extFunc, 100);
|
|
217
|
+
} else {
|
|
218
|
+
extFunc();
|
|
219
|
+
}
|
|
220
|
+
$.svgIcons(curConfig.imgPath + 'svg_edit_icons.svg', {
|
|
221
|
+
w:27, h:27,
|
|
222
|
+
id_match: false,
|
|
223
|
+
no_img: true, // Opera & Firefox 4 gives odd behavior w/images
|
|
224
|
+
fallback_path: curConfig.imgPath,
|
|
225
|
+
fallback:{
|
|
226
|
+
'logo':'logo.png',
|
|
227
|
+
'select':'select.png',
|
|
228
|
+
'select_node':'select_node.png',
|
|
229
|
+
'pencil':'pencil.png',
|
|
230
|
+
'pen':'line.png',
|
|
231
|
+
'rect':'square.png',
|
|
232
|
+
'ellipse':'ellipse.png',
|
|
233
|
+
'path':'path.png',
|
|
234
|
+
'text':'text.png',
|
|
235
|
+
'image':'image.png',
|
|
236
|
+
'zoom':'zoom.png',
|
|
237
|
+
'delete':'delete.png',
|
|
238
|
+
'spapelib':'shapelib.png',
|
|
239
|
+
'node_delete':'node_delete.png',
|
|
240
|
+
'align_left':'align-left.png',
|
|
241
|
+
'align_center':'align-center.png',
|
|
242
|
+
'align_right':'align-right.png',
|
|
243
|
+
'align_top':'align-top.png',
|
|
244
|
+
'align_middle':'align-middle.png',
|
|
245
|
+
'align_bottom':'align-bottom.png',
|
|
246
|
+
'arrow_right':'flyouth.png',
|
|
247
|
+
'arrow_down':'dropdown.gif'
|
|
248
|
+
},
|
|
249
|
+
placement: {
|
|
250
|
+
'#logo':'logo',
|
|
251
|
+
'#tool_select':'select',
|
|
252
|
+
'#tool_fhpath':'pencil',
|
|
253
|
+
'#tool_line':'pen',
|
|
254
|
+
'#tool_rect,#tools_rect_show':'rect',
|
|
255
|
+
'#tool_ellipse,#tools_ellipse_show':'ellipse',
|
|
256
|
+
'#tool_path':'path',
|
|
257
|
+
'#tool_text,#layer_rename':'text',
|
|
258
|
+
'#tool_image':'image',
|
|
259
|
+
'#tool_zoom':'zoom',
|
|
260
|
+
'#tool_node_clone':'node_clone',
|
|
261
|
+
'#tool_node_delete':'node_delete',
|
|
262
|
+
'#tool_add_subpath':'add_subpath',
|
|
263
|
+
'#tool_openclose_path':'open_path',
|
|
264
|
+
'#tool_alignleft, #tool_posleft':'align_left',
|
|
265
|
+
'#tool_aligncenter, #tool_poscenter':'align_center',
|
|
266
|
+
'#tool_alignright, #tool_posright':'align_right',
|
|
267
|
+
'#tool_aligntop, #tool_postop':'align_top',
|
|
268
|
+
'#tool_alignmiddle, #tool_posmiddle':'align_middle',
|
|
269
|
+
'#tool_alignbottom, #tool_posbottom':'align_bottom',
|
|
270
|
+
'#cur_position':'align',
|
|
271
|
+
'#zoomLabel':'zoom'
|
|
272
|
+
},
|
|
273
|
+
resize: {
|
|
274
|
+
'#logo .svg_icon': 15,
|
|
275
|
+
'.flyout_arrow_horiz .svg_icon': 5,
|
|
276
|
+
'#fill_bg .svg_icon, #stroke_bg .svg_icon': svgedit.browser.isTouch() ? 24 : 24,
|
|
277
|
+
'.palette_item:first .svg_icon': svgedit.browser.isTouch() ? 30 : 16,
|
|
278
|
+
'#zoomLabel .svg_icon': 16,
|
|
279
|
+
'#zoom_dropdown .svg_icon': 7
|
|
280
|
+
},
|
|
281
|
+
callback: function(icons) {
|
|
282
|
+
$('.toolbar_button button > svg, .toolbar_button button > img').each(function() {
|
|
283
|
+
$(this).parent().prepend(this);
|
|
284
|
+
});
|
|
285
|
+
$('.tool_button, .tool_button_current').addClass("loaded")
|
|
286
|
+
var tleft = $('#tools_left');
|
|
287
|
+
if (tleft.length != 0) {
|
|
288
|
+
var min_height = tleft.offset().top + tleft.outerHeight();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Look for any missing flyout icons from plugins
|
|
292
|
+
$('.tools_flyout').each(function() {
|
|
293
|
+
var shower = $('#' + this.id + '_show');
|
|
294
|
+
var sel = shower.attr('data-curopt');
|
|
295
|
+
// Check if there's an icon here
|
|
296
|
+
if(!shower.children('svg, img').length) {
|
|
297
|
+
var clone = $(sel).children().clone();
|
|
298
|
+
if(clone.length) {
|
|
299
|
+
clone[0].removeAttribute('style'); //Needed for Opera
|
|
300
|
+
shower.append(clone);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
methodDraw.runCallbacks();
|
|
305
|
+
|
|
306
|
+
setTimeout(function() {
|
|
307
|
+
$('.flyout_arrow_horiz:empty').each(function() {
|
|
308
|
+
$(this).append($.getSvgIcon('arrow_right').width(5).height(5));
|
|
309
|
+
});
|
|
310
|
+
}, 1);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
$('#rulers').on("dblclick", function(e){
|
|
315
|
+
$("#base_unit_container").css({
|
|
316
|
+
top: e.pageY-10,
|
|
317
|
+
left: e.pageX-50,
|
|
318
|
+
display: 'block'
|
|
319
|
+
})
|
|
320
|
+
})
|
|
321
|
+
$("#base_unit_container")
|
|
322
|
+
.on("mouseleave mouseenter", function(e){
|
|
323
|
+
t = setTimeout(function(){$("#base_unit_container").fadeOut(500)}, 200)
|
|
324
|
+
if(event.type == "mouseover") clearTimeout(t)
|
|
325
|
+
})
|
|
326
|
+
$("#base_unit")
|
|
327
|
+
.on("change", function(e) {
|
|
328
|
+
savePreferences();
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
Editor.canvas = svgCanvas = new $.SvgCanvas(document.getElementById("svgcanvas"), curConfig);
|
|
332
|
+
Editor.show_save_warning = false;
|
|
333
|
+
Editor.paintBox = {fill: null, stroke:null, canvas:null};
|
|
334
|
+
var palette = ["#444444", "#482816", "#422C10", "#3B2F0E", "#32320F",
|
|
335
|
+
"#293414", "#1F361B", "#153723", "#0C372C",
|
|
336
|
+
"#083734", "#0E353B", "#1A333F", "#273141",
|
|
337
|
+
"#332D40", "#3E2A3C", "#462735", "#4B252D",
|
|
338
|
+
"#4D2425", "#4C261D", "#666666", "#845335", "#7B572D",
|
|
339
|
+
"#6F5C2A", "#62612C", "#546433", "#46673D",
|
|
340
|
+
"#396849", "#306856", "#2D6862", "#33666C",
|
|
341
|
+
"#426373", "#535F75", "#645A73", "#74556D",
|
|
342
|
+
"#805064", "#884D58", "#8B4D4B", "#894F3F",
|
|
343
|
+
"#999999", "#C48157", "#B8874D", "#A98E49", "#97944B",
|
|
344
|
+
"#849854", "#729C62", "#619E73", "#559E84",
|
|
345
|
+
"#529D94", "#5B9BA2", "#6D97AB", "#8391AE",
|
|
346
|
+
"#9A8AAB", "#AF84A3", "#BF7E96", "#C97A86",
|
|
347
|
+
"#CE7975", "#CC7C65", "#BBBBBB", "#FFB27C", "#FABA6F",
|
|
348
|
+
"#E6C36A", "#CFCA6D", "#B8D078", "#A0D58A",
|
|
349
|
+
"#8CD79F", "#7DD8B5", "#7AD6CA", "#84D3DB",
|
|
350
|
+
"#9ACEE6", "#B6C7EA", "#D3BEE7", "#EDB6DC",
|
|
351
|
+
"#FFAFCC", "#FFAAB8", "#FFA9A2", "#FFAC8D",
|
|
352
|
+
"#DDDDDD", "#FFE7A2", "#FFF093", "#FFFA8D", "#FFFF91",
|
|
353
|
+
"#EEFF9F", "#D1FFB4", "#B9FFCE", "#A8FFE9",
|
|
354
|
+
"#A4FFFF", "#B1FFFF", "#CBFFFF", "#EDFFFF",
|
|
355
|
+
"#FFF5FF", "#FFEBFF", "#FFE2FF", "#FFDCEC",
|
|
356
|
+
"#FFDBD2", "#FFDFB8"
|
|
357
|
+
],
|
|
358
|
+
isMac = (navigator.platform.indexOf("Mac") >= 0),
|
|
359
|
+
isWebkit = (navigator.userAgent.indexOf("AppleWebKit") >= 0),
|
|
360
|
+
modKey = (isMac ? "meta+" : "ctrl+"), // ⌘
|
|
361
|
+
path = svgCanvas.pathActions,
|
|
362
|
+
undoMgr = svgCanvas.undoMgr,
|
|
363
|
+
Utils = svgedit.utilities,
|
|
364
|
+
default_img_url = curConfig.imgPath + "placeholder.svg",
|
|
365
|
+
workarea = $("#workarea"),
|
|
366
|
+
canv_menu = $("#cmenu_canvas"),
|
|
367
|
+
exportWindow = null,
|
|
368
|
+
tool_scale = 1,
|
|
369
|
+
ui_context = 'toolbars',
|
|
370
|
+
orig_source = '';
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
// This puts the correct shortcuts in the menus
|
|
374
|
+
if (!isMac) {
|
|
375
|
+
$('.shortcut').each(function(){
|
|
376
|
+
var text = $(this).text();
|
|
377
|
+
$(this).text(text.split("⌘").join("Ctrl+"))
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// This sets up alternative dialog boxes. They mostly work the same way as
|
|
382
|
+
// their UI counterparts, expect instead of returning the result, a callback
|
|
383
|
+
// needs to be included that returns the result as its first parameter.
|
|
384
|
+
// In the future we may want to add additional types of dialog boxes, since
|
|
385
|
+
// they should be easy to handle this way.
|
|
386
|
+
(function() {
|
|
387
|
+
$('#dialog_container').draggable({cancel:'#dialog_content, #dialog_buttons *', containment: 'window'});
|
|
388
|
+
var box = $('#dialog_box'), btn_holder = $('#dialog_buttons');
|
|
389
|
+
|
|
390
|
+
var dbox = function(type, msg, callback, defText) {
|
|
391
|
+
$('#dialog_content').html('<p>'+msg.replace(/\n/g,'</p><p>')+'</p>')
|
|
392
|
+
.toggleClass('prompt',(type=='prompt'));
|
|
393
|
+
btn_holder.empty();
|
|
394
|
+
|
|
395
|
+
var ok = $('<input type="button" value="' + uiStrings.common.ok + '">').appendTo(btn_holder);
|
|
396
|
+
|
|
397
|
+
if(type != 'alert') {
|
|
398
|
+
$('<input type="button" value="' + uiStrings.common.cancel + '">')
|
|
399
|
+
.appendTo(btn_holder)
|
|
400
|
+
.on("click touchstart", function() { box.hide();callback(false)});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if(type == 'prompt') {
|
|
404
|
+
var input = $('<input type="text">').prependTo(btn_holder);
|
|
405
|
+
input.val(defText || '');
|
|
406
|
+
input.bind('keydown', 'return', function() {ok.trigger("click touchstart");});
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if(type == 'process') {
|
|
410
|
+
ok.hide();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
box.show();
|
|
414
|
+
|
|
415
|
+
ok.on("click touchstart", function() {
|
|
416
|
+
box.hide();
|
|
417
|
+
var resp = (type == 'prompt')?input.val():true;
|
|
418
|
+
if(callback) callback(resp);
|
|
419
|
+
}).focus();
|
|
420
|
+
|
|
421
|
+
if(type == 'prompt') input.focus();
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
$.alert = function(msg, cb) { dbox('alert', msg, cb);};
|
|
425
|
+
$.confirm = function(msg, cb) { dbox('confirm', msg, cb);};
|
|
426
|
+
$.process_cancel = function(msg, cb) { dbox('process', msg, cb);};
|
|
427
|
+
$.prompt = function(msg, txt, cb) { dbox('prompt', msg, cb, txt);};
|
|
428
|
+
}());
|
|
429
|
+
|
|
430
|
+
var setSelectMode = function() {
|
|
431
|
+
var curr = $('.tool_button_current');
|
|
432
|
+
if(curr.length && curr[0].id !== 'tool_select') {
|
|
433
|
+
curr.removeClass('tool_button_current').addClass('tool_button');
|
|
434
|
+
$('#tool_select').addClass('tool_button_current').removeClass('tool_button');
|
|
435
|
+
}
|
|
436
|
+
svgCanvas.setMode('select');
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
var setEyedropperMode = function() {
|
|
440
|
+
var curr = $('.tool_button_current');
|
|
441
|
+
if(curr.length && curr[0].id !== 'tool_eyedropper') {
|
|
442
|
+
curr.removeClass('tool_button_current').addClass('tool_button');
|
|
443
|
+
$('#tool_eyedropper').addClass('tool_button_current').removeClass('tool_button');
|
|
444
|
+
}
|
|
445
|
+
svgCanvas.setMode('eyedropper');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
var togglePathEditMode = function(editmode, elems) {
|
|
449
|
+
$('#tools_bottom_2,#tools_bottom_3').toggle(!editmode);
|
|
450
|
+
if(editmode) {
|
|
451
|
+
// Change select icon
|
|
452
|
+
$('.context_panel').hide();
|
|
453
|
+
$('#path_node_panel').show();
|
|
454
|
+
$('.tool_button_current').removeClass('tool_button_current').addClass('tool_button');
|
|
455
|
+
$('#tool_select').addClass('tool_button_current').removeClass('tool_button');
|
|
456
|
+
setIcon('#tool_select', 'select_node');
|
|
457
|
+
multiselected = false;
|
|
458
|
+
} else {
|
|
459
|
+
if (elems[0]) {
|
|
460
|
+
var selector = svgCanvas.selectorManager.requestSelector(elems[0])
|
|
461
|
+
selector.reset(elems[0]);
|
|
462
|
+
selector.selectorRect.setAttribute('display', 'inline');
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
setIcon('#tool_select', 'select');
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// used to make the flyouts stay on the screen longer the very first time
|
|
470
|
+
var flyoutspeed = 1250;
|
|
471
|
+
var textBeingEntered = false;
|
|
472
|
+
var selectedElement = null;
|
|
473
|
+
var multiselected = false;
|
|
474
|
+
var editingsource = false;
|
|
475
|
+
var docprops = false;
|
|
476
|
+
var preferences = false;
|
|
477
|
+
var cur_context = '';
|
|
478
|
+
|
|
479
|
+
var saveHandler = function(window,svg) {
|
|
480
|
+
Editor.show_save_warning = false;
|
|
481
|
+
|
|
482
|
+
// by default, we add the XML prolog back, systems integrating SVG-edit (wikis, CMSs)
|
|
483
|
+
// can just provide their own custom save handler and might not want the XML prolog
|
|
484
|
+
svg = '<?xml version="1.0"?>\n' + svg;
|
|
485
|
+
|
|
486
|
+
// Opens the SVG in new window, with warning about Mozilla bug #308590 when applicable
|
|
487
|
+
|
|
488
|
+
var ua = navigator.userAgent;
|
|
489
|
+
|
|
490
|
+
// Chrome 5 (and 6?) don't allow saving, show source instead ( http://code.google.com/p/chromium/issues/detail?id=46735 )
|
|
491
|
+
// IE9 doesn't allow standalone Data URLs ( https://connect.microsoft.com/IE/feedback/details/542600/data-uri-images-fail-when-loaded-by-themselves )
|
|
492
|
+
if(~ua.indexOf('MSIE')) {
|
|
493
|
+
showSourceEditor(0,true);
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
var win = window.open("data:image/svg+xml;base64," + Utils.encode64(svg));
|
|
497
|
+
|
|
498
|
+
// Alert will only appear the first time saved OR the first time the bug is encountered
|
|
499
|
+
var done = $.pref('save_notice_done');
|
|
500
|
+
if(done !== "all") {
|
|
501
|
+
|
|
502
|
+
var note = uiStrings.notification.saveFromBrowser.replace('%s', 'SVG');
|
|
503
|
+
|
|
504
|
+
// Check if FF and has <defs/>
|
|
505
|
+
if(ua.indexOf('Gecko/') !== -1) {
|
|
506
|
+
if(svg.indexOf('<defs') !== -1) {
|
|
507
|
+
note += "\n\n" + uiStrings.notification.defsFailOnSave;
|
|
508
|
+
$.pref('save_notice_done', 'all');
|
|
509
|
+
done = "all";
|
|
510
|
+
} else {
|
|
511
|
+
$.pref('save_notice_done', 'part');
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
$.pref('save_notice_done', 'all');
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if(done !== 'part') {
|
|
518
|
+
win.alert(note);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
var exportHandler = function(window, data) {
|
|
524
|
+
var issues = data.issues;
|
|
525
|
+
|
|
526
|
+
if(!$('#export_canvas').length) {
|
|
527
|
+
$('<canvas>', {id: 'export_canvas'}).hide().appendTo('body');
|
|
528
|
+
}
|
|
529
|
+
var c = $('#export_canvas')[0];
|
|
530
|
+
|
|
531
|
+
c.width = svgCanvas.contentW;
|
|
532
|
+
c.height = svgCanvas.contentH;
|
|
533
|
+
canvg(c, data.svg, {renderCallback: function() {
|
|
534
|
+
var datauri = c.toDataURL('image/png');
|
|
535
|
+
exportWindow.location.href = datauri;
|
|
536
|
+
var done = $.pref('export_notice_done');
|
|
537
|
+
if(done !== "all") {
|
|
538
|
+
var note = uiStrings.notification.saveFromBrowser.replace('%s', 'PNG');
|
|
539
|
+
|
|
540
|
+
// Check if there's issues
|
|
541
|
+
if(issues.length) {
|
|
542
|
+
var pre = "\n \u2022 ";
|
|
543
|
+
note += ("\n\n" + uiStrings.notification.noteTheseIssues + pre + issues.join(pre));
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Note that this will also prevent the notice even though new issues may appear later.
|
|
547
|
+
// May want to find a way to deal with that without annoying the user
|
|
548
|
+
$.pref('export_notice_done', 'all');
|
|
549
|
+
exportWindow.alert(note);
|
|
550
|
+
}
|
|
551
|
+
}});
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
// called when we've selected a different element
|
|
555
|
+
var selectedChanged = function(window,elems) {
|
|
556
|
+
var mode = svgCanvas.getMode();
|
|
557
|
+
if(mode === "select") setSelectMode();
|
|
558
|
+
if (mode === "pathedit") return updateContextPanel();
|
|
559
|
+
// if elems[1] is present, then we have more than one element
|
|
560
|
+
selectedElement = (elems.length == 1 || elems[1] == null ? elems[0] : null);
|
|
561
|
+
elems = elems.filter(Boolean)
|
|
562
|
+
multiselected = (elems.length >= 2) ? elems : false;
|
|
563
|
+
if (svgCanvas.elementsAreSame(multiselected)) selectedElement = multiselected[0]
|
|
564
|
+
if (selectedElement != null) {
|
|
565
|
+
$('#multiselected_panel').hide()
|
|
566
|
+
updateToolbar();
|
|
567
|
+
if (multiselected.length) {//multiselected elements are the same
|
|
568
|
+
$('#tools_top').addClass('multiselected')
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
else if (multiselected.length) {
|
|
572
|
+
$('.context_panel').hide()
|
|
573
|
+
$('#tools_top').removeClass('multiselected')
|
|
574
|
+
$('#multiselected_panel').show()
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
$('.context_panel').hide()
|
|
578
|
+
$('#canvas_panel').show()
|
|
579
|
+
$('#tools_top').removeClass('multiselected')
|
|
580
|
+
}
|
|
581
|
+
svgCanvas.runExtensions("selectedChanged", {
|
|
582
|
+
elems: elems,
|
|
583
|
+
selectedElement: selectedElement,
|
|
584
|
+
multiselected: multiselected
|
|
585
|
+
});
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
// Call when part of element is in process of changing, generally
|
|
589
|
+
// on mousemove actions like rotate, move, etc.
|
|
590
|
+
var elementTransition = function(window,elems) {
|
|
591
|
+
var mode = svgCanvas.getMode();
|
|
592
|
+
var elem = elems[0];
|
|
593
|
+
|
|
594
|
+
if(!elem) return;
|
|
595
|
+
|
|
596
|
+
multiselected = (elems.length >= 2 && elems[1] != null) ? elems : null;
|
|
597
|
+
// Only updating fields for single elements for now
|
|
598
|
+
if(!multiselected) {
|
|
599
|
+
switch ( mode ) {
|
|
600
|
+
case "rotate":
|
|
601
|
+
var ang = svgCanvas.getRotationAngle(elem);
|
|
602
|
+
$('#angle').val(Math.round(ang));
|
|
603
|
+
rotateCursor(ang);
|
|
604
|
+
$('#tool_reorient').toggleClass('disabled', ang == 0);
|
|
605
|
+
break;
|
|
606
|
+
|
|
607
|
+
// TODO: Update values that change on move/resize, etc
|
|
608
|
+
// case "select":
|
|
609
|
+
// case "resize":
|
|
610
|
+
// break;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
svgCanvas.runExtensions("elementTransition", {
|
|
614
|
+
elems: elems
|
|
615
|
+
});
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
// called when any element has changed
|
|
619
|
+
var elementChanged = function(window,elems) {
|
|
620
|
+
var mode = svgCanvas.getMode();
|
|
621
|
+
if(mode === "select") {
|
|
622
|
+
setSelectMode();
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
for (var i = 0; i < elems.length; ++i) {
|
|
626
|
+
var elem = elems[i];
|
|
627
|
+
|
|
628
|
+
// if the element changed was the svg, then it could be a resolution change
|
|
629
|
+
if (elem && elem.tagName === "svg") {
|
|
630
|
+
//populateLayers();
|
|
631
|
+
updateCanvas();
|
|
632
|
+
}
|
|
633
|
+
// Update selectedElement if element is no longer part of the image.
|
|
634
|
+
// This occurs for the text elements in Firefox
|
|
635
|
+
else if(elem && selectedElement && selectedElement.parentNode == null) {
|
|
636
|
+
// || elem && elem.tagName == "path" && !multiselected) { // This was added in r1430, but not sure why
|
|
637
|
+
selectedElement = elem;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
Editor.show_save_warning = true;
|
|
642
|
+
|
|
643
|
+
// we update the contextual panel with potentially new
|
|
644
|
+
// positional/sizing information (we DON'T want to update the
|
|
645
|
+
// toolbar here as that creates an infinite loop)
|
|
646
|
+
// also this updates the history buttons
|
|
647
|
+
|
|
648
|
+
// we tell it to skip focusing the text control if the
|
|
649
|
+
// text element was previously in focus
|
|
650
|
+
updateContextPanel();
|
|
651
|
+
|
|
652
|
+
// In the event a gradient was flipped:
|
|
653
|
+
if(selectedElement && mode === "select") {
|
|
654
|
+
Editor.paintBox.fill.update();
|
|
655
|
+
Editor.paintBox.stroke.update();
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
svgCanvas.runExtensions("elementChanged", {
|
|
659
|
+
elems: elems
|
|
660
|
+
});
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
var zoomChanged = function(window, bbox, autoCenter) {
|
|
664
|
+
var scrbar = 15,
|
|
665
|
+
res = svgCanvas.getResolution(),
|
|
666
|
+
w_area = workarea,
|
|
667
|
+
canvas_pos = $('#svgcanvas').position();
|
|
668
|
+
var z_info = svgCanvas.setBBoxZoom(bbox, w_area.width()-scrbar, w_area.height()-scrbar);
|
|
669
|
+
if(!z_info) return;
|
|
670
|
+
var zoomlevel = z_info.zoom,
|
|
671
|
+
bb = z_info.bbox;
|
|
672
|
+
|
|
673
|
+
if(zoomlevel < .001) {
|
|
674
|
+
changeZoom({value: .1});
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
if (typeof animatedZoom != 'undefined') window.cancelAnimationFrame(animatedZoom)
|
|
678
|
+
// zoom duration 500ms
|
|
679
|
+
var start = Date.now();
|
|
680
|
+
var duration = 500;
|
|
681
|
+
var diff = (zoomlevel) - (res.zoom)
|
|
682
|
+
var zoom = $('#zoom')[0]
|
|
683
|
+
var current_zoom = res.zoom
|
|
684
|
+
var animateZoom = function(timestamp) {
|
|
685
|
+
var progress = Date.now() - start
|
|
686
|
+
var tick = progress / duration
|
|
687
|
+
tick = (Math.pow((tick-1), 3) +1);
|
|
688
|
+
svgCanvas.setZoom(current_zoom + (diff*tick));
|
|
689
|
+
updateCanvas();
|
|
690
|
+
if (tick < 1 && tick > -.90) {
|
|
691
|
+
window.animatedZoom = requestAnimationFrame(animateZoom)
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
$("#zoom").val(parseInt(zoomlevel*100))
|
|
695
|
+
$("option", "#zoom_select").removeAttr("selected")
|
|
696
|
+
$("option[value="+ parseInt(zoomlevel*100) +"]", "#zoom_select").attr("selected", "selected")
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
animateZoom()
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
//if(autoCenter) {
|
|
704
|
+
// updateCanvas();
|
|
705
|
+
//} else {
|
|
706
|
+
// updateCanvas(false, {x: bb.x * zoomlevel + (bb.width * zoomlevel)/2, y: bb.y * zoomlevel + (bb.height * zoomlevel)/2});
|
|
707
|
+
//}
|
|
708
|
+
|
|
709
|
+
if(svgCanvas.getMode() == 'zoom' && bb.width) {
|
|
710
|
+
// Go to select if a zoom box was drawn
|
|
711
|
+
setSelectMode();
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
zoomDone();
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
$('#cur_context_panel').delegate('a', 'click', function() {
|
|
718
|
+
var link = $(this);
|
|
719
|
+
if(link.attr('data-root')) {
|
|
720
|
+
svgCanvas.leaveContext();
|
|
721
|
+
} else {
|
|
722
|
+
svgCanvas.setContext(link.text());
|
|
723
|
+
}
|
|
724
|
+
svgCanvas.clearSelection();
|
|
725
|
+
return false;
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
var contextChanged = function(win, context) {
|
|
729
|
+
|
|
730
|
+
var link_str = '';
|
|
731
|
+
if(context) {
|
|
732
|
+
var str = '';
|
|
733
|
+
link_str = '<a href="#" data-root="y">' + svgCanvas.getCurrentDrawing().getCurrentLayerName() + '</a>';
|
|
734
|
+
|
|
735
|
+
$(context).parentsUntil('#svgcontent > g').andSelf().each(function() {
|
|
736
|
+
if(this.id) {
|
|
737
|
+
str += ' > ' + this.id;
|
|
738
|
+
if(this !== context) {
|
|
739
|
+
link_str += ' > <a href="#">' + this.id + '</a>';
|
|
740
|
+
} else {
|
|
741
|
+
link_str += ' > ' + this.id;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
cur_context = str;
|
|
747
|
+
} else {
|
|
748
|
+
cur_context = null;
|
|
749
|
+
}
|
|
750
|
+
$('#cur_context_panel').toggle(!!context).html(link_str);
|
|
751
|
+
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Makes sure the current selected paint is available to work with
|
|
755
|
+
var prepPaints = function() {
|
|
756
|
+
Editor.paintBox.fill.prep();
|
|
757
|
+
Editor.paintBox.stroke.prep();
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
var flyout_funcs = {};
|
|
761
|
+
|
|
762
|
+
var setupFlyouts = function(holders) {
|
|
763
|
+
$.each(holders, function(hold_sel, btn_opts) {
|
|
764
|
+
var buttons = $(hold_sel).children();
|
|
765
|
+
var show_sel = hold_sel + '_show';
|
|
766
|
+
var shower = $(show_sel);
|
|
767
|
+
var def = false;
|
|
768
|
+
buttons.addClass('tool_button')
|
|
769
|
+
.unbind('click mousedown mouseup') // may not be necessary
|
|
770
|
+
.each(function(i) {
|
|
771
|
+
// Get this buttons options
|
|
772
|
+
var opts = btn_opts[i];
|
|
773
|
+
|
|
774
|
+
// Remember the function that goes with this ID
|
|
775
|
+
flyout_funcs[opts.sel] = opts.fn;
|
|
776
|
+
|
|
777
|
+
if(opts.isDefault) def = i;
|
|
778
|
+
|
|
779
|
+
// Clicking the icon in flyout should set this set's icon
|
|
780
|
+
var func = function(event) {
|
|
781
|
+
var options = opts;
|
|
782
|
+
//find the currently selected tool if comes from keystroke
|
|
783
|
+
if (event.type === "keydown") {
|
|
784
|
+
var flyoutIsSelected = $(options.parent + "_show").hasClass('tool_button_current');
|
|
785
|
+
var currentOperation = $(options.parent + "_show").attr("data-curopt");
|
|
786
|
+
$.each(holders[opts.parent], function(i, tool){
|
|
787
|
+
if (tool.sel == currentOperation) {
|
|
788
|
+
if(!event.shiftKey || !flyoutIsSelected) {
|
|
789
|
+
options = tool;
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
options = holders[opts.parent][i+1] || holders[opts.parent][0];
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
if($(this).hasClass('disabled')) return false;
|
|
798
|
+
if (toolButtonClick(show_sel)) {
|
|
799
|
+
options.fn();
|
|
800
|
+
}
|
|
801
|
+
if(options.icon) {
|
|
802
|
+
var icon = $.getSvgIcon(options.icon, true);
|
|
803
|
+
} else {
|
|
804
|
+
var icon = $(options.sel).children().eq(0).clone();
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
icon[0].setAttribute('width',shower.width());
|
|
808
|
+
icon[0].setAttribute('height',shower.height());
|
|
809
|
+
shower.children(':not(.flyout_arrow_horiz)').remove();
|
|
810
|
+
shower.append(icon).attr('data-curopt', options.sel); // This sets the current mode
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
$(this).mouseup(func);
|
|
814
|
+
|
|
815
|
+
if(opts.key) {
|
|
816
|
+
$(document).bind('keydown', opts.key[0] + " shift+" + opts.key[0], func);
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
if(def) {
|
|
821
|
+
shower.attr('data-curopt', btn_opts[def].sel);
|
|
822
|
+
} else if(!shower.attr('data-curopt')) {
|
|
823
|
+
// Set first as default
|
|
824
|
+
shower.attr('data-curopt', btn_opts[0].sel);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
var timer;
|
|
828
|
+
|
|
829
|
+
var pos = $(show_sel).position();
|
|
830
|
+
$(hold_sel).css({'left': pos.left+34, 'top': pos.top+77});
|
|
831
|
+
|
|
832
|
+
// Clicking the "show" icon should set the current mode
|
|
833
|
+
shower.mousedown(function(evt) {
|
|
834
|
+
$('#workarea').one("mousedown", function(){$('#tools_shapelib').hide()})
|
|
835
|
+
if ($('#tools_shapelib').is(":visible")) toolButtonClick(show_sel, false);
|
|
836
|
+
if(shower.hasClass('disabled')) return false;
|
|
837
|
+
var holder = $(hold_sel);
|
|
838
|
+
var l = pos.left+34;
|
|
839
|
+
var w = holder.width()*-1;
|
|
840
|
+
var time = holder.data('shown_popop')?200:0;
|
|
841
|
+
timer = setTimeout(function() {
|
|
842
|
+
// Show corresponding menu
|
|
843
|
+
if(!shower.data('isLibrary')) {
|
|
844
|
+
holder.css('left', w).show().animate({
|
|
845
|
+
left: l
|
|
846
|
+
},50);
|
|
847
|
+
} else {
|
|
848
|
+
holder.css('left', l).show();
|
|
849
|
+
}
|
|
850
|
+
holder.data('shown_popop',true);
|
|
851
|
+
},time);
|
|
852
|
+
evt.preventDefault();
|
|
853
|
+
}).mouseup(function(evt) {
|
|
854
|
+
clearTimeout(timer);
|
|
855
|
+
var opt = $(this).attr('data-curopt');
|
|
856
|
+
// Is library and popped up, so do nothing
|
|
857
|
+
if(shower.data('isLibrary') && $(show_sel.replace('_show','')).is(':visible')) {
|
|
858
|
+
toolButtonClick(show_sel, true);
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (toolButtonClick(show_sel) && (opt in flyout_funcs)) {
|
|
862
|
+
flyout_funcs[opt]();
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
// $('#tools_rect').mouseleave(function(){$('#tools_rect').fadeOut();});
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
setFlyoutTitles();
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
var makeFlyoutHolder = function(id, child) {
|
|
873
|
+
var div = $('<div>',{
|
|
874
|
+
'class': 'tools_flyout',
|
|
875
|
+
id: id
|
|
876
|
+
}).appendTo('#svg_editor').append(child);
|
|
877
|
+
|
|
878
|
+
return div;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
var setFlyoutPositions = function() {
|
|
882
|
+
$('.tools_flyout').each(function() {
|
|
883
|
+
var shower = $('#' + this.id + '_show');
|
|
884
|
+
var pos = shower.offset();
|
|
885
|
+
var w = shower.outerWidth();
|
|
886
|
+
$(this).css({left: (pos.left + w)*tool_scale, top: pos.top});
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
var setFlyoutTitles = function() {
|
|
891
|
+
$('.tools_flyout').each(function() {
|
|
892
|
+
var shower = $('#' + this.id + '_show');
|
|
893
|
+
if(shower.data('isLibrary')) return;
|
|
894
|
+
|
|
895
|
+
var tooltips = [];
|
|
896
|
+
$(this).children().each(function() {
|
|
897
|
+
tooltips.push(this.title);
|
|
898
|
+
});
|
|
899
|
+
shower[0].title = tooltips.join(' / ');
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
var resize_timer;
|
|
904
|
+
|
|
905
|
+
var extAdded = function(window, ext) {
|
|
906
|
+
|
|
907
|
+
var cb_called = false;
|
|
908
|
+
var resize_done = false;
|
|
909
|
+
var cb_ready = true; // Set to false to delay callback (e.g. wait for $.svgIcons)
|
|
910
|
+
|
|
911
|
+
function prepResize() {
|
|
912
|
+
if(resize_timer) {
|
|
913
|
+
clearTimeout(resize_timer);
|
|
914
|
+
resize_timer = null;
|
|
915
|
+
}
|
|
916
|
+
if(!resize_done) {
|
|
917
|
+
resize_timer = setTimeout(function() {
|
|
918
|
+
resize_done = true;
|
|
919
|
+
setIconSize(curPrefs.iconsize);
|
|
920
|
+
}, 50);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
|
|
925
|
+
var runCallback = function() {
|
|
926
|
+
if(ext.callback && !cb_called && cb_ready) {
|
|
927
|
+
cb_called = true;
|
|
928
|
+
ext.callback();
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
var btn_selects = [];
|
|
933
|
+
|
|
934
|
+
if(ext.context_tools) {
|
|
935
|
+
$.each(ext.context_tools, function(i, tool) {
|
|
936
|
+
// Add select tool
|
|
937
|
+
var cont_id = tool.container_id?(' id="' + tool.container_id + '"'):"";
|
|
938
|
+
|
|
939
|
+
var panel = $('#' + tool.panel);
|
|
940
|
+
|
|
941
|
+
// create the panel if it doesn't exist
|
|
942
|
+
if(!panel.length)
|
|
943
|
+
panel = $('<div>', {id: tool.panel}).appendTo("#tools_top").hide();
|
|
944
|
+
|
|
945
|
+
// TODO: Allow support for other types, or adding to existing tool
|
|
946
|
+
switch (tool.type) {
|
|
947
|
+
case 'tool_button':
|
|
948
|
+
var html = '<div class="tool_button">' + tool.id + '</div>';
|
|
949
|
+
var div = $(html).appendTo(panel);
|
|
950
|
+
if (tool.events) {
|
|
951
|
+
$.each(tool.events, function(evt, func) {
|
|
952
|
+
$(div).bind(evt, func);
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
break;
|
|
956
|
+
case 'select':
|
|
957
|
+
var html = '<label' + cont_id + '>'
|
|
958
|
+
+ '<select id="' + tool.id + '">';
|
|
959
|
+
$.each(tool.options, function(val, text) {
|
|
960
|
+
var sel = (val == tool.defval) ? " selected":"";
|
|
961
|
+
html += '<option value="'+val+'"' + sel + '>' + text + '</option>';
|
|
962
|
+
});
|
|
963
|
+
html += "</select></label>";
|
|
964
|
+
// Creates the tool, hides & adds it, returns the select element
|
|
965
|
+
var sel = $(html).appendTo(panel).find('select');
|
|
966
|
+
|
|
967
|
+
$.each(tool.events, function(evt, func) {
|
|
968
|
+
$(sel).bind(evt, func);
|
|
969
|
+
});
|
|
970
|
+
break;
|
|
971
|
+
case 'button-select':
|
|
972
|
+
var html = '<div id="' + tool.id + '" class="dropdown toolset" title="' + tool.title + '">'
|
|
973
|
+
+ '<div id="cur_' + tool.id + '" class="icon_label"></div><button></button></div>';
|
|
974
|
+
|
|
975
|
+
var list = $('<ul id="' + tool.id + '_opts"></ul>').appendTo('#option_lists');
|
|
976
|
+
if(tool.colnum) {
|
|
977
|
+
list.addClass('optcols' + tool.colnum);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Creates the tool, hides & adds it, returns the select element
|
|
981
|
+
var dropdown = $(html).appendTo(panel).children();
|
|
982
|
+
|
|
983
|
+
btn_selects.push({
|
|
984
|
+
elem: ('#' + tool.id),
|
|
985
|
+
list: ('#' + tool.id + '_opts'),
|
|
986
|
+
title: tool.title,
|
|
987
|
+
callback: tool.events.change,
|
|
988
|
+
cur: ('#cur_' + tool.id)
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
break;
|
|
992
|
+
case 'input':
|
|
993
|
+
var html = '<label' + cont_id + '>'
|
|
994
|
+
+ '<span id="' + tool.id + '_label">'
|
|
995
|
+
+ tool.label + ':</span>'
|
|
996
|
+
+ '<input id="' + tool.id + '" title="' + tool.title
|
|
997
|
+
+ '" size="' + (tool.size || "4") + '" value="' + (tool.defval || "") + '" type="text"/></label>'
|
|
998
|
+
|
|
999
|
+
// Creates the tool, hides & adds it, returns the select element
|
|
1000
|
+
|
|
1001
|
+
// Add to given tool.panel
|
|
1002
|
+
var inp = $(html).appendTo(panel).find('input');
|
|
1003
|
+
|
|
1004
|
+
if(tool.spindata) {
|
|
1005
|
+
inp.SpinButton(tool.spindata);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
if(tool.events) {
|
|
1009
|
+
$.each(tool.events, function(evt, func) {
|
|
1010
|
+
inp.bind(evt, func);
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
break;
|
|
1014
|
+
|
|
1015
|
+
default:
|
|
1016
|
+
break;
|
|
1017
|
+
}
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if(ext.buttons) {
|
|
1022
|
+
var fallback_obj = {},
|
|
1023
|
+
placement_obj = {},
|
|
1024
|
+
svgicons = ext.svgicons;
|
|
1025
|
+
var holders = {};
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
// Add buttons given by extension
|
|
1029
|
+
$.each(ext.buttons, function(i, btn) {
|
|
1030
|
+
var icon;
|
|
1031
|
+
var id = btn.id;
|
|
1032
|
+
var num = i;
|
|
1033
|
+
// Give button a unique ID
|
|
1034
|
+
while($('#'+id).length) {
|
|
1035
|
+
id = btn.id + '_' + (++num);
|
|
1036
|
+
}
|
|
1037
|
+
if(!svgicons) {
|
|
1038
|
+
icon = (btn.type == "menu") ? "" : $('<img src="' + btn.icon + '">');
|
|
1039
|
+
} else {
|
|
1040
|
+
fallback_obj[id] = btn.icon;
|
|
1041
|
+
var svgicon = btn.svgicon ? btn.svgicon : btn.id;
|
|
1042
|
+
if(btn.type == 'app_menu') {
|
|
1043
|
+
placement_obj['#' + id + ' > div'] = svgicon;
|
|
1044
|
+
} else {
|
|
1045
|
+
placement_obj['#' + id] = svgicon;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
var cls, parent;
|
|
1050
|
+
|
|
1051
|
+
|
|
1052
|
+
|
|
1053
|
+
// Set button up according to its type
|
|
1054
|
+
switch ( btn.type ) {
|
|
1055
|
+
case 'mode_flyout':
|
|
1056
|
+
case 'mode':
|
|
1057
|
+
cls = 'tool_button';
|
|
1058
|
+
if(btn.cls) {
|
|
1059
|
+
cls += " " + btn.cls;
|
|
1060
|
+
}
|
|
1061
|
+
parent = "#tools_left";
|
|
1062
|
+
break;
|
|
1063
|
+
case 'context':
|
|
1064
|
+
cls = 'tool_button';
|
|
1065
|
+
parent = "#" + btn.panel;
|
|
1066
|
+
// create the panel if it doesn't exist
|
|
1067
|
+
if(!$(parent).length)
|
|
1068
|
+
$('<div>', {id: btn.panel}).appendTo("#tools_top");
|
|
1069
|
+
break;
|
|
1070
|
+
case 'menu':
|
|
1071
|
+
cls = 'menu_item tool_button';
|
|
1072
|
+
parent = "#" + (btn.after || btn.panel);
|
|
1073
|
+
break;
|
|
1074
|
+
case 'app_menu':
|
|
1075
|
+
cls = '';
|
|
1076
|
+
parent = btn.parent || '#main_menu ul';
|
|
1077
|
+
// create the panel if it doesn't exist
|
|
1078
|
+
if(!$(parent).length)
|
|
1079
|
+
$('<div>', {id: btn.panel}).appendTo("#tools_top");
|
|
1080
|
+
break;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
var button = $((btn.list || btn.type == 'app_menu')?'<li/>':'<div/>')
|
|
1084
|
+
.attr("id", id)
|
|
1085
|
+
.attr("title", btn.title)
|
|
1086
|
+
.addClass(cls);
|
|
1087
|
+
if(!btn.includeWith && !btn.list) {
|
|
1088
|
+
if("position" in btn) {
|
|
1089
|
+
$(parent).children().eq(btn.position).before(button);
|
|
1090
|
+
} else {
|
|
1091
|
+
if (btn.type != "menu" || !btn.after) button.appendTo(parent);
|
|
1092
|
+
else $(parent).after(button);
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
if(btn.type =='mode_flyout') {
|
|
1096
|
+
// Add to flyout menu / make flyout menu
|
|
1097
|
+
// var opts = btn.includeWith;
|
|
1098
|
+
// // opts.button, default, position
|
|
1099
|
+
var ref_btn = $(button);
|
|
1100
|
+
|
|
1101
|
+
var flyout_holder = ref_btn.parent();
|
|
1102
|
+
// Create a flyout menu if there isn't one already
|
|
1103
|
+
if(!ref_btn.parent().hasClass('tools_flyout')) {
|
|
1104
|
+
// Create flyout placeholder
|
|
1105
|
+
var tls_id = ref_btn[0].id.replace('tool_','tools_')
|
|
1106
|
+
var show_btn = ref_btn.clone()
|
|
1107
|
+
.attr('id',tls_id + '_show')
|
|
1108
|
+
.append($('<div>',{'class':'flyout_arrow_horiz'}));
|
|
1109
|
+
|
|
1110
|
+
ref_btn.before(show_btn);
|
|
1111
|
+
|
|
1112
|
+
// Create a flyout div
|
|
1113
|
+
flyout_holder = makeFlyoutHolder(tls_id, ref_btn);
|
|
1114
|
+
flyout_holder.data('isLibrary', true);
|
|
1115
|
+
show_btn.data('isLibrary', true);
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
// var ref_data = Actions.getButtonData(opts.button);
|
|
1121
|
+
|
|
1122
|
+
placement_obj['#' + tls_id + '_show'] = btn.id;
|
|
1123
|
+
// TODO: Find way to set the current icon using the iconloader if this is not default
|
|
1124
|
+
|
|
1125
|
+
// Include data for extension button as well as ref button
|
|
1126
|
+
var cur_h = holders['#'+flyout_holder[0].id] = [{
|
|
1127
|
+
sel: '#'+id,
|
|
1128
|
+
fn: btn.events.click,
|
|
1129
|
+
icon: btn.id,
|
|
1130
|
+
//key: btn.key,
|
|
1131
|
+
isDefault: true
|
|
1132
|
+
}, ref_data];
|
|
1133
|
+
|
|
1134
|
+
} else if(btn.type == 'app_menu' || btn.type == 'menu') {
|
|
1135
|
+
button.append(btn.title);
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
} else if(btn.list) {
|
|
1139
|
+
// Add button to list
|
|
1140
|
+
button.addClass('push_button');
|
|
1141
|
+
$('#' + btn.list + '_opts').append(button);
|
|
1142
|
+
if(btn.isDefault) {
|
|
1143
|
+
$('#cur_' + btn.list).append(button.children().clone());
|
|
1144
|
+
var svgicon = btn.svgicon?btn.svgicon:btn.id;
|
|
1145
|
+
placement_obj['#cur_' + btn.list] = svgicon;
|
|
1146
|
+
}
|
|
1147
|
+
} else if(btn.includeWith) {
|
|
1148
|
+
// Add to flyout menu / make flyout menu
|
|
1149
|
+
var opts = btn.includeWith;
|
|
1150
|
+
// opts.button, default, position
|
|
1151
|
+
var ref_btn = $(opts.button);
|
|
1152
|
+
|
|
1153
|
+
var flyout_holder = ref_btn.parent();
|
|
1154
|
+
// Create a flyout menu if there isn't one already
|
|
1155
|
+
if(!ref_btn.parent().hasClass('tools_flyout')) {
|
|
1156
|
+
// Create flyout placeholder
|
|
1157
|
+
var tls_id = ref_btn[0].id.replace('tool_','tools_')
|
|
1158
|
+
var show_btn = ref_btn.clone()
|
|
1159
|
+
.attr('id',tls_id + '_show')
|
|
1160
|
+
.append($('<div>',{'class':'flyout_arrow_horiz'}));
|
|
1161
|
+
|
|
1162
|
+
ref_btn.before(show_btn);
|
|
1163
|
+
|
|
1164
|
+
// Create a flyout div
|
|
1165
|
+
flyout_holder = makeFlyoutHolder(tls_id, ref_btn);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
var ref_data = Actions.getButtonData(opts.button);
|
|
1169
|
+
|
|
1170
|
+
if(opts.isDefault) {
|
|
1171
|
+
placement_obj['#' + tls_id + '_show'] = btn.id;
|
|
1172
|
+
}
|
|
1173
|
+
// TODO: Find way to set the current icon using the iconloader if this is not default
|
|
1174
|
+
|
|
1175
|
+
// Include data for extension button as well as ref button
|
|
1176
|
+
var cur_h = holders['#'+flyout_holder[0].id] = [{
|
|
1177
|
+
sel: '#'+id,
|
|
1178
|
+
fn: btn.events.click,
|
|
1179
|
+
icon: btn.id,
|
|
1180
|
+
key: btn.key,
|
|
1181
|
+
isDefault: btn.includeWith?btn.includeWith.isDefault:0
|
|
1182
|
+
}, ref_data];
|
|
1183
|
+
|
|
1184
|
+
// {sel:'#tool_rect', fn: clickRect, evt: 'mouseup', key: 4, parent: '#tools_rect', icon: 'rect'}
|
|
1185
|
+
|
|
1186
|
+
var pos = ("position" in opts)?opts.position:'last';
|
|
1187
|
+
var len = flyout_holder.children().length;
|
|
1188
|
+
|
|
1189
|
+
// Add at given position or end
|
|
1190
|
+
if(!isNaN(pos) && pos >= 0 && pos < len) {
|
|
1191
|
+
flyout_holder.children().eq(pos).before(button);
|
|
1192
|
+
} else {
|
|
1193
|
+
flyout_holder.append(button);
|
|
1194
|
+
cur_h.reverse();
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
if(!svgicons) {
|
|
1199
|
+
button.append(icon);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
if(!btn.list) {
|
|
1203
|
+
// Add given events to button
|
|
1204
|
+
$.each(btn.events, function(name, func) {
|
|
1205
|
+
if(name == "click") {
|
|
1206
|
+
if(btn.type == 'mode') {
|
|
1207
|
+
if(btn.includeWith) {
|
|
1208
|
+
button.bind(name, func);
|
|
1209
|
+
} else {
|
|
1210
|
+
button.bind(name, function() {
|
|
1211
|
+
if(toolButtonClick(button)) {
|
|
1212
|
+
func();
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
}
|
|
1216
|
+
if(btn.key) {
|
|
1217
|
+
$(document).bind('keydown', btn.key, func);
|
|
1218
|
+
if(btn.title) button.attr("title", btn.title + ' ['+btn.key+']');
|
|
1219
|
+
}
|
|
1220
|
+
} else {
|
|
1221
|
+
button.bind(name, func);
|
|
1222
|
+
}
|
|
1223
|
+
} else {
|
|
1224
|
+
button.bind(name, func);
|
|
1225
|
+
}
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
setupFlyouts(holders);
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
$.each(btn_selects, function() {
|
|
1232
|
+
addAltDropDown(this.elem, this.list, this.callback, {seticon: true});
|
|
1233
|
+
});
|
|
1234
|
+
|
|
1235
|
+
if (svgicons)
|
|
1236
|
+
cb_ready = false; // Delay callback
|
|
1237
|
+
|
|
1238
|
+
$.svgIcons(svgicons, {
|
|
1239
|
+
w:27, h:27,
|
|
1240
|
+
id_match: false,
|
|
1241
|
+
no_img: (!isWebkit),
|
|
1242
|
+
fallback: fallback_obj,
|
|
1243
|
+
placement: placement_obj,
|
|
1244
|
+
callback: function(icons) {
|
|
1245
|
+
// Non-ideal hack to make the icon match the current size
|
|
1246
|
+
if(curPrefs.iconsize && curPrefs.iconsize != 'm') {
|
|
1247
|
+
prepResize();
|
|
1248
|
+
}
|
|
1249
|
+
cb_ready = true; // Ready for callback
|
|
1250
|
+
runCallback();
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
runCallback();
|
|
1257
|
+
};
|
|
1258
|
+
|
|
1259
|
+
var getPaint = function(color, opac, type) {
|
|
1260
|
+
// update the editor's fill paint
|
|
1261
|
+
var opts = null;
|
|
1262
|
+
if (color.indexOf("url(#") === 0) {
|
|
1263
|
+
var refElem = svgCanvas.getRefElem(color);
|
|
1264
|
+
if(refElem) {
|
|
1265
|
+
refElem = refElem.cloneNode(true);
|
|
1266
|
+
} else {
|
|
1267
|
+
refElem = $("#" + type + "_color defs *")[0];
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
opts = { alpha: opac };
|
|
1271
|
+
opts[refElem.tagName] = refElem;
|
|
1272
|
+
}
|
|
1273
|
+
else if (color.indexOf("#") === 0) {
|
|
1274
|
+
opts = {
|
|
1275
|
+
alpha: opac,
|
|
1276
|
+
solidColor: color.substr(1)
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
else {
|
|
1280
|
+
opts = {
|
|
1281
|
+
alpha: opac,
|
|
1282
|
+
solidColor: 'none'
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
return new $.jGraduate.Paint(opts);
|
|
1286
|
+
};
|
|
1287
|
+
|
|
1288
|
+
// set the canvas properties at init
|
|
1289
|
+
var res = svgCanvas.getResolution();
|
|
1290
|
+
if(curConfig.baseUnit !== "px") {
|
|
1291
|
+
res.w = svgedit.units.convertUnit(res.w) + curConfig.baseUnit;
|
|
1292
|
+
res.h = svgedit.units.convertUnit(res.h) + curConfig.baseUnit;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
var createBackground = function(fill) {
|
|
1296
|
+
svgCanvas.createLayer("background")
|
|
1297
|
+
cur_shape = svgCanvas.addSvgElementFromJson({
|
|
1298
|
+
"element": "rect",
|
|
1299
|
+
"attr": {
|
|
1300
|
+
"x": -1,
|
|
1301
|
+
"y": -1,
|
|
1302
|
+
"width": res.w+2,
|
|
1303
|
+
"height": res.h+2,
|
|
1304
|
+
"stroke": "none",
|
|
1305
|
+
"id": "canvas_background",
|
|
1306
|
+
"opacity": 1,
|
|
1307
|
+
"fill": fill || "#fff",
|
|
1308
|
+
"style": "pointer-events:none"
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
svgCanvas.setCurrentLayer("Layer 1")
|
|
1312
|
+
svgCanvas.setCurrentLayerPosition("1")
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// create a new layer background if it doesn't exist
|
|
1316
|
+
if (!document.getElementById('canvas_background')) createBackground();
|
|
1317
|
+
var fill = document.getElementById('canvas_background').getAttribute("fill");
|
|
1318
|
+
|
|
1319
|
+
// updates the toolbar (colors, opacity, etc) based on the selected element
|
|
1320
|
+
// This function also updates the opacity and id elements that are in the context panel
|
|
1321
|
+
var updateToolbar = function() {
|
|
1322
|
+
if (selectedElement != null) {
|
|
1323
|
+
switch ( selectedElement.tagName ) {
|
|
1324
|
+
case 'use':
|
|
1325
|
+
$(".context_panel").hide();
|
|
1326
|
+
$("#use_panel").show();
|
|
1327
|
+
break;
|
|
1328
|
+
case 'image':
|
|
1329
|
+
$(".context_panel").hide();
|
|
1330
|
+
$("#image_panel").show();
|
|
1331
|
+
break;
|
|
1332
|
+
case 'foreignObject':
|
|
1333
|
+
$(".context_panel").hide();
|
|
1334
|
+
break;
|
|
1335
|
+
case 'g':
|
|
1336
|
+
case 'a':
|
|
1337
|
+
// Look for common styles
|
|
1338
|
+
var gWidth = null;
|
|
1339
|
+
|
|
1340
|
+
var childs = selectedElement.getElementsByTagName('*');
|
|
1341
|
+
for(var i = 0, len = childs.length; i < len; i++) {
|
|
1342
|
+
var swidth = childs[i].getAttribute("stroke-width");
|
|
1343
|
+
if(i === 0) {
|
|
1344
|
+
gWidth = swidth;
|
|
1345
|
+
} else if(gWidth !== swidth) {
|
|
1346
|
+
gWidth = null;
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
$('#stroke_width').val(gWidth === null ? "0" : gWidth);
|
|
1351
|
+
updateContextPanel();
|
|
1352
|
+
break;
|
|
1353
|
+
default:
|
|
1354
|
+
//removed because multiselect shouldnt set color
|
|
1355
|
+
//Editor.paintBox.fill.update(false);
|
|
1356
|
+
//Editor.paintBox.stroke.update(false);
|
|
1357
|
+
|
|
1358
|
+
$('#stroke_width').val(selectedElement.getAttribute("stroke-width") || 0);
|
|
1359
|
+
var dash = selectedElement.getAttribute("stroke-dasharray") || "none"
|
|
1360
|
+
$('option', '#stroke_style').removeAttr('selected');
|
|
1361
|
+
$('#stroke_style option[value="'+ dash +'"]').attr("selected", "selected");
|
|
1362
|
+
$('#stroke_style').trigger('change');
|
|
1363
|
+
|
|
1364
|
+
$.fn.dragInput.updateCursor($('#stroke_width')[0])
|
|
1365
|
+
$.fn.dragInput.updateCursor($('#blur')[0])
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
// All elements including image and group have opacity
|
|
1371
|
+
if(selectedElement != null) {
|
|
1372
|
+
var opac_perc = ((selectedElement.getAttribute("opacity")||1.0)*100);
|
|
1373
|
+
$('#group_opacity').val(opac_perc);
|
|
1374
|
+
$.fn.dragInput.updateCursor($('#group_opacity')[0])
|
|
1375
|
+
}
|
|
1376
|
+
};
|
|
1377
|
+
|
|
1378
|
+
var setImageURL = Editor.setImageURL = function(url) {
|
|
1379
|
+
if(!url) url = default_img_url;
|
|
1380
|
+
|
|
1381
|
+
svgCanvas.setImageURL(url);
|
|
1382
|
+
$('#image_url').val(url);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
var setInputWidth = function(elem) {
|
|
1386
|
+
var w = Math.min(Math.max(12 + elem.value.length * 6, 50), 300);
|
|
1387
|
+
$(elem).width(w);
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
// updates the context panel tools based on the selected element
|
|
1391
|
+
var updateContextPanel = function(e) {
|
|
1392
|
+
var elem = selectedElement;
|
|
1393
|
+
// If element has just been deleted, consider it null
|
|
1394
|
+
if(elem != null && !elem.parentNode) elem = null;
|
|
1395
|
+
if (multiselected && multiselected[0] != null && !multiselected[0].parentNode) multiselected = false;
|
|
1396
|
+
|
|
1397
|
+
var currentLayerName = svgCanvas.getCurrentDrawing().getCurrentLayerName();
|
|
1398
|
+
var currentMode = svgCanvas.getMode();
|
|
1399
|
+
var unit = curConfig.baseUnit !== 'px' ? curConfig.baseUnit : null;
|
|
1400
|
+
var is_node = currentMode == 'pathedit'; //elem ? (elem.id && elem.id.indexOf('pathpointgrip') == 0) : false;
|
|
1401
|
+
|
|
1402
|
+
if (is_node) {
|
|
1403
|
+
$('.context_panel').hide();
|
|
1404
|
+
$('#path_node_panel').show();
|
|
1405
|
+
$('#stroke_panel').hide();
|
|
1406
|
+
var point = path.getNodePoint();
|
|
1407
|
+
$('#tool_add_subpath').removeClass('push_button_pressed').addClass('tool_button');
|
|
1408
|
+
$('#tool_node_delete').toggleClass('disabled', !path.canDeleteNodes);
|
|
1409
|
+
|
|
1410
|
+
// Show open/close button based on selected point
|
|
1411
|
+
setIcon('#tool_openclose_path', path.closed_subpath ? 'open_path' : 'close_path');
|
|
1412
|
+
|
|
1413
|
+
if(point) {
|
|
1414
|
+
var seg_type = $('#seg_type');
|
|
1415
|
+
if(unit) {
|
|
1416
|
+
point.x = svgedit.units.convertUnit(point.x);
|
|
1417
|
+
point.y = svgedit.units.convertUnit(point.y);
|
|
1418
|
+
}
|
|
1419
|
+
$('#path_node_x').val(Math.round(point.x));
|
|
1420
|
+
$('#path_node_y').val(Math.round(point.y));
|
|
1421
|
+
if(point.type) {
|
|
1422
|
+
seg_type.val(point.type).removeAttr('disabled');
|
|
1423
|
+
$("#seg_type_label").html(point.type == 4 ? "Straight" : "Curve")
|
|
1424
|
+
} else {
|
|
1425
|
+
seg_type.val(4).attr('disabled','disabled');
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
$("#tools_top").removeClass("multiselected")
|
|
1429
|
+
$("#stroke_panel").hide();
|
|
1430
|
+
$("#canvas_panel").hide();
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
var menu_items = $('#cmenu_canvas li');
|
|
1435
|
+
$('.context_panel').hide();
|
|
1436
|
+
$('.menu_item', '#edit_menu').addClass('disabled');
|
|
1437
|
+
$('.menu_item', '#object_menu').addClass('disabled');
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
//hack to show the proper multialign box
|
|
1441
|
+
if (multiselected) {
|
|
1442
|
+
multiselected = multiselected.filter(Boolean);
|
|
1443
|
+
elem = (svgCanvas.elementsAreSame(multiselected)) ? multiselected[0] : null
|
|
1444
|
+
if (elem) $("#tools_top").addClass("multiselected")
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
if (!elem && !multiselected) {
|
|
1448
|
+
$("#tools_top").removeClass("multiselected")
|
|
1449
|
+
$("#stroke_panel").hide();
|
|
1450
|
+
$("#canvas_panel").show();
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
if (elem != null) {
|
|
1454
|
+
$("#stroke_panel").show();
|
|
1455
|
+
var elname = elem.nodeName;
|
|
1456
|
+
var angle = svgCanvas.getRotationAngle(elem);
|
|
1457
|
+
$('#angle').val(Math.round(angle));
|
|
1458
|
+
|
|
1459
|
+
var blurval = svgCanvas.getBlur(elem);
|
|
1460
|
+
$('#blur').val(blurval);
|
|
1461
|
+
if(!is_node && currentMode != 'pathedit') {
|
|
1462
|
+
$('#selected_panel').show();
|
|
1463
|
+
$('.action_selected').removeClass('disabled');
|
|
1464
|
+
// Elements in this array already have coord fields
|
|
1465
|
+
var x, y
|
|
1466
|
+
if(['g', 'polyline', 'path'].indexOf(elname) >= 0) {
|
|
1467
|
+
var bb = svgCanvas.getStrokedBBox([elem]);
|
|
1468
|
+
if(bb) {
|
|
1469
|
+
x = bb.x;
|
|
1470
|
+
y = bb.y;
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
if(unit) {
|
|
1475
|
+
x = svgedit.units.convertUnit(x);
|
|
1476
|
+
y = svgedit.units.convertUnit(y);
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
$("#" + elname +"_x").val(Math.round(x))
|
|
1480
|
+
$("#" + elname +"_y").val(Math.round(y))
|
|
1481
|
+
if (elname === "polyline") {
|
|
1482
|
+
//we're acting as if polylines were paths
|
|
1483
|
+
$("#path_x").val(Math.round(x))
|
|
1484
|
+
$("#path_y").val(Math.round(y))
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
// Elements in this array cannot be converted to a path
|
|
1488
|
+
var no_path = ['image', 'text', 'path', 'g', 'use'].indexOf(elname) == -1;
|
|
1489
|
+
if (no_path) $('.action_path_convert_selected').removeClass('disabled');
|
|
1490
|
+
if (elname === "path") $('.action_path_selected').removeClass('disabled');
|
|
1491
|
+
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
var link_href = null;
|
|
1495
|
+
if (el_name === 'a') {
|
|
1496
|
+
link_href = svgCanvas.getHref(elem);
|
|
1497
|
+
$('#g_panel').show();
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
if(elem.parentNode.tagName === 'a') {
|
|
1501
|
+
if(!$(elem).siblings().length) {
|
|
1502
|
+
$('#a_panel').show();
|
|
1503
|
+
link_href = svgCanvas.getHref(elem.parentNode);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// Hide/show the make_link buttons
|
|
1508
|
+
$('#tool_make_link, #tool_make_link').toggle(!link_href);
|
|
1509
|
+
|
|
1510
|
+
if(link_href) {
|
|
1511
|
+
$('#link_url').val(link_href);
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
// update contextual tools here
|
|
1515
|
+
var panels = {
|
|
1516
|
+
g: [],
|
|
1517
|
+
a: [],
|
|
1518
|
+
rect: ['rx','width','height', 'x', 'y'],
|
|
1519
|
+
image: ['width','height', 'x', 'y'],
|
|
1520
|
+
circle: ['cx','cy','r'],
|
|
1521
|
+
ellipse: ['cx','cy','rx','ry'],
|
|
1522
|
+
line: ['x1','y1','x2','y2'],
|
|
1523
|
+
text: ['x', 'y'],
|
|
1524
|
+
'use': [],
|
|
1525
|
+
path : []
|
|
1526
|
+
};
|
|
1527
|
+
|
|
1528
|
+
var el_name = elem.tagName;
|
|
1529
|
+
|
|
1530
|
+
if($(elem).data('gsvg')) {
|
|
1531
|
+
$('#g_panel').show();
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
if (el_name == "path" || el_name == "polyline") {
|
|
1535
|
+
$('#path_panel').show();
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
if(panels[el_name]) {
|
|
1539
|
+
var cur_panel = panels[el_name];
|
|
1540
|
+
$('#' + el_name + '_panel').show();
|
|
1541
|
+
|
|
1542
|
+
// corner radius has to live in a different panel
|
|
1543
|
+
// because otherwise it changes the position of the
|
|
1544
|
+
// of the elements
|
|
1545
|
+
if(el_name == "rect") $("#cornerRadiusLabel").show()
|
|
1546
|
+
else $("#cornerRadiusLabel").hide()
|
|
1547
|
+
|
|
1548
|
+
$.each(cur_panel, function(i, item) {
|
|
1549
|
+
var attrVal = elem.getAttribute(item);
|
|
1550
|
+
if(curConfig.baseUnit !== 'px' && elem[item]) {
|
|
1551
|
+
var bv = elem[item].baseVal.value;
|
|
1552
|
+
attrVal = svgedit.units.convertUnit(bv);
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
//update the draginput cursors
|
|
1556
|
+
var name_item = document.getElementById(el_name + '_' + item);
|
|
1557
|
+
name_item.value = Math.round(attrVal) || 0;
|
|
1558
|
+
if (name_item.getAttribute("data-cursor") === "true") {
|
|
1559
|
+
$.fn.dragInput.updateCursor(name_item );
|
|
1560
|
+
}
|
|
1561
|
+
});
|
|
1562
|
+
|
|
1563
|
+
if(el_name == 'text') {
|
|
1564
|
+
var font_family = elem.getAttribute("font-family");
|
|
1565
|
+
var select = document.getElementById("font_family_dropdown");
|
|
1566
|
+
select.selectedIndex = 3
|
|
1567
|
+
|
|
1568
|
+
$('#text_panel').css("display", "inline");
|
|
1569
|
+
$('#tool_italic').toggleClass('active', svgCanvas.getItalic())
|
|
1570
|
+
$('#tool_bold').toggleClass('active', svgCanvas.getBold())
|
|
1571
|
+
$('#font_family').val(font_family);
|
|
1572
|
+
$('#font_size').val(elem.getAttribute("font-size"));
|
|
1573
|
+
$('#text').val(elem.textContent);
|
|
1574
|
+
$('#preview_font').text(font_family.split(",")[0].replace(/'/g, "")).css('font-family', font_family);
|
|
1575
|
+
if (svgCanvas.addedNew) {
|
|
1576
|
+
// Timeout needed for IE9
|
|
1577
|
+
setTimeout(function() {
|
|
1578
|
+
$('#text').focus().select();
|
|
1579
|
+
},100);
|
|
1580
|
+
}
|
|
1581
|
+
} // text
|
|
1582
|
+
else if(el_name == 'image') {
|
|
1583
|
+
setImageURL(svgCanvas.getHref(elem));
|
|
1584
|
+
} // image
|
|
1585
|
+
else if(el_name === 'g' || el_name === 'use') {
|
|
1586
|
+
$('#container_panel').show();
|
|
1587
|
+
$('.action_group_selected').removeClass('disabled');
|
|
1588
|
+
var title = svgCanvas.getTitle();
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
menu_items[(el_name === 'g' ? 'en':'dis') + 'ableContextMenuItems']('#ungroup');
|
|
1592
|
+
menu_items[((el_name === 'g' || !multiselected) ? 'dis':'en') + 'ableContextMenuItems']('#group');
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
if (multiselected) {
|
|
1596
|
+
$('#multiselected_panel').show();
|
|
1597
|
+
$('.action_multi_selected').removeClass('disabled');
|
|
1598
|
+
menu_items
|
|
1599
|
+
.enableContextMenuItems('#group')
|
|
1600
|
+
.disableContextMenuItems('#ungroup');
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
if (!elem) {
|
|
1604
|
+
menu_items.disableContextMenuItems('#delete,#cut,#copy,#group,#ungroup,#move_front,#move_up,#move_down,#move_back');
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// update history buttons
|
|
1608
|
+
if (undoMgr.getUndoStackSize() > 0) {
|
|
1609
|
+
$('#tool_undo').removeClass( 'disabled');
|
|
1610
|
+
}
|
|
1611
|
+
else {
|
|
1612
|
+
$('#tool_undo').addClass( 'disabled');
|
|
1613
|
+
}
|
|
1614
|
+
if (undoMgr.getRedoStackSize() > 0) {
|
|
1615
|
+
$('#tool_redo').removeClass( 'disabled');
|
|
1616
|
+
}
|
|
1617
|
+
else {
|
|
1618
|
+
$('#tool_redo').addClass( 'disabled');
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
svgCanvas.addedNew = false;
|
|
1622
|
+
|
|
1623
|
+
if ( (elem && !is_node) || multiselected) {
|
|
1624
|
+
// update the selected elements' layer
|
|
1625
|
+
$('#selLayerNames').removeAttr('disabled').val(currentLayerName);
|
|
1626
|
+
|
|
1627
|
+
// Enable regular menu options
|
|
1628
|
+
canv_menu.enableContextMenuItems('#delete,#cut,#copy,#move_front,#move_up,#move_down,#move_back');
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
|
|
1632
|
+
$('#text').on("focus", function(e){ textBeingEntered = true; } );
|
|
1633
|
+
$('#text').on("blur", function(){ textBeingEntered = false; } );
|
|
1634
|
+
|
|
1635
|
+
// bind the selected event to our function that handles updates to the UI
|
|
1636
|
+
svgCanvas.bind("selected", selectedChanged);
|
|
1637
|
+
svgCanvas.bind("transition", elementTransition);
|
|
1638
|
+
svgCanvas.bind("changed", elementChanged);
|
|
1639
|
+
svgCanvas.bind("saved", saveHandler);
|
|
1640
|
+
svgCanvas.bind("exported", exportHandler);
|
|
1641
|
+
svgCanvas.bind("zoomed", zoomChanged);
|
|
1642
|
+
svgCanvas.bind("contextset", contextChanged);
|
|
1643
|
+
svgCanvas.bind("extension_added", extAdded);
|
|
1644
|
+
svgCanvas.textActions.setInputElem($("#text")[0]);
|
|
1645
|
+
|
|
1646
|
+
var str = '<div class="palette_item transparent" data-rgb="none"></div>\
|
|
1647
|
+
<div class="palette_item black" data-rgb="#000000"></div>\
|
|
1648
|
+
<div class="palette_item white" data-rgb="#ffffff"></div>'
|
|
1649
|
+
palette.forEach(function(item, i){
|
|
1650
|
+
str += '<div class="palette_item" style="background-color: ' + item + ';" data-rgb="' + item + '"></div>';
|
|
1651
|
+
});
|
|
1652
|
+
$('#palette').append(str);
|
|
1653
|
+
|
|
1654
|
+
var changeFontSize = function(ctl) {
|
|
1655
|
+
svgCanvas.setFontSize(ctl.value);
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
var changeStrokeWidth = function(ctl) {
|
|
1659
|
+
var val = ctl.value;
|
|
1660
|
+
if(val == 0 && selectedElement && ['line', 'polyline'].indexOf(selectedElement.nodeName) >= 0) {
|
|
1661
|
+
val = ctl.value = 1;
|
|
1662
|
+
}
|
|
1663
|
+
svgCanvas.setStrokeWidth(val);
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
//cache
|
|
1667
|
+
var $indicator = $('#tool_angle_indicator')
|
|
1668
|
+
var $reorient = $('#tool_reorient')
|
|
1669
|
+
|
|
1670
|
+
rotateCursor = function(angle){
|
|
1671
|
+
var rotate_string = 'rotate('+ angle + 'deg)'
|
|
1672
|
+
$indicator.css({
|
|
1673
|
+
'-webkit-transform': rotate_string,
|
|
1674
|
+
'-moz-transform': rotate_string,
|
|
1675
|
+
'-o-transform': rotate_string,
|
|
1676
|
+
'-ms-transform': rotate_string,
|
|
1677
|
+
'transform': rotate_string
|
|
1678
|
+
});
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
var changeRotationAngle = function(ctl) {
|
|
1682
|
+
var preventUndo = true;
|
|
1683
|
+
svgCanvas.setRotationAngle(ctl.value, preventUndo);
|
|
1684
|
+
rotateCursor(ctl.value)
|
|
1685
|
+
$('#tool_reorient').toggleClass('disabled', ctl.value == 0);
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
var changeZoom = function(ctl) {
|
|
1689
|
+
var zoomlevel = ctl.value / 100;
|
|
1690
|
+
if(zoomlevel < .001) {
|
|
1691
|
+
ctl.value = .1;
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
var zoom = svgCanvas.getZoom();
|
|
1695
|
+
var w_area = workarea;
|
|
1696
|
+
zoomChanged(window, {
|
|
1697
|
+
width: 0,
|
|
1698
|
+
height: 0,
|
|
1699
|
+
// center pt of scroll position
|
|
1700
|
+
x: (w_area[0].scrollLeft + w_area.width()/2)/zoom,
|
|
1701
|
+
y: (w_area[0].scrollTop + w_area.height()/2)/zoom,
|
|
1702
|
+
zoom: zoomlevel
|
|
1703
|
+
}, true);
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
var changeBlur = function(ctl, completed) {
|
|
1707
|
+
val = ctl.value;
|
|
1708
|
+
$('#blur').val(val);
|
|
1709
|
+
if (completed) {
|
|
1710
|
+
svgCanvas.setBlur(val, true);
|
|
1711
|
+
}
|
|
1712
|
+
else {
|
|
1713
|
+
svgCanvas.setBlurNoUndo(val);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
var operaRepaint = function() {
|
|
1718
|
+
// Repaints canvas in Opera. Needed for stroke-dasharray change as well as fill change
|
|
1719
|
+
if(!window.opera) return;
|
|
1720
|
+
$('<p/>').hide().appendTo('body').remove();
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
$('#stroke_style').change(function(){
|
|
1724
|
+
svgCanvas.setStrokeAttr('stroke-dasharray', $(this).val());
|
|
1725
|
+
$("#stroke_style_label").html(this.options[this.selectedIndex].text)
|
|
1726
|
+
operaRepaint();
|
|
1727
|
+
});
|
|
1728
|
+
|
|
1729
|
+
$('#seg_type').change(function() {
|
|
1730
|
+
svgCanvas.setSegType($(this).val());
|
|
1731
|
+
$("#seg_type_label").html(this.options[this.selectedIndex].text)
|
|
1732
|
+
});
|
|
1733
|
+
|
|
1734
|
+
// Lose focus for select elements when changed (Allows keyboard shortcuts to work better)
|
|
1735
|
+
$('select').change(function(){$(this).blur();});
|
|
1736
|
+
|
|
1737
|
+
$('#font_family').change(function() {
|
|
1738
|
+
svgCanvas.setFontFamily(this.value);
|
|
1739
|
+
});
|
|
1740
|
+
|
|
1741
|
+
$('#text').keyup(function(){
|
|
1742
|
+
svgCanvas.setTextContent(this.value);
|
|
1743
|
+
});
|
|
1744
|
+
|
|
1745
|
+
changeAttribute = function(el, completed) {
|
|
1746
|
+
var attr = el.getAttribute("data-attr");
|
|
1747
|
+
var multiplier = el.getAttribute("data-multiplier") || 1;
|
|
1748
|
+
multiplier = parseFloat(multiplier);
|
|
1749
|
+
var val = el.value * multiplier;
|
|
1750
|
+
var valid = svgedit.units.isValidUnit(attr, val, selectedElement);
|
|
1751
|
+
if(!valid) {
|
|
1752
|
+
$.alert(uiStrings.notification.invalidAttrValGiven);
|
|
1753
|
+
el.value = selectedElement.getAttribute(attr);
|
|
1754
|
+
return false;
|
|
1755
|
+
}
|
|
1756
|
+
//if (!noUndo) svgCanvas.changeSelectedAttribute(attr, val);
|
|
1757
|
+
svgCanvas.changeSelectedAttributeNoUndo(attr, val);
|
|
1758
|
+
};
|
|
1759
|
+
|
|
1760
|
+
picking = false;
|
|
1761
|
+
$(document).on("mouseup", function(){picking = false;})
|
|
1762
|
+
|
|
1763
|
+
$('#palette').on("mousemove mousedown touchstart touchmove", ".palette_item", function(evt){
|
|
1764
|
+
evt.preventDefault();
|
|
1765
|
+
|
|
1766
|
+
if (evt.type == "mousedown") picking = true;
|
|
1767
|
+
if (picking) {
|
|
1768
|
+
var isStroke = $('#tool_stroke').hasClass('active');
|
|
1769
|
+
var picker = isStroke ? "stroke" : "fill";
|
|
1770
|
+
var color = $(this).attr('data-rgb');
|
|
1771
|
+
var paint = null;
|
|
1772
|
+
var noUndo = true;
|
|
1773
|
+
if (evt.type == "mousedown") noUndo = false
|
|
1774
|
+
// Webkit-based browsers returned 'initial' here for no stroke
|
|
1775
|
+
if (color === 'transparent' || color === 'initial' || color === '#none') {
|
|
1776
|
+
color = 'none';
|
|
1777
|
+
paint = new $.jGraduate.Paint();
|
|
1778
|
+
}
|
|
1779
|
+
else {
|
|
1780
|
+
paint = new $.jGraduate.Paint({alpha: 100, solidColor: color.substr(1)});
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
Editor.paintBox[picker].setPaint(paint);
|
|
1784
|
+
|
|
1785
|
+
if (isStroke) {
|
|
1786
|
+
svgCanvas.setColor('stroke', color, noUndo);
|
|
1787
|
+
if (color != 'none' && svgCanvas.getStrokeOpacity() != 1) {
|
|
1788
|
+
svgCanvas.setPaintOpacity('stroke', 1.0);
|
|
1789
|
+
}
|
|
1790
|
+
} else {
|
|
1791
|
+
svgCanvas.setColor('fill', color, noUndo);
|
|
1792
|
+
if (color != 'none' && svgCanvas.getFillOpacity() != 1) {
|
|
1793
|
+
svgCanvas.setPaintOpacity('fill', 1.0);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
}).bind('contextmenu', function(e) {e.preventDefault()});
|
|
1798
|
+
|
|
1799
|
+
$("#toggle_stroke_tools").toggle(function() {
|
|
1800
|
+
$(".stroke_tool").css('display','table-cell');
|
|
1801
|
+
$(this).addClass('expanded');
|
|
1802
|
+
resetScrollPos();
|
|
1803
|
+
}, function() {
|
|
1804
|
+
$(".stroke_tool").css('display','none');
|
|
1805
|
+
$(this).removeClass('expanded');
|
|
1806
|
+
resetScrollPos();
|
|
1807
|
+
});
|
|
1808
|
+
|
|
1809
|
+
// This is a common function used when a tool has been clicked (chosen)
|
|
1810
|
+
// It does several common things:
|
|
1811
|
+
// - removes the tool_button_current class from whatever tool currently has it
|
|
1812
|
+
// - hides any flyouts
|
|
1813
|
+
// - adds the tool_button_current class to the button passed in
|
|
1814
|
+
var toolButtonClick = function(button, noHiding) {
|
|
1815
|
+
if ($(button).hasClass('disabled')) return false;
|
|
1816
|
+
if($(button).parent().hasClass('tools_flyout')) return true;
|
|
1817
|
+
var fadeFlyouts = fadeFlyouts || 'normal';
|
|
1818
|
+
if(!noHiding) {
|
|
1819
|
+
$('.tools_flyout').fadeOut(fadeFlyouts);
|
|
1820
|
+
}
|
|
1821
|
+
$('#styleoverrides').text('');
|
|
1822
|
+
$('.tool_button_current').removeClass('tool_button_current').addClass('tool_button');
|
|
1823
|
+
$(button).addClass('tool_button_current').removeClass('tool_button');
|
|
1824
|
+
return true;
|
|
1825
|
+
};
|
|
1826
|
+
|
|
1827
|
+
(function() {
|
|
1828
|
+
var last_x = null, last_y = null, w_area = workarea[0],
|
|
1829
|
+
panning = false, keypan = false;
|
|
1830
|
+
|
|
1831
|
+
var move_pan = function(evt) {
|
|
1832
|
+
if(panning === false) return;
|
|
1833
|
+
|
|
1834
|
+
w_area.scrollLeft -= (evt.clientX - last_x);
|
|
1835
|
+
w_area.scrollTop -= (evt.clientY - last_y);
|
|
1836
|
+
last_x = evt.clientX;
|
|
1837
|
+
last_y = evt.clientY;
|
|
1838
|
+
if(evt.type === 'mouseup' || evt.type === 'touchend') panning = false;
|
|
1839
|
+
return false;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
var start_pan = function(evt) {
|
|
1843
|
+
if(evt.button === 1 || keypan === true || (evt.originalEvent.touches && evt.originalEvent.touches.length >= 2)) {
|
|
1844
|
+
panning = true;
|
|
1845
|
+
last_x = evt.clientX;
|
|
1846
|
+
last_y = evt.clientY;
|
|
1847
|
+
return false;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
$('#svgcanvas')
|
|
1852
|
+
.on('mousemove mouseup touchend', move_pan)
|
|
1853
|
+
.on("mousedown touchmove", start_pan)
|
|
1854
|
+
|
|
1855
|
+
$(window).mouseup(function() {
|
|
1856
|
+
panning = false;
|
|
1857
|
+
});
|
|
1858
|
+
|
|
1859
|
+
$(document).bind('keydown', 'space', function(evt) {
|
|
1860
|
+
evt.preventDefault();
|
|
1861
|
+
svgCanvas.spaceKey = keypan = true;
|
|
1862
|
+
|
|
1863
|
+
}).bind('keyup', 'space', function(evt) {
|
|
1864
|
+
evt.preventDefault();
|
|
1865
|
+
svgCanvas.spaceKey = keypan = false;
|
|
1866
|
+
}).bind('keydown', 'alt', function(evt) {
|
|
1867
|
+
if(svgCanvas.getMode() === 'zoom') {
|
|
1868
|
+
workarea.addClass('out');
|
|
1869
|
+
}
|
|
1870
|
+
}).bind('keyup', 'alt', function(evt) {
|
|
1871
|
+
if(svgCanvas.getMode() === 'zoom') {
|
|
1872
|
+
workarea.removeClass('out');
|
|
1873
|
+
}
|
|
1874
|
+
})
|
|
1875
|
+
}());
|
|
1876
|
+
|
|
1877
|
+
|
|
1878
|
+
function setStrokeOpt(opt, changeElem) {
|
|
1879
|
+
var id = opt.id;
|
|
1880
|
+
var bits = id.split('_');
|
|
1881
|
+
var pre = bits[0];
|
|
1882
|
+
var val = bits[1];
|
|
1883
|
+
|
|
1884
|
+
if(changeElem) {
|
|
1885
|
+
svgCanvas.setStrokeAttr('stroke-' + pre, val);
|
|
1886
|
+
}
|
|
1887
|
+
operaRepaint();
|
|
1888
|
+
setIcon('#cur_' + pre , id, 20);
|
|
1889
|
+
$(opt).addClass('current').siblings().removeClass('current');
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
//menu handling
|
|
1893
|
+
var menus = $('.menu');
|
|
1894
|
+
var blinker = function(e) {
|
|
1895
|
+
e.target.style.background = "#fff";
|
|
1896
|
+
setTimeout(function(){e.target.style.background = "#ddd";}, 50);
|
|
1897
|
+
setTimeout(function(){e.target.style.background = "#fff";}, 150);
|
|
1898
|
+
setTimeout(function(){e.target.style.background = "#ddd";}, 200);
|
|
1899
|
+
setTimeout(function(){e.target.style.background = "";}, 200);
|
|
1900
|
+
setTimeout(function(){$('#menu_bar').removeClass('active')}, 220);
|
|
1901
|
+
return false;
|
|
1902
|
+
}
|
|
1903
|
+
var closer = function(e){
|
|
1904
|
+
if (e.target.nodeName && e.target.nodeName.toLowerCase() === "input") return false;
|
|
1905
|
+
if (!$(e.target).hasClass("menu_title") && !$(e.target).parent().hasClass("menu_title")) {
|
|
1906
|
+
if(!$(e.target).hasClass("disabled") && $(e.target).hasClass("menu_item")) blinker(e)
|
|
1907
|
+
else $('#menu_bar').removeClass('active')
|
|
1908
|
+
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
$('.menu_item').on('mousedown touchstart', function(e){blinker(e)});
|
|
1913
|
+
$("svg, body").on('mousedown touchstart', function(e){closer(e)});
|
|
1914
|
+
|
|
1915
|
+
var accumulatedDelta = 0
|
|
1916
|
+
$('#workarea').on('mousewheel', function(e, delta, deltaX, deltaY){
|
|
1917
|
+
if (e.altKey) {
|
|
1918
|
+
e.preventDefault();
|
|
1919
|
+
zoom = parseInt($("#zoom").val())
|
|
1920
|
+
$("#zoom").val(parseInt(zoom + deltaY*10)).change()
|
|
1921
|
+
}
|
|
1922
|
+
})
|
|
1923
|
+
$('.menu_title')
|
|
1924
|
+
.on('mousedown', function() {
|
|
1925
|
+
$("#tools_shapelib").hide()
|
|
1926
|
+
$("#menu_bar").toggleClass('active');
|
|
1927
|
+
menus.removeClass('open');
|
|
1928
|
+
$(this).parent().addClass('open');
|
|
1929
|
+
})
|
|
1930
|
+
.on('mouseover', function() {
|
|
1931
|
+
menus.removeClass('open');
|
|
1932
|
+
$(this).parent().addClass('open');
|
|
1933
|
+
});
|
|
1934
|
+
|
|
1935
|
+
|
|
1936
|
+
// Made public for UI customization.
|
|
1937
|
+
// TODO: Group UI functions into a public methodDraw.ui interface.
|
|
1938
|
+
Editor.addDropDown = function(elem, callback, dropUp) {
|
|
1939
|
+
if ($(elem).length == 0) return; // Quit if called on non-existant element
|
|
1940
|
+
var button = $(elem).find('button');
|
|
1941
|
+
|
|
1942
|
+
var list = $(elem).find('ul').attr('id', $(elem)[0].id + '-list');
|
|
1943
|
+
|
|
1944
|
+
if(!dropUp) {
|
|
1945
|
+
// Move list to place where it can overflow container
|
|
1946
|
+
$('#option_lists').append(list);
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
var on_button = false;
|
|
1950
|
+
if(dropUp) {
|
|
1951
|
+
$(elem).addClass('dropup');
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
list.find('li').bind('mouseup', callback);
|
|
1955
|
+
|
|
1956
|
+
$(window).mouseup(function(evt) {
|
|
1957
|
+
if(!on_button) {
|
|
1958
|
+
button.removeClass('down');
|
|
1959
|
+
list.hide();
|
|
1960
|
+
}
|
|
1961
|
+
on_button = false;
|
|
1962
|
+
});
|
|
1963
|
+
|
|
1964
|
+
button.bind('mousedown',function() {
|
|
1965
|
+
if (!button.hasClass('down')) {
|
|
1966
|
+
button.addClass('down');
|
|
1967
|
+
|
|
1968
|
+
if(!dropUp) {
|
|
1969
|
+
var pos = $(elem).offset();
|
|
1970
|
+
// position slider
|
|
1971
|
+
list.css({
|
|
1972
|
+
top: pos.top,
|
|
1973
|
+
left: pos.left - 110
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
list.show();
|
|
1977
|
+
|
|
1978
|
+
on_button = true;
|
|
1979
|
+
} else {
|
|
1980
|
+
button.removeClass('down');
|
|
1981
|
+
list.hide();
|
|
1982
|
+
}
|
|
1983
|
+
}).hover(function() {
|
|
1984
|
+
on_button = true;
|
|
1985
|
+
}).mouseout(function() {
|
|
1986
|
+
on_button = false;
|
|
1987
|
+
});
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
// TODO: Combine this with addDropDown or find other way to optimize
|
|
1991
|
+
var addAltDropDown = function(elem, list, callback, opts) {
|
|
1992
|
+
var button = $(elem);
|
|
1993
|
+
var list = $(list);
|
|
1994
|
+
var on_button = false;
|
|
1995
|
+
var dropUp = opts.dropUp;
|
|
1996
|
+
if(dropUp) {
|
|
1997
|
+
$(elem).addClass('dropup');
|
|
1998
|
+
}
|
|
1999
|
+
list.find('li').bind('mouseup', function() {
|
|
2000
|
+
if(opts.seticon) {
|
|
2001
|
+
setIcon('#cur_' + button[0].id , $(this).children());
|
|
2002
|
+
$(this).addClass('current').siblings().removeClass('current');
|
|
2003
|
+
}
|
|
2004
|
+
callback.apply(this, arguments);
|
|
2005
|
+
|
|
2006
|
+
});
|
|
2007
|
+
|
|
2008
|
+
$(window).mouseup(function(evt) {
|
|
2009
|
+
if(!on_button) {
|
|
2010
|
+
button.removeClass('down');
|
|
2011
|
+
list.hide();
|
|
2012
|
+
list.css({top:0, left:0});
|
|
2013
|
+
}
|
|
2014
|
+
on_button = false;
|
|
2015
|
+
});
|
|
2016
|
+
|
|
2017
|
+
var height = list.height();
|
|
2018
|
+
$(elem).bind('mousedown',function() {
|
|
2019
|
+
var off = $(elem).offset();
|
|
2020
|
+
if(dropUp) {
|
|
2021
|
+
off.top -= list.height();
|
|
2022
|
+
off.left += 8;
|
|
2023
|
+
} else {
|
|
2024
|
+
off.top += $(elem).height();
|
|
2025
|
+
}
|
|
2026
|
+
$(list).offset(off);
|
|
2027
|
+
|
|
2028
|
+
if (!button.hasClass('down')) {
|
|
2029
|
+
button.addClass('down');
|
|
2030
|
+
list.show();
|
|
2031
|
+
on_button = true;
|
|
2032
|
+
return false;
|
|
2033
|
+
} else {
|
|
2034
|
+
button.removeClass('down');
|
|
2035
|
+
// CSS position must be reset for Webkit
|
|
2036
|
+
list.hide();
|
|
2037
|
+
list.css({top:0, left:0});
|
|
2038
|
+
}
|
|
2039
|
+
}).hover(function() {
|
|
2040
|
+
on_button = true;
|
|
2041
|
+
}).mouseout(function() {
|
|
2042
|
+
on_button = false;
|
|
2043
|
+
});
|
|
2044
|
+
|
|
2045
|
+
if(opts.multiclick) {
|
|
2046
|
+
list.mousedown(function() {
|
|
2047
|
+
on_button = true;
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
$('#font_family_dropdown').change(function() {
|
|
2053
|
+
var fam = this.options[this.selectedIndex].value
|
|
2054
|
+
var fam_display = this.options[this.selectedIndex].text
|
|
2055
|
+
$('#preview_font').html(fam_display).css("font-family", fam);
|
|
2056
|
+
$('#font_family').val(fam).change();
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
$('div', '#position_opts').each(function(){
|
|
2060
|
+
this.addEventListener("mouseup", function(){
|
|
2061
|
+
var letter = this.id.replace('tool_pos','').charAt(0);
|
|
2062
|
+
svgCanvas.alignSelectedElements(letter, 'page');
|
|
2063
|
+
})
|
|
2064
|
+
});
|
|
2065
|
+
|
|
2066
|
+
/*
|
|
2067
|
+
|
|
2068
|
+
When a flyout icon is selected
|
|
2069
|
+
(if flyout) {
|
|
2070
|
+
- Change the icon
|
|
2071
|
+
- Make pressing the button run its stuff
|
|
2072
|
+
}
|
|
2073
|
+
- Run its stuff
|
|
2074
|
+
|
|
2075
|
+
When its shortcut key is pressed
|
|
2076
|
+
- If not current in list, do as above
|
|
2077
|
+
, else:
|
|
2078
|
+
- Just run its stuff
|
|
2079
|
+
|
|
2080
|
+
*/
|
|
2081
|
+
|
|
2082
|
+
// Unfocus text input when workarea is mousedowned.
|
|
2083
|
+
(function() {
|
|
2084
|
+
var inp;
|
|
2085
|
+
var unfocus = function() {
|
|
2086
|
+
$(inp).blur();
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
$('#svg_editor').find('button, select, input:not(#text)').focus(function() {
|
|
2090
|
+
inp = this;
|
|
2091
|
+
ui_context = 'toolbars';
|
|
2092
|
+
workarea.mousedown(unfocus);
|
|
2093
|
+
}).blur(function() {
|
|
2094
|
+
ui_context = 'canvas';
|
|
2095
|
+
workarea.unbind('mousedown', unfocus);
|
|
2096
|
+
// Go back to selecting text if in textedit mode
|
|
2097
|
+
if(svgCanvas.getMode() == 'textedit') {
|
|
2098
|
+
$('#text').focus();
|
|
2099
|
+
}
|
|
2100
|
+
});
|
|
2101
|
+
|
|
2102
|
+
}());
|
|
2103
|
+
|
|
2104
|
+
var clickSelect = function() {
|
|
2105
|
+
if (toolButtonClick('#tool_select')) {
|
|
2106
|
+
svgCanvas.setMode('select');
|
|
2107
|
+
}
|
|
2108
|
+
};
|
|
2109
|
+
|
|
2110
|
+
var clickFHPath = function() {
|
|
2111
|
+
if (toolButtonClick('#tool_fhpath')) {
|
|
2112
|
+
svgCanvas.setMode('fhpath');
|
|
2113
|
+
}
|
|
2114
|
+
};
|
|
2115
|
+
|
|
2116
|
+
var clickLine = function() {
|
|
2117
|
+
if (toolButtonClick('#tool_line')) {
|
|
2118
|
+
svgCanvas.setMode('line');
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
2121
|
+
|
|
2122
|
+
var clickSquare = function(){
|
|
2123
|
+
if (toolButtonClick('#tool_square')) {
|
|
2124
|
+
svgCanvas.setMode('square');
|
|
2125
|
+
}
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2128
|
+
var clickRect = function(){
|
|
2129
|
+
if (toolButtonClick('#tool_rect')) {
|
|
2130
|
+
svgCanvas.setMode('rect');
|
|
2131
|
+
}
|
|
2132
|
+
};
|
|
2133
|
+
|
|
2134
|
+
var clickFHRect = function(){
|
|
2135
|
+
if (toolButtonClick('#tool_fhrect')) {
|
|
2136
|
+
svgCanvas.setMode('fhrect');
|
|
2137
|
+
}
|
|
2138
|
+
};
|
|
2139
|
+
|
|
2140
|
+
var clickCircle = function(){
|
|
2141
|
+
if (toolButtonClick('#tool_circle')) {
|
|
2142
|
+
svgCanvas.setMode('circle');
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
|
|
2146
|
+
var clickEllipse = function(){
|
|
2147
|
+
if (toolButtonClick('#tool_ellipse')) {
|
|
2148
|
+
svgCanvas.setMode('ellipse');
|
|
2149
|
+
}
|
|
2150
|
+
};
|
|
2151
|
+
|
|
2152
|
+
var clickFHEllipse = function(){
|
|
2153
|
+
if (toolButtonClick('#tool_fhellipse')) {
|
|
2154
|
+
svgCanvas.setMode('fhellipse');
|
|
2155
|
+
}
|
|
2156
|
+
};
|
|
2157
|
+
|
|
2158
|
+
var clickImage = function(){
|
|
2159
|
+
if (toolButtonClick('#tool_image')) {
|
|
2160
|
+
svgCanvas.setMode('image');
|
|
2161
|
+
}
|
|
2162
|
+
};
|
|
2163
|
+
|
|
2164
|
+
var clickZoom = function(){
|
|
2165
|
+
if (toolButtonClick('#tool_zoom')) {
|
|
2166
|
+
svgCanvas.setMode('zoom');
|
|
2167
|
+
}
|
|
2168
|
+
};
|
|
2169
|
+
|
|
2170
|
+
var dblclickZoom = function(){
|
|
2171
|
+
if (toolButtonClick('#tool_zoom')) {
|
|
2172
|
+
zoomImage();
|
|
2173
|
+
setSelectMode();
|
|
2174
|
+
}
|
|
2175
|
+
};
|
|
2176
|
+
|
|
2177
|
+
var clickText = function(){
|
|
2178
|
+
if (toolButtonClick('#tool_text')) {
|
|
2179
|
+
svgCanvas.setMode('text');
|
|
2180
|
+
}
|
|
2181
|
+
};
|
|
2182
|
+
|
|
2183
|
+
var clickPath = function(){
|
|
2184
|
+
if (toolButtonClick('#tool_path')) {
|
|
2185
|
+
svgCanvas.setMode('path');
|
|
2186
|
+
}
|
|
2187
|
+
};
|
|
2188
|
+
|
|
2189
|
+
// Delete is a contextual tool that only appears in the ribbon if
|
|
2190
|
+
// an element has been selected
|
|
2191
|
+
var deleteSelected = function() {
|
|
2192
|
+
if (selectedElement != null || multiselected) {
|
|
2193
|
+
svgCanvas.deleteSelectedElements();
|
|
2194
|
+
}
|
|
2195
|
+
if (path.getNodePoint()) {
|
|
2196
|
+
path.deletePathNode();
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
|
|
2200
|
+
var cutSelected = function() {
|
|
2201
|
+
if (selectedElement != null || multiselected) {
|
|
2202
|
+
flash($('#edit_menu'));
|
|
2203
|
+
svgCanvas.cutSelectedElements();
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
|
|
2207
|
+
var copySelected = function() {
|
|
2208
|
+
if (selectedElement != null || multiselected) {
|
|
2209
|
+
flash($('#edit_menu'));
|
|
2210
|
+
svgCanvas.copySelectedElements();
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
2213
|
+
|
|
2214
|
+
var pasteSelected = function() {
|
|
2215
|
+
flash($('#edit_menu'));
|
|
2216
|
+
var zoom = svgCanvas.getZoom();
|
|
2217
|
+
var x = (workarea[0].scrollLeft + workarea.width()/2)/zoom - svgCanvas.contentW;
|
|
2218
|
+
var y = (workarea[0].scrollTop + workarea.height()/2)/zoom - svgCanvas.contentH;
|
|
2219
|
+
svgCanvas.pasteElements('point', x, y);
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
var moveToTopSelected = function() {
|
|
2223
|
+
if (selectedElement != null) {
|
|
2224
|
+
flash($('#object_menu'));
|
|
2225
|
+
svgCanvas.moveToTopSelectedElement();
|
|
2226
|
+
}
|
|
2227
|
+
};
|
|
2228
|
+
|
|
2229
|
+
var moveToBottomSelected = function() {
|
|
2230
|
+
if (selectedElement != null) {
|
|
2231
|
+
flash($('#object_menu'));
|
|
2232
|
+
svgCanvas.moveToBottomSelectedElement();
|
|
2233
|
+
}
|
|
2234
|
+
};
|
|
2235
|
+
|
|
2236
|
+
var moveUpSelected = function() {
|
|
2237
|
+
if (selectedElement != null) {
|
|
2238
|
+
flash($('#object_menu'));
|
|
2239
|
+
svgCanvas.moveUpDownSelected("Up");
|
|
2240
|
+
}
|
|
2241
|
+
};
|
|
2242
|
+
|
|
2243
|
+
var moveDownSelected = function() {
|
|
2244
|
+
if (selectedElement != null) {
|
|
2245
|
+
flash($('#object_menu'));
|
|
2246
|
+
svgCanvas.moveUpDownSelected("Down");
|
|
2247
|
+
}
|
|
2248
|
+
};
|
|
2249
|
+
|
|
2250
|
+
var moveUpDownSelected = function(dir) {
|
|
2251
|
+
if (selectedElement != null) {
|
|
2252
|
+
flash($('#object_menu'));
|
|
2253
|
+
svgCanvas.moveUpDownSelected(dir);
|
|
2254
|
+
}
|
|
2255
|
+
};
|
|
2256
|
+
|
|
2257
|
+
var convertToPath = function() {
|
|
2258
|
+
if (selectedElement != null) {
|
|
2259
|
+
svgCanvas.convertToPath();
|
|
2260
|
+
var elems = svgCanvas.getSelectedElems()
|
|
2261
|
+
svgCanvas.selectorManager.requestSelector(elems[0]).reset(elems[0])
|
|
2262
|
+
svgCanvas.selectorManager.requestSelector(elems[0]).selectorRect.setAttribute("display", "none");
|
|
2263
|
+
svgCanvas.setMode("pathedit")
|
|
2264
|
+
path.toEditMode(elems[0]);
|
|
2265
|
+
svgCanvas.clearSelection();
|
|
2266
|
+
updateContextPanel();
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
var reorientPath = function() {
|
|
2271
|
+
if (selectedElement != null) {
|
|
2272
|
+
path.reorient();
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
var makeHyperlink = function() {
|
|
2277
|
+
if (selectedElement != null || multiselected) {
|
|
2278
|
+
$.prompt(uiStrings.notification.enterNewLinkURL, "http://", function(url) {
|
|
2279
|
+
if(url) svgCanvas.makeHyperlink(url);
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
var moveSelected = function(dx,dy) {
|
|
2285
|
+
if (selectedElement != null || multiselected) {
|
|
2286
|
+
if(curConfig.gridSnapping) {
|
|
2287
|
+
// Use grid snap value regardless of zoom level
|
|
2288
|
+
var multi = svgCanvas.getZoom() * curConfig.snappingStep;
|
|
2289
|
+
dx *= multi;
|
|
2290
|
+
dy *= multi;
|
|
2291
|
+
}
|
|
2292
|
+
$('input').blur()
|
|
2293
|
+
svgCanvas.moveSelectedElements(dx,dy);
|
|
2294
|
+
}
|
|
2295
|
+
};
|
|
2296
|
+
|
|
2297
|
+
var linkControlPoints = function() {
|
|
2298
|
+
// var linked = document.getElementById('tool_node_link').checked;
|
|
2299
|
+
// path.linkControlPoints(linked);
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
var clonePathNode = function() {
|
|
2303
|
+
if (path.getNodePoint()) {
|
|
2304
|
+
path.clonePathNode();
|
|
2305
|
+
}
|
|
2306
|
+
};
|
|
2307
|
+
|
|
2308
|
+
var deletePathNode = function() {
|
|
2309
|
+
if (path.getNodePoint()) {
|
|
2310
|
+
path.deletePathNode();
|
|
2311
|
+
}
|
|
2312
|
+
};
|
|
2313
|
+
|
|
2314
|
+
var addSubPath = function() {
|
|
2315
|
+
var button = $('#tool_add_subpath');
|
|
2316
|
+
var sp = !button.hasClass('push_button_pressed');
|
|
2317
|
+
if (sp) {
|
|
2318
|
+
button.addClass('push_button_pressed').removeClass('tool_button');
|
|
2319
|
+
} else {
|
|
2320
|
+
button.removeClass('push_button_pressed').addClass('tool_button');
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
path.addSubPath(sp);
|
|
2324
|
+
|
|
2325
|
+
};
|
|
2326
|
+
|
|
2327
|
+
var opencloseSubPath = function() {
|
|
2328
|
+
path.opencloseSubPath();
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
var selectNext = function() {
|
|
2332
|
+
svgCanvas.cycleElement(1);
|
|
2333
|
+
};
|
|
2334
|
+
|
|
2335
|
+
var selectPrev = function() {
|
|
2336
|
+
svgCanvas.cycleElement(0);
|
|
2337
|
+
};
|
|
2338
|
+
|
|
2339
|
+
var rotateSelected = function(cw,step) {
|
|
2340
|
+
if (selectedElement == null || multiselected) return;
|
|
2341
|
+
if(!cw) step *= -1;
|
|
2342
|
+
var new_angle = $('#angle').val()*1 + step;
|
|
2343
|
+
svgCanvas.setRotationAngle(new_angle);
|
|
2344
|
+
updateContextPanel();
|
|
2345
|
+
};
|
|
2346
|
+
|
|
2347
|
+
var clickClear = function(){
|
|
2348
|
+
var dims = curConfig.dimensions;
|
|
2349
|
+
$.confirm(uiStrings.notification.QwantToClear, function(ok) {
|
|
2350
|
+
if(!ok) return;
|
|
2351
|
+
setSelectMode();
|
|
2352
|
+
svgCanvas.clear();
|
|
2353
|
+
svgCanvas.setResolution(dims[0], dims[1]);
|
|
2354
|
+
updateCanvas(true);
|
|
2355
|
+
zoomImage();
|
|
2356
|
+
updateContextPanel();
|
|
2357
|
+
prepPaints();
|
|
2358
|
+
svgCanvas.runExtensions('onNewDocument');
|
|
2359
|
+
});
|
|
2360
|
+
};
|
|
2361
|
+
|
|
2362
|
+
var clickBold = function(){
|
|
2363
|
+
svgCanvas.setBold( !svgCanvas.getBold() );
|
|
2364
|
+
updateContextPanel();
|
|
2365
|
+
};
|
|
2366
|
+
|
|
2367
|
+
var clickItalic = function(){
|
|
2368
|
+
svgCanvas.setItalic( !svgCanvas.getItalic() );
|
|
2369
|
+
updateContextPanel();
|
|
2370
|
+
};
|
|
2371
|
+
|
|
2372
|
+
var clickExport = function() {
|
|
2373
|
+
// Open placeholder window (prevents popup)
|
|
2374
|
+
if(!customHandlers.pngsave) {
|
|
2375
|
+
var str = uiStrings.notification.loadingImage;
|
|
2376
|
+
exportWindow = window.open("data:text/html;charset=utf-8,<title>" + str + "<\/title><h1>" + str + "<\/h1>");
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
if(window.canvg) {
|
|
2380
|
+
svgCanvas.rasterExport();
|
|
2381
|
+
} else {
|
|
2382
|
+
$.getScript('canvg/rgbcolor.js', function() {
|
|
2383
|
+
$.getScript('canvg/canvg.js', function() {
|
|
2384
|
+
svgCanvas.rasterExport();
|
|
2385
|
+
});
|
|
2386
|
+
});
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
// by default, svgCanvas.open() is a no-op.
|
|
2391
|
+
// it is up to an extension mechanism (opera widget, etc)
|
|
2392
|
+
// to call setCustomHandlers() which will make it do something
|
|
2393
|
+
var clickOpen = function(){
|
|
2394
|
+
svgCanvas.open();
|
|
2395
|
+
};
|
|
2396
|
+
var clickImport = function(){
|
|
2397
|
+
};
|
|
2398
|
+
|
|
2399
|
+
var flash = function($menu){
|
|
2400
|
+
var menu_title = $menu.prev();
|
|
2401
|
+
menu_title.css({
|
|
2402
|
+
"background": "white",
|
|
2403
|
+
"color": "black"
|
|
2404
|
+
});
|
|
2405
|
+
setTimeout(function(){menu_title.removeAttr("style")}, 200);
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
var clickUndo = function(){
|
|
2409
|
+
if (undoMgr.getUndoStackSize() > 0) {
|
|
2410
|
+
flash($('#edit_menu'));
|
|
2411
|
+
undoMgr.undo();
|
|
2412
|
+
}
|
|
2413
|
+
};
|
|
2414
|
+
|
|
2415
|
+
var clickRedo = function(){
|
|
2416
|
+
if (undoMgr.getRedoStackSize() > 0) {
|
|
2417
|
+
flash($('#edit_menu'));
|
|
2418
|
+
undoMgr.redo();
|
|
2419
|
+
}
|
|
2420
|
+
};
|
|
2421
|
+
|
|
2422
|
+
var clickGroup = function(){
|
|
2423
|
+
// group
|
|
2424
|
+
if (multiselected) {
|
|
2425
|
+
flash($('#object_menu'));
|
|
2426
|
+
svgCanvas.groupSelectedElements();
|
|
2427
|
+
}
|
|
2428
|
+
// ungroup
|
|
2429
|
+
else if(selectedElement){
|
|
2430
|
+
flash($('#object_menu'));
|
|
2431
|
+
svgCanvas.ungroupSelectedElement();
|
|
2432
|
+
}
|
|
2433
|
+
};
|
|
2434
|
+
|
|
2435
|
+
var clickClone = function(){
|
|
2436
|
+
flash($('#edit_menu'));
|
|
2437
|
+
svgCanvas.cloneSelectedElements(20,20);
|
|
2438
|
+
};
|
|
2439
|
+
|
|
2440
|
+
var clickAlign = function() {
|
|
2441
|
+
var letter = this.id.replace('tool_align','').charAt(0);
|
|
2442
|
+
svgCanvas.alignSelectedElements(letter, $('#align_relative_to').val());
|
|
2443
|
+
};
|
|
2444
|
+
|
|
2445
|
+
var clickSwitch = function() {
|
|
2446
|
+
var stroke_rect = document.querySelector('#tool_stroke rect');
|
|
2447
|
+
$("#tool_stroke").toggleClass('active')
|
|
2448
|
+
$("#tool_fill").toggleClass('active')
|
|
2449
|
+
var fill_rect = document.querySelector('#tool_fill rect');
|
|
2450
|
+
var fill_color = fill_rect.getAttribute("fill");
|
|
2451
|
+
var stroke_color = stroke_rect.getAttribute("fill");
|
|
2452
|
+
var stroke_opacity = parseFloat(stroke_rect.getAttribute("stroke-opacity"));
|
|
2453
|
+
if (isNaN(stroke_opacity)) {stroke_opacity = 100;}
|
|
2454
|
+
var fill_opacity = parseFloat(fill_rect.getAttribute("fill-opacity"));
|
|
2455
|
+
if (isNaN(fill_opacity)) {fill_opacity = 100;}
|
|
2456
|
+
var stroke = getPaint(stroke_color, stroke_opacity, "stroke");
|
|
2457
|
+
var fill = getPaint(fill_color, fill_opacity, "fill");
|
|
2458
|
+
Editor.paintBox.fill.setPaint(stroke, true);
|
|
2459
|
+
Editor.paintBox.stroke.setPaint(fill, true);
|
|
2460
|
+
|
|
2461
|
+
};
|
|
2462
|
+
|
|
2463
|
+
var zoomImage = function(multiplier) {
|
|
2464
|
+
var res = svgCanvas.getResolution();
|
|
2465
|
+
multiplier = multiplier?res.zoom * multiplier:1;
|
|
2466
|
+
// setResolution(res.w * multiplier, res.h * multiplier, true);
|
|
2467
|
+
$('#zoom').val(multiplier * 100);
|
|
2468
|
+
svgCanvas.setZoom(multiplier);
|
|
2469
|
+
zoomDone();
|
|
2470
|
+
updateCanvas(true);
|
|
2471
|
+
};
|
|
2472
|
+
|
|
2473
|
+
var zoomDone = function() {
|
|
2474
|
+
// updateBgImage();
|
|
2475
|
+
updateWireFrame();
|
|
2476
|
+
//updateCanvas(); // necessary?
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
var clickWireframe = function() {
|
|
2480
|
+
flash($('#view_menu'));
|
|
2481
|
+
var wf = !$('#tool_wireframe').hasClass('push_button_pressed');
|
|
2482
|
+
if (wf)
|
|
2483
|
+
$('#tool_wireframe').addClass('push_button_pressed');
|
|
2484
|
+
else
|
|
2485
|
+
$('#tool_wireframe').removeClass('push_button_pressed');
|
|
2486
|
+
workarea.toggleClass('wireframe');
|
|
2487
|
+
|
|
2488
|
+
if(supportsNonSS) return;
|
|
2489
|
+
var wf_rules = $('#wireframe_rules');
|
|
2490
|
+
if(!wf_rules.length) {
|
|
2491
|
+
wf_rules = $('<style id="wireframe_rules"><\/style>').appendTo('head');
|
|
2492
|
+
} else {
|
|
2493
|
+
wf_rules.empty();
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2496
|
+
updateWireFrame();
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
var clickSnapGrid = function() {
|
|
2500
|
+
flash($('#view_menu'));
|
|
2501
|
+
var sg = !$('#tool_snap').hasClass('push_button_pressed');
|
|
2502
|
+
if (sg)
|
|
2503
|
+
$('#tool_snap').addClass('push_button_pressed');
|
|
2504
|
+
else
|
|
2505
|
+
$('#tool_snap').removeClass('push_button_pressed');
|
|
2506
|
+
curConfig.gridSnapping = sg;
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
var minimizeModal = function() {
|
|
2510
|
+
|
|
2511
|
+
if (window.self != window.top) { //we're in an iframe
|
|
2512
|
+
top.exit_fullscreen();
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
var clickRulers = function() {
|
|
2517
|
+
flash($('#view_menu'));
|
|
2518
|
+
var rulers = !$('#tool_rulers').hasClass('push_button_pressed');
|
|
2519
|
+
if (rulers) {
|
|
2520
|
+
$('#tool_rulers').addClass('push_button_pressed');
|
|
2521
|
+
$('#show_rulers').attr("checked", true);
|
|
2522
|
+
curConfig.showRulers = true;
|
|
2523
|
+
}
|
|
2524
|
+
else {
|
|
2525
|
+
$('#tool_rulers').removeClass('push_button_pressed');
|
|
2526
|
+
$('#show_rulers').attr("checked", false);
|
|
2527
|
+
curConfig.showRulers = false;
|
|
2528
|
+
}
|
|
2529
|
+
$('#rulers').toggle(!!curConfig.showRulers)
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
var updateWireFrame = function() {
|
|
2533
|
+
// Test support
|
|
2534
|
+
if(supportsNonSS) return;
|
|
2535
|
+
|
|
2536
|
+
var rule = "#workarea.wireframe #svgcontent * { stroke-width: " + 1/svgCanvas.getZoom() + "px; }";
|
|
2537
|
+
$('#wireframe_rules').text(workarea.hasClass('wireframe') ? rule : "");
|
|
2538
|
+
}
|
|
2539
|
+
|
|
2540
|
+
var showSourceEditor = function(e, forSaving){
|
|
2541
|
+
if (editingsource) return;
|
|
2542
|
+
flash($('#view_menu'));
|
|
2543
|
+
editingsource = true;
|
|
2544
|
+
|
|
2545
|
+
$('#save_output_btns').toggle(!!forSaving);
|
|
2546
|
+
$('#tool_source_back').toggle(!forSaving);
|
|
2547
|
+
|
|
2548
|
+
var str = orig_source = svgCanvas.getSvgString();
|
|
2549
|
+
$('#svg_source_textarea').val(str);
|
|
2550
|
+
$('#svg_source_editor').fadeIn();
|
|
2551
|
+
$('#svg_source_textarea').focus().select();
|
|
2552
|
+
};
|
|
2553
|
+
|
|
2554
|
+
var clickSave = function(){
|
|
2555
|
+
flash($('#file_menu'));
|
|
2556
|
+
// In the future, more options can be provided here
|
|
2557
|
+
var saveOpts = {
|
|
2558
|
+
'images': curPrefs.img_save,
|
|
2559
|
+
'round_digits': 6
|
|
2560
|
+
}
|
|
2561
|
+
svgCanvas.save(saveOpts);
|
|
2562
|
+
};
|
|
2563
|
+
|
|
2564
|
+
var saveSourceEditor = function(){
|
|
2565
|
+
if (!editingsource) return;
|
|
2566
|
+
|
|
2567
|
+
var saveChanges = function() {
|
|
2568
|
+
svgCanvas.clearSelection();
|
|
2569
|
+
hideSourceEditor();
|
|
2570
|
+
zoomImage();
|
|
2571
|
+
prepPaints();
|
|
2572
|
+
}
|
|
2573
|
+
|
|
2574
|
+
if (!svgCanvas.setSvgString($('#svg_source_textarea').val())) {
|
|
2575
|
+
$.confirm(uiStrings.notification.QerrorsRevertToSource, function(ok) {
|
|
2576
|
+
if(!ok) return false;
|
|
2577
|
+
saveChanges();
|
|
2578
|
+
});
|
|
2579
|
+
} else {
|
|
2580
|
+
saveChanges();
|
|
2581
|
+
}
|
|
2582
|
+
setSelectMode();
|
|
2583
|
+
};
|
|
2584
|
+
|
|
2585
|
+
function setBackground(color, url) {
|
|
2586
|
+
// if(color == curPrefs.bkgd_color && url == curPrefs.bkgd_url) return;
|
|
2587
|
+
$.pref('bkgd_color', color);
|
|
2588
|
+
$.pref('bkgd_url', url);
|
|
2589
|
+
|
|
2590
|
+
// This should be done in svgcanvas.js for the borderRect fill
|
|
2591
|
+
svgCanvas.setBackground(color, url);
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
var setIcon = Editor.setIcon = function(elem, icon_id, forcedSize) {
|
|
2595
|
+
var icon = (typeof icon_id === 'string') ? $.getSvgIcon(icon_id, true) : icon_id.clone();
|
|
2596
|
+
if(!icon) {
|
|
2597
|
+
console.log('NOTE: Icon image missing: ' + icon_id);
|
|
2598
|
+
return;
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
$(elem).find("img").replaceWith(icon);
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
var ua_prefix;
|
|
2605
|
+
(ua_prefix = function() {
|
|
2606
|
+
var regex = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/;
|
|
2607
|
+
var someScript = document.getElementsByTagName('script')[0];
|
|
2608
|
+
for(var prop in someScript.style) {
|
|
2609
|
+
if(regex.test(prop)) {
|
|
2610
|
+
// test is faster than match, so it's better to perform
|
|
2611
|
+
// that on the lot and match only when necessary
|
|
2612
|
+
return prop.match(regex)[0];
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
// Nothing found so far?
|
|
2617
|
+
if('WebkitOpacity' in someScript.style) return 'Webkit';
|
|
2618
|
+
if('KhtmlOpacity' in someScript.style) return 'Khtml';
|
|
2619
|
+
|
|
2620
|
+
return '';
|
|
2621
|
+
}());
|
|
2622
|
+
|
|
2623
|
+
var scaleElements = function(elems, scale) {
|
|
2624
|
+
var prefix = '-' + ua_prefix.toLowerCase() + '-';
|
|
2625
|
+
|
|
2626
|
+
var sides = ['top', 'left', 'bottom', 'right'];
|
|
2627
|
+
|
|
2628
|
+
elems.each(function() {
|
|
2629
|
+
// console.log('go', scale);
|
|
2630
|
+
|
|
2631
|
+
// Handled in CSS
|
|
2632
|
+
// this.style[ua_prefix + 'Transform'] = 'scale(' + scale + ')';
|
|
2633
|
+
|
|
2634
|
+
var el = $(this);
|
|
2635
|
+
|
|
2636
|
+
var w = el.outerWidth() * (scale - 1);
|
|
2637
|
+
var h = el.outerHeight() * (scale - 1);
|
|
2638
|
+
var margins = {};
|
|
2639
|
+
|
|
2640
|
+
for(var i = 0; i < 4; i++) {
|
|
2641
|
+
var s = sides[i];
|
|
2642
|
+
|
|
2643
|
+
var cur = el.data('orig_margin-' + s);
|
|
2644
|
+
if(cur == null) {
|
|
2645
|
+
cur = parseInt(el.css('margin-' + s));
|
|
2646
|
+
// Cache the original margin
|
|
2647
|
+
el.data('orig_margin-' + s, cur);
|
|
2648
|
+
}
|
|
2649
|
+
var val = cur * scale;
|
|
2650
|
+
if(s === 'right') {
|
|
2651
|
+
val += w;
|
|
2652
|
+
} else if(s === 'bottom') {
|
|
2653
|
+
val += h;
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
el.css('margin-' + s, val);
|
|
2657
|
+
// el.css('outline', '1px solid red');
|
|
2658
|
+
}
|
|
2659
|
+
});
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
var setIconSize = Editor.setIconSize = function(size, force) {
|
|
2663
|
+
if(size == curPrefs.size && !force) return;
|
|
2664
|
+
// return;
|
|
2665
|
+
// var elems = $('.tool_button, .push_button, .tool_button_current, .disabled, .icon_label, #url_notice, #tool_open');
|
|
2666
|
+
|
|
2667
|
+
var sel_toscale = '#tools_top .toolset, #editor_panel > *, #history_panel > *,\
|
|
2668
|
+
#main_button, #tools_left > *, #path_node_panel > *, #multiselected_panel > *,\
|
|
2669
|
+
#g_panel > *, #tool_font_size > *, .tools_flyout';
|
|
2670
|
+
|
|
2671
|
+
var elems = $(sel_toscale);
|
|
2672
|
+
|
|
2673
|
+
var scale = 1;
|
|
2674
|
+
|
|
2675
|
+
if(typeof size == 'number') {
|
|
2676
|
+
scale = size;
|
|
2677
|
+
} else {
|
|
2678
|
+
var icon_sizes = { s:.75, m:1, l:1.25, xl:1.5 };
|
|
2679
|
+
scale = icon_sizes[size];
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
Editor.tool_scale = tool_scale = scale;
|
|
2683
|
+
|
|
2684
|
+
setFlyoutPositions();
|
|
2685
|
+
var hidden_ps = elems.parents(':hidden');
|
|
2686
|
+
hidden_ps.css('visibility', 'hidden').show();
|
|
2687
|
+
scaleElements(elems, scale);
|
|
2688
|
+
hidden_ps.css('visibility', 'visible').hide();
|
|
2689
|
+
|
|
2690
|
+
var rule_elem = $('#tool_size_rules');
|
|
2691
|
+
if(!rule_elem.length) {
|
|
2692
|
+
rule_elem = $('<style id="tool_size_rules"><\/style>').appendTo('head');
|
|
2693
|
+
} else {
|
|
2694
|
+
rule_elem.empty();
|
|
2695
|
+
}
|
|
2696
|
+
|
|
2697
|
+
if(size != 'm') {
|
|
2698
|
+
var style_str = '';
|
|
2699
|
+
$.each(cssResizeRules, function(selector, rules) {
|
|
2700
|
+
selector = '#svg_editor ' + selector.replace(/,/g,', #svg_editor');
|
|
2701
|
+
style_str += selector + '{';
|
|
2702
|
+
$.each(rules, function(prop, values) {
|
|
2703
|
+
if(typeof values === 'number') {
|
|
2704
|
+
var val = (values * scale) + 'px';
|
|
2705
|
+
} else if(values[size] || values.all) {
|
|
2706
|
+
var val = (values[size] || values.all);
|
|
2707
|
+
}
|
|
2708
|
+
style_str += (prop + ':' + val + ';');
|
|
2709
|
+
});
|
|
2710
|
+
style_str += '}';
|
|
2711
|
+
});
|
|
2712
|
+
//this.style[ua_prefix + 'Transform'] = 'scale(' + scale + ')';
|
|
2713
|
+
var prefix = '-' + ua_prefix.toLowerCase() + '-';
|
|
2714
|
+
style_str += (sel_toscale + '{' + prefix + 'transform: scale(' + scale + ');}'
|
|
2715
|
+
+ ' #svg_editor div.toolset .toolset {' + prefix + 'transform: scale(1); margin: 1px !important;}' // Hack for markers
|
|
2716
|
+
+ ' #svg_editor .ui-slider {' + prefix + 'transform: scale(' + (1/scale) + ');}' // Hack for sliders
|
|
2717
|
+
);
|
|
2718
|
+
rule_elem.text(style_str);
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
setFlyoutPositions();
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
var cancelOverlays = function() {
|
|
2725
|
+
$('#dialog_box').hide();
|
|
2726
|
+
if (!editingsource && !docprops && !preferences) {
|
|
2727
|
+
if(cur_context) {
|
|
2728
|
+
svgCanvas.leaveContext();
|
|
2729
|
+
}
|
|
2730
|
+
return;
|
|
2731
|
+
};
|
|
2732
|
+
|
|
2733
|
+
if (editingsource) {
|
|
2734
|
+
if (orig_source !== $('#svg_source_textarea').val()) {
|
|
2735
|
+
$.confirm(uiStrings.notification.QignoreSourceChanges, function(ok) {
|
|
2736
|
+
if(ok) hideSourceEditor();
|
|
2737
|
+
});
|
|
2738
|
+
} else {
|
|
2739
|
+
hideSourceEditor();
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
else if (docprops) {
|
|
2743
|
+
hideDocProperties();
|
|
2744
|
+
} else if (preferences) {
|
|
2745
|
+
hidePreferences();
|
|
2746
|
+
}
|
|
2747
|
+
resetScrollPos();
|
|
2748
|
+
};
|
|
2749
|
+
|
|
2750
|
+
var hideSourceEditor = function(){
|
|
2751
|
+
$('#svg_source_editor').hide();
|
|
2752
|
+
editingsource = false;
|
|
2753
|
+
$('#svg_source_textarea').blur();
|
|
2754
|
+
};
|
|
2755
|
+
|
|
2756
|
+
var win_wh = {width:$(window).width(), height:$(window).height()};
|
|
2757
|
+
|
|
2758
|
+
var resetScrollPos = $.noop, curScrollPos;
|
|
2759
|
+
|
|
2760
|
+
/* Fix for Issue 781: Drawing area jumps to top-left corner on window resize (IE9)
|
|
2761
|
+
if(svgedit.browser.isIE()) {
|
|
2762
|
+
(function() {
|
|
2763
|
+
resetScrollPos = function() {
|
|
2764
|
+
if(workarea[0].scrollLeft === 0
|
|
2765
|
+
&& workarea[0].scrollTop === 0) {
|
|
2766
|
+
workarea[0].scrollLeft = curScrollPos.left;
|
|
2767
|
+
workarea[0].scrollTop = curScrollPos.top;
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
curScrollPos = {
|
|
2772
|
+
left: workarea[0].scrollLeft,
|
|
2773
|
+
top: workarea[0].scrollTop
|
|
2774
|
+
};
|
|
2775
|
+
|
|
2776
|
+
$(window).resize(resetScrollPos);
|
|
2777
|
+
methodDraw.ready(function() {
|
|
2778
|
+
// TODO: Find better way to detect when to do this to minimize
|
|
2779
|
+
// flickering effect
|
|
2780
|
+
setTimeout(function() {
|
|
2781
|
+
resetScrollPos();
|
|
2782
|
+
}, 500);
|
|
2783
|
+
});
|
|
2784
|
+
|
|
2785
|
+
workarea.scroll(function() {
|
|
2786
|
+
curScrollPos = {
|
|
2787
|
+
left: workarea[0].scrollLeft,
|
|
2788
|
+
top: workarea[0].scrollTop
|
|
2789
|
+
};
|
|
2790
|
+
});
|
|
2791
|
+
}());
|
|
2792
|
+
}*/
|
|
2793
|
+
|
|
2794
|
+
$(window).resize(function(evt) {
|
|
2795
|
+
updateCanvas();
|
|
2796
|
+
});
|
|
2797
|
+
|
|
2798
|
+
(function() {
|
|
2799
|
+
workarea.scroll(function() {
|
|
2800
|
+
// TODO: jQuery's scrollLeft/Top() wouldn't require a null check
|
|
2801
|
+
if ($('#ruler_x').length != 0) {
|
|
2802
|
+
$('#ruler_x')[0].scrollLeft = workarea[0].scrollLeft;
|
|
2803
|
+
}
|
|
2804
|
+
if ($('#ruler_y').length != 0) {
|
|
2805
|
+
$('#ruler_y')[0].scrollTop = workarea[0].scrollTop;
|
|
2806
|
+
}
|
|
2807
|
+
});
|
|
2808
|
+
|
|
2809
|
+
}());
|
|
2810
|
+
|
|
2811
|
+
$('#url_notice').click(function() {
|
|
2812
|
+
$.alert(this.title);
|
|
2813
|
+
});
|
|
2814
|
+
|
|
2815
|
+
$('#change_image_url').click(promptImgURL);
|
|
2816
|
+
|
|
2817
|
+
function promptImgURL() {
|
|
2818
|
+
var curhref = svgCanvas.getHref(selectedElement);
|
|
2819
|
+
curhref = curhref.indexOf("data:") === 0?"":curhref;
|
|
2820
|
+
$.prompt(uiStrings.notification.enterNewImgURL, curhref, function(url) {
|
|
2821
|
+
if(url) setImageURL(url);
|
|
2822
|
+
});
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
// TODO: go back to the color boxes having white background-color and then setting
|
|
2826
|
+
// background-image to none.png (otherwise partially transparent gradients look weird)
|
|
2827
|
+
var colorPicker = function(elem) {
|
|
2828
|
+
var picker = elem[0].id == 'stroke_color' ? 'stroke' : 'fill';
|
|
2829
|
+
var is_background = elem[0].id == "canvas_color"
|
|
2830
|
+
if (is_background) picker = 'canvas'
|
|
2831
|
+
// var opacity = (picker == 'stroke' ? $('#stroke_opacity') : $('#fill_opacity'));
|
|
2832
|
+
var paint = Editor.paintBox[picker].paint;
|
|
2833
|
+
|
|
2834
|
+
var title = (picker == 'stroke' ? 'Pick a Stroke Paint and Opacity' : 'Pick a Fill Paint and Opacity');
|
|
2835
|
+
var was_none = false;
|
|
2836
|
+
var pos = is_background ? {'right': 175, 'top': 50} : {'left': 50, 'bottom': 50}
|
|
2837
|
+
|
|
2838
|
+
$("#color_picker")
|
|
2839
|
+
.draggable({cancel:'.jGraduate_tabs, .jGraduate_colPick, .jGraduate_gradPick, .jPicker', containment: 'window'})
|
|
2840
|
+
.removeAttr("style")
|
|
2841
|
+
.css(pos)
|
|
2842
|
+
.jGraduate(
|
|
2843
|
+
{
|
|
2844
|
+
paint: paint,
|
|
2845
|
+
window: { pickerTitle: title },
|
|
2846
|
+
images: { clientPath: curConfig.jGraduatePath },
|
|
2847
|
+
newstop: 'inverse'
|
|
2848
|
+
},
|
|
2849
|
+
function(p) {
|
|
2850
|
+
paint = new $.jGraduate.Paint(p);
|
|
2851
|
+
|
|
2852
|
+
Editor.paintBox[picker].setPaint(paint);
|
|
2853
|
+
svgCanvas.setPaint(picker, paint);
|
|
2854
|
+
|
|
2855
|
+
$('#color_picker').hide();
|
|
2856
|
+
},
|
|
2857
|
+
function(p) {
|
|
2858
|
+
$('#color_picker').hide();
|
|
2859
|
+
});
|
|
2860
|
+
};
|
|
2861
|
+
|
|
2862
|
+
var PaintBox = function(container, type) {
|
|
2863
|
+
var background = document.getElementById("canvas_background");
|
|
2864
|
+
var cur = {color: "fff", opacity: 1}
|
|
2865
|
+
if (type == "stroke") cur = curConfig['initStroke'];
|
|
2866
|
+
if (type == "fill") cur = curConfig['initFill'];
|
|
2867
|
+
if (type == "canvas" && background) {
|
|
2868
|
+
var rgb = background.getAttribute("fill").match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
|
|
2869
|
+
if (rgb) {
|
|
2870
|
+
var hex = ("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
|
|
2871
|
+
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
|
|
2872
|
+
("0" + parseInt(rgb[3],10).toString(16)).slice(-2);
|
|
2873
|
+
cur = {color: hex, opacity: 1}
|
|
2874
|
+
}
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
// set up gradients to be used for the buttons
|
|
2878
|
+
var svgdocbox = new DOMParser().parseFromString(
|
|
2879
|
+
'<svg xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%"\
|
|
2880
|
+
fill="#' + cur.color + '" opacity="' + cur.opacity + '"/>\
|
|
2881
|
+
<defs><linearGradient id="gradbox_"/></defs></svg>', 'text/xml');
|
|
2882
|
+
var docElem = svgdocbox.documentElement;
|
|
2883
|
+
|
|
2884
|
+
docElem = $(container)[0].appendChild(document.importNode(docElem, true));
|
|
2885
|
+
if (type === 'canvas') docElem.setAttribute('width',60.5);
|
|
2886
|
+
else docElem.setAttribute('width',"100%");
|
|
2887
|
+
|
|
2888
|
+
this.rect = docElem.firstChild;
|
|
2889
|
+
this.defs = docElem.getElementsByTagName('defs')[0];
|
|
2890
|
+
this.grad = this.defs.firstChild;
|
|
2891
|
+
this.paint = new $.jGraduate.Paint({solidColor: cur.color});
|
|
2892
|
+
this.type = type;
|
|
2893
|
+
|
|
2894
|
+
this.setPaint = function(paint, apply, noUndo) {
|
|
2895
|
+
this.paint = paint;
|
|
2896
|
+
var fillAttr = "none";
|
|
2897
|
+
var ptype = paint.type;
|
|
2898
|
+
var opac = paint.alpha / 100;
|
|
2899
|
+
switch ( ptype ) {
|
|
2900
|
+
case 'solidColor':
|
|
2901
|
+
fillAttr = (paint[ptype] == 'none' || paint[ptype] == 'one') ? 'none' : "#" + paint[ptype];
|
|
2902
|
+
break;
|
|
2903
|
+
case 'linearGradient':
|
|
2904
|
+
case 'radialGradient':
|
|
2905
|
+
this.defs.removeChild(this.grad);
|
|
2906
|
+
this.grad = this.defs.appendChild(paint[ptype]);
|
|
2907
|
+
var id = this.grad.id = 'gradbox_' + this.type;
|
|
2908
|
+
fillAttr = "url(#" + id + ')';
|
|
2909
|
+
}
|
|
2910
|
+
this.rect.setAttribute('fill', fillAttr);
|
|
2911
|
+
this.rect.setAttribute('opacity', opac);
|
|
2912
|
+
|
|
2913
|
+
if (this.type == "canvas") {
|
|
2914
|
+
//recache background in case it changed
|
|
2915
|
+
var background = document.getElementById("canvas_background");
|
|
2916
|
+
if (background) {
|
|
2917
|
+
res = svgCanvas.getResolution()
|
|
2918
|
+
background.setAttribute("x", -1);
|
|
2919
|
+
background.setAttribute("y", -1);
|
|
2920
|
+
background.setAttribute("width", res.w+2);
|
|
2921
|
+
background.setAttribute("height", res.h+2);
|
|
2922
|
+
if (fillAttr.indexOf("url") == -1) background.setAttribute('fill', fillAttr)
|
|
2923
|
+
}
|
|
2924
|
+
else createBackground(fillAttr)
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2927
|
+
if(apply) {
|
|
2928
|
+
svgCanvas.setColor(this.type, fillAttr, true);
|
|
2929
|
+
svgCanvas.setPaintOpacity(this.type, opac, true);
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
this.update = function(apply) {
|
|
2935
|
+
if(!selectedElement) return;
|
|
2936
|
+
var type = this.type;
|
|
2937
|
+
switch ( selectedElement.tagName ) {
|
|
2938
|
+
case 'use':
|
|
2939
|
+
case 'image':
|
|
2940
|
+
case 'foreignObject':
|
|
2941
|
+
// These elements don't have fill or stroke, so don't change
|
|
2942
|
+
// the current value
|
|
2943
|
+
return;
|
|
2944
|
+
case 'g':
|
|
2945
|
+
case 'a':
|
|
2946
|
+
var gPaint = null;
|
|
2947
|
+
|
|
2948
|
+
var childs = selectedElement.getElementsByTagName('*');
|
|
2949
|
+
for(var i = 0, len = childs.length; i < len; i++) {
|
|
2950
|
+
var elem = childs[i];
|
|
2951
|
+
var p = elem.getAttribute(type);
|
|
2952
|
+
if(i === 0) {
|
|
2953
|
+
gPaint = p;
|
|
2954
|
+
} else if(gPaint !== p) {
|
|
2955
|
+
gPaint = null;
|
|
2956
|
+
break;
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
if(gPaint === null) {
|
|
2960
|
+
// No common color, don't update anything
|
|
2961
|
+
var paintColor = null;
|
|
2962
|
+
return;
|
|
2963
|
+
}
|
|
2964
|
+
var paintColor = gPaint;
|
|
2965
|
+
|
|
2966
|
+
var paintOpacity = 1;
|
|
2967
|
+
break;
|
|
2968
|
+
default:
|
|
2969
|
+
var paintOpacity = parseFloat(selectedElement.getAttribute(type + "-opacity"));
|
|
2970
|
+
if (isNaN(paintOpacity)) {
|
|
2971
|
+
paintOpacity = 1.0;
|
|
2972
|
+
}
|
|
2973
|
+
|
|
2974
|
+
var defColor = type === "fill" ? "black" : "none";
|
|
2975
|
+
var paintColor = selectedElement.getAttribute(type) || defColor;
|
|
2976
|
+
}
|
|
2977
|
+
if(apply) {
|
|
2978
|
+
svgCanvas.setColor(type, paintColor, true);
|
|
2979
|
+
svgCanvas.setPaintOpacity(type, paintOpacity, true);
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
paintOpacity *= 100;
|
|
2983
|
+
|
|
2984
|
+
var paint = getPaint(paintColor, paintOpacity, type);
|
|
2985
|
+
// update the rect inside #fill_color/#stroke_color
|
|
2986
|
+
this.setPaint(paint);
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2989
|
+
this.prep = function() {
|
|
2990
|
+
var ptype = this.paint.type;
|
|
2991
|
+
|
|
2992
|
+
switch ( ptype ) {
|
|
2993
|
+
case 'linearGradient':
|
|
2994
|
+
case 'radialGradient':
|
|
2995
|
+
var paint = new $.jGraduate.Paint({copy: this.paint});
|
|
2996
|
+
svgCanvas.setPaint(type, paint);
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
};
|
|
3000
|
+
|
|
3001
|
+
Editor.paintBox.fill = new PaintBox('#fill_color', 'fill');
|
|
3002
|
+
Editor.paintBox.stroke = new PaintBox('#stroke_color', 'stroke');
|
|
3003
|
+
Editor.paintBox.canvas = new PaintBox('#canvas_color', 'canvas');
|
|
3004
|
+
|
|
3005
|
+
$('#stroke_width').val(curConfig.initStroke.width);
|
|
3006
|
+
$('#group_opacity').val(curConfig.initOpacity * 100);
|
|
3007
|
+
|
|
3008
|
+
// Use this SVG elem to test vectorEffect support
|
|
3009
|
+
var test_el = Editor.paintBox.fill.rect.cloneNode(false);
|
|
3010
|
+
test_el.setAttribute('style','vector-effect:non-scaling-stroke');
|
|
3011
|
+
var supportsNonSS = (test_el.style.vectorEffect === 'non-scaling-stroke');
|
|
3012
|
+
test_el.removeAttribute('style');
|
|
3013
|
+
var svgdocbox = Editor.paintBox.fill.rect.ownerDocument;
|
|
3014
|
+
// Use this to test support for blur element. Seems to work to test support in Webkit
|
|
3015
|
+
var blur_test = svgdocbox.createElementNS('http://www.w3.org/2000/svg', 'feGaussianBlur');
|
|
3016
|
+
if(typeof blur_test.stdDeviationX === "undefined") {
|
|
3017
|
+
$('#tool_blur').hide();
|
|
3018
|
+
}
|
|
3019
|
+
$(blur_test).remove();
|
|
3020
|
+
|
|
3021
|
+
|
|
3022
|
+
|
|
3023
|
+
// Test for embedImage support (use timeout to not interfere with page load)
|
|
3024
|
+
setTimeout(function() {
|
|
3025
|
+
svgCanvas.embedImage('images/placeholder.svg', function(datauri) {
|
|
3026
|
+
if(!datauri) {
|
|
3027
|
+
// Disable option
|
|
3028
|
+
$('#image_save_opts [value=embed]').attr('disabled','disabled');
|
|
3029
|
+
$('#image_save_opts input').val(['ref']);
|
|
3030
|
+
curPrefs.img_save = 'ref';
|
|
3031
|
+
$('#image_opt_embed').css('color','#666').attr('title',uiStrings.notification.featNotSupported);
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
},1000);
|
|
3035
|
+
|
|
3036
|
+
$('#tool_fill').click(function(){
|
|
3037
|
+
if ($('#tool_fill').hasClass('active')) {
|
|
3038
|
+
colorPicker($('#fill_color'));
|
|
3039
|
+
}
|
|
3040
|
+
else {
|
|
3041
|
+
$('#tool_fill').addClass('active');
|
|
3042
|
+
$("#tool_stroke").removeClass('active');
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
|
|
3046
|
+
$('#tool_stroke').on("click", function(){
|
|
3047
|
+
if ($('#tool_stroke').hasClass('active')) {
|
|
3048
|
+
colorPicker($('#stroke_color'));
|
|
3049
|
+
}
|
|
3050
|
+
else {
|
|
3051
|
+
$('#tool_stroke').addClass('active');
|
|
3052
|
+
$("#tool_fill").removeClass('active');
|
|
3053
|
+
}
|
|
3054
|
+
});
|
|
3055
|
+
|
|
3056
|
+
$('#tool_canvas').on("click touchstart", function(){
|
|
3057
|
+
colorPicker($('#canvas_color'));
|
|
3058
|
+
});
|
|
3059
|
+
|
|
3060
|
+
$('#tool_stroke').on("touchstart", function(){
|
|
3061
|
+
$('#tool_stroke').addClass('active');
|
|
3062
|
+
$("#tool_fill").removeClass('active');
|
|
3063
|
+
colorPicker($('#stroke_color'));
|
|
3064
|
+
});
|
|
3065
|
+
|
|
3066
|
+
$('#tool_fill').on("touchstart", function(){
|
|
3067
|
+
$('#tool_fill').addClass('active');
|
|
3068
|
+
$("#tool_stroke").removeClass('active');
|
|
3069
|
+
colorPicker($('#fill_color'));
|
|
3070
|
+
});
|
|
3071
|
+
|
|
3072
|
+
$('#zoom_select').on("change", function() {
|
|
3073
|
+
var val = this.options[this.selectedIndex].text
|
|
3074
|
+
val = val.split("%")[0]
|
|
3075
|
+
$("#zoom").val(val).trigger("change")
|
|
3076
|
+
});
|
|
3077
|
+
|
|
3078
|
+
$('.push_button').mousedown(function() {
|
|
3079
|
+
if (!$(this).hasClass('disabled')) {
|
|
3080
|
+
$(this).addClass('push_button_pressed').removeClass('push_button');
|
|
3081
|
+
}
|
|
3082
|
+
}).mouseout(function() {
|
|
3083
|
+
$(this).removeClass('push_button_pressed').addClass('push_button');
|
|
3084
|
+
}).mouseup(function() {
|
|
3085
|
+
$(this).removeClass('push_button_pressed').addClass('push_button');
|
|
3086
|
+
});
|
|
3087
|
+
|
|
3088
|
+
|
|
3089
|
+
// function changeResolution(x,y) {
|
|
3090
|
+
// var zoom = svgCanvas.getResolution().zoom;
|
|
3091
|
+
// setResolution(x * zoom, y * zoom);
|
|
3092
|
+
// }
|
|
3093
|
+
|
|
3094
|
+
var centerCanvas = function() {
|
|
3095
|
+
// this centers the canvas vertically in the workarea (horizontal handled in CSS)
|
|
3096
|
+
workarea.css('line-height', workarea.height() + 'px');
|
|
3097
|
+
};
|
|
3098
|
+
|
|
3099
|
+
$(window).bind('load resize', centerCanvas);
|
|
3100
|
+
|
|
3101
|
+
function stepFontSize(elem, step) {
|
|
3102
|
+
var orig_val = elem.value-0;
|
|
3103
|
+
var sug_val = orig_val + step;
|
|
3104
|
+
var increasing = sug_val >= orig_val;
|
|
3105
|
+
if(step === 0) return orig_val;
|
|
3106
|
+
|
|
3107
|
+
if(orig_val >= 24) {
|
|
3108
|
+
if(increasing) {
|
|
3109
|
+
return Math.round(orig_val * 1.1);
|
|
3110
|
+
} else {
|
|
3111
|
+
return Math.round(orig_val / 1.1);
|
|
3112
|
+
}
|
|
3113
|
+
} else if(orig_val <= 1) {
|
|
3114
|
+
if(increasing) {
|
|
3115
|
+
return orig_val * 2;
|
|
3116
|
+
} else {
|
|
3117
|
+
return orig_val / 2;
|
|
3118
|
+
}
|
|
3119
|
+
} else {
|
|
3120
|
+
return sug_val;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
function stepZoom(elem, step) {
|
|
3125
|
+
var orig_val = elem.value-0;
|
|
3126
|
+
if(orig_val === 0) return 100;
|
|
3127
|
+
var sug_val = orig_val + step;
|
|
3128
|
+
if(step === 0) return orig_val;
|
|
3129
|
+
|
|
3130
|
+
if(orig_val >= 100) {
|
|
3131
|
+
return sug_val;
|
|
3132
|
+
} else {
|
|
3133
|
+
if(sug_val >= orig_val) {
|
|
3134
|
+
return orig_val * 2;
|
|
3135
|
+
} else {
|
|
3136
|
+
return orig_val / 2;
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
var changeCanvasSize = function(ctl){
|
|
3142
|
+
var width = $("#canvas_width");
|
|
3143
|
+
var height = $("#canvas_height");
|
|
3144
|
+
var w = width.val();
|
|
3145
|
+
var h = height.val()
|
|
3146
|
+
|
|
3147
|
+
if(w != "fit" && !svgedit.units.isValidUnit('width', w)) {
|
|
3148
|
+
$.alert(uiStrings.notification.invalidAttrValGiven);
|
|
3149
|
+
width.parent().addClass('error');
|
|
3150
|
+
return false;
|
|
3151
|
+
}
|
|
3152
|
+
|
|
3153
|
+
width.parent().removeClass('error');
|
|
3154
|
+
|
|
3155
|
+
if(h != "fit" && !svgedit.units.isValidUnit('height', h)) {
|
|
3156
|
+
$.alert(uiStrings.notification.invalidAttrValGiven);
|
|
3157
|
+
height.parent().addClass('error');
|
|
3158
|
+
return false;
|
|
3159
|
+
}
|
|
3160
|
+
height.parent().removeClass('error');
|
|
3161
|
+
if(!svgCanvas.setResolution(w, h)) {
|
|
3162
|
+
$.alert(uiStrings.notification.noContentToFitTo);
|
|
3163
|
+
var dims = svgCanvas.getResolution()
|
|
3164
|
+
width.val(dims.w)
|
|
3165
|
+
height.val(dims.h)
|
|
3166
|
+
return false;
|
|
3167
|
+
}
|
|
3168
|
+
updateCanvas();
|
|
3169
|
+
}
|
|
3170
|
+
|
|
3171
|
+
|
|
3172
|
+
$('#resolution').change(function(){
|
|
3173
|
+
var w = $('#canvas_width')[0];
|
|
3174
|
+
var h = $('#canvas_height')[0];
|
|
3175
|
+
if(!this.selectedIndex) {
|
|
3176
|
+
$('#resolution_label').html("Custom");
|
|
3177
|
+
w.removeAttribute("readonly");
|
|
3178
|
+
w.focus();
|
|
3179
|
+
w.select();
|
|
3180
|
+
if(w.value == 'fit') {
|
|
3181
|
+
w.value = 100
|
|
3182
|
+
h.value = 100
|
|
3183
|
+
}
|
|
3184
|
+
} else if(this.value == 'content') {
|
|
3185
|
+
w.value = 'fit'
|
|
3186
|
+
h.value = 'fit'
|
|
3187
|
+
changeCanvasSize();
|
|
3188
|
+
var res = svgCanvas.getResolution()
|
|
3189
|
+
w.value = res.w
|
|
3190
|
+
h.value = res.h
|
|
3191
|
+
|
|
3192
|
+
} else {
|
|
3193
|
+
var dims = this.value.split('x');
|
|
3194
|
+
dims[0] = parseInt(dims[0]);
|
|
3195
|
+
dims[1] = parseInt(dims[1]);
|
|
3196
|
+
var diff_w = dims[0] - w.value;
|
|
3197
|
+
var diff_h = dims[1] - h.value;
|
|
3198
|
+
//animate
|
|
3199
|
+
var start = Date.now();
|
|
3200
|
+
var duration = 1000;
|
|
3201
|
+
var animateCanvasSize = function(timestamp) {
|
|
3202
|
+
var progress = Date.now() - start;
|
|
3203
|
+
var tick = progress / duration;
|
|
3204
|
+
tick = (Math.pow((tick-1), 3) +1);
|
|
3205
|
+
w.value = (dims[0] - diff_w + (tick*diff_w)).toFixed(0);
|
|
3206
|
+
h.value = (dims[1] - diff_h + (tick*diff_h)).toFixed(0);
|
|
3207
|
+
changeCanvasSize();
|
|
3208
|
+
if (tick >= 1) {
|
|
3209
|
+
var res = svgCanvas.getResolution()
|
|
3210
|
+
$('#canvas_width').val(res.w.toFixed())
|
|
3211
|
+
$('#canvas_height').val(res.h.toFixed())
|
|
3212
|
+
$('#resolution_label').html("<div class='pull'>" + res.w + "<span>×</span></br>" + res.h + "</div>");
|
|
3213
|
+
}
|
|
3214
|
+
else {
|
|
3215
|
+
requestAnimationFrame(animateCanvasSize)
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
animateCanvasSize()
|
|
3219
|
+
|
|
3220
|
+
}
|
|
3221
|
+
});
|
|
3222
|
+
|
|
3223
|
+
$('#zoom').change(function(){
|
|
3224
|
+
changeZoom(this)
|
|
3225
|
+
})
|
|
3226
|
+
|
|
3227
|
+
//Prevent browser from erroneously repopulating fields
|
|
3228
|
+
$('input,select').attr("autocomplete","off");
|
|
3229
|
+
|
|
3230
|
+
// Associate all button actions as well as non-button keyboard shortcuts
|
|
3231
|
+
var Actions = function() {
|
|
3232
|
+
// sel:'selector', fn:function, evt:'event', key:[key, preventDefault, NoDisableInInput]
|
|
3233
|
+
var tool_buttons = [
|
|
3234
|
+
{sel:'#tool_select', fn: clickSelect, evt: 'click', key: ['V', true]},
|
|
3235
|
+
{sel:'#tool_fhpath', fn: clickFHPath, evt: 'click', key: ['Q', true]},
|
|
3236
|
+
{sel:'#tool_line', fn: clickLine, evt: 'click', key: ['L', true]},
|
|
3237
|
+
{sel:'#tool_rect', fn: clickRect, evt: 'click', key: ['R', true], icon: 'rect'},
|
|
3238
|
+
{sel:'#tool_ellipse', fn: clickEllipse, evt: 'mouseup', key: ['C', true], icon: 'ellipse'},
|
|
3239
|
+
//{sel:'#tool_circle', fn: clickCircle, evt: 'mouseup', icon: 'circle'},
|
|
3240
|
+
//{sel:'#tool_fhellipse', fn: clickFHEllipse, evt: 'mouseup', parent: '#tools_ellipse', icon: 'fh_ellipse'},
|
|
3241
|
+
{sel:'#tool_path', fn: clickPath, evt: 'click', key: ['P', true]},
|
|
3242
|
+
{sel:'#tool_text', fn: clickText, evt: 'click', key: ['T', true]},
|
|
3243
|
+
{sel:'#tool_image', fn: clickImage, evt: 'mouseup'},
|
|
3244
|
+
{sel:'#tool_zoom', fn: clickZoom, evt: 'mouseup', key: ['Z', true]},
|
|
3245
|
+
{sel:'#tool_clear', fn: clickClear, evt: 'mouseup', key: [modKey + 'N', true]},
|
|
3246
|
+
{sel:'#tool_save', fn: function() { editingsource?saveSourceEditor():clickSave()}, evt: 'mouseup', key: [modKey + 'S', true]},
|
|
3247
|
+
{sel:'#tool_export', fn: clickExport, evt: 'mouseup'},
|
|
3248
|
+
{sel:'#tool_open', fn: clickOpen, evt: 'mouseup'},
|
|
3249
|
+
{sel:'#tool_import', fn: clickImport, evt: 'mouseup'},
|
|
3250
|
+
{sel:'#tool_source', fn: showSourceEditor, evt: 'click', key: [modKey + 'U', true]},
|
|
3251
|
+
{sel:'#tool_wireframe', fn: clickWireframe, evt: 'click'},
|
|
3252
|
+
{sel:'#tool_snap', fn: clickSnapGrid, evt: 'click'},
|
|
3253
|
+
{sel:'#tool_rulers', fn: clickRulers, evt: 'click'},
|
|
3254
|
+
{sel:'#tool_source_cancel,#svg_source_overlay,#tool_docprops_cancel,#tool_prefs_cancel', fn: cancelOverlays, evt: 'click', key: ['esc', false, false], hidekey: true},
|
|
3255
|
+
{sel:'#tool_source_save', fn: saveSourceEditor, evt: 'click'},
|
|
3256
|
+
{sel:'#tool_delete,#tool_delete_multi', fn: deleteSelected, evt: 'click', key: ['del/backspace', true]},
|
|
3257
|
+
{sel:'#tool_reorient', fn: reorientPath, evt: 'click'},
|
|
3258
|
+
{sel:'#tool_node_link', fn: linkControlPoints, evt: 'change'},
|
|
3259
|
+
{sel:'#tool_node_clone', fn: clonePathNode, evt: 'click'},
|
|
3260
|
+
{sel:'#tool_node_delete', fn: deletePathNode, evt: 'click'},
|
|
3261
|
+
{sel:'#tool_openclose_path', fn: opencloseSubPath, evt: 'click'},
|
|
3262
|
+
{sel:'#tool_add_subpath', fn: addSubPath, evt: 'click'},
|
|
3263
|
+
{sel:'#tool_move_top', fn: moveToTopSelected, evt: 'click', key: modKey + 'shift+up'},
|
|
3264
|
+
{sel:'#tool_move_bottom', fn: moveToBottomSelected, evt: 'click', key: modKey + 'shift+down'},
|
|
3265
|
+
{sel:'#tool_move_up', fn: moveUpSelected, evt:'click', key: [modKey+'up', true]},
|
|
3266
|
+
{sel:'#tool_move_down', fn: moveDownSelected, evt:'click', key: [modKey+'down', true]},
|
|
3267
|
+
{sel:'#tool_topath', fn: convertToPath, evt: 'click'},
|
|
3268
|
+
{sel:'#tool_make_link,#tool_make_link_multi', fn: makeHyperlink, evt: 'click'},
|
|
3269
|
+
{sel:'#tool_clone,#tool_clone_multi', fn: clickClone, evt: 'click', key: [modKey + 'D', true]},
|
|
3270
|
+
{sel:'#tool_group', fn: clickGroup, evt: 'click', key: [modKey + 'G', true]},
|
|
3271
|
+
{sel:'#tool_ungroup', fn: clickGroup, evt: 'click', key: modKey + 'shift+G'},
|
|
3272
|
+
{sel:'#tool_unlink_use', fn: clickGroup, evt: 'click'},
|
|
3273
|
+
{sel:'[id^=tool_align]', fn: clickAlign, evt: 'click'},
|
|
3274
|
+
{sel:'#tool_undo', fn: clickUndo, evt: 'click', key: modKey + 'z'},
|
|
3275
|
+
{sel:'#tool_redo', fn: clickRedo, evt: 'click', key: ['y', true]},
|
|
3276
|
+
{sel:'#tool_cut', fn: cutSelected, evt: 'click', key: [modKey+'x', true]},
|
|
3277
|
+
{sel:'#tool_copy', fn: copySelected, evt: 'click', key: modKey+'c'},
|
|
3278
|
+
{sel:'#tool_paste', fn: pasteSelected, evt: 'click', key: modKey+'v'},
|
|
3279
|
+
{sel:'#tool_switch', fn: clickSwitch, evt: 'click', key: ['x', true]},
|
|
3280
|
+
{sel:'#tool_bold', fn: clickBold, evt: 'mousedown', key: [modKey + 'B', true]},
|
|
3281
|
+
{sel:'#tool_italic', fn: clickItalic, evt: 'mousedown', key: [modKey + 'I', true]},
|
|
3282
|
+
//{sel:'#sidepanel_handle', fn: toggleSidePanel, key: ['X']},
|
|
3283
|
+
{sel:'#copy_save_done', fn: cancelOverlays, evt: 'click'},
|
|
3284
|
+
|
|
3285
|
+
// Shortcuts not associated with buttons
|
|
3286
|
+
|
|
3287
|
+
{key: 'ctrl+left', fn: function(){rotateSelected(0,1)}},
|
|
3288
|
+
{key: 'ctrl+right', fn: function(){rotateSelected(1,1)}},
|
|
3289
|
+
{key: 'ctrl+shift+left', fn: function(){rotateSelected(0,5)}},
|
|
3290
|
+
{key: 'ctrl+shift+right', fn: function(){rotateSelected(1,5)}},
|
|
3291
|
+
{key: 'shift+O', fn: selectPrev},
|
|
3292
|
+
{key: 'shift+P', fn: selectNext},
|
|
3293
|
+
{key: [modKey+'+', true], fn: function(){zoomImage(2);}},
|
|
3294
|
+
{key: [modKey+'-', true], fn: function(){zoomImage(.5);}},
|
|
3295
|
+
{key: ['up', true], fn: function(){moveSelected(0,-1);}},
|
|
3296
|
+
{key: ['down', true], fn: function(){moveSelected(0,1);}},
|
|
3297
|
+
{key: ['left', true], fn: function(){moveSelected(-1,0);}},
|
|
3298
|
+
{key: ['right', true], fn: function(){moveSelected(1,0);}},
|
|
3299
|
+
{key: 'shift+up', fn: function(){moveSelected(0,-10)}},
|
|
3300
|
+
{key: 'shift+down', fn: function(){moveSelected(0,10)}},
|
|
3301
|
+
{key: 'shift+left', fn: function(){moveSelected(-10,0)}},
|
|
3302
|
+
{key: 'shift+right', fn: function(){moveSelected(10,0)}},
|
|
3303
|
+
{key: ['alt+up', true], fn: function(){svgCanvas.cloneSelectedElements(0,-1)}},
|
|
3304
|
+
{key: ['alt+down', true], fn: function(){svgCanvas.cloneSelectedElements(0,1)}},
|
|
3305
|
+
{key: ['alt+left', true], fn: function(){svgCanvas.cloneSelectedElements(-1,0)}},
|
|
3306
|
+
{key: ['alt+right', true], fn: function(){svgCanvas.cloneSelectedElements(1,0)}},
|
|
3307
|
+
{key: ['alt+shift+up', true], fn: function(){svgCanvas.cloneSelectedElements(0,-10)}},
|
|
3308
|
+
{key: ['alt+shift+down', true], fn: function(){svgCanvas.cloneSelectedElements(0,10)}},
|
|
3309
|
+
{key: ['alt+shift+left', true], fn: function(){svgCanvas.cloneSelectedElements(-10,0)}},
|
|
3310
|
+
{key: ['alt+shift+right', true], fn: function(){svgCanvas.cloneSelectedElements(10,0)}},
|
|
3311
|
+
{key: modKey + 'A', fn: function(){svgCanvas.selectAllInCurrentLayer();}},
|
|
3312
|
+
{key: 'I', fn: function(){setEyedropperMode()}},
|
|
3313
|
+
|
|
3314
|
+
// Standard shortcuts
|
|
3315
|
+
{key: modKey + 'shift+z', fn: clickRedo},
|
|
3316
|
+
{key: 'esc', fn: minimizeModal}
|
|
3317
|
+
];
|
|
3318
|
+
|
|
3319
|
+
// Tooltips not directly associated with a single function
|
|
3320
|
+
var key_assocs = {
|
|
3321
|
+
'4/Shift+4': '#tools_rect_show',
|
|
3322
|
+
'5/Shift+5': '#tools_ellipse_show'
|
|
3323
|
+
};
|
|
3324
|
+
|
|
3325
|
+
return {
|
|
3326
|
+
setAll: function() {
|
|
3327
|
+
var flyouts = {};
|
|
3328
|
+
|
|
3329
|
+
$.each(tool_buttons, function(i, opts) {
|
|
3330
|
+
// Bind function to button
|
|
3331
|
+
if(opts.sel) {
|
|
3332
|
+
var btn = $(opts.sel);
|
|
3333
|
+
if (btn.length == 0) return true; // Skip if markup does not exist
|
|
3334
|
+
if(opts.evt) {
|
|
3335
|
+
if (svgedit.browser.isTouch() && opts.evt === "click") opts.evt = "mousedown"
|
|
3336
|
+
btn[opts.evt](opts.fn);
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
// Add to parent flyout menu, if able to be displayed
|
|
3340
|
+
if(opts.parent && $(opts.parent + '_show').length != 0) {
|
|
3341
|
+
var f_h = $(opts.parent);
|
|
3342
|
+
if(!f_h.length) {
|
|
3343
|
+
f_h = makeFlyoutHolder(opts.parent.substr(1));
|
|
3344
|
+
}
|
|
3345
|
+
|
|
3346
|
+
f_h.append(btn);
|
|
3347
|
+
|
|
3348
|
+
if(!$.isArray(flyouts[opts.parent])) {
|
|
3349
|
+
flyouts[opts.parent] = [];
|
|
3350
|
+
}
|
|
3351
|
+
flyouts[opts.parent].push(opts);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
|
|
3356
|
+
// Bind function to shortcut key
|
|
3357
|
+
if(opts.key) {
|
|
3358
|
+
// Set shortcut based on options
|
|
3359
|
+
var keyval, shortcut = '', disInInp = true, fn = opts.fn, pd = false;
|
|
3360
|
+
if($.isArray(opts.key)) {
|
|
3361
|
+
keyval = opts.key[0];
|
|
3362
|
+
if(opts.key.length > 1) pd = opts.key[1];
|
|
3363
|
+
if(opts.key.length > 2) disInInp = opts.key[2];
|
|
3364
|
+
} else {
|
|
3365
|
+
keyval = opts.key;
|
|
3366
|
+
}
|
|
3367
|
+
keyval += '';
|
|
3368
|
+
if (svgedit.browser.isMac && keyval.indexOf("+") != -1) {
|
|
3369
|
+
var modifier_key = keyval.split("+")[0];
|
|
3370
|
+
if (modifier_key == "ctrl") keyval.replace("ctrl", "cmd")
|
|
3371
|
+
}
|
|
3372
|
+
|
|
3373
|
+
$.each(keyval.split('/'), function(i, key) {
|
|
3374
|
+
$(document).bind('keydown', key, function(e) {
|
|
3375
|
+
fn();
|
|
3376
|
+
if(pd) {
|
|
3377
|
+
e.preventDefault();
|
|
3378
|
+
}
|
|
3379
|
+
// Prevent default on ALL keys?
|
|
3380
|
+
return false;
|
|
3381
|
+
});
|
|
3382
|
+
});
|
|
3383
|
+
|
|
3384
|
+
// Put shortcut in title
|
|
3385
|
+
if(opts.sel && !opts.hidekey && btn.attr('title')) {
|
|
3386
|
+
var new_title = btn.attr('title').split('[')[0] + ' (' + keyval + ')';
|
|
3387
|
+
key_assocs[keyval] = opts.sel;
|
|
3388
|
+
// Disregard for menu items
|
|
3389
|
+
if(!btn.parents('#main_menu').length) {
|
|
3390
|
+
btn.attr('title', new_title);
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
}
|
|
3394
|
+
});
|
|
3395
|
+
|
|
3396
|
+
// Setup flyouts
|
|
3397
|
+
setupFlyouts(flyouts);
|
|
3398
|
+
|
|
3399
|
+
$(window).bind('keydown', 'tab', function(e) {
|
|
3400
|
+
if(ui_context === 'canvas') {
|
|
3401
|
+
e.preventDefault();
|
|
3402
|
+
selectNext();
|
|
3403
|
+
}
|
|
3404
|
+
}).bind('keydown', 'shift+tab', function(e) {
|
|
3405
|
+
if(ui_context === 'canvas') {
|
|
3406
|
+
e.preventDefault();
|
|
3407
|
+
selectPrev();
|
|
3408
|
+
}
|
|
3409
|
+
});
|
|
3410
|
+
|
|
3411
|
+
$('#tool_zoom').dblclick(dblclickZoom);
|
|
3412
|
+
},
|
|
3413
|
+
setTitles: function() {
|
|
3414
|
+
$.each(key_assocs, function(keyval, sel) {
|
|
3415
|
+
var menu = ($(sel).parents('#main_menu').length);
|
|
3416
|
+
|
|
3417
|
+
$(sel).each(function() {
|
|
3418
|
+
if(menu) {
|
|
3419
|
+
var t = $(this).text().split(' [')[0];
|
|
3420
|
+
} else {
|
|
3421
|
+
var t = this.title.split(' [')[0];
|
|
3422
|
+
}
|
|
3423
|
+
var key_str = '';
|
|
3424
|
+
// Shift+Up
|
|
3425
|
+
$.each(keyval.split('/'), function(i, key) {
|
|
3426
|
+
var mod_bits = key.split('+'), mod = '';
|
|
3427
|
+
if(mod_bits.length > 1) {
|
|
3428
|
+
mod = mod_bits[0] + '+';
|
|
3429
|
+
key = mod_bits[1];
|
|
3430
|
+
}
|
|
3431
|
+
key_str += (i?'/':'') + mod + (uiStrings['key_'+key] || key);
|
|
3432
|
+
});
|
|
3433
|
+
if(menu) {
|
|
3434
|
+
this.lastChild.textContent = t +' ['+key_str+']';
|
|
3435
|
+
} else {
|
|
3436
|
+
this.title = t +' ['+key_str+']';
|
|
3437
|
+
}
|
|
3438
|
+
});
|
|
3439
|
+
});
|
|
3440
|
+
},
|
|
3441
|
+
getButtonData: function(sel) {
|
|
3442
|
+
var b;
|
|
3443
|
+
$.each(tool_buttons, function(i, btn) {
|
|
3444
|
+
if(btn.sel === sel) b = btn;
|
|
3445
|
+
});
|
|
3446
|
+
return b;
|
|
3447
|
+
}
|
|
3448
|
+
};
|
|
3449
|
+
}();
|
|
3450
|
+
|
|
3451
|
+
Actions.setAll();
|
|
3452
|
+
|
|
3453
|
+
// Select given tool
|
|
3454
|
+
Editor.ready(function() {
|
|
3455
|
+
var tool,
|
|
3456
|
+
itool = curConfig.initTool,
|
|
3457
|
+
container = $("#tools_left, #svg_editor .tools_flyout"),
|
|
3458
|
+
pre_tool = container.find("#tool_" + itool),
|
|
3459
|
+
reg_tool = container.find("#" + itool);
|
|
3460
|
+
if(pre_tool.length) {
|
|
3461
|
+
tool = pre_tool;
|
|
3462
|
+
} else if(reg_tool.length){
|
|
3463
|
+
tool = reg_tool;
|
|
3464
|
+
} else {
|
|
3465
|
+
tool = $("#tool_select");
|
|
3466
|
+
}
|
|
3467
|
+
tool.click().mouseup();
|
|
3468
|
+
|
|
3469
|
+
if(curConfig.wireframe) {
|
|
3470
|
+
$('#tool_wireframe').click();
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
if(curConfig.showlayers) {
|
|
3474
|
+
toggleSidePanel();
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
$('#rulers').toggle(!!curConfig.showRulers);
|
|
3478
|
+
});
|
|
3479
|
+
|
|
3480
|
+
|
|
3481
|
+
$('#canvas_height').dragInput({ min: 10, max: null, step: 10, callback: changeCanvasSize, cursor: false, dragAdjust: .1 });
|
|
3482
|
+
$('#canvas_width') .dragInput({ min: 10, max: null, step: 10, callback: changeCanvasSize, cursor: false, dragAdjust: .1 });
|
|
3483
|
+
$('#rect_width') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3484
|
+
$('#rect_height') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3485
|
+
$('#ellipse_cx') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3486
|
+
$('#ellipse_cy') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3487
|
+
$('#ellipse_rx') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3488
|
+
$('#ellipse_ry') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3489
|
+
$("#image_height") .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3490
|
+
$('#circle_cx') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3491
|
+
$('#circle_cy') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3492
|
+
$('#circle_r') .dragInput({ min: 1, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3493
|
+
$("#image_height") .dragInput({ min: 0, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3494
|
+
$('#selected_x') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3495
|
+
$('#selected_y') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3496
|
+
$("#path_node_x") .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3497
|
+
$("#path_node_y") .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3498
|
+
$("#image_width") .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3499
|
+
$('#line_x1') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3500
|
+
$('#line_x2') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3501
|
+
$('#line_y1') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3502
|
+
$('#line_y2') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3503
|
+
$('#path_x') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3504
|
+
$('#path_y') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3505
|
+
$('#rect_x') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3506
|
+
$('#rect_y') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3507
|
+
$('#g_x') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3508
|
+
$('#g_y') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3509
|
+
$('#image_x') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3510
|
+
$('#text_y') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3511
|
+
$('#text_x') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3512
|
+
$('#image_y') .dragInput({ min: null, max: null, step: 1, callback: changeAttribute, cursor: false });
|
|
3513
|
+
$('#rect_rx') .dragInput({ min: 0, max: 100, step: 1, callback: changeAttribute, cursor: true });
|
|
3514
|
+
$('#stroke_width') .dragInput({ min: 0, max: 99, step: 1, callback: changeStrokeWidth, cursor: true, smallStep: 0.1, start: 1.5 });
|
|
3515
|
+
$('#angle') .dragInput({ min: -180, max: 180, step: 1, callback: changeRotationAngle, cursor: false, dragAdjust: 0.5 });
|
|
3516
|
+
$('#font_size') .dragInput({ min: 1, max: 250, step: 1, callback: changeFontSize, cursor: true, stepfunc: stepFontSize, dragAdjust: .15 });
|
|
3517
|
+
$('#group_opacity').dragInput({ min: 0, max: 100, step: 5, callback: changeAttribute, cursor: true, start: 100 });
|
|
3518
|
+
$('#blur') .dragInput({ min: 0, max: 10, step: .1, callback: changeBlur, cursor: true, start: 0 });
|
|
3519
|
+
// Set default zoom
|
|
3520
|
+
$('#zoom').val(svgCanvas.getZoom() * 100);
|
|
3521
|
+
|
|
3522
|
+
$("#workarea").contextMenu({
|
|
3523
|
+
menu: 'cmenu_canvas',
|
|
3524
|
+
inSpeed: 0
|
|
3525
|
+
},
|
|
3526
|
+
function(action, el, pos) {
|
|
3527
|
+
switch ( action ) {
|
|
3528
|
+
case 'delete':
|
|
3529
|
+
deleteSelected();
|
|
3530
|
+
break;
|
|
3531
|
+
case 'cut':
|
|
3532
|
+
cutSelected();
|
|
3533
|
+
break;
|
|
3534
|
+
case 'copy':
|
|
3535
|
+
copySelected();
|
|
3536
|
+
break;
|
|
3537
|
+
case 'paste':
|
|
3538
|
+
svgCanvas.pasteElements();
|
|
3539
|
+
break;
|
|
3540
|
+
case 'paste_in_place':
|
|
3541
|
+
svgCanvas.pasteElements('in_place');
|
|
3542
|
+
break;
|
|
3543
|
+
case 'group':
|
|
3544
|
+
svgCanvas.groupSelectedElements();
|
|
3545
|
+
break;
|
|
3546
|
+
case 'ungroup':
|
|
3547
|
+
svgCanvas.ungroupSelectedElement();
|
|
3548
|
+
break;
|
|
3549
|
+
case 'move_front':
|
|
3550
|
+
moveToTopSelected();
|
|
3551
|
+
break;
|
|
3552
|
+
case 'move_up':
|
|
3553
|
+
moveUpDownSelected('Up');
|
|
3554
|
+
break;
|
|
3555
|
+
case 'move_down':
|
|
3556
|
+
moveUpDownSelected('Down');
|
|
3557
|
+
break;
|
|
3558
|
+
case 'move_back':
|
|
3559
|
+
moveToBottomSelected();
|
|
3560
|
+
break;
|
|
3561
|
+
default:
|
|
3562
|
+
if(svgedit.contextmenu && svgedit.contextmenu.hasCustomHandler(action)){
|
|
3563
|
+
svgedit.contextmenu.getCustomHandler(action).call();
|
|
3564
|
+
}
|
|
3565
|
+
break;
|
|
3566
|
+
}
|
|
3567
|
+
|
|
3568
|
+
});
|
|
3569
|
+
|
|
3570
|
+
$('.contextMenu li').mousedown(function(ev) {
|
|
3571
|
+
ev.preventDefault();
|
|
3572
|
+
})
|
|
3573
|
+
|
|
3574
|
+
$('#cmenu_canvas li').disableContextMenu();
|
|
3575
|
+
canv_menu.enableContextMenuItems('#delete,#cut,#copy');
|
|
3576
|
+
|
|
3577
|
+
window.onbeforeunload = function() {
|
|
3578
|
+
// Suppress warning if page is empty
|
|
3579
|
+
if(undoMgr.getUndoStackSize() === 0) {
|
|
3580
|
+
Editor.show_save_warning = false;
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3583
|
+
// show_save_warning is set to "false" when the page is saved.
|
|
3584
|
+
if(!curConfig.no_save_warning && Editor.show_save_warning) {
|
|
3585
|
+
// Browser already asks question about closing the page
|
|
3586
|
+
return uiStrings.notification.unsavedChanges;
|
|
3587
|
+
}
|
|
3588
|
+
};
|
|
3589
|
+
|
|
3590
|
+
Editor.openPrep = function(func) {
|
|
3591
|
+
$('#main_menu').hide();
|
|
3592
|
+
if(undoMgr.getUndoStackSize() === 0) {
|
|
3593
|
+
func(true);
|
|
3594
|
+
} else {
|
|
3595
|
+
$.confirm(uiStrings.notification.QwantToOpen, func);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
if (window.FileReader) {
|
|
3600
|
+
|
|
3601
|
+
var import_image = function(e) {
|
|
3602
|
+
e.stopPropagation();
|
|
3603
|
+
e.preventDefault();
|
|
3604
|
+
$("#workarea").removeAttr("style");
|
|
3605
|
+
$('#main_menu').hide();
|
|
3606
|
+
var file = null;
|
|
3607
|
+
if (e.type == "drop") file = e.dataTransfer.files[0]
|
|
3608
|
+
else file = this.files[0];
|
|
3609
|
+
if (file) {
|
|
3610
|
+
if(file.type.indexOf("image") != -1) {
|
|
3611
|
+
//detected an image
|
|
3612
|
+
|
|
3613
|
+
//svg handing
|
|
3614
|
+
if(file.type.indexOf("svg") != -1) {
|
|
3615
|
+
var reader = new FileReader();
|
|
3616
|
+
reader.onloadend = function(e) {
|
|
3617
|
+
svgCanvas.importSvgString(e.target.result, true);
|
|
3618
|
+
svgCanvas.ungroupSelectedElement()
|
|
3619
|
+
svgCanvas.ungroupSelectedElement()
|
|
3620
|
+
svgCanvas.groupSelectedElements()
|
|
3621
|
+
svgCanvas.alignSelectedElements("m", "page")
|
|
3622
|
+
svgCanvas.alignSelectedElements("c", "page")
|
|
3623
|
+
};
|
|
3624
|
+
reader.readAsText(file);
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
//image handling
|
|
3628
|
+
else {
|
|
3629
|
+
var reader = new FileReader();
|
|
3630
|
+
reader.onloadend = function(e) {
|
|
3631
|
+
// lets insert the new image until we know its dimensions
|
|
3632
|
+
insertNewImage = function(img_width, img_height){
|
|
3633
|
+
var newImage = svgCanvas.addSvgElementFromJson({
|
|
3634
|
+
"element": "image",
|
|
3635
|
+
"attr": {
|
|
3636
|
+
"x": 0,
|
|
3637
|
+
"y": 0,
|
|
3638
|
+
"width": img_width,
|
|
3639
|
+
"height": img_height,
|
|
3640
|
+
"id": svgCanvas.getNextId(),
|
|
3641
|
+
"style": "pointer-events:inherit"
|
|
3642
|
+
}
|
|
3643
|
+
});
|
|
3644
|
+
svgCanvas.setHref(newImage, e.target.result);
|
|
3645
|
+
svgCanvas.selectOnly([newImage])
|
|
3646
|
+
svgCanvas.alignSelectedElements("m", "page")
|
|
3647
|
+
svgCanvas.alignSelectedElements("c", "page")
|
|
3648
|
+
updateContextPanel();
|
|
3649
|
+
}
|
|
3650
|
+
// put a placeholder img so we know the default dimensions
|
|
3651
|
+
var img_width = 100;
|
|
3652
|
+
var img_height = 100;
|
|
3653
|
+
var img = new Image()
|
|
3654
|
+
img.src = e.target.result
|
|
3655
|
+
document.body.appendChild(img);
|
|
3656
|
+
img.onload = function() {
|
|
3657
|
+
img_width = img.offsetWidth
|
|
3658
|
+
img_height = img.offsetHeight
|
|
3659
|
+
insertNewImage(img_width, img_height);
|
|
3660
|
+
document.body.removeChild(img);
|
|
3661
|
+
}
|
|
3662
|
+
};
|
|
3663
|
+
reader.readAsDataURL(file)
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
var workarea = $("#workarea")
|
|
3670
|
+
|
|
3671
|
+
function onDragEnter(e) {
|
|
3672
|
+
e.stopPropagation();
|
|
3673
|
+
e.preventDefault();
|
|
3674
|
+
workarea.css({
|
|
3675
|
+
"-webkit-transform": "scale3d(1.1,1.1,1)",
|
|
3676
|
+
"-moz-transform": "scale3d(1.1,1.1,1)",
|
|
3677
|
+
"-o-transform": "scale(1.1)",
|
|
3678
|
+
"-ms-transform": "scale3d(1.1,1.1,1)",
|
|
3679
|
+
"transform": "scale3d(1.1,1.1,1)"
|
|
3680
|
+
})
|
|
3681
|
+
|
|
3682
|
+
}
|
|
3683
|
+
|
|
3684
|
+
function onDragOver(e) {
|
|
3685
|
+
e.stopPropagation();
|
|
3686
|
+
e.preventDefault();
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
function onDragLeave(e) {
|
|
3690
|
+
workarea.removeAttr("style")
|
|
3691
|
+
e.stopPropagation();
|
|
3692
|
+
e.preventDefault();
|
|
3693
|
+
}
|
|
3694
|
+
|
|
3695
|
+
workarea[0].addEventListener('dragenter', onDragEnter, false);
|
|
3696
|
+
workarea[0].addEventListener('dragover', onDragOver, false);
|
|
3697
|
+
workarea[0].addEventListener('dragleave', onDragLeave, false);
|
|
3698
|
+
workarea[0].addEventListener('drop', import_image, false);
|
|
3699
|
+
|
|
3700
|
+
var open = $('<input type="file">').change(function() {
|
|
3701
|
+
var f = this;
|
|
3702
|
+
Editor.openPrep(function(ok) {
|
|
3703
|
+
if(!ok) return;
|
|
3704
|
+
svgCanvas.clear();
|
|
3705
|
+
if(f.files.length==1) {
|
|
3706
|
+
var reader = new FileReader();
|
|
3707
|
+
reader.onloadend = function(e) {
|
|
3708
|
+
loadSvgString(e.target.result);
|
|
3709
|
+
updateCanvas();
|
|
3710
|
+
};
|
|
3711
|
+
reader.readAsText(f.files[0]);
|
|
3712
|
+
}
|
|
3713
|
+
});
|
|
3714
|
+
});
|
|
3715
|
+
$("#tool_open").show().prepend(open);
|
|
3716
|
+
|
|
3717
|
+
var img_import = $('<input type="file">').change(import_image);
|
|
3718
|
+
$("#tool_import").show().prepend(img_import);
|
|
3719
|
+
}
|
|
3720
|
+
|
|
3721
|
+
|
|
3722
|
+
var updateCanvas = Editor.updateCanvas = function(center, new_ctr) {
|
|
3723
|
+
var w = workarea.width(), h = workarea.height();
|
|
3724
|
+
var w_orig = w, h_orig = h;
|
|
3725
|
+
var zoom = svgCanvas.getZoom();
|
|
3726
|
+
var w_area = workarea;
|
|
3727
|
+
var cnvs = $("#svgcanvas");
|
|
3728
|
+
|
|
3729
|
+
var old_ctr = {
|
|
3730
|
+
x: w_area[0].scrollLeft + w_orig/2,
|
|
3731
|
+
y: w_area[0].scrollTop + h_orig/2
|
|
3732
|
+
};
|
|
3733
|
+
|
|
3734
|
+
var multi = curConfig.canvas_expansion;
|
|
3735
|
+
w = Math.max(w_orig, svgCanvas.contentW * zoom * multi);
|
|
3736
|
+
h = Math.max(h_orig, svgCanvas.contentH * zoom * multi);
|
|
3737
|
+
|
|
3738
|
+
if(w == w_orig && h == h_orig) {
|
|
3739
|
+
workarea.css('overflow','hidden');
|
|
3740
|
+
} else {
|
|
3741
|
+
workarea.css('overflow','scroll');
|
|
3742
|
+
}
|
|
3743
|
+
|
|
3744
|
+
var old_can_y = cnvs.height()/2;
|
|
3745
|
+
var old_can_x = cnvs.width()/2;
|
|
3746
|
+
cnvs.width(w).height(h);
|
|
3747
|
+
var new_can_y = h/2;
|
|
3748
|
+
var new_can_x = w/2;
|
|
3749
|
+
var offset = svgCanvas.updateCanvas(w, h);
|
|
3750
|
+
|
|
3751
|
+
var ratio = new_can_x / old_can_x;
|
|
3752
|
+
|
|
3753
|
+
var scroll_x = w/2 - w_orig/2;
|
|
3754
|
+
var scroll_y = h/2 - h_orig/2;
|
|
3755
|
+
|
|
3756
|
+
if(!new_ctr) {
|
|
3757
|
+
|
|
3758
|
+
var old_dist_x = old_ctr.x - old_can_x;
|
|
3759
|
+
var new_x = new_can_x + old_dist_x * ratio;
|
|
3760
|
+
|
|
3761
|
+
var old_dist_y = old_ctr.y - old_can_y;
|
|
3762
|
+
var new_y = new_can_y + old_dist_y * ratio;
|
|
3763
|
+
|
|
3764
|
+
new_ctr = {
|
|
3765
|
+
x: new_x,
|
|
3766
|
+
y: new_y
|
|
3767
|
+
};
|
|
3768
|
+
|
|
3769
|
+
} else {
|
|
3770
|
+
new_ctr.x += offset.x,
|
|
3771
|
+
new_ctr.y += offset.y;
|
|
3772
|
+
}
|
|
3773
|
+
|
|
3774
|
+
//width.val(offset.x)
|
|
3775
|
+
//height.val(offset.y)
|
|
3776
|
+
|
|
3777
|
+
if(center) {
|
|
3778
|
+
// Go to top-left for larger documents
|
|
3779
|
+
if(svgCanvas.contentW > w_area.width()) {
|
|
3780
|
+
// Top-left
|
|
3781
|
+
workarea[0].scrollLeft = offset.x - 10;
|
|
3782
|
+
workarea[0].scrollTop = offset.y - 10;
|
|
3783
|
+
} else {
|
|
3784
|
+
// Center
|
|
3785
|
+
w_area[0].scrollLeft = scroll_x;
|
|
3786
|
+
w_area[0].scrollTop = scroll_y;
|
|
3787
|
+
}
|
|
3788
|
+
} else {
|
|
3789
|
+
w_area[0].scrollLeft = new_ctr.x - w_orig/2;
|
|
3790
|
+
w_area[0].scrollTop = new_ctr.y - h_orig/2;
|
|
3791
|
+
}
|
|
3792
|
+
if(curConfig.showRulers) {
|
|
3793
|
+
updateRulers(cnvs, zoom);
|
|
3794
|
+
workarea.scroll();
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
|
|
3798
|
+
// Make [1,2,5] array
|
|
3799
|
+
var r_intervals = [];
|
|
3800
|
+
for(var i = .1; i < 1E5; i *= 10) {
|
|
3801
|
+
r_intervals.push(1 * i);
|
|
3802
|
+
r_intervals.push(2 * i);
|
|
3803
|
+
r_intervals.push(5 * i);
|
|
3804
|
+
}
|
|
3805
|
+
|
|
3806
|
+
function updateRulers(scanvas, zoom) {
|
|
3807
|
+
var workarea = document.getElementById("workarea");
|
|
3808
|
+
var title_show = document.getElementById("title_show");
|
|
3809
|
+
var offset_x = 66;
|
|
3810
|
+
var offset_y = 48;
|
|
3811
|
+
if(!zoom) zoom = svgCanvas.getZoom();
|
|
3812
|
+
if(!scanvas) scanvas = $("#svgcanvas");
|
|
3813
|
+
|
|
3814
|
+
var limit = 30000;
|
|
3815
|
+
|
|
3816
|
+
var c_elem = svgCanvas.getContentElem();
|
|
3817
|
+
|
|
3818
|
+
var units = svgedit.units.getTypeMap();
|
|
3819
|
+
var unit = units[curConfig.baseUnit]; // 1 = 1px
|
|
3820
|
+
|
|
3821
|
+
for(var d = 0; d < 2; d++) {
|
|
3822
|
+
var is_x = (d === 0);
|
|
3823
|
+
var dim = is_x ? 'x' : 'y';
|
|
3824
|
+
var lentype = is_x?'width':'height';
|
|
3825
|
+
var content_d = c_elem.getAttribute(dim)-0;
|
|
3826
|
+
|
|
3827
|
+
var $hcanv_orig = $('#ruler_' + dim + ' canvas:first');
|
|
3828
|
+
|
|
3829
|
+
// Bit of a hack to fully clear the canvas in Safari & IE9
|
|
3830
|
+
$hcanv = $hcanv_orig.clone();
|
|
3831
|
+
$hcanv_orig.replaceWith($hcanv);
|
|
3832
|
+
|
|
3833
|
+
var hcanv = $hcanv[0];
|
|
3834
|
+
|
|
3835
|
+
// Set the canvas size to the width of the container
|
|
3836
|
+
var ruler_len = scanvas[lentype]()*2;
|
|
3837
|
+
var total_len = ruler_len;
|
|
3838
|
+
hcanv.parentNode.style[lentype] = total_len + 'px';
|
|
3839
|
+
|
|
3840
|
+
var canv_count = 1;
|
|
3841
|
+
var ctx_num = 0;
|
|
3842
|
+
var ctx_arr;
|
|
3843
|
+
var ctx = hcanv.getContext("2d");
|
|
3844
|
+
|
|
3845
|
+
ctx.fillStyle = "rgb(200,0,0)";
|
|
3846
|
+
ctx.fillRect(0,0,hcanv.width,hcanv.height);
|
|
3847
|
+
|
|
3848
|
+
// Remove any existing canvasses
|
|
3849
|
+
$hcanv.siblings().remove();
|
|
3850
|
+
|
|
3851
|
+
// Create multiple canvases when necessary (due to browser limits)
|
|
3852
|
+
if(ruler_len >= limit) {
|
|
3853
|
+
var num = parseInt(ruler_len / limit) + 1;
|
|
3854
|
+
ctx_arr = Array(num);
|
|
3855
|
+
ctx_arr[0] = ctx;
|
|
3856
|
+
for(var i = 1; i < num; i++) {
|
|
3857
|
+
hcanv[lentype] = limit;
|
|
3858
|
+
var copy = hcanv.cloneNode(true);
|
|
3859
|
+
hcanv.parentNode.appendChild(copy);
|
|
3860
|
+
ctx_arr[i] = copy.getContext('2d');
|
|
3861
|
+
}
|
|
3862
|
+
|
|
3863
|
+
copy[lentype] = ruler_len % limit;
|
|
3864
|
+
|
|
3865
|
+
// set copy width to last
|
|
3866
|
+
ruler_len = limit;
|
|
3867
|
+
}
|
|
3868
|
+
|
|
3869
|
+
hcanv[lentype] = ruler_len;
|
|
3870
|
+
|
|
3871
|
+
var u_multi = unit * zoom;
|
|
3872
|
+
|
|
3873
|
+
// Calculate the main number interval
|
|
3874
|
+
var raw_m = 50 / u_multi;
|
|
3875
|
+
var multi = 1;
|
|
3876
|
+
for(var i = 0; i < r_intervals.length; i++) {
|
|
3877
|
+
var num = r_intervals[i];
|
|
3878
|
+
multi = num;
|
|
3879
|
+
if(raw_m <= num) {
|
|
3880
|
+
break;
|
|
3881
|
+
}
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
var big_int = multi * u_multi;
|
|
3885
|
+
ctx.font = "normal 9px 'Lucida Grande', sans-serif";
|
|
3886
|
+
ctx.fillStyle = "#777";
|
|
3887
|
+
|
|
3888
|
+
var ruler_d = ((content_d / u_multi) % multi) * u_multi;
|
|
3889
|
+
var label_pos = ruler_d - big_int;
|
|
3890
|
+
for (; ruler_d < total_len; ruler_d += big_int) {
|
|
3891
|
+
label_pos += big_int;
|
|
3892
|
+
var real_d = ruler_d - content_d;
|
|
3893
|
+
|
|
3894
|
+
var cur_d = Math.round(ruler_d) + .5;
|
|
3895
|
+
if(is_x) {
|
|
3896
|
+
ctx.moveTo(cur_d, 15);
|
|
3897
|
+
ctx.lineTo(cur_d, 0);
|
|
3898
|
+
} else {
|
|
3899
|
+
ctx.moveTo(15, cur_d);
|
|
3900
|
+
ctx.lineTo(0, cur_d);
|
|
3901
|
+
}
|
|
3902
|
+
|
|
3903
|
+
var num = (label_pos - content_d) / u_multi;
|
|
3904
|
+
var label;
|
|
3905
|
+
if(multi >= 1) {
|
|
3906
|
+
label = Math.round(num);
|
|
3907
|
+
} else {
|
|
3908
|
+
var decs = (multi+'').split('.')[1].length;
|
|
3909
|
+
label = num.toFixed(decs)-0;
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3912
|
+
// Do anything special for negative numbers?
|
|
3913
|
+
// var is_neg = label < 0;
|
|
3914
|
+
// real_d2 = Math.abs(real_d2);
|
|
3915
|
+
|
|
3916
|
+
// Change 1000s to Ks
|
|
3917
|
+
if(label !== 0 && label !== 1000 && label % 1000 === 0) {
|
|
3918
|
+
label = (label / 1000) + 'K';
|
|
3919
|
+
}
|
|
3920
|
+
|
|
3921
|
+
if(is_x) {
|
|
3922
|
+
ctx.fillText(label, ruler_d+2, 8);
|
|
3923
|
+
ctx.fillStyle = "#777";
|
|
3924
|
+
} else {
|
|
3925
|
+
var str = (label+'').split('');
|
|
3926
|
+
for(var i = 0; i < str.length; i++) {
|
|
3927
|
+
ctx.fillText(str[i], 1, (ruler_d+9) + i*9);
|
|
3928
|
+
ctx.fillStyle = "#777";
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
var part = big_int / 10;
|
|
3933
|
+
for(var i = 1; i < 10; i++) {
|
|
3934
|
+
var sub_d = Math.round(ruler_d + part * i) + .5;
|
|
3935
|
+
if(ctx_arr && sub_d > ruler_len) {
|
|
3936
|
+
ctx_num++;
|
|
3937
|
+
ctx.stroke();
|
|
3938
|
+
if(ctx_num >= ctx_arr.length) {
|
|
3939
|
+
i = 10;
|
|
3940
|
+
ruler_d = total_len;
|
|
3941
|
+
continue;
|
|
3942
|
+
}
|
|
3943
|
+
ctx = ctx_arr[ctx_num];
|
|
3944
|
+
ruler_d -= limit;
|
|
3945
|
+
sub_d = Math.round(ruler_d + part * i) + .5;
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3948
|
+
var line_num = (i % 2)?12:10;
|
|
3949
|
+
if(is_x) {
|
|
3950
|
+
ctx.moveTo(sub_d, 15);
|
|
3951
|
+
ctx.lineTo(sub_d, line_num);
|
|
3952
|
+
} else {
|
|
3953
|
+
ctx.moveTo(15, sub_d);
|
|
3954
|
+
ctx.lineTo(line_num ,sub_d);
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
}
|
|
3958
|
+
ctx.strokeStyle = "#666";
|
|
3959
|
+
ctx.stroke();
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
|
|
3963
|
+
// $(function() {
|
|
3964
|
+
updateCanvas(true);
|
|
3965
|
+
// });
|
|
3966
|
+
|
|
3967
|
+
// var revnums = "svg-editor.js ($Rev: 2083 $) ";
|
|
3968
|
+
// revnums += svgCanvas.getVersion();
|
|
3969
|
+
// $('#copyright')[0].setAttribute("title", revnums);
|
|
3970
|
+
|
|
3971
|
+
// Callback handler for embedapi.js
|
|
3972
|
+
try{
|
|
3973
|
+
var json_encode = function(obj){
|
|
3974
|
+
//simple partial JSON encoder implementation
|
|
3975
|
+
if(window.JSON && JSON.stringify) return JSON.stringify(obj);
|
|
3976
|
+
var enc = arguments.callee; //for purposes of recursion
|
|
3977
|
+
if(typeof obj == "boolean" || typeof obj == "number"){
|
|
3978
|
+
return obj+'' //should work...
|
|
3979
|
+
}else if(typeof obj == "string"){
|
|
3980
|
+
//a large portion of this is stolen from Douglas Crockford's json2.js
|
|
3981
|
+
return '"'+
|
|
3982
|
+
obj.replace(
|
|
3983
|
+
/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g
|
|
3984
|
+
, function (a) {
|
|
3985
|
+
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
|
3986
|
+
})
|
|
3987
|
+
+'"'; //note that this isn't quite as purtyful as the usualness
|
|
3988
|
+
}else if(obj.length){ //simple hackish test for arrayish-ness
|
|
3989
|
+
for(var i = 0; i < obj.length; i++){
|
|
3990
|
+
obj[i] = enc(obj[i]); //encode every sub-thingy on top
|
|
3991
|
+
}
|
|
3992
|
+
return "["+obj.join(",")+"]";
|
|
3993
|
+
}else{
|
|
3994
|
+
var pairs = []; //pairs will be stored here
|
|
3995
|
+
for(var k in obj){ //loop through thingys
|
|
3996
|
+
pairs.push(enc(k)+":"+enc(obj[k])); //key: value
|
|
3997
|
+
}
|
|
3998
|
+
return "{"+pairs.join(",")+"}" //wrap in the braces
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
window.addEventListener("message", function(e){
|
|
4002
|
+
var cbid = parseInt(e.data.substr(0, e.data.indexOf(";")));
|
|
4003
|
+
try{
|
|
4004
|
+
e.source.postMessage("SVGe"+cbid+";"+json_encode(eval(e.data)), "*");
|
|
4005
|
+
}catch(err){
|
|
4006
|
+
e.source.postMessage("SVGe"+cbid+";error:"+err.message, "*");
|
|
4007
|
+
}
|
|
4008
|
+
}, false)
|
|
4009
|
+
}catch(err){
|
|
4010
|
+
window.embed_error = err;
|
|
4011
|
+
}
|
|
4012
|
+
|
|
4013
|
+
|
|
4014
|
+
|
|
4015
|
+
// For Compatibility with older extensions
|
|
4016
|
+
$(function() {
|
|
4017
|
+
window.svgCanvas = svgCanvas;
|
|
4018
|
+
svgCanvas.ready = methodDraw.ready;
|
|
4019
|
+
});
|
|
4020
|
+
|
|
4021
|
+
|
|
4022
|
+
Editor.setLang = function(lang, allStrings) {
|
|
4023
|
+
$.pref('lang', lang);
|
|
4024
|
+
$('#lang_select').val(lang);
|
|
4025
|
+
if(allStrings) {
|
|
4026
|
+
|
|
4027
|
+
var notif = allStrings.notification;
|
|
4028
|
+
|
|
4029
|
+
svgCanvas.runExtensions("langChanged", lang);
|
|
4030
|
+
|
|
4031
|
+
// Update flyout tooltips
|
|
4032
|
+
setFlyoutTitles();
|
|
4033
|
+
|
|
4034
|
+
// Copy title for certain tool elements
|
|
4035
|
+
var elems = {
|
|
4036
|
+
'#stroke_color': '#tool_stroke .icon_label, #tool_stroke .color_block',
|
|
4037
|
+
'#fill_color': '#tool_fill label, #tool_fill .color_block',
|
|
4038
|
+
'#linejoin_miter': '#cur_linejoin',
|
|
4039
|
+
'#linecap_butt': '#cur_linecap'
|
|
4040
|
+
}
|
|
4041
|
+
|
|
4042
|
+
$.each(elems, function(source, dest) {
|
|
4043
|
+
$(dest).attr('title', $(source)[0].title);
|
|
4044
|
+
});
|
|
4045
|
+
|
|
4046
|
+
// Copy alignment titles
|
|
4047
|
+
$('#multiselected_panel div[id^=tool_align]').each(function() {
|
|
4048
|
+
$('#tool_pos' + this.id.substr(10))[0].title = this.title;
|
|
4049
|
+
});
|
|
4050
|
+
|
|
4051
|
+
}
|
|
4052
|
+
};
|
|
4053
|
+
};
|
|
4054
|
+
|
|
4055
|
+
var callbacks = [];
|
|
4056
|
+
|
|
4057
|
+
function loadSvgString(str, callback) {
|
|
4058
|
+
var success = svgCanvas.setSvgString(str) !== false;
|
|
4059
|
+
callback = callback || $.noop;
|
|
4060
|
+
if(success) {
|
|
4061
|
+
callback(true);
|
|
4062
|
+
} else {
|
|
4063
|
+
$.alert(uiStrings.notification.errorLoadingSVG, function() {
|
|
4064
|
+
callback(false);
|
|
4065
|
+
});
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
4068
|
+
|
|
4069
|
+
Editor.ready = function(cb) {
|
|
4070
|
+
if(!is_ready) {
|
|
4071
|
+
callbacks.push(cb);
|
|
4072
|
+
} else {
|
|
4073
|
+
cb();
|
|
4074
|
+
}
|
|
4075
|
+
};
|
|
4076
|
+
|
|
4077
|
+
Editor.runCallbacks = function() {
|
|
4078
|
+
$.each(callbacks, function() {
|
|
4079
|
+
this();
|
|
4080
|
+
});
|
|
4081
|
+
is_ready = true;
|
|
4082
|
+
};
|
|
4083
|
+
|
|
4084
|
+
Editor.loadFromString = function(str) {
|
|
4085
|
+
Editor.ready(function() {
|
|
4086
|
+
loadSvgString(str);
|
|
4087
|
+
});
|
|
4088
|
+
};
|
|
4089
|
+
|
|
4090
|
+
Editor.loadFromURL = function(url, opts) {
|
|
4091
|
+
if(!opts) opts = {};
|
|
4092
|
+
|
|
4093
|
+
var cache = opts.cache;
|
|
4094
|
+
var cb = opts.callback;
|
|
4095
|
+
|
|
4096
|
+
Editor.ready(function() {
|
|
4097
|
+
$.ajax({
|
|
4098
|
+
'url': url,
|
|
4099
|
+
'dataType': 'text',
|
|
4100
|
+
cache: !!cache,
|
|
4101
|
+
success: function(str) {
|
|
4102
|
+
loadSvgString(str, cb);
|
|
4103
|
+
},
|
|
4104
|
+
error: function(xhr, stat, err) {
|
|
4105
|
+
if(xhr.status != 404 && xhr.responseText) {
|
|
4106
|
+
loadSvgString(xhr.responseText, cb);
|
|
4107
|
+
} else {
|
|
4108
|
+
$.alert(uiStrings.notification.URLloadFail + ": \n"+err+'', cb);
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
});
|
|
4112
|
+
});
|
|
4113
|
+
};
|
|
4114
|
+
|
|
4115
|
+
Editor.loadFromDataURI = function(str) {
|
|
4116
|
+
Editor.ready(function() {
|
|
4117
|
+
var pre = 'data:image/svg+xml;base64,';
|
|
4118
|
+
var src = str.substring(pre.length);
|
|
4119
|
+
loadSvgString(svgedit.utilities.decode64(src));
|
|
4120
|
+
});
|
|
4121
|
+
};
|
|
4122
|
+
|
|
4123
|
+
Editor.addExtension = function() {
|
|
4124
|
+
var args = arguments;
|
|
4125
|
+
|
|
4126
|
+
// Note that we don't want this on Editor.ready since some extensions
|
|
4127
|
+
// may want to run before then (like server_opensave).
|
|
4128
|
+
$(function() {
|
|
4129
|
+
if(svgCanvas) svgCanvas.addExtension.apply(this, args);
|
|
4130
|
+
});
|
|
4131
|
+
};
|
|
4132
|
+
|
|
4133
|
+
return Editor;
|
|
4134
|
+
}(jQuery);
|
|
4135
|
+
|
|
4136
|
+
// Run init once DOM is loaded
|
|
4137
|
+
$(methodDraw.init);
|
|
4138
|
+
|
|
4139
|
+
|
|
4140
|
+
})();
|