diff --git a/index.htm b/index.htm index 4542070..f4e05e5 100644 --- a/index.htm +++ b/index.htm @@ -2,7 +2,7 @@ Summer html image map creator - +
-
Attrubutes
+
Attributes

@@ -78,6 +79,19 @@

Attrubutes

+ +
+ + +
+

Settings

+ +

+ + +

+ +
@@ -154,6 +168,6 @@

Editing mode

- + \ No newline at end of file diff --git a/main.css b/main.css index 808eb87..bc59e3b 100644 --- a/main.css +++ b/main.css @@ -300,6 +300,18 @@ a:link, a:visited { .error#url { border: 2px solid #F00; } +#summer_settings { + position: absolute; + top: 100px; + left: 100px; + background: rgba(0,0,0,0.9); + border-radius: 5px; + padding: 10px; + box-shadow: rgba(0,0,0,0.2) 0 0 2px 1px; + display: none; + z-index: 1000; + color: #FFF; +} #edit_details { position: absolute; top: 100px; diff --git a/main.min.css b/main.min.css new file mode 100644 index 0000000..da0a7e4 --- /dev/null +++ b/main.min.css @@ -0,0 +1 @@ +a,applet,article,aside,audio,body,canvas,dd,details,div,dl,dt,em,embed,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,img,input,label,li,mark,menu,nav,object,ol,output,p,ruby,section,span,strong,summary,time,ul,video{margin:0;padding:0;border:0;outline:0;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;background:0 0}:focus{outline:0}ol,ul{list-style:none}html{height:100%}body{padding:0;margin:0;font-family:Arial,Tahoma,sans-serif;font-size:14px;color:#000;height:100%;min-height:100%;background:#FFF url(data:image/gif;base64,R0lGODlhCgAKAIABANzc3P///yH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAACgAKAAACEYQdmYcaDNxjEspKndVZbc8UADs=);line-height:1}img{border:0}a:link,a:visited{outline:0;text-decoration:none;color:#000}.clear{clear:both}.clearfix:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}#noscript{text-align:center;display:block;font-size:20px;padding:5px 0;background:red}#header{background:#000;padding:5px 0;position:fixed;z-index:1001;width:100%;box-shadow:rgba(0,0,0,.2) 0 0 2px 2px}#logo{margin-right:10px;margin-left:10px;margin-top:-4px;margin-bottom:-4px;display:inline-block;vertical-align:top}#logo a:link,#logo a:visited{color:#32c832}#logo a:hover{color:#FFF}#logo img{display:block}#nav,#nav ul{display:inline;vertical-align:middle}#nav li{margin-right:5px;display:inline}#nav a:link,#nav a:visited{border:1px solid #FFF;border-radius:3px;font-size:10px;padding:5px 10px;display:inline-block;color:#FFF}#nav a:active,#nav a:hover{border:1px solid #32c832;color:#32c832}#nav .selected a,#nav a:active{background:#FFF;color:#000;box-shadow:0 0 1px #222 inset;border:1px solid #FFF}#coords{position:absolute;top:10px;right:15px;color:#FFF;font-size:11px}#debug{color:#EEE;position:absolute;top:10px;right:100px;z-index:1001;font-size:11px}#wrapper{position:relative;display:none}#image_wrapper{padding:45px 0 10px}#image{position:relative;overflow:hidden;display:block;margin:0 auto;border-radius:3px;box-shadow:rgba(0,0,0,.2) 0 0 2px 2px}.draw#image{cursor:crosshair}#image map{position:absolute;top:0;left:0;width:100%;height:100%;display:block}#img{position:relative;z-index:1}#code{background:rgba(0,0,0,.9);color:#FFF;font-family:monospace;font-size:11px;line-height:1.3;position:fixed;left:3%;width:94%;bottom:10px;z-index:1000;box-shadow:rgba(0,0,0,.2) 0 0 2px 2px;display:none;border-radius:3px}#code_content{padding:10px}.close_button{width:10px;height:10px;display:block;background:#FFF url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACbgAAAm4Bt/774AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABKSURBVAiZfc2xCYBAFATR90WwiSvUzDOyCcuzCaM1UMHIgc1mmcKOI0mHqupoIw4sVTW5mbFKAhvybEti8EN/zc+zj2hYP/ET7QIK9BpShkyrPwAAAABJRU5ErkJggg==) 50% 50% no-repeat;position:absolute;top:10px;right:10px;box-shadow:0 0 1px #222 inset;border-radius:1px;cursor:pointer}#about{position:absolute;top:10px;left:0;width:100%;font-family:'News Cycle';font-size:24px;background:0 0;padding:2px 10px 5px;-o-box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;color:#000}#get_image_wrapper{padding:35px 0}#get_image{width:200px;margin:0 auto;font-size:16px;text-align:center;background:#FFF;padding:20px 30px;border-radius:5px;box-shadow:rgba(0,0,0,.2) 0 0 2px 2px;position:relative}#logo_get_image{margin-bottom:20px}#loading{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-size:20px;background:rgba(255,255,255,.95) url(data:image/gif;base64,R0lGODlhIwAjAPUAAP///zLIMuL24tn02fH68czwzPL78vr9+tLy0tz13Of458/xz/f899fz1+z57N/138Xvxer46pfil7LqsjvKO33bfZ3knZPhk4rfijLIMoDcgGPVY7jruKrnqm3XbVXRVbzsvL3svaXmpXDYcHfad6jnqEjNSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAIwAjAAAG/0CAcEgsGo/IpFExcCifSgGkUDBAr8QDlZrAegnbAsJrNDwUByJ4OyYqIBCr0lCYIhhD+nZALEguFyJpSQlhBYMACFQQEUMIgBKRD0oKhl1ChVR4AAQXkZ8ETwuGcg5UbQATnpEXEFAMhg1CWgUCQg+rgBNYDA1bEKGJBU4HFqwSh2QKowULmAVCBZAgTmSzD3WNB40GfxMKWAcGBJtDvZdCAhOTQ9sNCwPBQwJbCwgCBIhJEQgdGB4bAnpIBoCeISoLElQzAkEDwA0fAkrcUELIgIO/IIArcgADxIkgMQhZY2hBgwfyOD7g8A/kBxLQhBgYgMDkAwf6cgIbEiGEBZcNIzSISKnEwTs3FChw0AeAqRIGFzU2RZCmQoYMG5xZY4ANoZA3ThJcvYphIRRTYaoNgGALwIWxGShofeJgyhZZTU/JhHuVXRJaYTahLbCpA98P5Y4YXNQWQKZhsyjwjYlkcQG8QhRxmTdZyQHNfgHo0TskwYerGqCIS8wpzFyZVJxiGS3G2hVmbG1DWUNVNxQmRH0LLxIEACH5BAkKAAAALAAAAAAjACMAAAb/QIBwSCwaj8ikUTFwKJ9KAaRQMECvxAOVmsB6CdsCwms0PBQHIng7JjIEgrTSUJgiGEP6dkBU1MVPCWEFcgAIVBARQxFTWwRKfmFdQoJUeABag4VIC4NWAA5UbQADYRACUAyDDUKZD0JriHxXDA1bEI+GBU4AnVsKZAAKvguUBUIKjQ+XwQcPdYoH0VQDzE8HBgTWALWTQgYDuXkCZ9sCWwsIAgSbSARSExYS8xavQueDVAsJvEYN8RcCzhsoAYKQUvkQQQBmZELACwQHXpgAK+GCBg/EGYmwAKDAgCK8gUNw8YGDTe0QfAJgoEGIDhY6hNiWxEGDNngIbBhBKJibnlILAQgw4cTChw0YvHlh8EyfkAsZOoDaQHWDiJVQQoXJ9SEDCSETjm74QGLWEweNqLASliGDCTwHPFSlyjBJpjCXJrTNMAuC2LEa2hXBhwiVkBF7pWIiMXeD2SOEC6xlaWKvh0WNHxs5cKiAPSEF9rotpEADVQtQsG0LIZqCtVqayYTea0KwTyIGKOzVcPsJiLZEeys5cMEDB+HIkQQBACH5BAkKAAAALAAAAAAjACMAAAb/QIBwSCwaj8ikUTFwKJ9KAaRQMECvxAOVmsB6CdsCwms0PBQHIng7JjIEgrTSUJgiGEP6dkBU1MVPCWEFcgAIVBARQxFTWwRKfmFdQoJUeABag4VIC4NWAA5UbQADYRACUAyDDUKZD0JriHxXDA1bEI+GBU4AnVsKZAARvguUBUIKjQ+XwQcPdYoH0VQDn1AHBgTMQrWTQgYDuUPYBAabAAJbCwgCBOdHBwQKDb4FC+Lpg1QLCbxGDqX0bUFFSiAiCMCMlGokcFasMAsaCLBmhEGEAfXYiAOHIOIDB4UYJBwSZ5yDB/QaPHgHb8IHClbSGLBgwVswIQs2ZMiAARQJoyshLlyYMNLLABI7M1DA4zIEAAMSJFyQAGHbkw5Jd04QouGDBSEFpkq1oAiKiKwZPsDasIFEmgMWxE4VhyQB2gxtILDdQLCBWKkdnmhAq2GIhL1OhYj4K6GoEQxZTVxiMILtBwlDCMSN2lhJBAo7K4gbsLdtIQIdoiZW4gACKyI5947YdECBYzKk97q9qYSy5RK8nxRgS4JucCMHOlw4drz5kSAAIfkECQoAAAAsAAAAACMAIwAABv9AgHBILBqPyKRRMXAon0oBpFAwQK/EA5WawHoJ2wLCazQ8FAcieDsmMgSCtNJQmCIYQ/p2QFTUxU8JYQVyAAhUEBFDEVNbBEp+YV1CglR4AFqDhUgLg1YADlRtAANhEAJQDIMNQpkPQmuIfFcMDVsQj4YFTgCdWwpkABG+C5QFQgqND5fBBwJ1igfRVAOfUFIhCdaYA5NCBgO5QwcGBAabBxoZ6xQmGCGoTwcECg2+BQviGOv8/BQeJbYNcVBqUJh4HvopXIfhSMFGBmdxWLjOBAkOm9wwucdGHIQNJih8IDEhwaUDvPJkcfDAXoMHGQEwOJARQoUReNJoQSAuGCWdDBs+dABgQESaB1O0+VQgYYNTD2kWYGCViUocLyGcOv1wDECHCyGQQVwgEEmID1o3aBDCQMIFo0I4EnqiIK3TeAkuSJDAywFEQEpEpP0gYggIvRdYCTkUpiyREmiDapBzQARiDuM8KSFAwqkFa0z3Sig8pJZVKAYQxBvyQLQEC2UcYwm9l7TPJAcsIIZw+0nrt8x6I4HAwZvw40WCAAAh+QQJCgAAACwAAAAAIwAjAAAG/0CAcEgsGo/IpFExcCifSgGkUDBAr8QDlZrAegnbAsJrhGgsESJ4OyYyBILDs5CpUwZDQxg/VBSmbUkkdYROQghUEGlCEVNbBEoWhHUeQwlbDEJaYQVySQQUkxkQjFSBA2EQAlAIoh+aVA9Ca4l8UA0mkxOHBYYLYQpkBpJ2mZdCCo4PmWRCAoMZEgAHaZsDVlcRDQsKzEILHyNEBgOQWQYEBp6aIhvuHiQiCIYA2EYHBArbWwvmAB0f3Al8dyGENyIOUHEKswoAhoEDP0jcZUSho4V8CkAM6OFMJyQMmPzihMBfAwwkRpyB0C1PEXvTHDzY1uDBuiEHbgpJUMLCOpAtJZsViTDhAoYC0xDIeTAlAUwsDkBIuCDBJ4BkTjZRieOlwVQJU7sAGKAK2cUFT5EguEB1agdYYoaM3KLTCAGweC8YcoBJiIOLcZVAaDuV1M4t9BCFSUtkMNgLHdYpLiB2GifGQxiIABtinR42bhpshfKG3qwwC4wYwHzlsymhUEaWha1kjVLaT5j4w827SBAAIfkECQoAAAAsAAAAACMAIwAABv9AgHBILBqPyGTxgBlNlFBlJUMtRK9EAYWa8WC/IW7GdPgWGxYOgRjmUspDhkAATw42n81IMCyIN3UKBRAFCFASG4kfHmsABiZcFkMRhAWWjUggeYkbGEMeXA1CB5alBXVHBiOceA9CHVQUDEIDphB8UAmsGxq0VL0ABLYDWA8VnB9WjxlPAAumCmYHEx6JI2Wga5SWD7NmQhEWeBwACSIApAUDBlgEAg8OqA8aF0QGA5ijBgQGqAAhFiRIsCACwgN2QrwZOeBuwDNLCzBBuCBQ4IWLaRr4E+LAoamPuCZUHCnhIgYrRmoN+liKWLmSFTF2COEKCQMFHj8iwKRgggieCzPx1fGHcJSDBw0WNHiwEQmBpERI7fxWhEEtCNEOICjzgFCCol8YPCi1QIgCCA7QmaLzxcHHtAAG3DJbqcACsEkc1C0gSm2hIQ9LNY3K0ptbS4b3GlIiwBaucqXgAkDwEW+RxqX6CqFsKcGQdKUsR+VcU4gBU4sTNrD0OMkBAwqFCCNrxIBoLKdLpaaa5OFc3kpmbwUOBWc+4siJBAEAIfkECQoAAAAsAAAAACMAIwAABv9AgHBILBqPyGTx0LlAlFCl6LPZDKJYYsRT3Vyy4EV3QzqAi4LQgkEUd0fm4QKDUUAVksvF4hg2xhhEEhmEJgZKIBcSeRZsAAwkVR8cQyKElyBKC4qLF5RCF1QbD0IDl5ekSQcWnHl2ACFVJI4bpxkaURF5nR1CChsfIkIcthtxUBFNihcJj5EFjxSnGI5YBwuse2YXG4cXlyMNZ0MGIRIY4gohAAKEH0/WBgTVQg4dmUMQGxPHAAfyBvqxK0BwAQIBBI4JHPJPQYMFBAssIDBEQMSLEhP0OeJgAEaMAkp9jAgBwqsiHgtAGFngCgACIxc0eEARCQMFAyBiRFATgIGeAQhkPnDQT+Ahhg4ePJy5EImDh0QOFOA5rggDjyb9ITDzYGWCo2cYPIi4wBeEPlIjCmjqFOPGARBCAlCwsiBYJQ7qEhTnjyACORjZMvzoyEHEwnqnQrFIUi6ABBE3AkCA8a4RxnuJUCbYTEjaiJaXbE4lxMDFv0MYNCDoWJUBei8vli1iIDQY0xFRV9VEMO5uKDCnCv7ta0BP4siLBAEAIfkECQoAAAAsAAAAACMAIwAABv9AgHBILBqPyKQRwkkon8rQRSJRQK9Eg2V64WC/DypV9DUaHooDMSwWqYcJkcjxNBQgBQRjqBBfJkQTGxsfJHtJCQWKim8HIlwLQxwfg4ORSQqLik5CHFMSEUIKlZWhSguaBQZCDRcXbkIYpB8lUAypDUIErhBCCJSDHxhvTwwNixAEAI4XTgcjpBPEVwqoeUIgF2oTwBICZUMHD3ehBLkRgxgDWAcGBIdDxpysGAXEBwIQIQV0RAKLCxAIIDANST5ZFDIopBDizb9UihYk6GekwwaFGDNmwCBkAERkEKwUOXBRo0YPuj4uaPBA2ZEDBSSU1GgCxBADAxCsfOBgWsGXVULwdajwgcKHCqagOGhwKWgeoOEOFEzCwGPIZQjUPMCTAN4XBuMiioJAB+aib18cpOo3AAJaBXgiQlXiIK6iXMsUIRhibdHUkRAPqVUk2O41JQ8VuYWziCKCVHONJC6A19eieWYXRR75uMCDLJr2xjtWAK2Sdl4BENDU9ObmL3YWiQb3xNpi2k9W5/mLu4iCAS57C0cSBAA7AAAAAAAAAAAA) 50% 50% no-repeat;z-index:3;border-radius:5px;line-height:3}#get_image b{display:block;font-size:25px;margin:10px 0}#get_image label{display:block;margin-bottom:5px}#button{margin-top:20px;font-size:21px}#dropzone{border:2px dashed #999;width:200px;height:200px;background:#FAFAFA url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAAiCAYAAADCp/A1AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAApjAAAKYwGDMomsAAAAB3RJTUUH3AkYCxg3B2a5QgAAAKtJREFUWMPt17sNgDAMRdE8tsj+w2UM6CiQEv9jIvm1COl0uUZbbIxxt03rvWP27WoHrJCFLGQhC1nIQr7DzohQI3fXjqaOkJFl0nxDVj9K+hKZocsNYGQXOafQ8YfTgTohcMKNA+rnHdAVkIWMhlJANjIKygGKkN5QLlCM9IJKgCqkFSoFqpFaqAZoQkqhWqAZyYVagC5ICmoFuiFnUA+gK/IL9QKGLOJlegBB2VeWydvIHgAAAABJRU5ErkJggg==) 50% 50% no-repeat;overflow:hidden;text-align:center;line-height:200px;position:relative}.error#dropzone{border:2px dashed red}.clear_button{display:block;height:16px;width:16px;position:absolute;top:6px;right:6px;line-height:1!important;overflow:hidden;cursor:pointer;text-indent:-9999px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAD1QAAA9UBZ3cOpgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAG4SURBVDiNrZOxattQFIa/c5UMtsBbIbMRQZ7iyFC/QjEesqoPYPAUsnQoaAp472RI92jJEGjaNwjFpY68RWQIXQoudocKVEPj29shuo6Fm9JCv/Gi7+ic/54rxhjWaX5o7jo/nedAC6EFgGEMjLXSp5Onk5v178UWEESCUXAIDIAKv2cBvLxqX70y3ItijEEQ2R/tXwjSeUQsYTDvknbSNRijAIJRcChIp+E2iOoRXtXbkLyqR1SPaLgNBOkU3SJ7o71dxzgToBLVIw6eHJAtM/ppnzRPAfBdn6E/pLZV43x2zvHtMcBCi26qIrAKQDyNyZYZta0aQ3+I7/olOVtmxNPYNlVxcEIJ3gdvELr2dF3IdQ6A67gbXRVhXKjVVRWkeUo/7ZPrHNdxcR2XXOebMoDQUn+T+p9QxZKssCPYP9tObCYlDGMFDwW8qlcKrHfdo3fdKwVbumLFR6WVPuV+wwh3wpVsZ7aZ2CLhTmj1hUbHzvT19OvJ55MceDb7MUOJYvBpwM33h5Wf3825/HbJttrm7MsZ87s5wIuknbz9P6tsMCZpJ13gyI7zCAvgyMqw9hot//qcfwEDGehh48P3mQAAAABJRU5ErkJggg==);z-index:2}#dropzone img{max-width:100%;max-height:100%;vertical-align:middle}#url_wrapper{position:relative;display:block}#url{border:2px solid #999;border-radius:3px;background:#FFF;padding:2px 25px 2px 5px;width:100%;box-shadow:1px 1px 3px rgba(0,0,0,.2) inset;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.error#url{border:2px solid red}#summer_settings{position:absolute;top:100px;left:100px;background:rgba(0,0,0,.9);border-radius:5px;padding:10px;box-shadow:rgba(0,0,0,.2) 0 0 2px 1px;display:none;z-index:1000;color:#FFF}#edit_details{position:absolute;top:100px;left:100px;background:rgba(0,0,0,.9);border-radius:5px;padding:10px;box-shadow:rgba(0,0,0,.2) 0 0 2px 1px;display:none;z-index:1000;color:#FFF;font-size:0}#edit_details h5{margin-bottom:10px;font-size:14px;cursor:move}.changed#edit_details h5,p.changed label{color:#32c832}#edit_details p{margin-bottom:10px}#edit_details label{font-size:11px;display:block;margin-bottom:2px}#edit_details input[type=text]{background:#FFF;font-size:12px;font-family:sans-serif;padding:2px 5px;width:120px;border-radius:5px;box-shadow:rgba(0,0,0,.5) 0 1px 2px inset}.changed#edit_details button{box-shadow:rgba(50,200,50,1) 0 0 1px 2px}#help{display:none;width:400px;border-radius:3px;background:#FFF;position:absolute;top:35px;left:50%;margin-left:-200px;z-index:1003;box-shadow:rgba(0,0,0,.2) 0 0 2px 2px}#help .txt{padding:20px 20px 5px;line-height:1.4}.txt p{margin-bottom:3px}#help section{margin-bottom:20px}#help .close_button{background:#000 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACbgAAAm4Bt/774AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABKSURBVAiZdc2xDYAwAAPBA0ViiQxKR6hgCMZjCSpTEAkavnxL7yHJgRPNQ0MtXS6Y+jBjlUSSLS9bEqMfSm/O2D+pq6Bi/ZxfqDfkbiIp0Zzd1AAAAABJRU5ErkJggg==) 50% 50% no-repeat;box-shadow:0 0 1px #EEE inset;border-radius:2px}#help h2{margin-bottom:5px}#help footer{color:#999;font-size:10px;padding:0 20px 20px;line-height:1.3}#help footer a{color:#777;text-decoration:underline}.key{background:#F5F5F5;color:#555;text-shadow:0 0 1px #EEE;padding:1px 5px;border:1px solid #CCC;border-radius:3px;display:inline-block;min-width:16px;text-align:center;font-size:11px;box-shadow:1px 1px 0 rgba(255,255,255,1) inset,-1px -1px 0 rgba(0,0,0,.08) inset;overflow:hidden;cursor:default;vertical-align:middle}.key:active{padding:2px 5px 0;box-shadow:1px 1px 0 rgba(0,0,0,.08) inset,-1px -1px 0 rgba(255,255,255,1) inset}#overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:1002;background:#000;opacity:.5;display:none}#from_html_wrapper{display:none;width:500px;border-radius:5px;background:rgba(0,0,0,.9);position:absolute;top:35px;left:50%;margin-left:-250px;z-index:1002;color:#FFF}#from_html_wrapper .close_button{background:#000 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACbgAAAm4Bt/774AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABKSURBVAiZdc2xDYAwAAPBA0ViiQxKR6hgCMZjCSpTEAkavnxL7yHJgRPNQ0MtXS6Y+jBjlUSSLS9bEqMfSm/O2D+pq6Bi/ZxfqDfkbiIp0Zzd1AAAAABJRU5ErkJggg==) 50% 50% no-repeat;box-shadow:0 0 1px #EEE inset;border-radius:2px}#from_html_form{padding:20px}#from_html_form h5{margin-bottom:15px}#from_html_form label{display:block;font-size:12px}#from_html_form textarea{border:0;border-radius:3px;background:#FFF;padding:2px 5px;margin-bottom:5px;width:100%;height:100px;box-shadow:1px 1px 3px rgba(0,0,0,.2) inset;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-family:monospace;font-size:11px;line-height:1.3}#svg{position:absolute;top:0;left:0;z-index:2;display:inline-block}#svg rect{stroke-width:3px;stroke:red;fill:rgba(255,255,255,.3)}#svg rect.with_href{fill:rgba(0,0,0,.3)}.edit>#svg rect:hover{fill:rgba(50,200,50,.3)}#svg rect.active{fill:rgba(0,0,0,.5)}#svg circle{stroke-width:3px;stroke:#0F0;fill:rgba(255,255,255,.3)}#svg circle.with_href{fill:rgba(0,0,0,.3)}.edit>#svg circle:hover{fill:rgba(50,200,50,.3)}#svg polygon,#svg polyline{stroke-width:3px;stroke:#00F;fill:rgba(255,255,255,.3)}#svg polygon.with_href{fill:rgba(0,0,0,.3)}.edit>#svg polygon:hover{fill:rgba(50,200,50,.3)}#svg .selected{fill:rgba(50,200,50,.5)!important}#svg rect.helper{fill:#FFF;stroke:#000;stroke-width:2px}#svg rect.helper:hover{fill:red}.edit>#svg circle,.edit>#svg polygon,.edit>#svg rect{cursor:move}.edit>#svg .pointer{cursor:pointer}.edit>#svg .e-resize{cursor:e-resize}.edit>#svg .ne-resize{cursor:ne-resize}.edit>#svg .nw-resize{cursor:nw-resize}.edit>#svg .n-resize{cursor:n-resize}.edit>#svg .se-resize{cursor:se-resize}.edit>#svg .sw-resize{cursor:sw-resize}.edit>#svg .s-resize{cursor:s-resize}.edit>#svg .w-resize{cursor:w-resize} \ No newline at end of file diff --git a/scripts.js b/scripts.js index 6f7cf6e..a6f4f56 100644 --- a/scripts.js +++ b/scripts.js @@ -8,2248 +8,2348 @@ * Thu May 15 2013 15:15:27 GMT+0400 */ -"use strict"; - function SummerHtmlImageMapCreator() { - - /* Utilities */ - var utils = { - offsetX : function(node) { - var box = node.getBoundingClientRect(), - scroll = window.pageXOffset; - - return Math.round(box.left + scroll); - }, - offsetY : function(node) { - var box = node.getBoundingClientRect(), - scroll = window.pageYOffset; - - return Math.round(box.top + scroll); - }, - rightX : function(x) { - return x-app.getOffset('x'); - }, - rightY : function(y) { - return y-app.getOffset('y'); - }, - trim : function(str) { - return str.replace(/^\s+|\s+$/g, ''); - }, - id : function (str) { - return document.getElementById(str); - }, - hide : function(node) { - node.style.display = 'none'; - - return this; - }, - show : function(node) { - node.style.display = 'block'; - - return this; - }, - encode : function(str) { - return str.replace(//g, '>'); - }, - foreach : function(arr, func) { - for(var i = 0, count = arr.length; i < count; i++) { - func(arr[i], i); - } - }, - foreachReverse : function(arr, func) { - for(var i = arr.length - 1; i >= 0; i--) { - func(arr[i], i); - } - }, - debug : (function() { - var output = document.getElementById('debug'); - return function() { - output.innerHTML = [].join.call(arguments, ' '); - } - })(), - stopEvent : function(e) { - e.stopPropagation(); - e.preventDefault(); - - return this; - }, - addClass : function(node, str) { - // node.className.baseVal for SVG-elements - // or - // node.className for HTML-elements - var is_svg = node.className.baseVal !== undefined ? true : false, - arr = is_svg ? node.className.baseVal.split(' ') : node.className.split(' '), - isset = false; - - utils.foreach(arr, function(x) { - if(x === str) { - isset = true; - } - }); - - if (!isset) { - arr.push(str); - is_svg ? node.className.baseVal = arr.join(' ') : node.className = arr.join(' '); - } - - return this; - }, - removeClass : function(node, str) { - var is_svg = node.className.baseVal !== undefined ? true : false, - arr = is_svg ? node.className.baseVal.split(' ') : node.className.split(' '), - isset = false; - - utils.foreach(arr, function(x, i) { - if(x === str) { - isset = true; - arr.splice(i--, 1); - } - }); - - if (isset) { - is_svg ? node.className.baseVal = arr.join(' ') : node.className = arr.join(' '); - } - - return this; - }, - hasClass : function(node, str) { - var is_svg = node.className.baseVal !== undefined ? true : false, - arr = is_svg ? node.className.baseVal.split(' ') : node.className.split(' '), - isset = false; - - utils.foreach(arr, function(x) { - if(x === str) { - isset = true; - } - }); - - return isset; - }, - extend : function(obj, options) { - var target = {}; - - for (name in obj) { - if(obj.hasOwnProperty(name)) { - target[name] = options[name] ? options[name] : obj[name]; - } - } - - return target; - }, - supportFileReader : (function() { - return (typeof FileReader !== 'undefined'); - })() - }; - - - /* Main object */ - var app = (function() { - var body = document.getElementsByTagName('body')[0], - wrapper = utils.id('wrapper'), - svg = utils.id('svg'), - img = utils.id('img'), - img_src = null, - container = utils.id('image'), - about = utils.id('about'), - coords_info = utils.id('coords'), - offset = {x: 0, y: 0}, - shape = null, - is_draw = false, - mode = null, // drawing || editing || preview - objects = [], - new_area = null, - selected_area = null, - edit_type, - events = [], - map, - filename, - KEYS = { - F1 : 112, - ESC : 27, - TOP : 38, - BOTTOM : 40, - LEFT : 37, - RIGHT : 39, - DELETE : 46, - I : 73, - S : 83 - }; - - function recalcOffsetValues() { - offset.x = utils.offsetX(container); - offset.y = utils.offsetY(container); - }; - - /* Get offset value */ - window.addEventListener('resize', recalcOffsetValues, false); - - /* Disable selection */ - container.addEventListener('mousedown', function(e) { e.preventDefault(); }, false); - - /* Disable image dragging */ - img.addEventListener('dragstart', function(e){ - e.preventDefault(); - }, false); - - /* Display cursor coordinates info */ - container.addEventListener('mousemove', function(e){ - coords_info.innerHTML = 'x: ' + utils.rightX(e.pageX) + ', ' + 'y: ' + utils.rightY(e.pageY); - }, false); - - container.addEventListener('mouseleave', function(){ - coords_info.innerHTML = ''; - }, false); - - /* Add mousedown event for svg */ - function onSvgMousedown(e) { - if (mode === 'editing') { - if (e.target.parentNode.tagName === 'g') { - info.unload(); - selected_area = e.target.parentNode.obj; - - app.deselectAll(); - selected_area.select(); - selected_area.delta = { - 'x' : e.pageX, - 'y' : e.pageY - }; - - if (utils.hasClass(e.target, 'helper')) { - var helper = e.target; - edit_type = helper.action; - - if (helper.n >= 0) { // if typeof selected_area == polygon - selected_area.selected_point = helper.n; - } - - app.addEvent(container, 'mousemove', selected_area.onEdit) - .addEvent(container, 'mouseup', selected_area.onEditStop); - } else if (e.target.tagName === 'rect' || e.target.tagName === 'circle' || e.target.tagName === 'polygon') { - edit_type = 'move'; - - app.addEvent(container, 'mousemove', selected_area.onEdit) - .addEvent(container, 'mouseup', selected_area.onEditStop); - }; - } else { - app.deselectAll(); - info.unload(); - }; - }; - } - - container.addEventListener('mousedown', onSvgMousedown, false); - - /* Add click event for svg */ - function onSvgClick(e) { - if (mode === 'drawing' && !is_draw && shape) { - code.hide(); - switch (shape) { - case 'rect': - new_area = new Rect(utils.rightX(e.pageX), utils.rightY(e.pageY)); - - app.addEvent(container, 'mousemove', new_area.onDraw) - .addEvent(container, 'click', new_area.onDrawStop); - - break; - case 'circle': - new_area = new Circle(utils.rightX(e.pageX), utils.rightY(e.pageY)); - - app.addEvent(container, 'mousemove', new_area.onDraw) - .addEvent(container, 'click', new_area.onDrawStop); - - break; - case 'polygon': - new_area = new Polygon(utils.rightX(e.pageX), utils.rightY(e.pageY)); - - app.addEvent(container, 'mousemove', new_area.onDraw) - .addEvent(container, 'click', new_area.onDrawAddPoint) - .addEvent(document, 'keydown', new_area.onDrawStop) - .addEvent(new_area.helpers[0].helper, 'click', new_area.onDrawStop); - - break; - }; - }; - }; - - container.addEventListener('click', onSvgClick, false); - - /* Bug with keydown event for SVG in Opera browser - (when hot keys don't work after focusing on svg element) */ - - function operaSvgKeydownBugFix() { - window.focus(); - } - if (window.navigator.appName === 'Opera') { - container.addEventListener('mousedown', operaSvgKeydownBugFix, false); - container.addEventListener('mouseup', operaSvgKeydownBugFix, false); - container.addEventListener('click', operaSvgKeydownBugFix, false); - container.addEventListener('dblclick', operaSvgKeydownBugFix, false); - }; - - /* Add dblclick event for svg */ - function onAreaDblClick(e) { - if (mode === 'editing') { - if (e.target.tagName === 'rect' || e.target.tagName === 'circle' || e.target.tagName === 'polygon') { - selected_area = e.target.parentNode.obj; - info.load(selected_area, e.pageX, e.pageY); - }; - }; - }; - - container.addEventListener('dblclick', onAreaDblClick, false); - - - /* Add keydown event for document */ - function onDocumentKeyDown(e) { - switch (e.keyCode) { - case KEYS.F1: /* F1 key */ - help.show(); - e.preventDefault(); - - break; - - case KEYS.ESC: /* ESC key */ - help.hide(); - if (is_draw) { - is_draw = false; - new_area.remove(); - objects.pop(); - app.removeAllEvents(); - } else if (mode === 'editing') { - selected_area.redraw(); - app.removeAllEvents(); - }; - - break; - - case KEYS.TOP: /* Top arrow key */ - if (mode === 'editing' && selected_area) { - selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](0, -1))); - e.preventDefault(); - } - - break; - - case KEYS.BOTTOM: /* Bottom arrow key */ - if (mode === 'editing' && selected_area) { - selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](0, 1))); - e.preventDefault(); - } - break; - - case KEYS.LEFT: /* Left arrow key */ - if (mode === 'editing' && selected_area) { - selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](-1, 0))); - e.preventDefault(); - } - - break; - - case KEYS.RIGHT: /* Right arrow key */ - if (mode === 'editing' && selected_area) { - selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](1, 0))); - e.preventDefault(); - } - - break; - - case KEYS.DELETE: /* DELETE key */ - if (mode === 'editing' && selected_area) { - app.removeObject(selected_area); - selected_area = null; - info.unload(); - } - - break; - - case KEYS.I: /* i (edit info) key */ - if (mode === 'editing' && selected_area) { - var params = selected_area.params, - x = params.x || params.cx || params[0], - y = params.y || params.cy || params[1]; - - info.load(selected_area, x + app.getOffset('x'), y + app.getOffset('y')); - } - - break; - - case KEYS.S: /* s (save) key */ - app.saveInLocalStorage(); - - break; - - } - } - - document.addEventListener('keydown', onDocumentKeyDown, false); - - /* Returned object */ - return { - saveInLocalStorage : function() { - var obj = { - areas : [], - img : img_src - }; - - utils.foreach(objects, function(x) { - obj.areas.push(x.toJSON()); - }); - - window.localStorage.setItem('SummerHTMLImageMapCreator', JSON.stringify(obj)); - - alert('Saved'); - - return this; - }, - loadFromLocalStorage : function() { - var str = window.localStorage.getItem('SummerHTMLImageMapCreator'), - obj = JSON.parse(str), - areas = obj.areas; - - this.loadImage(obj.img); - - utils.foreach(areas, function(x) { - switch (x.type) { - case 'rect': - if (x.coords.length === 4) { - Rect.createFromSaved({ - coords : x.coords, - href : x.href, - alt : x.alt, - title : x.title - }); - } - break; - - case 'circle': - if (x.coords.length === 3) { - Circle.createFromSaved({ - coords : x.coords, - href : x.href, - alt : x.alt, - title : x.title - }); - } - break; - - case 'polygon': - if (x.coords.length >= 6 && x.coords.length % 2 === 0) { - Polygon.createFromSaved({ - coords : x.coords, - href : x.href, - alt : x.alt, - title : x.title - }); - } - break; - } - }); - - return this; - }, - hide : function() { - utils.hide(wrapper); - return this; - }, - show : function() { - utils.show(wrapper); - return this; - }, - recalcOffsetValues: function() { - recalcOffsetValues(); - return this; - }, - setDimensions : function(width, height) { - svg.setAttribute('width', width); - svg.setAttribute('height', height); - container.style.width = width + 'px'; - container.style.height = height + 'px'; - return this; - }, - loadImage : function(url) { - get_image.showLoadIndicator(); - img.src = url; - img_src = url; - - img.onload = function() { - get_image.hideLoadIndicator().hide(); - app.show() - .setDimensions(img.width, img.height) - .recalcOffsetValues(); - }; - return this; - }, - preview : (function() { - img.setAttribute('usemap', '#map'); - map = document.createElement('map'); - map.setAttribute('name', 'map'); - container.appendChild(map); - - return function() { - info.unload(); - app.setShape(null); - utils.hide(svg); - map.innerHTML = app.getHTMLCode(); - code.print(); - return this; - } - })(), - hidePreview : function() { - utils.show(svg); - map.innerHTML = ''; - return this; - }, - addNodeToSvg : function(node) { - svg.appendChild(node); - return this; - }, - removeNodeFromSvg : function(node) { - svg.removeChild(node); - return this; - }, - getOffset : function(arg) { - switch(arg) { - case 'x': - return offset.x; - break; - case 'y': - return offset.y; - break; - } - return undefined; - }, - clear : function(){ - //remove all areas - objects.length = 0; - while(svg.childNodes[0]) { - svg.removeChild(svg.childNodes[0]); - } - code.hide(); - info.unload(); - return this; - }, - removeObject : function(obj) { - utils.foreach(objects, function(x, i) { - if(x === obj) { - objects.splice(i, 1); - } - }); - obj.remove(); - return this; - }, - deselectAll : function() { - utils.foreach(objects, function(x) { - x.deselect(); - }); - return this; - }, - getIsDraw : function() { - return is_draw; - }, - setIsDraw : function(arg) { - is_draw = arg; - return this; - }, - setMode : function(arg) { - mode = arg; - return this; - }, - getMode : function() { - return mode; - }, - setShape : function(arg) { - shape = arg; - return this; - }, - getShape : function() { - return shape; - }, - addObject : function(object) { - objects.push(object); - return this; - }, - getNewArea : function() { - return new_area; - }, - resetNewArea : function() { - new_area = null; - return this; - }, - getSelectedArea : function() { - return selected_area; - }, - setSelectedArea : function(obj) { - selected_area = obj; - return this; - }, - getEditType : function() { - return edit_type; - }, - setFilename : function(str) { - filename = str; - return this; - }, - setEditClass : function() { - utils.removeClass(container, 'draw') - .addClass(container, 'edit'); - return this; - }, - setDrawClass : function() { - utils.removeClass(container, 'edit') - .addClass(container, 'draw'); - return this; - }, - setDefaultClass : function() { - utils.removeClass(container, 'edit') - .removeClass(container, 'draw'); - return this; - }, - addEvent : function(target, eventType, func) { - events.push(new AppEvent(target, eventType, func)); - return this; - }, - removeAllEvents : function() { - utils.foreach(events, function(x) { - x.remove(); - }); - events.length = 0; - return this; - }, - getHTMLCode : function(arg) { - var html_code = ''; - if (arg) { - if (!objects.length) { - return '0 objects'; - } - html_code += utils.encode('') + - '
' + utils.encode('') + '
'; - utils.foreachReverse(objects, function(x) { - html_code += '    ' + utils.encode(x.toString()) + '
'; - }); - html_code += utils.encode('
'); - } else { - utils.foreachReverse(objects, function(x) { - html_code += x.toString(); - }); - } - return html_code; - } - }; - })(); - - /* Help block */ - var help = (function() { - var block = utils.id('help'), - overlay = utils.id('overlay'), - close_button = block.querySelector('.close_button'); - - function hide() { - utils.hide(block); - utils.hide(overlay); - } - - function show() { - utils.show(block); - utils.show(overlay); - } - - overlay.addEventListener('click', hide, false); - - close_button.addEventListener('click', hide, false); - - return { - show : show, - hide : hide - }; - })(); - - /* For html code of created map */ - var code = (function(){ - var block = utils.id('code'), - content = utils.id('code_content'), - close_button = block.querySelector('.close_button'); - - close_button.addEventListener('click', function(e) { - utils.hide(block); - e.preventDefault(); - }, false); - - return { - print: function() { - content.innerHTML = app.getHTMLCode(true); - utils.show(block); - }, - hide: function() { - utils.hide(block); - } - }; - })(); - - + "use strict"; + /* Utilities */ + var utils = { + offsetX : function (node) { + var box = node.getBoundingClientRect(), + scroll = window.pageXOffset; + + return Math.round(box.left + scroll); + }, + offsetY : function (node) { + var box = node.getBoundingClientRect(), + scroll = window.pageYOffset; + + return Math.round(box.top + scroll); + }, + rightX : function (x) { + return x - app.getOffset('x'); + }, + rightY : function (y) { + return y - app.getOffset('y'); + }, + trim : function (str) { + return str.replace(/^\s+|\s+$/g, ''); + }, + id : function (str) { + return document.getElementById(str); + }, + hide : function (node) { + node.style.display = 'none'; + + return this; + }, + show : function (node) { + node.style.display = 'block'; + + return this; + }, + encode : function (str) { + return str.replace(//g, '>'); + }, + foreach : function (arr, func) { + for (var i = 0, count = arr.length; i < count; i++) { + func(arr[i], i); + } + }, + foreachReverse : function (arr, func) { + for (var i = arr.length - 1; i >= 0; i -- ) { + func(arr[i], i); + } + }, + debug : (function () { + var output = document.getElementById('debug'); + return function () { + output.innerHTML = [].join.call(arguments, ' '); + } + })(), + stopEvent : function (e) { + e.stopPropagation(); + e.preventDefault(); + + return this; + }, + addClass : function (node, str) { + // node.className.baseVal for SVG - elements + // or + // node.className for HTML - elements + var is_svg = node.className.baseVal !== undefined ? true : false, + arr = is_svg ? node.className.baseVal.split(' ') : node.className.split(' '), + isset = false; + + utils.foreach(arr, function (x) { + if(x === str) { + isset = true; + } + }); + + if (!isset) { + arr.push(str); + is_svg ? node.className.baseVal = arr.join(' ') : node.className = arr.join(' '); + } + + return this; + }, + removeClass : function (node, str) { + var is_svg = node.className.baseVal !== undefined ? true : false, + arr = is_svg ? node.className.baseVal.split(' ') : node.className.split(' '), + isset = false; + + utils.foreach(arr, function (x, i) { + if(x === str) { + isset = true; + arr.splice(i -- , 1); + } + }); + + if (isset) { + is_svg ? node.className.baseVal = arr.join(' ') : node.className = arr.join(' '); + } + + return this; + }, + hasClass : function (node, str) { + var is_svg = node.className.baseVal !== undefined ? true : false, + arr = is_svg ? node.className.baseVal.split(' ') : node.className.split(' '), + isset = false; + + utils.foreach(arr, function (x) { + if(x === str) { + isset = true; + } + }); + + return isset; + }, + extend : function (obj, options) { + var target = {} + + for (name in obj) { + if(obj.hasOwnProperty(name)) { + target[name] = options[name] ? options[name] : obj[name]; + } + } + + return target; + }, + supportFileReader : (function () { + return (typeof FileReader !== 'undefined'); + })() + } + + + /* Main object */ + var app = (function () { + var body = document.getElementsByTagName('body')[0], + wrapper = utils.id('wrapper'), + svg = utils.id('svg'), + img = utils.id('img'), + img_src = null, + container = utils.id('image'), + about = utils.id('about'), + coords_info = utils.id('coords'), + offset = {x: 0, y: 0}, + shape = null, + is_draw = false, + mode = null, // drawing || editing || preview + objects = [], + new_area = null, + selected_area = null, + edit_type, + events = [], + map, + filename, + KEYS = { + F1 : 112, + ESC : 27, + TOP : 38, + BOTTOM : 40, + LEFT : 37, + RIGHT : 39, + DELETE : 46, + I : 73, + S : 83 + } + + function recalcOffsetValues() { + offset.x = utils.offsetX(container); + offset.y = utils.offsetY(container); + } + + /* Get offset value */ + window.addEventListener('resize', recalcOffsetValues, false); + + /* Disable selection */ + container.addEventListener('mousedown', function (e) { e.preventDefault(); }, false); + + /* Disable image dragging */ + img.addEventListener('dragstart', function (e){ + e.preventDefault(); + }, false); + + /* Display cursor coordinates info */ + container.addEventListener('mousemove', function (e){ + coords_info.innerHTML = 'x: ' + utils.rightX(e.pageX) + ', ' + 'y: ' + utils.rightY(e.pageY); + }, false); + + container.addEventListener('mouseleave', function (){ + coords_info.innerHTML = ''; + }, false); + + /* Add mousedown event for svg */ + function onSvgMousedown(e) { + if (mode === 'editing') { + if (e.target.parentNode.tagName === 'g') { + info.unload(); + selected_area = e.target.parentNode.obj; + + app.deselectAll(); + selected_area.select(); + selected_area.delta = { + 'x' : e.pageX, + 'y' : e.pageY + } + + if (utils.hasClass(e.target, 'helper')) { + var helper = e.target; + edit_type = helper.action; + + if (helper.n >= 0) { // if typeof selected_area == polygon + selected_area.selected_point = helper.n; + } + + app.addEvent(container, 'mousemove', selected_area.onEdit) + .addEvent(container, 'mouseup', selected_area.onEditStop); + } else if (e.target.tagName === 'rect' || e.target.tagName === 'circle' || e.target.tagName === 'polygon') { + edit_type = 'move'; + + app.addEvent(container, 'mousemove', selected_area.onEdit) + .addEvent(container, 'mouseup', selected_area.onEditStop); + } + } else { + app.deselectAll(); + info.unload(); + } + } + } + + container.addEventListener('mousedown', onSvgMousedown, false); + + /* Add click event for svg */ + function onSvgClick(e) { + if (mode === 'drawing' && !is_draw && shape) { + code.hide(); + switch (shape) { + case 'rect': + new_area = new Rect(utils.rightX(e.pageX), utils.rightY(e.pageY)); + + app.addEvent(container, 'mousemove', new_area.onDraw) + .addEvent(container, 'click', new_area.onDrawStop); + + break; + case 'circle': + new_area = new Circle(utils.rightX(e.pageX), utils.rightY(e.pageY)); + + app.addEvent(container, 'mousemove', new_area.onDraw) + .addEvent(container, 'click', new_area.onDrawStop); + + break; + case 'polygon': + new_area = new Polygon(utils.rightX(e.pageX), utils.rightY(e.pageY)); + + app.addEvent(container, 'mousemove', new_area.onDraw) + .addEvent(container, 'click', new_area.onDrawAddPoint) + .addEvent(document, 'keydown', new_area.onDrawStop) + .addEvent(new_area.helpers[0].helper, 'click', new_area.onDrawStop); + + break; + } + } + } + + container.addEventListener('click', onSvgClick, false); + + /* Bug with keydown event for SVG in Opera browser + (when hot keys don't work after focusing on svg element) */ + + function operaSvgKeydownBugFix() { + window.focus(); + } + if (window.navigator.appName === 'Opera') { + container.addEventListener('mousedown', operaSvgKeydownBugFix, false); + container.addEventListener('mouseup', operaSvgKeydownBugFix, false); + container.addEventListener('click', operaSvgKeydownBugFix, false); + container.addEventListener('dblclick', operaSvgKeydownBugFix, false); + } + + /* Add dblclick event for svg */ + function onAreaDblClick(e) { + if (mode === 'editing') { + if (e.target.tagName === 'rect' || e.target.tagName === 'circle' || e.target.tagName === 'polygon') { + selected_area = e.target.parentNode.obj; + info.load(selected_area, e.pageX, e.pageY); + } + } + } + + container.addEventListener('dblclick', onAreaDblClick, false); + + + /* Add keydown event for document */ + function onDocumentKeyDown(e) { + switch (e.keyCode) { + case KEYS.F1: /* F1 key */ + help.show(); + e.preventDefault(); + + break; + + case KEYS.ESC: /* ESC key */ + help.hide(); + if (is_draw) { + is_draw = false; + new_area.remove(); + objects.pop(); + app.removeAllEvents(); + } else if (mode === 'editing') { + selected_area.redraw(); + app.removeAllEvents(); + } + + break; + + case KEYS.TOP: /* Top arrow key */ + if (mode === 'editing' && selected_area) { + selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](0, - 1))); + e.preventDefault(); + } + + break; + + case KEYS.BOTTOM: /* Bottom arrow key */ + if (mode === 'editing' && selected_area) { + selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](0, 1))); + e.preventDefault(); + } + break; + + case KEYS.LEFT: /* Left arrow key */ + if (mode === 'editing' && selected_area) { + selected_area.setParams(selected_area.dynamicEdit(selected_area['move']( - 1, 0))); + e.preventDefault(); + } + + break; + + case KEYS.RIGHT: /* Right arrow key */ + if (mode === 'editing' && selected_area) { + selected_area.setParams(selected_area.dynamicEdit(selected_area['move'](1, 0))); + e.preventDefault(); + } + + break; + + case KEYS.DELETE: /* DELETE key */ + if (mode === 'editing' && selected_area) { + app.removeObject(selected_area); + selected_area = null; + info.unload(); + } + + break; + + case KEYS.I: /* i (edit info) key */ + if (mode === 'editing' && selected_area) { + var params = selected_area.params, + x = params.x || params.cx || params[0], + y = params.y || params.cy || params[1]; + + info.load(selected_area, x + app.getOffset('x'), y + app.getOffset('y')); + } + + break; + + case KEYS.S: /* s (save) key */ + app.saveInLocalStorage(); + + break; + + } + } + + document.addEventListener('keydown', onDocumentKeyDown, false); + + /* Returned object */ + return { + saveInLocalStorage : function () { + var obj = { + areas : [], + img : img_src + } + + utils.foreach(objects, function (x) { + obj.areas.push(x.toJSON()); + }); + + window.localStorage.setItem('SummerHTMLImageMapCreator', JSON.stringify(obj)); + + alert('Saved'); + + return this; + }, + loadFromLocalStorage : function () { + var str = window.localStorage.getItem('SummerHTMLImageMapCreator'), + obj = JSON.parse(str), + areas = obj.areas; + + this.loadImage(obj.img); + + utils.foreach(areas, function (x) { + switch (x.type) { + case 'rect': + if (x.coords.length === 4) { + Rect.createFromSaved({ + coords : x.coords, + href : x.href, + alt : x.alt, + title : x.title + }); + } + break; + + case 'circle': + if (x.coords.length === 3) { + Circle.createFromSaved({ + coords : x.coords, + href : x.href, + alt : x.alt, + title : x.title + }); + } + break; + + case 'polygon': + if (x.coords.length >= 6 && x.coords.length % 2 === 0) { + Polygon.createFromSaved({ + coords : x.coords, + href : x.href, + alt : x.alt, + title : x.title + }); + } + break; + } + }); + + return this; + }, + hide : function () { + utils.hide(wrapper); + return this; + }, + show : function () { + utils.show(wrapper); + return this; + }, + recalcOffsetValues: function () { + recalcOffsetValues(); + return this; + }, + setDimensions : function (width, height) { + svg.setAttribute('width', width); + svg.setAttribute('height', height); + container.style.width = width + 'px'; + container.style.height = height + 'px'; + return this; + }, + loadImage : function (url) { + get_image.showLoadIndicator(); + img.src = url; + img_src = url; + + img.onload = function () { + get_image.hideLoadIndicator().hide(); + app.show() + .setDimensions(img.width, img.height) + .recalcOffsetValues(); + } + return this; + }, + preview : (function () { + img.setAttribute('usemap', '#map'); + map = document.createElement('map'); + map.setAttribute('name', 'map'); + container.appendChild(map); + + return function () { + info.unload(); + app.setShape(null); + utils.hide(svg); + map.innerHTML = app.getHTMLCode(); + code.print(); + return this; + } + })(), + hidePreview : function () { + utils.show(svg); + map.innerHTML = ''; + return this; + }, + addNodeToSvg : function (node) { + svg.appendChild(node); + return this; + }, + removeNodeFromSvg : function (node) { + svg.removeChild(node); + return this; + }, + getOffset : function (arg) { + switch(arg) { + case 'x': + return offset.x; + break; + case 'y': + return offset.y; + break; + } + return undefined; + }, + clear : function (){ + //remove all areas + objects.length = 0; + while(svg.childNodes[0]) { + svg.removeChild(svg.childNodes[0]); + } + code.hide(); + info.unload(); + return this; + }, + removeObject : function (obj) { + utils.foreach(objects, function (x, i) { + if(x === obj) { + objects.splice(i, 1); + } + }); + obj.remove(); + return this; + }, + deselectAll : function () { + utils.foreach(objects, function (x) { + x.deselect(); + }); + return this; + }, + getIsDraw : function () { + return is_draw; + }, + setIsDraw : function (arg) { + is_draw = arg; + return this; + }, + setMode : function (arg) { + mode = arg; + return this; + }, + getMode : function () { + return mode; + }, + setShape : function (arg) { + shape = arg; + return this; + }, + getShape : function () { + return shape; + }, + addObject : function (object) { + objects.push(object); + return this; + }, + getNewArea : function () { + return new_area; + }, + resetNewArea : function () { + new_area = null; + return this; + }, + getSelectedArea : function () { + return selected_area; + }, + setSelectedArea : function (obj) { + selected_area = obj; + return this; + }, + getEditType : function () { + return edit_type; + }, + setFilename : function (str) { + filename = str; + return this; + }, + setEditClass : function () { + utils.removeClass(container, 'draw') + .addClass(container, 'edit'); + return this; + }, + setDrawClass : function () { + utils.removeClass(container, 'edit') + .addClass(container, 'draw'); + return this; + }, + setDefaultClass : function () { + utils.removeClass(container, 'edit') + .removeClass(container, 'draw'); + return this; + }, + addEvent : function (target, eventType, func) { + events.push(new AppEvent(target, eventType, func)); + return this; + }, + removeAllEvents : function () { + utils.foreach(events, function (x) { + x.remove(); + }); + events.length = 0; + return this; + }, + getHTMLCode : function (arg) { + var html_code = ''; + if (arg) { + if (!objects.length) { + return '0 objects'; + } + html_code += utils.encode('') + + '
' + utils.encode('') + '
'; + utils.foreachReverse(objects, function (x) { + html_code += '    ' + utils.encode(x.toString()) + '
'; + }); + html_code += utils.encode('
'); + } else { + utils.foreachReverse(objects, function (x) { + html_code += x.toString(); + }); + } + return html_code; + } + } + })(); + + /* Help block */ + var help = (function () { + var block = utils.id('help'), + overlay = utils.id('overlay'), + close_button = block.querySelector('.close_button'); + + function hide() { + utils.hide(block); + utils.hide(overlay); + } + + function show() { + utils.show(block); + utils.show(overlay); + } + + overlay.addEventListener('click', hide, false); + + close_button.addEventListener('click', hide, false); + + return { + show : show, + hide : hide + } + })(); + + /* For html code of created map */ + var code = (function (){ + var block = utils.id('code'), + content = utils.id('code_content'), + close_button = block.querySelector('.close_button'); + + close_button.addEventListener('click', function (e) { + utils.hide(block); + e.preventDefault(); + }, false); + + return { + print: function () { + content.innerHTML = app.getHTMLCode(true); + utils.show(block); + }, + hide: function () { + utils.hide(block); + } + } + })(); + + /* Edit selected area info */ - var info = (function() { - var form = utils.id('edit_details'), - header = form.querySelector('h5'), - href_attr = utils.id('href_attr'), - alt_attr = utils.id('alt_attr'), - title_attr = utils.id('title_attr'), - save_button = utils.id('save_details'), - close_button = form.querySelector('.close_button'), - sections = form.querySelectorAll('p'), - obj, - x, - y, - temp_x, - temp_y; - - function changedReset() { - utils.removeClass(form, 'changed'); - utils.foreach(sections, function(x) { - utils.removeClass(x, 'changed'); - }); - } - - function save(e) { - obj.href = href_attr.value; - obj.alt = alt_attr.value; - obj.title = title_attr.value; - - obj.href ? obj.with_href() : obj.without_href(); - - changedReset(); - - e.preventDefault(); - }; - - function unload() { - obj = null; - changedReset(); - utils.hide(form); - } - - function setCoords(x, y) { - form.style.left = (x + 5) + 'px'; - form.style.top = (y + 5) + 'px'; - } - - function moveEditBlock(e) { - setCoords(x + e.pageX - temp_x, y + e.pageY - temp_y); - } - - function stopMoveEditBlock(e) { - x = x + e.pageX - temp_x; - y = y + e.pageY - temp_y; - setCoords(x, y); - - app.removeAllEvents(); - } - - function change() { - utils.addClass(form, 'changed'); - utils.addClass(this.parentNode, 'changed'); - } - - save_button.addEventListener('click', save, false); - - href_attr.addEventListener('keydown', function(e) { e.stopPropagation(); }, false); - alt_attr.addEventListener('keydown', function(e) { e.stopPropagation(); }, false); - title_attr.addEventListener('keydown', function(e) { e.stopPropagation(); }, false); - - href_attr.addEventListener('change', change, false); - alt_attr.addEventListener('change', change, false); - title_attr.addEventListener('change', change, false); - - close_button.addEventListener('click', unload, false); - - header.addEventListener('mousedown', function(e) { - temp_x = e.pageX, - temp_y = e.pageY; - - app.addEvent(document, 'mousemove', moveEditBlock); - app.addEvent(header, 'mouseup', stopMoveEditBlock); - - e.preventDefault(); - }, false); - - return { - load : function(object, new_x, new_y) { - obj = object; - href_attr.value = object.href ? object.href : ''; - alt_attr.value = object.alt ? object.alt : ''; - title_attr.value = object.title ? object.title : ''; - utils.show(form); - if (new_x && new_y) { - x = new_x; - y = new_y; - setCoords(x, y); - } - }, - unload : unload - }; - })(); - - - /* Load areas from html code */ - var from_html_form = (function() { - var form = utils.id('from_html_wrapper'), - code_input = utils.id('code_input'), - load_button = utils.id('load_code_button'), - close_button = form.querySelector('.close_button'), - regexp_area = //gmi, - regexp_href = / href="([\S\s]+?)"/, - regexp_alt = / alt="([\S\s]+?)"/, - regexp_title = / title="([\S\s]+?)"/; - - function test(str) { - var result_area, - result_href, - result_alt, - result_title, - type, - coords, - area, - href, - alt, - title, - success = false; - - if (str) { - result_area = regexp_area.exec(str); - - while (result_area) { - success = true; - - area = result_area[0]; - - type = result_area[1]; - coords = result_area[2].split(/ ?, ?/); - - result_href = regexp_href.exec(area); - if (result_href) { - href = result_href[1]; - } else { - href = ''; - } - - result_alt = regexp_alt.exec(area); - if (result_alt) { - alt = result_alt[1]; - } else { - alt = ''; - } - - result_title = regexp_title.exec(area); - if (result_title) { - title = result_title[1]; - } else { - title = ''; - } - - for (var i = 0, len = coords.length; i < len; i++) { - coords[i] = Number(coords[i]); - } - - switch (type) { - case 'rect': - if (coords.length === 4) { - Rect.createFromSaved({ - coords : coords, - href : href, - alt : alt, - title : title - }); - } - break; - - case 'circle': - if (coords.length === 3) { - Circle.createFromSaved({ - coords : coords, - href : href, - alt : alt, - title : title - }); - } - break; - - case 'poly': - if (coords.length >= 6 && coords.length % 2 === 0) { - Polygon.createFromSaved({ - coords : coords, - href : href, - alt : alt, - title : title - }); - } - break; - } - - result_area = regexp_area.exec(str); - } - - if (success) { - hide(); - } - } - } - - function load(e) { - test(code_input.value); - - e.preventDefault(); - }; - - function hide() { - utils.hide(form); - } - - load_button.addEventListener('click', load, false); - - close_button.addEventListener('click', hide, false); - - return { - show : function() { - code_input.value = ''; - utils.show(form); - }, - hide : hide - }; - })(); - - - /* Get image form */ - var get_image = (function() { - var block = utils.id('get_image_wrapper'), - loading_indicator = utils.id('loading'), - button = utils.id('button'), - filename = null, - last_changed = null; - - // Drag'n'drop - the first way to loading an image - var drag_n_drop = (function() { - var dropzone = utils.id('dropzone'), - dropzone_clear_button = dropzone.querySelector('.clear_button'), - sm_img = utils.id('sm_img'); - - if (!utils.supportFileReader) { // For IE9 - utils.hide(utils.id('file_reader_support')); - }; - - function testFile(type) { - switch (type) { - case 'image/jpeg': - case 'image/gif': - case 'image/png': - return true; - break; - } - return false; - } - - dropzone.addEventListener('dragover', function(e){ - utils.stopEvent(e); - }, false); - - dropzone.addEventListener('dragleave', function(e){ - utils.stopEvent(e); - }, false); - - dropzone.addEventListener('drop', function(e){ - utils.stopEvent(e); - - var reader = new FileReader(), - file = e.dataTransfer.files[0]; - - if (testFile(file.type)) { - utils.removeClass(dropzone, 'error'); - - reader.readAsDataURL(file); - - reader.onload = function(e) { - sm_img.src = e.target.result; - sm_img.style.display = 'inline-block'; - filename = file.name; - utils.show(dropzone_clear_button); - last_changed = drag_n_drop; - }; - } else { - clearDropzone(); - utils.addClass(dropzone, 'error'); - } - - }, false); - - function clearDropzone() { - sm_img.src = ''; - - utils.hide(sm_img) - .hide(dropzone_clear_button) - .removeClass(dropzone, 'error'); - - last_changed = url_input; - }; - - dropzone_clear_button.addEventListener('click', clearDropzone, false); - - return { - clear : clearDropzone, - init : function() { - dropzone.draggable = true; - this.clear(); - utils.hide(sm_img) - .hide(dropzone_clear_button); - }, - test : function() { - return sm_img.src ? true : false; - }, - getImage : function() { - return sm_img.src; - } - }; - })(); - - - /* Set a url - the second way to loading an image */ - var url_input = (function() { - var url = utils.id('url'), - url_clear_button = url.parentNode.querySelector('.clear_button'); - - function testUrl(str) { - var url_str = utils.trim(str), - temp_array = url_str.split('.'), - ext; - - if(temp_array.length > 1) { - ext = temp_array[temp_array.length-1].toLowerCase(); - switch (ext) { - case 'jpg': - case 'jpeg': - case 'gif': - case 'png': - return true; - break; - }; - }; - - return false; - } - - function onUrlChange() { - setTimeout(function(){ - if(url.value.length) { - utils.show(url_clear_button); - last_changed = url_input; - } else { - utils.hide(url_clear_button); - last_changed = drag_n_drop; - } - }, 0); - } - - url.addEventListener('keypress', onUrlChange, false); - url.addEventListener('change', onUrlChange, false); - url.addEventListener('paste', onUrlChange, false); - - function clearUrl() { - url.value = ''; - utils.hide(url_clear_button); - utils.removeClass(url, 'error'); - last_changed = url_input; - }; - - url_clear_button.addEventListener('click', clearUrl, false); - - return { - clear : clearUrl, - init : function() { - this.clear(); - utils.hide(url_clear_button); - }, - test : function() { - if(testUrl(url.value)) { - utils.removeClass(url, 'error'); - return true; - } else { - utils.addClass(url, 'error'); - }; - return false; - }, - getImage : function() { - var tmp_arr = url.value.split('/'); - filename = tmp_arr[tmp_arr.length - 1]; - - return utils.trim(url.value) - } - }; - })(); - - - /* Block init */ - function init() { - utils.hide(loading_indicator); - drag_n_drop.init(); - url_input.init(); - } - init(); - - /* Block clear */ - function clear() { - drag_n_drop.clear(); - url_input.clear(); - last_changed = null; - }; - - /* Selected image loading */ - function onButtonClick(e) { - if (last_changed === url_input && url_input.test()) { - app.loadImage(url_input.getImage()).setFilename(filename); - } else if (last_changed === drag_n_drop && drag_n_drop.test()) { - app.loadImage(drag_n_drop.getImage()).setFilename(filename); - } - - e.preventDefault(); - }; - - button.addEventListener('click', onButtonClick, false); - - /* Returned object */ - return { - show : function() { - clear(); - utils.show(block); - - return this; - }, - hide : function() { - utils.hide(block); - - return this; - }, - showLoadIndicator : function() { - utils.show(loading_indicator); - - return this; - }, - hideLoadIndicator : function() { - utils.hide(loading_indicator); - - return this; - } - }; - })(); - - - /* Buttons and actions */ - var buttons = (function() { - var all = utils.id('nav').getElementsByTagName('li'), - save = utils.id('save'), - load = utils.id('load'), - rectangle = utils.id('rect'), - circle = utils.id('circle'), - polygon = utils.id('polygon'), - edit = utils.id('edit'), - clear = utils.id('clear'), - from_html = utils.id('from_html'), - to_html = utils.id('to_html'), - preview = utils.id('preview'), - new_image = utils.id('new_image'), - show_help = utils.id('show_help'); - - function deselectAll() { - utils.foreach(all, function(x) { - utils.removeClass(x, 'selected'); - }); - } - - function selectOne(button) { - deselectAll(); - utils.addClass(button, 'selected'); - } - - function onSaveButtonClick(e) { - // Save in localStorage - app.saveInLocalStorage(); - - e.preventDefault(); - } - - function onLoadButtonClick(e) { - // Load from localStorage - app.clear() - .loadFromLocalStorage(); - - e.preventDefault(); - } - - function onShapeButtonClick(e) { - // shape = rect || circle || polygon - app.setMode('drawing') - .setDrawClass() - .setShape(this.id) - .deselectAll() - .hidePreview(); - info.unload(); - selectOne(this); - - e.preventDefault(); - } - - function onClearButtonClick(e) { - // Clear all - if (confirm('Clear all?')) { - app.setMode(null) - .setDefaultClass() - .setShape(null) - .clear() - .hidePreview(); - deselectAll(); - } - - e.preventDefault(); - } - - function onFromHtmlButtonClick(e) { - // Load areas from html - from_html_form.show(); - - e.preventDefault(); - } - - function onToHtmlButtonClick(e) { - // Generate html code only - info.unload(); - code.print(); - - e.preventDefault(); - } - - function onPreviewButtonClick(e) { - if (app.getMode() === 'preview') { - app.setMode(null) - .hidePreview(); - deselectAll(); - } else { - app.deselectAll() - .setMode('preview') - .setDefaultClass() - .preview(); - selectOne(this); - } - - e.preventDefault(); - } - - function onEditButtonClick(e) { - if (app.getMode() === 'editing') { - app.setMode(null) - .setDefaultClass() - .deselectAll(); - deselectAll(); - utils.show(svg); - } else { - app.setShape(null) - .setMode('editing') - .setEditClass(); - selectOne(this); - } - app.hidePreview(); - e.preventDefault(); - } - - function onNewImageButtonClick(e) { - // New image - clear all and back to loading image screen - if(confirm('Discard all changes?')) { - app.setMode(null) - .setDefaultClass() - .setShape(null) - .setIsDraw(false) - .clear() - .hide() - .hidePreview(); - deselectAll(); - get_image.show(); - } - - e.preventDefault(); - } - - function onShowHelpButtonClick(e) { - help.show(); - - e.preventDefault(); - } - - save.addEventListener('click', onSaveButtonClick, false); - load.addEventListener('click', onLoadButtonClick, false); - rectangle.addEventListener('click', onShapeButtonClick, false); - circle.addEventListener('click', onShapeButtonClick, false); - polygon.addEventListener('click', onShapeButtonClick, false); - clear.addEventListener('click', onClearButtonClick, false); - from_html.addEventListener('click', onFromHtmlButtonClick, false); - to_html.addEventListener('click', onToHtmlButtonClick, false); - preview.addEventListener('click', onPreviewButtonClick, false); - edit.addEventListener('click', onEditButtonClick, false); - new_image.addEventListener('click', onNewImageButtonClick, false); - show_help.addEventListener('click', onShowHelpButtonClick, false); - })(); - - - /* AppEvent constructor */ - function AppEvent(target, eventType, func) { - this.target = target; - this.eventType = eventType; - this.func = func; - - target.addEventListener(eventType, func, false); - }; - - AppEvent.prototype.remove = function() { - this.target.removeEventListener(this.eventType, this.func, false); - }; - - - /* Helper constructor */ - function Helper(node, x, y) { - this.helper = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); - this.helper.setAttribute('class', 'helper'); - this.helper.setAttribute('height', 5); - this.helper.setAttribute('width', 5); - this.helper.setAttribute('x', x-3); - this.helper.setAttribute('y', y-3); - node.appendChild(this.helper); - }; - - Helper.prototype.setCoords = function(x, y) { - this.helper.setAttribute('x', x-3); - this.helper.setAttribute('y', y-3); - - return this; - }; - - Helper.prototype.setAction = function(action) { - this.helper.action = action; - - return this; - }; - - Helper.prototype.setCursor = function(cursor) { - utils.addClass(this.helper, cursor); - - return this; - }; - - Helper.prototype.setId = function(id) { - this.helper.n = id; - - return this; - }; - - /* Rectangle constructor */ - var Rect = function (x, y){ - app.setIsDraw(true); - - this.params = { - x : x, //distance from the left edge of the image to the left side of the rectangle - y : y, //distance from the top edge of the image to the top side of the rectangle - width : 0, //width of rectangle - height : 0 //height of rectangle - }; - - this.href = ''; //href attribute - not required - this.alt = ''; //alt attribute - not required - this.title = ''; //title attribute - not required - - this.g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); //container - this.rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); //rectangle - app.addNodeToSvg(this.g); - this.g.appendChild(this.rect); - - this.g.obj = this; /* Link to parent object */ - - this.helpers = { //object with all helpers-rectangles - center : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - top : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - bottom : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - left : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - right : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - top_left : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - top_right : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - bottom_left : new Helper(this.g, x-this.params.width/2, y-this.params.height/2), - bottom_right : new Helper(this.g, x-this.params.width/2, y-this.params.height/2) - }; - - this.helpers.center.setAction('move').setCursor('move'); - this.helpers.left.setAction('editLeft').setCursor('e-resize'); - this.helpers.right.setAction('editRight').setCursor('w-resize'); - this.helpers.top.setAction('editTop').setCursor('n-resize'); - this.helpers.bottom.setAction('editBottom').setCursor('s-resize'); - this.helpers.top_left.setAction('editTopLeft').setCursor('nw-resize'); - this.helpers.top_right.setAction('editTopRight').setCursor('ne-resize'); - this.helpers.bottom_left.setAction('editBottomLeft').setCursor('sw-resize'); - this.helpers.bottom_right.setAction('editBottomRight').setCursor('se-resize'); - - this.select().redraw(); - - /* Add this object to array of all objects */ - app.addObject(this); - }; - - Rect.prototype.setCoords = function(params){ - this.rect.setAttribute('x', params.x); - this.rect.setAttribute('y', params.y); - this.rect.setAttribute('width', params.width); - this.rect.setAttribute('height', params.height); - - this.helpers.center.setCoords(params.x + params.width/2, params.y + params.height/2); - this.helpers.top.setCoords(params.x + params.width/2, params.y); - this.helpers.bottom.setCoords(params.x + params.width/2, params.y + params.height); - this.helpers.left.setCoords(params.x, params.y + params.height/2); - this.helpers.right.setCoords(params.x + params.width, params.y + params.height/2); - this.helpers.top_left.setCoords(params.x, params.y); - this.helpers.top_right.setCoords(params.x + params.width, params.y); - this.helpers.bottom_left.setCoords(params.x, params.y + params.height); - this.helpers.bottom_right.setCoords(params.x + params.width, params.y + params.height); - - return this; - }; - - Rect.prototype.setParams = function(params){ - this.params.x = params.x; - this.params.y = params.y; - this.params.width = params.width; - this.params.height = params.height; - - return this; - }; - - Rect.prototype.redraw = function() { - this.setCoords(this.params); - - return this; - }; - - Rect.prototype.dynamicDraw = function(x1,y1,square){ - var x0 = this.params.x, - y0 = this.params.y, - new_x, - new_y, - new_width, - new_height, - delta, - temp_params; - - new_width = Math.abs(x1-x0); - new_height = Math.abs(y1-y0); - - if (square) { - delta = new_width-new_height; - if (delta > 0) { - new_width = new_height; - } else { - new_height = new_width; - } - } - - if (x0>x1) { - new_x = x1; - if (square && delta > 0) { - new_x = x1 + Math.abs(delta); - } - } else { - new_x = x0; - } - - if (y0>y1) { - new_y = y1; - if (square && delta < 0) { - new_y = y1 + Math.abs(delta); - } - } else { - new_y = y0; - } - - temp_params = { /* params */ - x : new_x, - y : new_y, - width : new_width, - height: new_height - }; - - this.setCoords(temp_params); - - return temp_params; - }; - - Rect.prototype.onDraw = function(e) { - var _n_f = app.getNewArea(), - square = e.shiftKey ? true : false; - - _n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY), square); - }; - - Rect.prototype.onDrawStop = function(e) { - var _n_f = app.getNewArea(), - square = e.shiftKey ? true : false; - - _n_f.setParams(_n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY), square)).deselect(); - - app.removeAllEvents() - .setIsDraw(false) - .resetNewArea(); - }; - - Rect.prototype.move = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.x += dx; - temp_params.y += dy; - - return temp_params; - }; - - Rect.prototype.editLeft = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.x += dx; - temp_params.width -= dx; - - return temp_params; - }; - - Rect.prototype.editRight = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.width += dx; - - return temp_params; - }; - - Rect.prototype.editTop = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.y += dy; - temp_params.height -= dy; - - return temp_params; - }; - - Rect.prototype.editBottom = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.height += dy; - - return temp_params; - }; - - Rect.prototype.editTopLeft = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.x += dx; - temp_params.y += dy; - temp_params.width -= dx; - temp_params.height -= dy; - - return temp_params; - }; - - Rect.prototype.editTopRight = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.y += dy; - temp_params.width += dx; - temp_params.height -= dy; - - return temp_params; - }; - - Rect.prototype.editBottomLeft = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.x += dx; - temp_params.width -= dx; - temp_params.height += dy; - - return temp_params; - }; - - Rect.prototype.editBottomRight = function(dx, dy) { //offset x and y - var temp_params = Object.create(this.params); - - temp_params.width += dx; - temp_params.height += dy; - - return temp_params; - }; - - Rect.prototype.dynamicEdit = function(temp_params, save_proportions) { - if (temp_params.width < 0) { - temp_params.width = Math.abs(temp_params.width); - temp_params.x -= temp_params.width; - } - - if (temp_params.height < 0) { - temp_params.height = Math.abs(temp_params.height); - temp_params.y -= temp_params.height; - } - - if (save_proportions) { - var proportions = this.params.width / this.params.height, - new_proportions = temp_params.width / temp_params.height, - delta = new_proportions - proportions, - x0 = this.params.x, - y0 = this.params.y, - x1 = temp_params.x, - y1 = temp_params.y; - - if (delta > 0) { - temp_params.width = Math.round(temp_params.height * proportions); - } else { - temp_params.height = Math.round(temp_params.width / proportions); - } - - } - - this.setCoords(temp_params); - - return temp_params; - - }; - - Rect.prototype.onEdit = function(e) { - var _s_f = app.getSelectedArea(), - edit_type = app.getEditType(), - save_proportions = e.shiftKey ? true : false; - - _s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y), save_proportions); - }; - - Rect.prototype.onEditStop = function(e) { - var _s_f = app.getSelectedArea(), - edit_type = app.getEditType(), - save_proportions = e.shiftKey ? true : false; - - _s_f.setParams(_s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y), save_proportions)); - app.removeAllEvents(); - }; - - Rect.prototype.remove = function() { - app.removeNodeFromSvg(this.g); - }; - - Rect.prototype.select = function() { - utils.addClass(this.rect, 'selected'); - - return this; - }; - - Rect.prototype.deselect = function() { - utils.removeClass(this.rect, 'selected'); - - return this; - }; - - Rect.prototype.with_href = function() { - utils.addClass(this.rect, 'with_href'); - - return this; - } - - Rect.prototype.without_href = function() { - utils.removeClass(this.rect, 'with_href'); - - return this; - } - - Rect.prototype.toString = function() { //to html map area code - var x2 = this.params.x + this.params.width, - y2 = this.params.y + this.params.height; - return '' + this.alt + ''; - }; - - Rect.createFromSaved = function(params) { - var coords = params.coords, - href = params.href, - alt = params.alt, - title = params.title, - area = new Rect(coords[0], coords[1]); - - area.setParams(area.dynamicDraw(coords[2], coords[3])).deselect(); - - app.setIsDraw(false) - .resetNewArea(); - - if (href) { - area.href = href; - } - - if (alt) { - area.alt = alt; - } - - if (title) { - area.title = title; - } - }; - - Rect.prototype.toJSON = function() { - return { - type : 'rect', - coords : [ - this.params.x, - this.params.y, - this.params.x + this.params.width, - this.params.y + this.params.height - ], - href : this.href, - alt : this.alt, - title : this.title - } - }; - - - /* Circle constructor */ - var Circle = function (x, y){ - app.setIsDraw(true); - - this.params = { - cx : x, //distance from the left edge of the image to the center of the circle - cy : y, //distance from the top edge of the image to the center of the circle - radius : 0 //radius of the circle - }; - - this.href = ''; //href attribute - not required - this.alt = ''; //alt attribute - not required - this.title = ''; //title attribute - not required - - this.g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); - this.circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); - app.addNodeToSvg(this.g); - this.g.appendChild(this.circle); - - this.g.obj = this; /* Link to parent object */ - - this.helpers = { //array of all helpers-rectangles - center : new Helper(this.g, x, y), - top : new Helper(this.g, x, y), - bottom : new Helper(this.g, x, y), - left : new Helper(this.g, x, y), - right : new Helper(this.g, x, y) - }; - - this.helpers.center.setAction('move'); - this.helpers.top.setAction('editTop').setCursor('n-resize'); - this.helpers.bottom.setAction('editBottom').setCursor('s-resize'); - this.helpers.left.setAction('editLeft').setCursor('w-resize'); - this.helpers.right.setAction('editRight').setCursor('e-resize'); - - this.select().redraw(); - - app.addObject(this); //add this object to array of all objects - }; - - Circle.prototype.setCoords = function(params){ - this.circle.setAttribute('cx', params.cx); - this.circle.setAttribute('cy', params.cy); - this.circle.setAttribute('r', params.radius); - - this.helpers.center.setCoords(params.cx, params.cy); - this.helpers.top.setCoords(params.cx, params.cy - params.radius); - this.helpers.right.setCoords(params.cx + params.radius, params.cy); - this.helpers.bottom.setCoords(params.cx, params.cy + params.radius); - this.helpers.left.setCoords(params.cx - params.radius, params.cy); - - return this; - }; - - Circle.prototype.setParams = function(params){ - this.params.cx = params.cx; - this.params.cy = params.cy; - this.params.radius = params.radius; - - return this; - }; - - Circle.prototype.redraw = function() { - this.setCoords(this.params); - - return this; - }; - - Circle.prototype.dynamicDraw = function(x1,y1){ - var x0 = this.params.cx, - y0 = this.params.cy, - dx, - dy, - radius, - temp_params; - - x1 = x1 ? x1 : x0; - y1 = y1 ? y1 : y0; - - dx = Math.abs(x0-x1); - dy = Math.abs(y0-y1); - radius = Math.round(Math.sqrt(dx*dx + dy*dy)); - - temp_params = { /* params */ - cx : x0, - cy : y0, - radius : radius - }; - - this.setCoords(temp_params); - - return temp_params; - }; - - Circle.prototype.onDraw = function(e) { - var _n_f = app.getNewArea(); - _n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY)); - }; - - Circle.prototype.onDrawStop = function(e) { - var _n_f = app.getNewArea(); - _n_f.setParams(_n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY))).deselect(); - - app.removeAllEvents() - .setIsDraw(false) - .resetNewArea(); - }; - - Circle.prototype.move = function(dx, dy){ //offset x and y - var temp_params = Object.create(this.params); - - temp_params.cx += dx; - temp_params.cy += dy; - - return temp_params; - }; - - Circle.prototype.editTop = function(dx, dy){ //offset x and y - var temp_params = Object.create(this.params); - - temp_params.radius -= dy; - - return temp_params; - }; - - Circle.prototype.editBottom = function(dx, dy){ //offset x and y - var temp_params = Object.create(this.params); - - temp_params.radius += dy; - - return temp_params; - }; - - Circle.prototype.editLeft = function(dx, dy){ //offset x and y - var temp_params = Object.create(this.params); - - temp_params.radius -= dx; - - return temp_params; - }; - - Circle.prototype.editRight = function(dx, dy){ //offset x and y - var temp_params = Object.create(this.params); - - temp_params.radius += dx; - - return temp_params; - }; - - Circle.prototype.dynamicEdit = function(temp_params) { - if (temp_params.radius < 0) { - temp_params.radius = Math.abs(temp_params.radius); - } - - this.setCoords(temp_params); - - return temp_params; - }; - - Circle.prototype.onEdit = function(e) { - var _s_f = app.getSelectedArea(), - edit_type = app.getEditType(); - - _s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y)); - }; - - Circle.prototype.onEditStop = function(e) { - var _s_f = app.getSelectedArea(), - edit_type = app.getEditType(); - - _s_f.setParams(_s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y))); - - app.removeAllEvents(); - }; - - Circle.prototype.remove = function(){ - app.removeNodeFromSvg(this.g); - }; - - Circle.prototype.select = function() { - utils.addClass(this.circle, 'selected'); - - return this; - }; - - Circle.prototype.deselect = function() { - utils.removeClass(this.circle, 'selected'); - - return this; - }; - - Circle.prototype.with_href = function() { - utils.addClass(this.circle, 'with_href'); - - return this; - } - - Circle.prototype.without_href = function() { - utils.removeClass(this.circle, 'with_href'); - - return this; - } - - Circle.prototype.toString = function() { //to html map area code - return '' + this.alt + ''; - }; - - Circle.createFromSaved = function(params) { - var coords = params.coords, - href = params.href, - alt = params.alt, - title = params.title, - area = new Circle(coords[0], coords[1]); - - area.setParams(area.dynamicDraw(coords[0], coords[1] + coords[2])).deselect(); - - app.setIsDraw(false) - .resetNewArea(); - - if (href) { - area.href = href; - } - - if (alt) { - area.alt = alt; - } - - if (title) { - area.title = title; - } - }; - - Circle.prototype.toJSON = function() { - return { - type : 'circle', - coords : [ - this.params.cx, - this.params.cy, - this.params.radius - ], - href : this.href, - alt : this.alt, - title : this.title - } - }; - - - /* Polygon constructor */ - var Polygon = function(x, y){ - app.setIsDraw(true); - - this.params = [x, y]; //array of coordinates of polygon points - - this.href = ''; //href attribute - not required - this.alt = ''; //alt attribute - not required - this.title = ''; //title attribute - not required - - this.g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); - this.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); - app.addNodeToSvg(this.g); - this.g.appendChild(this.polygon); - - this.g.obj = this; /* Link to parent object */ - - this.helpers = [ //array of all helpers-rectangles - new Helper(this.g, this.params[0], this.params[1]) - ]; - - this.helpers[0].setAction('pointMove').setCursor('pointer').setId(0); - - this.selected_point = -1; - - this.select().redraw(); - - app.addObject(this); //add this object to array of all objects - }; - - Polygon.prototype.setCoords = function(params){ - var coords_values = params.join(' '); - this.polygon.setAttribute('points', coords_values); - utils.foreach(this.helpers, function(x, i) { - x.setCoords(params[2*i], params[2*i+1]); - }); - - return this; - }; - - Polygon.prototype.setParams = function(arr) { - this.params = arr; - - return this; - }; - - Polygon.prototype.addPoint = function(x, y){ - var helper = new Helper(this.g, x, y); - helper.setAction('pointMove').setCursor('pointer').setId(this.helpers.length); - this.helpers.push(helper); - this.params.push(x, y); - this.redraw(); - - return this; - }; - - Polygon.prototype.redraw = function() { - this.setCoords(this.params); - - return this; - }; - - Polygon.prototype.right_angle = function(x, y){ - var old_x = this.params[this.params.length-2], - old_y = this.params[this.params.length-1], - dx = x - old_x, - dy = - (y - old_y), - tan = dy/dx; //tangens - - if (dx > 0 && dy > 0) { - if (tan > 2.414) { - x = old_x; - } else if (tan < 0.414) { - y = old_y; - } else { - Math.abs(dx) > Math.abs(dy) ? x = old_x + dy : y = old_y - dx; - } - } else if (dx < 0 && dy > 0) { - if (tan < -2.414) { - x = old_x; - } else if (tan > -0.414) { - y = old_y; - } else { - Math.abs(dx) > Math.abs(dy) ? x = old_x - dy : y = old_y + dx; - } - } else if (dx < 0 && dy < 0) { - if (tan > 2.414) { - x = old_x; - } else if (tan < 0.414) { - y = old_y; - } else { - Math.abs(dx) > Math.abs(dy) ? x = old_x + dy : y = old_y - dx; - } - } else if (dx > 0 && dy < 0) { - if (tan < -2.414) { - x = old_x; - } else if (tan > -0.414) { - y = old_y; - } else { - Math.abs(dx) > Math.abs(dy) ? x = old_x - dy : y = old_y + dx; - } - } - - return { - x : x, - y : y - }; - }; - - Polygon.prototype.dynamicDraw = function(x, y, right_angle){ - var temp_params = [].concat(this.params); - - if (right_angle) { - var right_coords = this.right_angle(x, y); - x = right_coords.x; - y = right_coords.y; - } - - temp_params.push(x, y); - - this.setCoords(temp_params); - - return temp_params; - }; - - Polygon.prototype.onDraw = function(e) { - var _n_f = app.getNewArea(); - var right_angle = e.shiftKey ? true : false; - - _n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY), right_angle); - }; - - Polygon.prototype.onDrawAddPoint = function(e) { - var x = utils.rightX(e.pageX), - y = utils.rightY(e.pageY), - - _n_f = app.getNewArea(); - - if (e.shiftKey) { - var right_coords = _n_f.right_angle(x, y); - x = right_coords.x; - y = right_coords.y; - } - _n_f.addPoint(x, y); - }; - - Polygon.prototype.onDrawStop = function(e) { - var _n_f = app.getNewArea(); - if (e.type == 'click' || (e.type == 'keydown' && e.keyCode == 13)) { // key Enter - if (_n_f.params.length >= 6) { //>= 3 points for polygon - _n_f.polyline = _n_f.polygon; - _n_f.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); - _n_f.g.replaceChild(_n_f.polygon, _n_f.polyline); - _n_f.setCoords(_n_f.params).deselect(); - delete(_n_f.polyline); - - app.removeAllEvents() - .setIsDraw(false) - .resetNewArea(); - } - }; - e.stopPropagation(); - }; - - Polygon.prototype.move = function(x, y){ //offset x and y - for (var i = 0, count = this.params.length; i < count; i++) { - i % 2 ? this.params[i] += y : this.params[i] += x; - } - this.redraw(); - }; - - Polygon.prototype.pointMove = function(x, y){ //offset x and y - this.params[2 * this.selected_point] += x; - this.params[2 * this.selected_point + 1] += y; - this.redraw(); - }; - - Polygon.prototype.onEdit = function(e) { - var _s_f = app.getSelectedArea(), - edit_type = app.getEditType(); - _s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y); - _s_f.delta.x = e.pageX; - _s_f.delta.y = e.pageY; - }; - - Polygon.prototype.onEditStop = function(e) { - var _s_f = app.getSelectedArea(), - edit_type = app.getEditType(); - _s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y); - app.removeAllEvents(); - }; - - Polygon.prototype.remove = function(){ - app.removeNodeFromSvg(this.g); - }; - - Polygon.prototype.select = function() { - utils.addClass(this.polygon, 'selected'); - - return this; - }; - - Polygon.prototype.deselect = function() { - utils.removeClass(this.polygon, 'selected'); - - return this; - }; - - Polygon.prototype.with_href = function() { - utils.addClass(this.polygon, 'with_href'); - - return this; - } - - Polygon.prototype.without_href = function() { - utils.removeClass(this.polygon, 'with_href'); - - return this; - } - - Polygon.prototype.toString = function() { //to html map area code - for (var i = 0, count = this.params.length, str = ''; i < count; i++) { - str += this.params[i]; - if (i != count - 1) { - str += ', '; - } - } - return '' + this.alt + ''; - }; - - Polygon.createFromSaved = function(params) { - var coords = params.coords, - href = params.href, - alt = params.alt, - title = params.title, - area = new Polygon(coords[0], coords[1]); - - for (var i = 2, c = coords.length; i < c; i+=2) { - area.addPoint(coords[i], coords[i+1]); - } - - area.polyline = area.polygon; - area.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); - area.g.replaceChild(area.polygon, area.polyline); - area.setCoords(area.params).deselect(); - delete(area.polyline); - - app.setIsDraw(false) - .resetNewArea(); - - if (href) { - area.href = href; - } - - if (alt) { - area.alt = alt; - } - - if (title) { - area.title = title; - } - }; - - Polygon.prototype.toJSON = function() { - return { - type : 'polygon', - coords : this.params, - href : this.href, - alt : this.alt, - title : this.title - } - }; - -}; + var info = (function () { + var form = utils.id('edit_details'), + header = form.querySelector('h5'), + href_attr = utils.id('href_attr'), + alt_attr = utils.id('alt_attr'), + title_attr = utils.id('title_attr'), + save_button = utils.id('save_details'), + clear_button = utils.id('details_clear'), + close_button = form.querySelector('.close_button'), + sections = form.querySelectorAll('p'), + obj, + x, + y, + temp_x, + temp_y; + + function changedReset() { + utils.removeClass(form, 'changed'); + utils.foreach(sections, function (x) { + utils.removeClass(x, 'changed'); + }); + } + + function save(e) { + obj.href = href_attr.value; + obj.alt = alt_attr.value; + obj.title = title_attr.value; + + obj.href ? obj.with_href() : obj.without_href(); + + if (summer_settings.settings_auto_close_edit) { + unload(); + } + + e.preventDefault(); + } + + function clear(e) { + href_attr.value = ''; + alt_attr.value = ''; + title_attr.value = ''; + changedReset(); + e.preventDefault(); + } + + function unload() { + obj = null; + changedReset(); + utils.hide(form); + } + + function setCoords(x, y) { + form.style.left = (x + 5) + 'px'; + form.style.top = (y + 5) + 'px'; + } + + function moveEditBlock(e) { + setCoords(x + e.pageX - temp_x, y + e.pageY - temp_y); + } + + function stopMoveEditBlock(e) { + x = x + e.pageX - temp_x; + y = y + e.pageY - temp_y; + setCoords(x, y); + + app.removeAllEvents(); + } + + function change() { + utils.addClass(form, 'changed'); + utils.addClass(this.parentNode, 'changed'); + } + + save_button.addEventListener('click', save, false); + clear_button.addEventListener('click', clear, false); + + href_attr.addEventListener('keydown', function (e) { e.stopPropagation(); }, false); + alt_attr.addEventListener('keydown', function (e) { e.stopPropagation(); }, false); + title_attr.addEventListener('keydown', function (e) { e.stopPropagation(); }, false); + + href_attr.addEventListener('change', change, false); + alt_attr.addEventListener('change', change, false); + title_attr.addEventListener('change', change, false); + + close_button.addEventListener('click', unload, false); + + header.addEventListener('mousedown', function (e) { + temp_x = e.pageX, + temp_y = e.pageY; + + app.addEvent(document, 'mousemove', moveEditBlock); + app.addEvent(header, 'mouseup', stopMoveEditBlock); + + e.preventDefault(); + }, false); + + return { + load : function (object, new_x, new_y) { + obj = object; + href_attr.value = object.href ? object.href : ''; + alt_attr.value = object.alt ? object.alt : ''; + title_attr.value = object.title ? object.title : ''; + utils.show(form); + if (new_x && new_y) { + x = new_x; + y = new_y; + setCoords(x, y); + } + }, + unload : unload + } + })(); + + + /* Load areas from html code */ + var from_html_form = (function () { + var form = utils.id('from_html_wrapper'), + code_input = utils.id('code_input'), + load_button = utils.id('load_code_button'), + close_button = form.querySelector('.close_button'), + regexp_area = //gmi, + regexp_href = / href="([\S\s]+?)"/, + regexp_alt = / alt="([\S\s]+?)"/, + regexp_title = / title="([\S\s]+?)"/; + + function test(str) { + var result_area, + result_href, + result_alt, + result_title, + type, + coords, + area, + href, + alt, + title, + success = false; + + if (str) { + result_area = regexp_area.exec(str); + + while (result_area) { + success = true; + + area = result_area[0]; + + type = result_area[1]; + coords = result_area[2].split(/ ?, ?/); + + result_href = regexp_href.exec(area); + if (result_href) { + href = result_href[1]; + } else { + href = ''; + } + + result_alt = regexp_alt.exec(area); + if (result_alt) { + alt = result_alt[1]; + } else { + alt = ''; + } + + result_title = regexp_title.exec(area); + if (result_title) { + title = result_title[1]; + } else { + title = ''; + } + + for (var i = 0, len = coords.length; i < len; i++) { + coords[i] = Number(coords[i]); + } + + switch (type) { + case 'rect': + if (coords.length === 4) { + Rect.createFromSaved({ + coords : coords, + href : href, + alt : alt, + title : title + }); + } + break; + + case 'circle': + if (coords.length === 3) { + Circle.createFromSaved({ + coords : coords, + href : href, + alt : alt, + title : title + }); + } + break; + + case 'poly': + if (coords.length >= 6 && coords.length % 2 === 0) { + Polygon.createFromSaved({ + coords : coords, + href : href, + alt : alt, + title : title + }); + } + break; + } + + result_area = regexp_area.exec(str); + } + + if (success) { + hide(); + } + } + } + + function load(e) { + test(code_input.value); + + e.preventDefault(); + } + + function hide() { + utils.hide(form); + } + + load_button.addEventListener('click', load, false); + + close_button.addEventListener('click', hide, false); + + return { + show : function () { + code_input.value = ''; + utils.show(form); + }, + hide : hide + } + })(); + + /* Load settings */ + var summer_settings = load_settings(); + + function load_settings() { + var settings = null; + settings = localStorage.getItem('SummerHTMLImageMapCreator_settings'); + if (settings == null) { + settings = { 'settings_auto_close_edit' : true,} + } + else { + try { settings = JSON.parse(settings); + } + catch (err) { //corrupted settings? + console.log(err); + console.log(settings); + settings = { 'settings_auto_close_edit' : true,} + } + } + return settings; + } + + var settings_dialog = (function () { + var form = utils.id('summer_settings'), + buttons = { + 'settings_auto_close_edit' : utils.id('settings_auto_close_edit'),}, + close_button = form.querySelector('.close_button'), + save_button = utils.id('settings_save'), + reset_button = utils.id('settings_reset'), + x = null; + + function get_value(button) { + if (button.type === 'checkbox') { + return button.checked; + } + return button.value; + } + + function set_value(button, value) { + if (button.type === 'checkbox') { + button.checked = value; + } + else { + button.value = value; + } + } + + function show() { + for (x in summer_settings) { + set_value(buttons[x], summer_settings[x]); + } + utils.show(form); + } + + function save(e) { + e.preventDefault(); + for (x in summer_settings) { + summer_settings[x] = get_value(buttons[x]); + } + localStorage.setItem('SummerHTMLImageMapCreator_settings', JSON.stringify(summer_settings)); + hide(); + } + + function to_default(e) { + e.preventDefault(); + for (x in buttons) { + set_value(buttons[x], buttons[x].getAttribute("data - default")); //nicer to use dataset property but that is not available in ie10 and under which still has much too big of a market share. + } + } + + function hide() { + utils.hide(form); + } + + save_button.addEventListener('click', save, false); + + close_button.addEventListener('click', hide, false); + + reset_button.addEventListener('click', to_default, false); + + return { + show : show, + hide : hide + } + })(); + + /* Get image form */ + var get_image = (function () { + var block = utils.id('get_image_wrapper'), + loading_indicator = utils.id('loading'), + button = utils.id('button'), + filename = null, + last_changed = null; + + // Drag'n'drop - the first way to loading an image + var drag_n_drop = (function () { + var dropzone = utils.id('dropzone'), + dropzone_clear_button = dropzone.querySelector('.clear_button'), + sm_img = utils.id('sm_img'); + + if (!utils.supportFileReader) { // For IE9 + utils.hide(utils.id('file_reader_support')); + } + + function testFile(type) { + switch (type) { + case 'image/jpeg': + case 'image/gif': + case 'image/png': + return true; + break; + } + return false; + } + + dropzone.addEventListener('dragover', function (e){ + utils.stopEvent(e); + }, false); + + dropzone.addEventListener('dragleave', function (e){ + utils.stopEvent(e); + }, false); + + dropzone.addEventListener('drop', function (e){ + utils.stopEvent(e); + + var reader = new FileReader(), + file = e.dataTransfer.files[0]; + + if (testFile(file.type)) { + utils.removeClass(dropzone, 'error'); + + reader.readAsDataURL(file); + + reader.onload = function (e) { + sm_img.src = e.target.result; + sm_img.style.display = 'inline - block'; + filename = file.name; + utils.show(dropzone_clear_button); + last_changed = drag_n_drop; + } + } else { + clearDropzone(); + utils.addClass(dropzone, 'error'); + } + + }, false); + + function clearDropzone() { + sm_img.src = ''; + + utils.hide(sm_img) + .hide(dropzone_clear_button) + .removeClass(dropzone, 'error'); + + last_changed = url_input; + } + + dropzone_clear_button.addEventListener('click', clearDropzone, false); + + return { + clear : clearDropzone, + init : function () { + dropzone.draggable = true; + this.clear(); + utils.hide(sm_img) + .hide(dropzone_clear_button); + }, + test : function () { + return sm_img.src ? true : false; + }, + getImage : function () { + return sm_img.src; + } + } + })(); + + + /* Set a url - the second way to loading an image */ + var url_input = (function () { + var url = utils.id('url'), + url_clear_button = url.parentNode.querySelector('.clear_button'); + + function testUrl(str) { + var url_str = utils.trim(str), + temp_array = url_str.split('.'), + ext; + + if(temp_array.length > 1) { + ext = temp_array[temp_array.length - 1].toLowerCase(); + switch (ext) { + case 'jpg': + case 'jpeg': + case 'gif': + case 'png': + return true; + break; + } + } + + return false; + } + + function onUrlChange() { + setTimeout(function (){ + if(url.value.length) { + utils.show(url_clear_button); + last_changed = url_input; + } else { + utils.hide(url_clear_button); + last_changed = drag_n_drop; + } + }, 0); + } + + url.addEventListener('keypress', onUrlChange, false); + url.addEventListener('change', onUrlChange, false); + url.addEventListener('paste', onUrlChange, false); + + function clearUrl() { + url.value = ''; + utils.hide(url_clear_button); + utils.removeClass(url, 'error'); + last_changed = url_input; + } + + url_clear_button.addEventListener('click', clearUrl, false); + + return { + clear : clearUrl, + init : function () { + this.clear(); + utils.hide(url_clear_button); + }, + test : function () { + if(testUrl(url.value)) { + utils.removeClass(url, 'error'); + return true; + } else { + utils.addClass(url, 'error'); + } + return false; + }, + getImage : function () { + var tmp_arr = url.value.split('/'); + filename = tmp_arr[tmp_arr.length - 1]; + + return utils.trim(url.value) + } + } + })(); + + + /* Block init */ + function init() { + utils.hide(loading_indicator); + drag_n_drop.init(); + url_input.init(); + } + init(); + + /* Block clear */ + function clear() { + drag_n_drop.clear(); + url_input.clear(); + last_changed = null; + } + + /* Selected image loading */ + function onButtonClick(e) { + if (last_changed === url_input && url_input.test()) { + app.loadImage(url_input.getImage()).setFilename(filename); + } else if (last_changed === drag_n_drop && drag_n_drop.test()) { + app.loadImage(drag_n_drop.getImage()).setFilename(filename); + } + + e.preventDefault(); + } + + button.addEventListener('click', onButtonClick, false); + + /* Returned object */ + return { + show : function () { + clear(); + utils.show(block); + + return this; + }, + hide : function () { + utils.hide(block); + + return this; + }, + showLoadIndicator : function () { + utils.show(loading_indicator); + + return this; + }, + hideLoadIndicator : function () { + utils.hide(loading_indicator); + + return this; + } + } + })(); + + + /* Buttons and actions */ + var buttons = (function () { + var all = utils.id('nav').getElementsByTagName('li'), + save = utils.id('save'), + load = utils.id('load'), + rectangle = utils.id('rect'), + circle = utils.id('circle'), + polygon = utils.id('polygon'), + edit = utils.id('edit'), + clear = utils.id('clear'), + from_html = utils.id('from_html'), + to_html = utils.id('to_html'), + preview = utils.id('preview'), + new_image = utils.id('new_image'), + settings = utils.id('show_settings'), + show_help = utils.id('show_help'); + + function deselectAll() { + utils.foreach(all, function (x) { + utils.removeClass(x, 'selected'); + }); + } + + function selectOne(button) { + deselectAll(); + utils.addClass(button, 'selected'); + } + + function onSaveButtonClick(e) { + // Save in localStorage + app.saveInLocalStorage(); + + e.preventDefault(); + } + + function onLoadButtonClick(e) { + // Load from localStorage + app.clear() + .loadFromLocalStorage(); + + e.preventDefault(); + } + + function onShapeButtonClick(e) { + // shape = rect || circle || polygon + app.setMode('drawing') + .setDrawClass() + .setShape(this.id) + .deselectAll() + .hidePreview(); + info.unload(); + selectOne(this); + + e.preventDefault(); + } + + function onClearButtonClick(e) { + // Clear all + if (confirm('Clear all?')) { + app.setMode(null) + .setDefaultClass() + .setShape(null) + .clear() + .hidePreview(); + deselectAll(); + } + + e.preventDefault(); + } + + function onFromHtmlButtonClick(e) { + // Load areas from html + from_html_form.show(); + + e.preventDefault(); + } + + function onSettingsClick (e) { + settings_dialog.show(); + e.preventDefault(); + } + function onToHtmlButtonClick(e) { + // Generate html code only + info.unload(); + code.print(); + + e.preventDefault(); + } + + function onPreviewButtonClick(e) { + if (app.getMode() === 'preview') { + app.setMode(null) + .hidePreview(); + deselectAll(); + } else { + app.deselectAll() + .setMode('preview') + .setDefaultClass() + .preview(); + selectOne(this); + } + + e.preventDefault(); + } + + function onEditButtonClick(e) { + if (app.getMode() === 'editing') { + app.setMode(null) + .setDefaultClass() + .deselectAll(); + deselectAll(); + utils.show(svg); + } else { + app.setShape(null) + .setMode('editing') + .setEditClass(); + selectOne(this); + } + app.hidePreview(); + e.preventDefault(); + } + + function onNewImageButtonClick(e) { + // New image - clear all and back to loading image screen + if(confirm('Discard all changes?')) { + app.setMode(null) + .setDefaultClass() + .setShape(null) + .setIsDraw(false) + .clear() + .hide() + .hidePreview(); + deselectAll(); + get_image.show(); + } + + e.preventDefault(); + } + + function onShowHelpButtonClick(e) { + help.show(); + + e.preventDefault(); + } + + save.addEventListener('click', onSaveButtonClick, false); + load.addEventListener('click', onLoadButtonClick, false); + rectangle.addEventListener('click', onShapeButtonClick, false); + circle.addEventListener('click', onShapeButtonClick, false); + polygon.addEventListener('click', onShapeButtonClick, false); + clear.addEventListener('click', onClearButtonClick, false); + from_html.addEventListener('click', onFromHtmlButtonClick, false); + to_html.addEventListener('click', onToHtmlButtonClick, false); + preview.addEventListener('click', onPreviewButtonClick, false); + edit.addEventListener('click', onEditButtonClick, false); + new_image.addEventListener('click', onNewImageButtonClick, false); + settings.addEventListener('click', onSettingsClick, false); + show_help.addEventListener('click', onShowHelpButtonClick, false); + })(); + + + /* AppEvent constructor */ + function AppEvent(target, eventType, func) { + this.target = target; + this.eventType = eventType; + this.func = func; + + target.addEventListener(eventType, func, false); + } + + AppEvent.prototype.remove = function () { + this.target.removeEventListener(this.eventType, this.func, false); + } + + + /* Helper constructor */ + function Helper(node, x, y) { + this.helper = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + this.helper.setAttribute('class', 'helper'); + this.helper.setAttribute('height', 5); + this.helper.setAttribute('width', 5); + this.helper.setAttribute('x', x - 3); + this.helper.setAttribute('y', y - 3); + node.appendChild(this.helper); + } + + Helper.prototype.setCoords = function (x, y) { + this.helper.setAttribute('x', x - 3); + this.helper.setAttribute('y', y - 3); + + return this; + } + + Helper.prototype.setAction = function (action) { + this.helper.action = action; + + return this; + } + + Helper.prototype.setCursor = function (cursor) { + utils.addClass(this.helper, cursor); + + return this; + } + + Helper.prototype.setId = function (id) { + this.helper.n = id; + + return this; + } + + /* Rectangle constructor */ + var Rect = function (x, y){ + app.setIsDraw(true); + + this.params = { + x : x, //distance from the left edge of the image to the left side of the rectangle + y : y, //distance from the top edge of the image to the top side of the rectangle + width : 0, //width of rectangle + height : 0 //height of rectangle + } + + this.href = ''; //href attribute - not required + this.alt = ''; //alt attribute - not required + this.title = ''; //title attribute - not required + + this.g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); //container + this.rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); //rectangle + app.addNodeToSvg(this.g); + this.g.appendChild(this.rect); + + this.g.obj = this; /* Link to parent object */ + + this.helpers = { //object with all helpers - rectangles + center : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + top : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + bottom : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + left : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + right : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + top_left : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + top_right : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + bottom_left : new Helper(this.g, x - this.params.width/2, y - this.params.height/2), + bottom_right : new Helper(this.g, x - this.params.width/2, y - this.params.height/2) + } + + this.helpers.center.setAction('move').setCursor('move'); + this.helpers.left.setAction('editLeft').setCursor('e - resize'); + this.helpers.right.setAction('editRight').setCursor('w - resize'); + this.helpers.top.setAction('editTop').setCursor('n - resize'); + this.helpers.bottom.setAction('editBottom').setCursor('s - resize'); + this.helpers.top_left.setAction('editTopLeft').setCursor('nw - resize'); + this.helpers.top_right.setAction('editTopRight').setCursor('ne - resize'); + this.helpers.bottom_left.setAction('editBottomLeft').setCursor('sw - resize'); + this.helpers.bottom_right.setAction('editBottomRight').setCursor('se - resize'); + + this.select().redraw(); + + /* Add this object to array of all objects */ + app.addObject(this); + } + + Rect.prototype.setCoords = function (params){ + this.rect.setAttribute('x', params.x); + this.rect.setAttribute('y', params.y); + this.rect.setAttribute('width', params.width); + this.rect.setAttribute('height', params.height); + + this.helpers.center.setCoords(params.x + params.width/2, params.y + params.height/2); + this.helpers.top.setCoords(params.x + params.width/2, params.y); + this.helpers.bottom.setCoords(params.x + params.width/2, params.y + params.height); + this.helpers.left.setCoords(params.x, params.y + params.height/2); + this.helpers.right.setCoords(params.x + params.width, params.y + params.height/2); + this.helpers.top_left.setCoords(params.x, params.y); + this.helpers.top_right.setCoords(params.x + params.width, params.y); + this.helpers.bottom_left.setCoords(params.x, params.y + params.height); + this.helpers.bottom_right.setCoords(params.x + params.width, params.y + params.height); + + return this; + } + + Rect.prototype.setParams = function (params){ + this.params.x = params.x; + this.params.y = params.y; + this.params.width = params.width; + this.params.height = params.height; + + return this; + } + + Rect.prototype.redraw = function () { + this.setCoords(this.params); + + return this; + } + + Rect.prototype.dynamicDraw = function (x1,y1,square){ + var x0 = this.params.x, + y0 = this.params.y, + new_x, + new_y, + new_width, + new_height, + delta, + temp_params; + + new_width = Math.abs(x1 - x0); + new_height = Math.abs(y1 - y0); + + if (square) { + delta = new_width - new_height; + if (delta > 0) { + new_width = new_height; + } else { + new_height = new_width; + } + } + + if (x0>x1) { + new_x = x1; + if (square && delta > 0) { + new_x = x1 + Math.abs(delta); + } + } else { + new_x = x0; + } + + if (y0>y1) { + new_y = y1; + if (square && delta < 0) { + new_y = y1 + Math.abs(delta); + } + } else { + new_y = y0; + } + + temp_params = { /* params */ + x : new_x, + y : new_y, + width : new_width, + height: new_height + } + + this.setCoords(temp_params); + + return temp_params; + } + + Rect.prototype.onDraw = function (e) { + var _n_f = app.getNewArea(), + square = e.shiftKey ? true : false; + + _n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY), square); + } + + Rect.prototype.onDrawStop = function (e) { + var _n_f = app.getNewArea(), + square = e.shiftKey ? true : false; + + _n_f.setParams(_n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY), square)).deselect(); + + app.removeAllEvents() + .setIsDraw(false) + .resetNewArea(); + } + + Rect.prototype.move = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.x += dx; + temp_params.y += dy; + + return temp_params; + } + + Rect.prototype.editLeft = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.x += dx; + temp_params.width -= dx; + + return temp_params; + } + + Rect.prototype.editRight = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.width += dx; + + return temp_params; + } + + Rect.prototype.editTop = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.y += dy; + temp_params.height -= dy; + + return temp_params; + } + + Rect.prototype.editBottom = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.height += dy; + + return temp_params; + } + + Rect.prototype.editTopLeft = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.x += dx; + temp_params.y += dy; + temp_params.width -= dx; + temp_params.height -= dy; + + return temp_params; + } + + Rect.prototype.editTopRight = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.y += dy; + temp_params.width += dx; + temp_params.height -= dy; + + return temp_params; + } + + Rect.prototype.editBottomLeft = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.x += dx; + temp_params.width -= dx; + temp_params.height += dy; + + return temp_params; + } + + Rect.prototype.editBottomRight = function (dx, dy) { //offset x and y + var temp_params = Object.create(this.params); + + temp_params.width += dx; + temp_params.height += dy; + + return temp_params; + } + + Rect.prototype.dynamicEdit = function (temp_params, save_proportions) { + if (temp_params.width < 0) { + temp_params.width = Math.abs(temp_params.width); + temp_params.x -= temp_params.width; + } + + if (temp_params.height < 0) { + temp_params.height = Math.abs(temp_params.height); + temp_params.y -= temp_params.height; + } + + if (save_proportions) { + var proportions = this.params.width / this.params.height, + new_proportions = temp_params.width / temp_params.height, + delta = new_proportions - proportions, + x0 = this.params.x, + y0 = this.params.y, + x1 = temp_params.x, + y1 = temp_params.y; + + if (delta > 0) { + temp_params.width = Math.round(temp_params.height * proportions); + } else { + temp_params.height = Math.round(temp_params.width / proportions); + } + + } + + this.setCoords(temp_params); + + return temp_params; + + } + + Rect.prototype.onEdit = function (e) { + var _s_f = app.getSelectedArea(), + edit_type = app.getEditType(), + save_proportions = e.shiftKey ? true : false; + + _s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y), save_proportions); + } + + Rect.prototype.onEditStop = function (e) { + var _s_f = app.getSelectedArea(), + edit_type = app.getEditType(), + save_proportions = e.shiftKey ? true : false; + + _s_f.setParams(_s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y), save_proportions)); + app.removeAllEvents(); + } + + Rect.prototype.remove = function () { + app.removeNodeFromSvg(this.g); + } + + Rect.prototype.select = function () { + utils.addClass(this.rect, 'selected'); + + return this; + } + + Rect.prototype.deselect = function () { + utils.removeClass(this.rect, 'selected'); + + return this; + } + + Rect.prototype.with_href = function () { + utils.addClass(this.rect, 'with_href'); + + return this; + } + + Rect.prototype.without_href = function () { + utils.removeClass(this.rect, 'with_href'); + + return this; + } + + Rect.prototype.toString = function () { //to html map area code + var x2 = this.params.x + this.params.width, + y2 = this.params.y + this.params.height; + return '' + this.alt + ''; + } + + Rect.createFromSaved = function (params) { + var coords = params.coords, + href = params.href, + alt = params.alt, + title = params.title, + area = new Rect(coords[0], coords[1]); + + area.setParams(area.dynamicDraw(coords[2], coords[3])).deselect(); + + app.setIsDraw(false) + .resetNewArea(); + + if (href) { + area.href = href; + } + + if (alt) { + area.alt = alt; + } + + if (title) { + area.title = title; + } + } + + Rect.prototype.toJSON = function () { + return { + type : 'rect', + coords : [ + this.params.x, + this.params.y, + this.params.x + this.params.width, + this.params.y + this.params.height + ], + href : this.href, + alt : this.alt, + title : this.title + } + } + + + /* Circle constructor */ + var Circle = function (x, y){ + app.setIsDraw(true); + + this.params = { + cx : x, //distance from the left edge of the image to the center of the circle + cy : y, //distance from the top edge of the image to the center of the circle + radius : 0 //radius of the circle + } + + this.href = ''; //href attribute - not required + this.alt = ''; //alt attribute - not required + this.title = ''; //title attribute - not required + + this.g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + this.circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); + app.addNodeToSvg(this.g); + this.g.appendChild(this.circle); + + this.g.obj = this; /* Link to parent object */ + + this.helpers = { //array of all helpers - rectangles + center : new Helper(this.g, x, y), + top : new Helper(this.g, x, y), + bottom : new Helper(this.g, x, y), + left : new Helper(this.g, x, y), + right : new Helper(this.g, x, y) + } + + this.helpers.center.setAction('move'); + this.helpers.top.setAction('editTop').setCursor('n - resize'); + this.helpers.bottom.setAction('editBottom').setCursor('s - resize'); + this.helpers.left.setAction('editLeft').setCursor('w - resize'); + this.helpers.right.setAction('editRight').setCursor('e - resize'); + + this.select().redraw(); + + app.addObject(this); //add this object to array of all objects + } + + Circle.prototype.setCoords = function (params){ + this.circle.setAttribute('cx', params.cx); + this.circle.setAttribute('cy', params.cy); + this.circle.setAttribute('r', params.radius); + + this.helpers.center.setCoords(params.cx, params.cy); + this.helpers.top.setCoords(params.cx, params.cy - params.radius); + this.helpers.right.setCoords(params.cx + params.radius, params.cy); + this.helpers.bottom.setCoords(params.cx, params.cy + params.radius); + this.helpers.left.setCoords(params.cx - params.radius, params.cy); + + return this; + } + + Circle.prototype.setParams = function (params){ + this.params.cx = params.cx; + this.params.cy = params.cy; + this.params.radius = params.radius; + + return this; + } + + Circle.prototype.redraw = function () { + this.setCoords(this.params); + + return this; + } + + Circle.prototype.dynamicDraw = function (x1,y1){ + var x0 = this.params.cx, + y0 = this.params.cy, + dx, + dy, + radius, + temp_params; + + x1 = x1 ? x1 : x0; + y1 = y1 ? y1 : y0; + + dx = Math.abs(x0 - x1); + dy = Math.abs(y0 - y1); + radius = Math.round(Math.sqrt(dx*dx + dy*dy)); + + temp_params = { /* params */ + cx : x0, + cy : y0, + radius : radius + } + + this.setCoords(temp_params); + + return temp_params; + } + + Circle.prototype.onDraw = function (e) { + var _n_f = app.getNewArea(); + _n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY)); + } + + Circle.prototype.onDrawStop = function (e) { + var _n_f = app.getNewArea(); + _n_f.setParams(_n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY))).deselect(); + + app.removeAllEvents() + .setIsDraw(false) + .resetNewArea(); + } + + Circle.prototype.move = function (dx, dy){ //offset x and y + var temp_params = Object.create(this.params); + + temp_params.cx += dx; + temp_params.cy += dy; + + return temp_params; + } + + Circle.prototype.editTop = function (dx, dy){ //offset x and y + var temp_params = Object.create(this.params); + + temp_params.radius -= dy; + + return temp_params; + } + + Circle.prototype.editBottom = function (dx, dy){ //offset x and y + var temp_params = Object.create(this.params); + + temp_params.radius += dy; + + return temp_params; + } + + Circle.prototype.editLeft = function (dx, dy){ //offset x and y + var temp_params = Object.create(this.params); + + temp_params.radius -= dx; + + return temp_params; + } + + Circle.prototype.editRight = function (dx, dy){ //offset x and y + var temp_params = Object.create(this.params); + + temp_params.radius += dx; + + return temp_params; + } + + Circle.prototype.dynamicEdit = function (temp_params) { + if (temp_params.radius < 0) { + temp_params.radius = Math.abs(temp_params.radius); + } + + this.setCoords(temp_params); + + return temp_params; + } + + Circle.prototype.onEdit = function (e) { + var _s_f = app.getSelectedArea(), + edit_type = app.getEditType(); + + _s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y)); + } + + Circle.prototype.onEditStop = function (e) { + var _s_f = app.getSelectedArea(), + edit_type = app.getEditType(); + + _s_f.setParams(_s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y))); + + app.removeAllEvents(); + } + + Circle.prototype.remove = function (){ + app.removeNodeFromSvg(this.g); + } + + Circle.prototype.select = function () { + utils.addClass(this.circle, 'selected'); + + return this; + } + + Circle.prototype.deselect = function () { + utils.removeClass(this.circle, 'selected'); + + return this; + } + + Circle.prototype.with_href = function () { + utils.addClass(this.circle, 'with_href'); + + return this; + } + + Circle.prototype.without_href = function () { + utils.removeClass(this.circle, 'with_href'); + + return this; + } + + Circle.prototype.toString = function () { //to html map area code + return '' + this.alt + ''; + } + + Circle.createFromSaved = function (params) { + var coords = params.coords, + href = params.href, + alt = params.alt, + title = params.title, + area = new Circle(coords[0], coords[1]); + + area.setParams(area.dynamicDraw(coords[0], coords[1] + coords[2])).deselect(); + + app.setIsDraw(false) + .resetNewArea(); + + if (href) { + area.href = href; + } + + if (alt) { + area.alt = alt; + } + + if (title) { + area.title = title; + } + } + + Circle.prototype.toJSON = function () { + return { + type : 'circle', + coords : [ + this.params.cx, + this.params.cy, + this.params.radius + ], + href : this.href, + alt : this.alt, + title : this.title + } + } + + + /* Polygon constructor */ + var Polygon = function (x, y){ + app.setIsDraw(true); + + this.params = [x, y]; //array of coordinates of polygon points + + this.href = ''; //href attribute - not required + this.alt = ''; //alt attribute - not required + this.title = ''; //title attribute - not required + + this.g = document.createElementNS('http://www.w3.org/2000/svg', 'g'); + this.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'); + app.addNodeToSvg(this.g); + this.g.appendChild(this.polygon); + + this.g.obj = this; /* Link to parent object */ + + this.helpers = [ //array of all helpers - rectangles + new Helper(this.g, this.params[0], this.params[1]) + ]; + + this.helpers[0].setAction('pointMove').setCursor('pointer').setId(0); + + this.selected_point = - 1; + + this.select().redraw(); + + app.addObject(this); //add this object to array of all objects + } + + Polygon.prototype.setCoords = function (params){ + var coords_values = params.join(' '); + this.polygon.setAttribute('points', coords_values); + utils.foreach(this.helpers, function (x, i) { + x.setCoords(params[2*i], params[2*i+1]); + }); + + return this; + } + + Polygon.prototype.setParams = function (arr) { + this.params = arr; + + return this; + } + + Polygon.prototype.addPoint = function (x, y){ + var helper = new Helper(this.g, x, y); + helper.setAction('pointMove').setCursor('pointer').setId(this.helpers.length); + this.helpers.push(helper); + this.params.push(x, y); + this.redraw(); + + return this; + } + + Polygon.prototype.redraw = function () { + this.setCoords(this.params); + + return this; + } + + Polygon.prototype.right_angle = function (x, y){ + var old_x = this.params[this.params.length - 2], + old_y = this.params[this.params.length - 1], + dx = x - old_x, + dy = - (y - old_y), + tan = dy/dx; //tangens + + if (dx > 0 && dy > 0) { + if (tan > 2.414) { + x = old_x; + } else if (tan < 0.414) { + y = old_y; + } else { + Math.abs(dx) > Math.abs(dy) ? x = old_x + dy : y = old_y - dx; + } + } else if (dx < 0 && dy > 0) { + if (tan < - 2.414) { + x = old_x; + } else if (tan > - 0.414) { + y = old_y; + } else { + Math.abs(dx) > Math.abs(dy) ? x = old_x - dy : y = old_y + dx; + } + } else if (dx < 0 && dy < 0) { + if (tan > 2.414) { + x = old_x; + } else if (tan < 0.414) { + y = old_y; + } else { + Math.abs(dx) > Math.abs(dy) ? x = old_x + dy : y = old_y - dx; + } + } else if (dx > 0 && dy < 0) { + if (tan < - 2.414) { + x = old_x; + } else if (tan > - 0.414) { + y = old_y; + } else { + Math.abs(dx) > Math.abs(dy) ? x = old_x - dy : y = old_y + dx; + } + } + + return { + x : x, + y : y + } + } + + Polygon.prototype.dynamicDraw = function (x, y, right_angle){ + var temp_params = [].concat(this.params); + + if (right_angle) { + var right_coords = this.right_angle(x, y); + x = right_coords.x; + y = right_coords.y; + } + + temp_params.push(x, y); + + this.setCoords(temp_params); + + return temp_params; + } + + Polygon.prototype.onDraw = function (e) { + var _n_f = app.getNewArea(); + var right_angle = e.shiftKey ? true : false; + + _n_f.dynamicDraw(utils.rightX(e.pageX), utils.rightY(e.pageY), right_angle); + } + + Polygon.prototype.onDrawAddPoint = function (e) { + var x = utils.rightX(e.pageX), + y = utils.rightY(e.pageY), + + _n_f = app.getNewArea(); + + if (e.shiftKey) { + var right_coords = _n_f.right_angle(x, y); + x = right_coords.x; + y = right_coords.y; + } + _n_f.addPoint(x, y); + } + + Polygon.prototype.onDrawStop = function (e) { + var _n_f = app.getNewArea(); + if (e.type == 'click' || (e.type == 'keydown' && e.keyCode == 13)) { // key Enter + if (_n_f.params.length >= 6) { //>= 3 points for polygon + _n_f.polyline = _n_f.polygon; + _n_f.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); + _n_f.g.replaceChild(_n_f.polygon, _n_f.polyline); + _n_f.setCoords(_n_f.params).deselect(); + delete(_n_f.polyline); + + app.removeAllEvents() + .setIsDraw(false) + .resetNewArea(); + } + } + e.stopPropagation(); + } + + Polygon.prototype.move = function (x, y){ //offset x and y + for (var i = 0, count = this.params.length; i < count; i++) { + i % 2 ? this.params[i] += y : this.params[i] += x; + } + this.redraw(); + } + + Polygon.prototype.pointMove = function (x, y){ //offset x and y + this.params[2 * this.selected_point] += x; + this.params[2 * this.selected_point + 1] += y; + this.redraw(); + } + + Polygon.prototype.onEdit = function (e) { + var _s_f = app.getSelectedArea(), + edit_type = app.getEditType(); + _s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y); + _s_f.delta.x = e.pageX; + _s_f.delta.y = e.pageY; + } + + Polygon.prototype.onEditStop = function (e) { + var _s_f = app.getSelectedArea(), + edit_type = app.getEditType(); + _s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y); + app.removeAllEvents(); + } + + Polygon.prototype.remove = function (){ + app.removeNodeFromSvg(this.g); + } + + Polygon.prototype.select = function () { + utils.addClass(this.polygon, 'selected'); + + return this; + } + + Polygon.prototype.deselect = function () { + utils.removeClass(this.polygon, 'selected'); + + return this; + } + + Polygon.prototype.with_href = function () { + utils.addClass(this.polygon, 'with_href'); + + return this; + } + + Polygon.prototype.without_href = function () { + utils.removeClass(this.polygon, 'with_href'); + + return this; + } + + Polygon.prototype.toString = function () { //to html map area code + for (var i = 0, count = this.params.length, str = ''; i < count; i++) { + str += this.params[i]; + if (i != count - 1) { + str += ', '; + } + } + return '' + this.alt + ''; + } + + Polygon.createFromSaved = function (params) { + var coords = params.coords, + href = params.href, + alt = params.alt, + title = params.title, + area = new Polygon(coords[0], coords[1]); + + for (var i = 2, c = coords.length; i < c; i+=2) { + area.addPoint(coords[i], coords[i+1]); + } + + area.polyline = area.polygon; + area.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'); + area.g.replaceChild(area.polygon, area.polyline); + area.setCoords(area.params).deselect(); + delete(area.polyline); + + app.setIsDraw(false) + .resetNewArea(); + + if (href) { + area.href = href; + } + + if (alt) { + area.alt = alt; + } + + if (title) { + area.title = title; + } + } + + Polygon.prototype.toJSON = function () { + return { + type : 'polygon', + coords : this.params, + href : this.href, + alt : this.alt, + title : this.title + } + } + +} document.addEventListener("DOMContentLoaded", SummerHtmlImageMapCreator, false); \ No newline at end of file diff --git a/scripts.min.js b/scripts.min.js new file mode 100644 index 0000000..a568461 --- /dev/null +++ b/scripts.min.js @@ -0,0 +1 @@ +function SummerHtmlImageMapCreator(){"use strict";function u(){var e=null;e=localStorage.getItem("SummerHTMLImageMapCreator_settings");if(e==null){e={settings_auto_close_edit:true}}else{try{e=JSON.parse(e)}catch(t){console.log(t);console.log(e);e={settings_auto_close_edit:true}}}return e}function c(e,t,n){this.target=e;this.eventType=t;this.func=n;e.addEventListener(t,n,false)}function h(e,t,n){this.helper=document.createElementNS("http://www.w3.org/2000/svg","rect");this.helper.setAttribute("class","helper");this.helper.setAttribute("height",5);this.helper.setAttribute("width",5);this.helper.setAttribute("x",t-3);this.helper.setAttribute("y",n-3);e.appendChild(this.helper)}var e={offsetX:function(e){var t=e.getBoundingClientRect(),n=window.pageXOffset;return Math.round(t.left+n)},offsetY:function(e){var t=e.getBoundingClientRect(),n=window.pageYOffset;return Math.round(t.top+n)},rightX:function(e){return e-t.getOffset("x")},rightY:function(e){return e-t.getOffset("y")},trim:function(e){return e.replace(/^\s+|\s+$/g,"")},id:function(e){return document.getElementById(e)},hide:function(e){e.style.display="none";return this},show:function(e){e.style.display="block";return this},encode:function(e){return e.replace(//g,">")},foreach:function(e,t){for(var n=0,r=e.length;n=0;n--){t(e[n],n)}},debug:function(){var e=document.getElementById("debug");return function(){e.innerHTML=[].join.call(arguments," ")}}(),stopEvent:function(e){e.stopPropagation();e.preventDefault();return this},addClass:function(t,n){var r=t.className.baseVal!==undefined?true:false,i=r?t.className.baseVal.split(" "):t.className.split(" "),s=false;e.foreach(i,function(e){if(e===n){s=true}});if(!s){i.push(n);r?t.className.baseVal=i.join(" "):t.className=i.join(" ")}return this},removeClass:function(t,n){var r=t.className.baseVal!==undefined?true:false,i=r?t.className.baseVal.split(" "):t.className.split(" "),s=false;e.foreach(i,function(e,t){if(e===n){s=true;i.splice(t--,1)}});if(s){r?t.className.baseVal=i.join(" "):t.className=i.join(" ")}return this},hasClass:function(t,n){var r=t.className.baseVal!==undefined?true:false,i=r?t.className.baseVal.split(" "):t.className.split(" "),s=false;e.foreach(i,function(e){if(e===n){s=true}});return s},extend:function(e,t){var n={};for(name in e){if(e.hasOwnProperty(name)){n[name]=t[name]?t[name]:e[name]}}return n},supportFileReader:function(){return typeof FileReader!=="undefined"}()};var t=function(){function O(){y.x=e.offsetX(h);y.y=e.offsetY(h)}function M(n){if(E==="editing"){if(n.target.parentNode.tagName==="g"){i.unload();T=n.target.parentNode.obj;t.deselectAll();T.select();T.delta={x:n.pageX,y:n.pageY};if(e.hasClass(n.target,"helper")){var r=n.target;N=r.action;if(r.n>=0){T.selected_point=r.n}t.addEvent(h,"mousemove",T.onEdit).addEvent(h,"mouseup",T.onEditStop)}else if(n.target.tagName==="rect"||n.target.tagName==="circle"||n.target.tagName==="polygon"){N="move";t.addEvent(h,"mousemove",T.onEdit).addEvent(h,"mouseup",T.onEditStop)}}else{t.deselectAll();i.unload()}}}function _(n){if(E==="drawing"&&!w&&b){r.hide();switch(b){case"rect":x=new p(e.rightX(n.pageX),e.rightY(n.pageY));t.addEvent(h,"mousemove",x.onDraw).addEvent(h,"click",x.onDrawStop);break;case"circle":x=new d(e.rightX(n.pageX),e.rightY(n.pageY));t.addEvent(h,"mousemove",x.onDraw).addEvent(h,"click",x.onDrawStop);break;case"polygon":x=new v(e.rightX(n.pageX),e.rightY(n.pageY));t.addEvent(h,"mousemove",x.onDraw).addEvent(h,"click",x.onDrawAddPoint).addEvent(document,"keydown",x.onDrawStop).addEvent(x.helpers[0].helper,"click",x.onDrawStop);break}}}function D(){window.focus()}function P(e){if(E==="editing"){if(e.target.tagName==="rect"||e.target.tagName==="circle"||e.target.tagName==="polygon"){T=e.target.parentNode.obj;i.load(T,e.pageX,e.pageY)}}}function H(e){switch(e.keyCode){case A.F1:n.show();e.preventDefault();break;case A.ESC:n.hide();if(w){w=false;x.remove();S.pop();t.removeAllEvents()}else if(E==="editing"){T.redraw();t.removeAllEvents()}break;case A.TOP:if(E==="editing"&&T){T.setParams(T.dynamicEdit(T["move"](0,-1)));e.preventDefault()}break;case A.BOTTOM:if(E==="editing"&&T){T.setParams(T.dynamicEdit(T["move"](0,1)));e.preventDefault()}break;case A.LEFT:if(E==="editing"&&T){T.setParams(T.dynamicEdit(T["move"](-1,0)));e.preventDefault()}break;case A.RIGHT:if(E==="editing"&&T){T.setParams(T.dynamicEdit(T["move"](1,0)));e.preventDefault()}break;case A.DELETE:if(E==="editing"&&T){t.removeObject(T);T=null;i.unload()}break;case A.I:if(E==="editing"&&T){var r=T.params,s=r.x||r.cx||r[0],o=r.y||r.cy||r[1];i.load(T,s+t.getOffset("x"),o+t.getOffset("y"))}break;case A.S:t.saveInLocalStorage();break}}var s=document.getElementsByTagName("body")[0],o=e.id("wrapper"),u=e.id("svg"),a=e.id("img"),l=null,h=e.id("image"),m=e.id("about"),g=e.id("coords"),y={x:0,y:0},b=null,w=false,E=null,S=[],x=null,T=null,N,C=[],k,L,A={F1:112,ESC:27,TOP:38,BOTTOM:40,LEFT:37,RIGHT:39,DELETE:46,I:73,S:83};window.addEventListener("resize",O,false);h.addEventListener("mousedown",function(e){e.preventDefault()},false);a.addEventListener("dragstart",function(e){e.preventDefault()},false);h.addEventListener("mousemove",function(t){g.innerHTML="x: "+e.rightX(t.pageX)+", "+"y: "+e.rightY(t.pageY)},false);h.addEventListener("mouseleave",function(){g.innerHTML=""},false);h.addEventListener("mousedown",M,false);h.addEventListener("click",_,false);if(window.navigator.appName==="Opera"){h.addEventListener("mousedown",D,false);h.addEventListener("mouseup",D,false);h.addEventListener("click",D,false);h.addEventListener("dblclick",D,false)}h.addEventListener("dblclick",P,false);document.addEventListener("keydown",H,false);return{saveInLocalStorage:function(){var t={areas:[],img:l};e.foreach(S,function(e){t.areas.push(e.toJSON())});window.localStorage.setItem("SummerHTMLImageMapCreator",JSON.stringify(t));alert("Saved");return this},loadFromLocalStorage:function(){var t=window.localStorage.getItem("SummerHTMLImageMapCreator"),n=JSON.parse(t),r=n.areas;this.loadImage(n.img);e.foreach(r,function(e){switch(e.type){case"rect":if(e.coords.length===4){p.createFromSaved({coords:e.coords,href:e.href,alt:e.alt,title:e.title})}break;case"circle":if(e.coords.length===3){d.createFromSaved({coords:e.coords,href:e.href,alt:e.alt,title:e.title})}break;case"polygon":if(e.coords.length>=6&&e.coords.length%2===0){v.createFromSaved({coords:e.coords,href:e.href,alt:e.alt,title:e.title})}break}});return this},hide:function(){e.hide(o);return this},show:function(){e.show(o);return this},recalcOffsetValues:function(){O();return this},setDimensions:function(e,t){u.setAttribute("width",e);u.setAttribute("height",t);h.style.width=e+"px";h.style.height=t+"px";return this},loadImage:function(e){f.showLoadIndicator();a.src=e;l=e;a.onload=function(){f.hideLoadIndicator().hide();t.show().setDimensions(a.width,a.height).recalcOffsetValues()};return this},preview:function(){a.setAttribute("usemap","#map");k=document.createElement("map");k.setAttribute("name","map");h.appendChild(k);return function(){i.unload();t.setShape(null);e.hide(u);k.innerHTML=t.getHTMLCode();r.print();return this}}(),hidePreview:function(){e.show(u);k.innerHTML="";return this},addNodeToSvg:function(e){u.appendChild(e);return this},removeNodeFromSvg:function(e){u.removeChild(e);return this},getOffset:function(e){switch(e){case"x":return y.x;break;case"y":return y.y;break}return undefined},clear:function(){S.length=0;while(u.childNodes[0]){u.removeChild(u.childNodes[0])}r.hide();i.unload();return this},removeObject:function(t){e.foreach(S,function(e,n){if(e===t){S.splice(n,1)}});t.remove();return this},deselectAll:function(){e.foreach(S,function(e){e.deselect()});return this},getIsDraw:function(){return w},setIsDraw:function(e){w=e;return this},setMode:function(e){E=e;return this},getMode:function(){return E},setShape:function(e){b=e;return this},getShape:function(){return b},addObject:function(e){S.push(e);return this},getNewArea:function(){return x},resetNewArea:function(){x=null;return this},getSelectedArea:function(){return T},setSelectedArea:function(e){T=e;return this},getEditType:function(){return N},setFilename:function(e){L=e;return this},setEditClass:function(){e.removeClass(h,"draw").addClass(h,"edit");return this},setDrawClass:function(){e.removeClass(h,"edit").addClass(h,"draw");return this},setDefaultClass:function(){e.removeClass(h,"edit").removeClass(h,"draw");return this},addEvent:function(e,t,n){C.push(new c(e,t,n));return this},removeAllEvents:function(){e.foreach(C,function(e){e.remove()});C.length=0;return this},getHTMLCode:function(t){var n="";if(t){if(!S.length){return"0 objects"}n+=e.encode('')+"
"+e.encode('')+"
";e.foreachReverse(S,function(t){n+="    "+e.encode(t.toString())+"
"});n+=e.encode("
")}else{e.foreachReverse(S,function(e){n+=e.toString()})}return n}}}();var n=function(){function i(){e.hide(t);e.hide(n)}function s(){e.show(t);e.show(n)}var t=e.id("help"),n=e.id("overlay"),r=t.querySelector(".close_button");n.addEventListener("click",i,false);r.addEventListener("click",i,false);return{show:s,hide:i}}();var r=function(){var n=e.id("code"),r=e.id("code_content"),i=n.querySelector(".close_button");i.addEventListener("click",function(t){e.hide(n);t.preventDefault()},false);return{print:function(){r.innerHTML=t.getHTMLCode(true);e.show(n)},hide:function(){e.hide(n)}}}();var i=function(){function g(){e.removeClass(n,"changed");e.foreach(c,function(t){e.removeClass(t,"changed")})}function y(e){h.href=i.value;h.alt=s.value;h.title=u.value;h.href?h.with_href():h.without_href();if(o.settings_auto_close_edit){w()}e.preventDefault()}function b(e){i.value="";s.value="";u.value="";g();e.preventDefault()}function w(){h=null;g();e.hide(n)}function E(e,t){n.style.left=e+5+"px";n.style.top=t+5+"px"}function S(e){E(p+e.pageX-v,d+e.pageY-m)}function x(e){p=p+e.pageX-v;d=d+e.pageY-m;E(p,d);t.removeAllEvents()}function T(){e.addClass(n,"changed");e.addClass(this.parentNode,"changed")}var n=e.id("edit_details"),r=n.querySelector("h5"),i=e.id("href_attr"),s=e.id("alt_attr"),u=e.id("title_attr"),a=e.id("save_details"),f=e.id("details_clear"),l=n.querySelector(".close_button"),c=n.querySelectorAll("p"),h,p,d,v,m;a.addEventListener("click",y,false);f.addEventListener("click",b,false);i.addEventListener("keydown",function(e){e.stopPropagation()},false);s.addEventListener("keydown",function(e){e.stopPropagation()},false);u.addEventListener("keydown",function(e){e.stopPropagation()},false);i.addEventListener("change",T,false);s.addEventListener("change",T,false);u.addEventListener("change",T,false);l.addEventListener("click",w,false);r.addEventListener("mousedown",function(e){v=e.pageX,m=e.pageY;t.addEvent(document,"mousemove",S);t.addEvent(r,"mouseup",x);e.preventDefault()},false);return{load:function(t,r,o){h=t;i.value=t.href?t.href:"";s.value=t.alt?t.alt:"";u.value=t.title?t.title:"";e.show(n);if(r&&o){p=r;d=o;E(p,d)}},unload:w}}();var s=function(){function f(e){var t,n,r,i,f,l,h,m,g,y,b=false;if(e){t=s.exec(e);while(t){b=true;h=t[0];f=t[1];l=t[2].split(/ ?, ?/);n=o.exec(h);if(n){m=n[1]}else{m=""}r=u.exec(h);if(r){g=r[1]}else{g=""}i=a.exec(h);if(i){y=i[1]}else{y=""}for(var w=0,E=l.length;w=6&&l.length%2===0){v.createFromSaved({coords:l,href:m,alt:g,title:y})}break}t=s.exec(e)}if(b){c()}}}function l(e){f(n.value);e.preventDefault()}function c(){e.hide(t)}var t=e.id("from_html_wrapper"),n=e.id("code_input"),r=e.id("load_code_button"),i=t.querySelector(".close_button"),s=//gmi,o=/ href="([\S\s]+?)"/,u=/ alt="([\S\s]+?)"/,a=/ title="([\S\s]+?)"/;r.addEventListener("click",l,false);i.addEventListener("click",c,false);return{show:function(){n.value="";e.show(t)},hide:c}}();var o=u();var a=function(){function a(e){if(e.type==="checkbox"){return e.checked}return e.value}function f(e,t){if(e.type==="checkbox"){e.checked=t}else{e.value=t}}function l(){for(u in o){f(n[u],o[u])}e.show(t)}function c(e){e.preventDefault();for(u in o){o[u]=a(n[u])}localStorage.setItem("SummerHTMLImageMapCreator_settings",JSON.stringify(o));p()}function h(e){e.preventDefault();for(u in n){f(n[u],n[u].getAttribute("data - default"))}}function p(){e.hide(t)}var t=e.id("summer_settings"),n={settings_auto_close_edit:e.id("settings_auto_close_edit")},r=t.querySelector(".close_button"),i=e.id("settings_save"),s=e.id("settings_reset"),u=null;i.addEventListener("click",c,false);r.addEventListener("click",p,false);s.addEventListener("click",h,false);return{show:l,hide:p}}();var f=function(){function f(){e.hide(r);u.init();a.init()}function l(){u.clear();a.clear();o=null}function c(e){if(o===a&&a.test()){t.loadImage(a.getImage()).setFilename(s)}else if(o===u&&u.test()){t.loadImage(u.getImage()).setFilename(s)}e.preventDefault()}var n=e.id("get_image_wrapper"),r=e.id("loading"),i=e.id("button"),s=null,o=null;var u=function(){function i(e){switch(e){case"image/jpeg":case"image/gif":case"image/png":return true;break}return false}function f(){r.src="";e.hide(r).hide(n).removeClass(t,"error");o=a}var t=e.id("dropzone"),n=t.querySelector(".clear_button"),r=e.id("sm_img");if(!e.supportFileReader){e.hide(e.id("file_reader_support"))}t.addEventListener("dragover",function(t){e.stopEvent(t)},false);t.addEventListener("dragleave",function(t){e.stopEvent(t)},false);t.addEventListener("drop",function(a){e.stopEvent(a);var l=new FileReader,c=a.dataTransfer.files[0];if(i(c.type)){e.removeClass(t,"error");l.readAsDataURL(c);l.onload=function(t){r.src=t.target.result;r.style.display="inline - block";s=c.name;e.show(n);o=u}}else{f();e.addClass(t,"error")}},false);n.addEventListener("click",f,false);return{clear:f,init:function(){t.draggable=true;this.clear();e.hide(r).hide(n)},test:function(){return r.src?true:false},getImage:function(){return r.src}}}();var a=function(){function r(t){var n=e.trim(t),r=n.split("."),i;if(r.length>1){i=r[r.length-1].toLowerCase();switch(i){case"jpg":case"jpeg":case"gif":case"png":return true;break}}return false}function i(){setTimeout(function(){if(t.value.length){e.show(n);o=a}else{e.hide(n);o=u}},0)}function f(){t.value="";e.hide(n);e.removeClass(t,"error");o=a}var t=e.id("url"),n=t.parentNode.querySelector(".clear_button");t.addEventListener("keypress",i,false);t.addEventListener("change",i,false);t.addEventListener("paste",i,false);n.addEventListener("click",f,false);return{clear:f,init:function(){this.clear();e.hide(n)},test:function(){if(r(t.value)){e.removeClass(t,"error");return true}else{e.addClass(t,"error")}return false},getImage:function(){var n=t.value.split("/");s=n[n.length-1];return e.trim(t.value)}}}();f();i.addEventListener("click",c,false);return{show:function(){l();e.show(n);return this},hide:function(){e.hide(n);return this},showLoadIndicator:function(){e.show(r);return this},hideLoadIndicator:function(){e.hide(r);return this}}}();var l=function(){function S(){e.foreach(o,function(t){e.removeClass(t,"selected")})}function x(t){S();e.addClass(t,"selected")}function T(e){t.saveInLocalStorage();e.preventDefault()}function N(e){t.clear().loadFromLocalStorage();e.preventDefault()}function C(e){t.setMode("drawing").setDrawClass().setShape(this.id).deselectAll().hidePreview();i.unload();x(this);e.preventDefault()}function k(e){if(confirm("Clear all?")){t.setMode(null).setDefaultClass().setShape(null).clear().hidePreview();S()}e.preventDefault()}function L(e){s.show();e.preventDefault()}function A(e){a.show();e.preventDefault()}function O(e){i.unload();r.print();e.preventDefault()}function M(e){if(t.getMode()==="preview"){t.setMode(null).hidePreview();S()}else{t.deselectAll().setMode("preview").setDefaultClass().preview();x(this)}e.preventDefault()}function _(n){if(t.getMode()==="editing"){t.setMode(null).setDefaultClass().deselectAll();S();e.show(svg)}else{t.setShape(null).setMode("editing").setEditClass();x(this)}t.hidePreview();n.preventDefault()}function D(e){if(confirm("Discard all changes?")){t.setMode(null).setDefaultClass().setShape(null).setIsDraw(false).clear().hide().hidePreview();S();f.show()}e.preventDefault()}function P(e){n.show();e.preventDefault()}var o=e.id("nav").getElementsByTagName("li"),u=e.id("save"),l=e.id("load"),c=e.id("rect"),h=e.id("circle"),p=e.id("polygon"),d=e.id("edit"),v=e.id("clear"),m=e.id("from_html"),g=e.id("to_html"),y=e.id("preview"),b=e.id("new_image"),w=e.id("show_settings"),E=e.id("show_help");u.addEventListener("click",T,false);l.addEventListener("click",N,false);c.addEventListener("click",C,false);h.addEventListener("click",C,false);p.addEventListener("click",C,false);v.addEventListener("click",k,false);m.addEventListener("click",L,false);g.addEventListener("click",O,false);y.addEventListener("click",M,false);d.addEventListener("click",_,false);b.addEventListener("click",D,false);w.addEventListener("click",A,false);E.addEventListener("click",P,false)}();c.prototype.remove=function(){this.target.removeEventListener(this.eventType,this.func,false)};h.prototype.setCoords=function(e,t){this.helper.setAttribute("x",e-3);this.helper.setAttribute("y",t-3);return this};h.prototype.setAction=function(e){this.helper.action=e;return this};h.prototype.setCursor=function(t){e.addClass(this.helper,t);return this};h.prototype.setId=function(e){this.helper.n=e;return this};var p=function(e,n){t.setIsDraw(true);this.params={x:e,y:n,width:0,height:0};this.href="";this.alt="";this.title="";this.g=document.createElementNS("http://www.w3.org/2000/svg","g");this.rect=document.createElementNS("http://www.w3.org/2000/svg","rect");t.addNodeToSvg(this.g);this.g.appendChild(this.rect);this.g.obj=this;this.helpers={center:new h(this.g,e-this.params.width/2,n-this.params.height/2),top:new h(this.g,e-this.params.width/2,n-this.params.height/2),bottom:new h(this.g,e-this.params.width/2,n-this.params.height/2),left:new h(this.g,e-this.params.width/2,n-this.params.height/2),right:new h(this.g,e-this.params.width/2,n-this.params.height/2),top_left:new h(this.g,e-this.params.width/2,n-this.params.height/2),top_right:new h(this.g,e-this.params.width/2,n-this.params.height/2),bottom_left:new h(this.g,e-this.params.width/2,n-this.params.height/2),bottom_right:new h(this.g,e-this.params.width/2,n-this.params.height/2)};this.helpers.center.setAction("move").setCursor("move");this.helpers.left.setAction("editLeft").setCursor("e - resize");this.helpers.right.setAction("editRight").setCursor("w - resize");this.helpers.top.setAction("editTop").setCursor("n - resize");this.helpers.bottom.setAction("editBottom").setCursor("s - resize");this.helpers.top_left.setAction("editTopLeft").setCursor("nw - resize");this.helpers.top_right.setAction("editTopRight").setCursor("ne - resize");this.helpers.bottom_left.setAction("editBottomLeft").setCursor("sw - resize");this.helpers.bottom_right.setAction("editBottomRight").setCursor("se - resize");this.select().redraw();t.addObject(this)};p.prototype.setCoords=function(e){this.rect.setAttribute("x",e.x);this.rect.setAttribute("y",e.y);this.rect.setAttribute("width",e.width);this.rect.setAttribute("height",e.height);this.helpers.center.setCoords(e.x+e.width/2,e.y+e.height/2);this.helpers.top.setCoords(e.x+e.width/2,e.y);this.helpers.bottom.setCoords(e.x+e.width/2,e.y+e.height);this.helpers.left.setCoords(e.x,e.y+e.height/2);this.helpers.right.setCoords(e.x+e.width,e.y+e.height/2);this.helpers.top_left.setCoords(e.x,e.y);this.helpers.top_right.setCoords(e.x+e.width,e.y);this.helpers.bottom_left.setCoords(e.x,e.y+e.height);this.helpers.bottom_right.setCoords(e.x+e.width,e.y+e.height);return this};p.prototype.setParams=function(e){this.params.x=e.x;this.params.y=e.y;this.params.width=e.width;this.params.height=e.height;return this};p.prototype.redraw=function(){this.setCoords(this.params);return this};p.prototype.dynamicDraw=function(e,t,n){var r=this.params.x,i=this.params.y,s,o,u,a,f,l;u=Math.abs(e-r);a=Math.abs(t-i);if(n){f=u-a;if(f>0){u=a}else{a=u}}if(r>e){s=e;if(n&&f>0){s=e+Math.abs(f)}}else{s=r}if(i>t){o=t;if(n&&f<0){o=t+Math.abs(f)}}else{o=i}l={x:s,y:o,width:u,height:a};this.setCoords(l);return l};p.prototype.onDraw=function(n){var r=t.getNewArea(),i=n.shiftKey?true:false;r.dynamicDraw(e.rightX(n.pageX),e.rightY(n.pageY),i)};p.prototype.onDrawStop=function(n){var r=t.getNewArea(),i=n.shiftKey?true:false;r.setParams(r.dynamicDraw(e.rightX(n.pageX),e.rightY(n.pageY),i)).deselect();t.removeAllEvents().setIsDraw(false).resetNewArea()};p.prototype.move=function(e,t){var n=Object.create(this.params);n.x+=e;n.y+=t;return n};p.prototype.editLeft=function(e,t){var n=Object.create(this.params);n.x+=e;n.width-=e;return n};p.prototype.editRight=function(e,t){var n=Object.create(this.params);n.width+=e;return n};p.prototype.editTop=function(e,t){var n=Object.create(this.params);n.y+=t;n.height-=t;return n};p.prototype.editBottom=function(e,t){var n=Object.create(this.params);n.height+=t;return n};p.prototype.editTopLeft=function(e,t){var n=Object.create(this.params);n.x+=e;n.y+=t;n.width-=e;n.height-=t;return n};p.prototype.editTopRight=function(e,t){var n=Object.create(this.params);n.y+=t;n.width+=e;n.height-=t;return n};p.prototype.editBottomLeft=function(e,t){var n=Object.create(this.params);n.x+=e;n.width-=e;n.height+=t;return n};p.prototype.editBottomRight=function(e,t){var n=Object.create(this.params);n.width+=e;n.height+=t;return n};p.prototype.dynamicEdit=function(e,t){if(e.width<0){e.width=Math.abs(e.width);e.x-=e.width}if(e.height<0){e.height=Math.abs(e.height);e.y-=e.height}if(t){var n=this.params.width/this.params.height,r=e.width/e.height,i=r-n,s=this.params.x,o=this.params.y,u=e.x,a=e.y;if(i>0){e.width=Math.round(e.height*n)}else{e.height=Math.round(e.width/n)}}this.setCoords(e);return e};p.prototype.onEdit=function(e){var n=t.getSelectedArea(),r=t.getEditType(),i=e.shiftKey?true:false;n.dynamicEdit(n[r](e.pageX-n.delta.x,e.pageY-n.delta.y),i)};p.prototype.onEditStop=function(e){var n=t.getSelectedArea(),r=t.getEditType(),i=e.shiftKey?true:false;n.setParams(n.dynamicEdit(n[r](e.pageX-n.delta.x,e.pageY-n.delta.y),i));t.removeAllEvents()};p.prototype.remove=function(){t.removeNodeFromSvg(this.g)};p.prototype.select=function(){e.addClass(this.rect,"selected");return this};p.prototype.deselect=function(){e.removeClass(this.rect,"selected");return this};p.prototype.with_href=function(){e.addClass(this.rect,"with_href");return this};p.prototype.without_href=function(){e.removeClass(this.rect,"with_href");return this};p.prototype.toString=function(){var e=this.params.x+this.params.width,t=this.params.y+this.params.height;return''+this.alt+'"};p.createFromSaved=function(e){var n=e.coords,r=e.href,i=e.alt,s=e.title,o=new p(n[0],n[1]);o.setParams(o.dynamicDraw(n[2],n[3])).deselect();t.setIsDraw(false).resetNewArea();if(r){o.href=r}if(i){o.alt=i}if(s){o.title=s}};p.prototype.toJSON=function(){return{type:"rect",coords:[this.params.x,this.params.y,this.params.x+this.params.width,this.params.y+this.params.height],href:this.href,alt:this.alt,title:this.title}};var d=function(e,n){t.setIsDraw(true);this.params={cx:e,cy:n,radius:0};this.href="";this.alt="";this.title="";this.g=document.createElementNS("http://www.w3.org/2000/svg","g");this.circle=document.createElementNS("http://www.w3.org/2000/svg","circle");t.addNodeToSvg(this.g);this.g.appendChild(this.circle);this.g.obj=this;this.helpers={center:new h(this.g,e,n),top:new h(this.g,e,n),bottom:new h(this.g,e,n),left:new h(this.g,e,n),right:new h(this.g,e,n)};this.helpers.center.setAction("move");this.helpers.top.setAction("editTop").setCursor("n - resize");this.helpers.bottom.setAction("editBottom").setCursor("s - resize");this.helpers.left.setAction("editLeft").setCursor("w - resize");this.helpers.right.setAction("editRight").setCursor("e - resize");this.select().redraw();t.addObject(this)};d.prototype.setCoords=function(e){this.circle.setAttribute("cx",e.cx);this.circle.setAttribute("cy",e.cy);this.circle.setAttribute("r",e.radius);this.helpers.center.setCoords(e.cx,e.cy);this.helpers.top.setCoords(e.cx,e.cy-e.radius);this.helpers.right.setCoords(e.cx+e.radius,e.cy);this.helpers.bottom.setCoords(e.cx,e.cy+e.radius);this.helpers.left.setCoords(e.cx-e.radius,e.cy);return this};d.prototype.setParams=function(e){this.params.cx=e.cx;this.params.cy=e.cy;this.params.radius=e.radius;return this};d.prototype.redraw=function(){this.setCoords(this.params);return this};d.prototype.dynamicDraw=function(e,t){var n=this.params.cx,r=this.params.cy,i,s,o,u;e=e?e:n;t=t?t:r;i=Math.abs(n-e);s=Math.abs(r-t);o=Math.round(Math.sqrt(i*i+s*s));u={cx:n,cy:r,radius:o};this.setCoords(u);return u};d.prototype.onDraw=function(n){var r=t.getNewArea();r.dynamicDraw(e.rightX(n.pageX),e.rightY(n.pageY))};d.prototype.onDrawStop=function(n){var r=t.getNewArea();r.setParams(r.dynamicDraw(e.rightX(n.pageX),e.rightY(n.pageY))).deselect();t.removeAllEvents().setIsDraw(false).resetNewArea()};d.prototype.move=function(e,t){var n=Object.create(this.params);n.cx+=e;n.cy+=t;return n};d.prototype.editTop=function(e,t){var n=Object.create(this.params);n.radius-=t;return n};d.prototype.editBottom=function(e,t){var n=Object.create(this.params);n.radius+=t;return n};d.prototype.editLeft=function(e,t){var n=Object.create(this.params);n.radius-=e;return n};d.prototype.editRight=function(e,t){var n=Object.create(this.params);n.radius+=e;return n};d.prototype.dynamicEdit=function(e){if(e.radius<0){e.radius=Math.abs(e.radius)}this.setCoords(e);return e};d.prototype.onEdit=function(e){var n=t.getSelectedArea(),r=t.getEditType();n.dynamicEdit(n[r](e.pageX-n.delta.x,e.pageY-n.delta.y))};d.prototype.onEditStop=function(e){var n=t.getSelectedArea(),r=t.getEditType();n.setParams(n.dynamicEdit(n[r](e.pageX-n.delta.x,e.pageY-n.delta.y)));t.removeAllEvents()};d.prototype.remove=function(){t.removeNodeFromSvg(this.g)};d.prototype.select=function(){e.addClass(this.circle,"selected");return this};d.prototype.deselect=function(){e.removeClass(this.circle,"selected");return this};d.prototype.with_href=function(){e.addClass(this.circle,"with_href");return this};d.prototype.without_href=function(){e.removeClass(this.circle,"with_href");return this};d.prototype.toString=function(){return''+this.alt+'"};d.createFromSaved=function(e){var n=e.coords,r=e.href,i=e.alt,s=e.title,o=new d(n[0],n[1]);o.setParams(o.dynamicDraw(n[0],n[1]+n[2])).deselect();t.setIsDraw(false).resetNewArea();if(r){o.href=r}if(i){o.alt=i}if(s){o.title=s}};d.prototype.toJSON=function(){return{type:"circle",coords:[this.params.cx,this.params.cy,this.params.radius],href:this.href,alt:this.alt,title:this.title}};var v=function(e,n){t.setIsDraw(true);this.params=[e,n];this.href="";this.alt="";this.title="";this.g=document.createElementNS("http://www.w3.org/2000/svg","g");this.polygon=document.createElementNS("http://www.w3.org/2000/svg","polyline");t.addNodeToSvg(this.g);this.g.appendChild(this.polygon);this.g.obj=this;this.helpers=[new h(this.g,this.params[0],this.params[1])];this.helpers[0].setAction("pointMove").setCursor("pointer").setId(0);this.selected_point=-1;this.select().redraw();t.addObject(this)};v.prototype.setCoords=function(t){var n=t.join(" ");this.polygon.setAttribute("points",n);e.foreach(this.helpers,function(e,n){e.setCoords(t[2*n],t[2*n+1])});return this};v.prototype.setParams=function(e){this.params=e;return this};v.prototype.addPoint=function(e,t){var n=new h(this.g,e,t);n.setAction("pointMove").setCursor("pointer").setId(this.helpers.length);this.helpers.push(n);this.params.push(e,t);this.redraw();return this};v.prototype.redraw=function(){this.setCoords(this.params);return this};v.prototype.right_angle=function(e,t){var n=this.params[this.params.length-2],r=this.params[this.params.length-1],i=e-n,s=-(t-r),o=s/i;if(i>0&&s>0){if(o>2.414){e=n}else if(o<.414){t=r}else{Math.abs(i)>Math.abs(s)?e=n+s:t=r-i}}else if(i<0&&s>0){if(o<-2.414){e=n}else if(o>-.414){t=r}else{Math.abs(i)>Math.abs(s)?e=n-s:t=r+i}}else if(i<0&&s<0){if(o>2.414){e=n}else if(o<.414){t=r}else{Math.abs(i)>Math.abs(s)?e=n+s:t=r-i}}else if(i>0&&s<0){if(o<-2.414){e=n}else if(o>-.414){t=r}else{Math.abs(i)>Math.abs(s)?e=n-s:t=r+i}}return{x:e,y:t}};v.prototype.dynamicDraw=function(e,t,n){var r=[].concat(this.params);if(n){var i=this.right_angle(e,t);e=i.x;t=i.y}r.push(e,t);this.setCoords(r);return r};v.prototype.onDraw=function(n){var r=t.getNewArea();var i=n.shiftKey?true:false;r.dynamicDraw(e.rightX(n.pageX),e.rightY(n.pageY),i)};v.prototype.onDrawAddPoint=function(n){var r=e.rightX(n.pageX),i=e.rightY(n.pageY),s=t.getNewArea();if(n.shiftKey){var o=s.right_angle(r,i);r=o.x;i=o.y}s.addPoint(r,i)};v.prototype.onDrawStop=function(e){var n=t.getNewArea();if(e.type=="click"||e.type=="keydown"&&e.keyCode==13){if(n.params.length>=6){n.polyline=n.polygon;n.polygon=document.createElementNS("http://www.w3.org/2000/svg","polygon");n.g.replaceChild(n.polygon,n.polyline);n.setCoords(n.params).deselect();delete n.polyline;t.removeAllEvents().setIsDraw(false).resetNewArea()}}e.stopPropagation()};v.prototype.move=function(e,t){for(var n=0,r=this.params.length;n"};v.createFromSaved=function(e){var n=e.coords,r=e.href,i=e.alt,s=e.title,o=new v(n[0],n[1]);for(var u=2,a=n.length;u