adding modals

master
Mark MacKay 2021-04-28 12:36:17 -05:00
parent 862d628fad
commit 5142f634b5
19 changed files with 640 additions and 311 deletions

71
src/css/base.css Normal file
View File

@ -0,0 +1,71 @@
:root {
/* grays blues reds */
--z0:rgb(24, 32, 40); --a0: rgb(24, 32, 40); --b0:rgb(41, 23, 35);
--z1:rgb(36, 44, 52); --a1: rgb(34, 52, 68); --b1:rgb(68, 33, 52);
--z2:rgb(49, 56, 64); --a2: rgb(42, 74, 97); --b2:rgb(97, 42, 67);
--z3:rgb(63, 69, 76); --a3: rgb(47, 98, 127); --b3:rgb(129, 51, 79);
--z4:rgb(76, 83, 89); --a4: rgb(49, 122,159); --b4:rgb(161, 60, 88);
--z5:rgb(91, 97, 103); --a5: rgb(48, 148,191); --b5:rgb(193, 71, 94);
--z6:rgb(105, 111, 116); --a6: rgb(40, 174, 223); --b6:rgb(225, 84, 97);
--z7:rgb(120, 125, 130); --a7: rgb(14, 202, 255); --b7:rgb(255, 100, 96);
--z8:rgb(120, 125, 130); --a8: rgb(14, 202, 255); --b8:rgb(255, 100, 96);
--z9:rgb(137, 142, 146); --a9: rgb(89, 209, 254); --b9:rgb(255, 125, 116);
--z10:rgb(155, 159, 163); --a10:rgb(126, 216, 254); --b10:rgb(255, 147, 137);
--z11:rgb(174, 177, 180); --a11:rgb(155, 223, 253); --b11:rgb(255, 168, 159);
--z12:rgb(192, 195, 197); --a12:rgb(181, 230, 253); --b12:rgb(255, 189, 181);
--z13:rgb(211, 213, 214); --a13:rgb(205, 237, 252); --b13:rgb(255, 210, 204);
--z14:rgb(230, 231, 232); --a14:rgb(228, 243, 251); --b14:rgb(255, 230, 227);
--z15:rgb(250, 250, 250); --a15:rgb(250, 250, 250); --b15:rgb(250, 250, 250);
-webkit-font-smoothing: antialiased;
}
.inverted {
--z15:rgb(24, 32, 40); --a15:rgb(24, 32, 40); --b15:rgb(41, 23, 35);
--z14:rgb(36, 44, 52); --a14:rgb(34, 52, 68); --b14:rgb(68, 33, 52);
--z13:rgb(49, 56, 64); --a13:rgb(42, 74, 97); --b13:rgb(97, 42, 67);
--z12:rgb(63, 69, 76); --a12:rgb(47, 98, 127); --b12:rgb(129, 51, 79);
--z11:rgb(76, 83, 89); --a11:rgb(49, 122, 159); --b11:rgb(161, 60, 88);
--z10:rgb(91, 97, 103); --a10:rgb(48, 148, 191); --b10:rgb(193, 71, 94);
--z9:rgb(105, 111, 116); --a9:rgb(40, 174, 223); --b9 :rgb(225, 84, 97);
--z8:rgb(120, 125, 130); --a8:rgb(14, 202, 255); --b8 :rgb(255, 100, 96);
--z7:rgb(120, 125, 130); --a7:rgb(14, 202, 255); --b7 :rgb(255, 100, 96);
--z6:rgb(137, 142, 146); --a6:rgb(89, 209, 254); --b6 :rgb(255, 125, 116);
--z5:rgb(155, 159, 163); --a5:rgb(126, 216, 254); --b5 :rgb(255, 147, 137);
--z4:rgb(174, 177, 180); --a4:rgb(155, 223, 253); --b4 :rgb(255, 168, 159);
--z3:rgb(192, 195, 197); --a3:rgb(181, 230, 253); --b3 :rgb(255, 189, 181);
--z2:rgb(211, 213, 214); --a2:rgb(205, 237, 252); --b2 :rgb(255, 210, 204);
--z1:rgb(230, 231, 232); --a1:rgb(228, 243, 251); --b1 :rgb(255, 230, 227);
--z0:rgb(250, 250, 250); --a0:rgb(250, 250, 250); --b0 :rgb(250, 250, 250);
-webkit-font-smoothing: auto;
}
:root {
--x1: 4px;
--x2: 8px;
--x3: 12px;
--x4: 16px;
--x5: 20px;
--x6: 24px;
--x7: 28px;
--x8: 32px;
--x9: 36px;
--x10: 40px;
--x11: 44px;
--x12: 48px;
--x13: 52px;
--x14: 56px;
--x15: 60px;
--mono-font: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
--ui-font: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
--transition-duration: 333ms;
--transition-fast: 200ms;
}
a, a:link, a:active, a:visited {
color: var(--a6);
}
a:hover {
color: var(--a8);
}

74
src/css/dialog.css Normal file
View File

@ -0,0 +1,74 @@
#dialog_box {
display: none;
}
#dialog_box_overlay {
background: black;
opacity: .5;
height:100%;
left:0;
position:absolute;
top:0;
width:100%;
z-index: 6;
}
#dialog_content {
height: 95px;
padding: 32px;
overflow: auto;
text-align: left;
font-size: 16px;
}
#dialog_content h4 {
margin: 0;
}
#dialog_buttons input:last-child {
position: absolute;
left: 10px;
bottom: 10px;
}
#dialog_buttons input:first-child {
position: absolute;
right: 10px;
bottom: 10px;
}
#dialog_content.prompt {
height: 75px;
}
#dialog_content p {
line-height: 1.3em;
}
#dialog_container {
position: absolute;
left: 50%;
top: 50%;
width: 400px;
transform: translate(-50%, -50%);
position:fixed;
z-index:50001;
background: #fff;
}
#dialog_container, #dialog_content {
border-radius: 3px;
}
#dialog_buttons input[type=text] {
width: 90%;
display: block;
margin: 0 0 5px 11px;
}
#dialog_buttons input[type=button] {
margin: 0 1em;
}

View File

@ -27,7 +27,6 @@
font-size: 14px;
color: white;
font-weight: bold;
font-family: sans-serif;
}
.draginput label#resolution_label, .draginput label#seg_type_label {
@ -73,7 +72,6 @@
padding: 0 5px;
color: #333;
z-index: 10;
font-family: sans-serif;
font-weight: bold;
text-align: right;
padding-right: 10px;

25
src/css/keyboard.css Normal file
View File

@ -0,0 +1,25 @@
#shortcuts {
columns: 4;
}
.shortcut-keys {
display: flex;
margin: var(--x1) 0;
break-inside: avoid;
}
.shortcut-key {
text-transform: uppercase;
color: var(--z4);
border: solid var(--z4) 1px;
border-radius: var(--x1);
padding: 0 var(--x1);
margin: 2px;
font-size: 12px;
font-weight: 600;
}
.shortcut-name {
margin-left: var(--x2);
line-height: 160%;
white-space: nowrap;
}

View File

@ -1,4 +1,3 @@
#menu {
display: none;
position: absolute;
@ -111,7 +110,7 @@
.menu_list .menu_item:hover,
.menu_list .menu_item.push_button_pressed:hover {
background: rgba(0,0,0,0.1);
background: var(--a14);
color: #000;
}

View File

@ -1,5 +1,6 @@
/* Comment to prevent wrong concat */
body {
background: #3f3f3c;
font: 14px/120% -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
@ -331,26 +332,56 @@ div#font-selector .font-item:hover {
input[type=text].tuco, input[type=number].tuco {width: 150px;}
input[type=submit], input[type=button], button {
background: #4F80FF;
color: #fff;
border-radius: 3px;
padding: 7px 17px;
background: var(--a7);
color: var(--z1);
border-radius: var(--x1);
padding: var(--x2) var(--x4);
border: none;
line-height: 140%;
font-size: 14px;
font-weight: bold;
font-family: sans-serif;
font-size: 16px;
font-weight: 550;
cursor: pointer;
}
input[type=submit]:hover, button:hover {
box-shadow: inset 0 3px 10px rgba(255, 255, 255, 0.1),
inset 0 -3px 10px rgba(0, 0, 0, 0.2);
input[type=submit]:hover,
input[type=button]:hover,
button:hover {
background: var(--a9);
}
input[type=submit]:hover, button:hover {background: #2F84C1;}
input[type=submit]:active, button:active { box-shadow: inset 0 2px 2px rgba(0,0,0,0.2); border-bottom: solid rgba(255,255,255,0.1) 1px;}
input[type=submit]:active,
input[type=button]:active,
button:active {
box-shadow: 0 0 0 var(--x1) var(--a14);
outline: none;
}
input[type=submit]:focus,
input[type=button]:focus,
button:focus {
outline: none;
}
button.cancel, input.Cancel, input.cancel, input.jGraduate_Cancel, button.cancel {
-webkit-appearance: none;
background-color: var(--z10);
margin: 0;
}
button.cancel:hover, input.Cancel:hover, input.cancel:hover, input.jGraduate_Cancel:hover, button.cancel:hover {
background-color: var(--z11);
}
button.warning {
-webkit-appearance: none;
background-color: var(--b6);
color: var(--z15);
margin: 0;
}
button.warning:hover {
background-color: var(--b7);
}
#tools_left {
position: absolute;
@ -591,164 +622,14 @@ input[type=file] {
background-color: #F4E284;
}
#svg_source_editor {
display: none;
}
#svg_source_editor #svg_source_overlay {
position: absolute;
top: 0px;
right: 0px;
left: 0px;
bottom: 0px;
background-color: black;
opacity: 0.6;
z-index: 5;
}
#svg_source_editor #svg_source_container {
position: absolute;
top: 30px;
left: 100px;
right: 100px;
bottom: 30px;
background-color: #fff;
border-radius: 3px;
opacity: 1.0;
text-align: center;
z-index: 6;
padding: 15px 0;
}
#svg_source_editor form {
position: absolute;
display: block;
top: 15px;
bottom: 55px;
left: 15px;
right: 12px;
padding: 5px;
font-size: 12px;
}
#svg_source_textarea {
width: 100%;
height: 100%;
line-height: 140%;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 12px;
}
#svg_source_editor #tool_source_back {
position: absolute;
bottom: 45px;
left: 15px;
right: 15px;
}
#svg_source_editor #tool_source_back #tool_source_save {
display: block;
position: absolute;
right: 0;
}
#svg_source_editor #tool_source_back #tool_source_cancel {
display: block;
position: absolute;
left: 0;
}
button.cancel, input.Cancel, input.cancel, input.jGraduate_Cancel, button.cancel {
-webkit-appearance: none;
background-color: #999;
box-shadow: 0 0 1px rgba(0,0,0,0.5);
margin: 0;
}
.toolbar_button button .svg_icon {
display: none;
}
#dialog_box {
display: none;
}
#dialog_box_overlay {
background: black;
opacity: .5;
height:100%;
left:0;
position:absolute;
top:0;
width:100%;
z-index: 6;
}
#dialog_content {
height: 95px;
margin: 10px 10px 5px 10px;
overflow: auto;
text-align: left;
font-size: 13px;
}
#dialog_buttons input:last-child {
background: #999 !important;
position: absolute;
left: 10px;
bottom: 10px;
}
#dialog_buttons input:first-child {
position: absolute;
right: 10px;
bottom: 10px;
}
#dialog_content.prompt {
height: 75px;
}
#dialog_content p {
margin: 10px;
line-height: 1.3em;
}
#dialog_container {
position: absolute;
left: 50%;
top: 50%;
width: 300px;
margin-left: -150px;
height: 150px;
margin-top: -80px;
position:fixed;
z-index:50001;
background: #fff;
}
#dialog_container, #dialog_content {
border-radius: 3px;
}
#dialog_buttons input[type=text] {
width: 90%;
display: block;
margin: 0 0 5px 11px;
}
#dialog_buttons input[type=button] {
margin: 0 1em;
}
.invisible {
visibility: none;
}
.touch .shortcut {
display: none;
}

45
src/css/modal.css Normal file
View File

@ -0,0 +1,45 @@
.modal {
background: rgba(50,50,50,0.8);
position: absolute;
z-index: 1000;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
font-size: 16px;
line-height: 150%;
}
.modal.hidden {
opacity: 0;
pointer-events: none;
transition: opacity 300ms ease;
}
.modal-item {
background-color: white;
position: relative;
border-radius: var(--x1);
padding: var(--x12);
max-width: 600px;
margin: 32px;
}
.modal-item.modal-item-wide {
max-width: none;
width: 900px;
}
.modal-item.modal-item-source {
height: 504px;
max-width: none;
width: 704px;
}
.modal h1:first-child {
margin-top: 0;
}

45
src/css/source.css Normal file
View File

@ -0,0 +1,45 @@
#svg_source_editor {
position: relative;
width: 800px;
height: 600px;
margin: -48px;
}
#svg_source_container {
width: 800px;
position: relative;
height: 100%;
}
#svg_source_editor form {
position: absolute;
top: 0;
bottom: 55px;
left: 0;
right: 0;
font-size: 14px;
background-color: #eee;
border-radius: 8px 8px 0 0;
}
#svg_source_textarea {
width: calc(100% - 64px);
height: calc(100% - 64px);
line-height: 140%;
font-family: var(--mono-font);
font-size: 14px;
color: #555;
border: none;
padding: 32px;
background-color: transparent;
}
#svg_source_editor #tool_source_back {
position: absolute;
display: flex;
justify-content: space-between;
bottom: 0;
left: 0;
right: 0;
padding: var(--x2) var(--x2);
}

View File

@ -11,6 +11,7 @@
<meta name="description" content="Method Draw is an open source SVG editor for the web, you can use it online without signing up.">
<!-- build:css all.css -->
<link rel="stylesheet" href="css/base.css" type="text/css"/>
<link rel="stylesheet" href="css/jpicker.css" type="text/css"/>
<link rel="stylesheet" href="css/jgraduate.css" type="text/css"/>
<link rel="stylesheet" href="css/fonts.css" type="text/css"/>
@ -22,6 +23,10 @@
<link rel="stylesheet" href="css/color-tool.css" type="text/css"/>
<link rel="stylesheet" href="css/context-menu.css" type="text/css"/>
<link rel="stylesheet" href="css/shapelib.css" type="text/css"/>
<link rel="stylesheet" href="css/modal.css" type="text/css"/>
<link rel="stylesheet" href="css/source.css" type="text/css"/>
<link rel="stylesheet" href="css/keyboard.css" type="text/css"/>
<link rel="stylesheet" href="css/dialog.css" type="text/css"/>
<link rel="stylesheet" href="css/method-draw.css" type="text/css"/>
<!-- endbuild -->
</head>
@ -59,10 +64,11 @@
</svg>
</div>
<div class="menu_list">
<div id="tool_about" class="menu_item">About this Editor...</div>
<div id="modal_about" class="menu_item" data-action="about">About this app...</div>
<div class="separator"></div>
<div id="tool_about" class="menu_item">Preferences...</div>
<div id="tool_about" class="menu_item">Keyboard Shortcuts...</div>
<div id="modal_preferences" class="menu_item" data-action="configure">Configure...</div>
<div id="modal_shortcuts" class="menu_item" data-action="shortcuts">Keyboard Shortcuts...</div>
<div id="modal_donate" class="menu_item" data-action="donate">Donate or sponsor...</div>
</div>
</a>
@ -119,7 +125,7 @@
<div class="menu_item push_button_pressed" id="tool_rulers">View Rulers <span class="shortcut">⇧R</span></div>
<div class="menu_item" id="tool_wireframe">View Wireframe</div>
<div class="separator"></div>
<div class="menu_item" id="tool_source">Source... <span class="shortcut">⌘U</span></div>
<div class="menu_item" id="tool_source" data-action="source">Source... <span class="shortcut">⌘U</span></div>
</div>
</div>
</div>
@ -629,22 +635,7 @@
</div> <!-- svg_editor -->
<div id="svg_source_editor">
<div id="svg_source_overlay" class="overlay"></div>
<div id="svg_source_container">
<div id="save_output_btns">
<p id="copy_save_note">Copy the contents of this box into a text editor, then save the file with a .svg extension.</p>
<button id="copy_save_done">Done</button>
</div>
<form>
<textarea id="svg_source_textarea" spellcheck="false"></textarea>
</form>
<div id="tool_source_back" class="toolbar_button">
<button id="tool_source_cancel" class="cancel">Cancel</button>
<button id="tool_source_save" class="ok">Apply Changes</button>
</div>
</div>
</div>
<div id="dialog_box">
<div id="dialog_box_overlay"></div>

View File

@ -1,4 +1,62 @@
MD.Keyboard = function(){
const keys = {
"v": { name: "Select tool", cb: ()=> state.set("canvasMode", "select") },
"q": { name: "Freehand tool", cb: ()=> state.set("canvasMode", "fhpath") },
"l": { name: "Line tool", cb: ()=> state.set("canvasMode", "fhplineath")},
"r": { name: "Rectangle tool", cb: ()=> state.set("canvasMode", "rect")},
"o": { name: "Ellipse tool", cb: ()=> state.set("canvasMode", "ellipse")},
"s": { name: "Shape tool", cb: ()=> state.set("canvasMode", "shapelib")},
"p": { name: "Path tool", cb: ()=> state.set("canvasMode", "path")},
"t": { name: "Text tool", cb: ()=> state.set("canvasMode", "text")},
"z": { name: "Zoom tool", cb: ()=> state.set("canvasMode", "zoom")},
"e": { name: "Eyedropper tool", cb: ()=> state.set("canvasMode", "eyedropper")},
"x": { name: "Switch fill/stroke", cb: ()=> editor.switchPaint()},
"alt": { name: false, cb: ()=> $("#workarea").toggleClass("out", canvasMode === "zoom" )},
"cmd_s": { name: "Save SVG File", cb: ()=> editor.save()},
"cmd_z": { name: "Undo", cb: ()=> editor.undo()},
"cmd_y": { name: "Redo", cb: ()=> editor.redo()},
"cmd_shift_z": { name: "Redo", cb: ()=> editor.redo()},
"cmd_c": { name: "Copy", cb: ()=> editor.copySelected()},
"cmd_x": { name: "Cut", cb: ()=> editor.cutSelected()},
"cmd_v": { name: "Paste", cb: ()=> editor.pasteSelected()},
"cmd_d": { name: "Duplicate", cb: ()=> editor.duplicateSelected()},
"cmd_u": { name: "View source", cb: ()=> editor.source()},
"cmd_a": { name: "Select All", cb: ()=> svgCanvas.selectAllInCurrentLayer()},
"cmd_b": { name: "Set bold text", cb: ()=> editor.text.setBold()},
"cmd_i": { name: "Set italic text", cb: ()=> editor.text.setItalic()},
"cmd_g": { name: "Group selected", cb: ()=> editor.groupSelected()},
"cmd_shift_g": { name: "Ungroup", cb: ()=> editor.ungroupSelected()},
"cmd_o": { name: "Open SVG File", cb: ()=> editor.import.open()},
"cmd_k": { name: "Place image", cb: ()=> editor.import.place()},
"backspace": { name: "Delete", cb: ()=> editor.deleteSelected()},
"ctrl_arrowleft": { name: "Rotate -1deg", cb: ()=> editor.rotateSelected(0,1)},
"ctrl_arrowright": { name: "Rotate +1deg", cb: ()=> editor.rotateSelected(1,1)},
"ctrl_shift_arrowleft": { name: "Rotate -5deg", cb: ()=> editor.rotateSelected(0,5)},
"ctrl_shift_arrowright": { name: "Rotate +5deg ", cb: ()=> editor.rotateSelected(1,5)},
"shift_o": { name: "Next item", cb: ()=> svgCanvas.cycleElement(0)},
"shift_p": { name: "Prev item", cb: ()=> svgCanvas.cycleElement(1)},
"shift_r": { name: "Show/hide rulers", cb: ()=> editor.rulers.toggleRulers()},
"cmd_+": { name: "Zoom in", cb: ()=> editor.zoom.multiply(1.5)},
"cmd_-": { name: "Zoom out", cb: ()=> editor.zoom.multiply(0.75)},
"cmd_=": { name: "Actual size", cb: ()=> editor.zoom.reset()},
"arrowleft": { name: "Nudge left", cb: ()=> editor.moveSelected(-1,0)},
"arrowright": { name: "Nudge right", cb: ()=> editor.moveSelected(1,0)},
"arrowup": { name: "Nudge up", cb: ()=> editor.moveSelected(0,-1)},
"arrowdown": { name: "Nudge down", cb: ()=> editor.moveSelected(0,1)},
"shift_arrowleft": {name: "Jump left", cb: () => editor.moveSelected(state.get("canvasSnapStep") * -1, 0)},
"shift_arrowright": {name: "Jump right", cb: () => editor.moveSelected(state.get("canvasSnapStep") * 1, 0)},
"shift_arrowup": {name: "Jump up", cb: () => editor.moveSelected(0, state.get("canvasSnapStep") * -1)},
"shift_arrowdown": {name: "Jump down", cb: () => editor.moveSelected(0, state.get("canvasSnapStep") * 1)},
"cmd_arrowup":{ name: "Bring forward", cb: () => editor.moveUpSelected()},
"cmd_arrowdown":{ name: "Send backward", cb: () => editor.moveDownSelected()},
"cmd_shift_arrowup":{ name: "Bring to front", cb: () => editor.moveToTopSelected()},
"cmd_shift_arrowdown":{ name: "Send to back", cb: () => editor.moveToBottomSelected()},
"escape": { name: false, cb: ()=> editor.escapeMode()},
"enter": { name: false, cb: ()=> editor.escapeMode()},
" ": { name: "Pan canvas", cb: ()=> editor.pan.startPan()},
};
document.addEventListener("keydown", function(e){
if ($("#color_picker").is(":visible")) return e;
const modKey = !svgedit.browser.isMac() ? "ctrlKey" : "metaKey";
@ -6,67 +64,18 @@ MD.Keyboard = function(){
const shift = e.shiftKey ? "shift_" : "";
const key = cmd + shift + e.key.toLowerCase();
const canvasMode = state.get("canvasMode");
const keys = {
v: ()=> state.set("canvasMode", "select"),
q: ()=> state.set("canvasMode", "fhpath"),
l: ()=> state.set("canvasMode", "line"),
r: ()=> state.set("canvasMode", "rect"),
o: ()=> state.set("canvasMode", "ellipse"),
s: ()=> state.set("canvasMode", "shapelib"),
p: ()=> state.set("canvasMode", "path"),
t: ()=> state.set("canvasMode", "text"),
z: ()=> state.set("canvasMode", "zoom"),
e: ()=> state.set("canvasMode", "eyedropper"),
x: ()=> editor.switchPaint(),
"alt": ()=> { if (canvasMode === "zoom") $("#workarea").addClass("out") },
"cmd_s": ()=> editor.save(),
"cmd_z": ()=> editor.undo(),
"cmd_shift_z": ()=> editor.redo(),
"cmd_c": ()=> editor.copySelected(),
"cmd_x": ()=> editor.cutSelected(),
"cmd_v": ()=> editor.pasteSelected(),
"cmd_d": ()=> editor.duplicateSelected(),
"cmd_u": ()=> editor.modal.viewSource(),
"cmd_a": ()=> svgCanvas.selectAllInCurrentLayer(),
"cmd_b": ()=> editor.text.setBold(),
"cmd_i": ()=> editor.text.setItalic(),
"cmd_g": ()=> editor.groupSelected(),
"cmd_o": ()=> editor.import.open(),
"cmd_k": ()=> editor.import.place(),
"cmd_shift_g": ()=> editor.ungroupSelected(),
"backspace": () => editor.deleteSelected(),
"ctrl_arrowleft": () => editor.rotateSelected(0,1),
"ctrl_arrowright": () => editor.rotateSelected(1,1),
"ctrl_shift_arrowleft": () => editor.rotateSelected(0,5),
"ctrl_shift_arrowright": () => editor.rotateSelected(1,5),
"shift_o": () => svgCanvas.cycleElement(0),
"shift_p": () => svgCanvas.cycleElement(1),
"shift_r": () => editor.rulers.toggleRulers(),
"cmd_+": () => editor.zoom.multiply(1.5),
"cmd_=": () => editor.zoom.multiply(1.5),
"cmd_-": () => editor.zoom.multiply(0.75),
"arrowleft": () => editor.moveSelected(-1,0),
"arrowright": () => editor.moveSelected(1,0),
"arrowup": () => editor.moveSelected(0,-1),
"arrowdown": () => editor.moveSelected(0,1),
"cmd_arrowup": () => editor.moveUpSelected(),
"cmd_arrowdown": () => editor.moveDownSelected(),
"cmd_shift_arrowup": () => editor.moveToTopSelected(),
"cmd_shift_arrowdown": () => editor.moveToBottomSelected(),
"shift_arrowleft": () => editor.moveSelected(state.get("canvasSnapStep") * -1, 0),
"shift_arrowright": () => editor.moveSelected(state.get("canvasSnapStep") * 1, 0),
"shift_arrowup": () => editor.moveSelected(0, state.get("canvasSnapStep") * -1),
"shift_arrowdown": () => editor.moveSelected(0, state.get("canvasSnapStep") * 1),
"escape": () => editor.escapeMode(),
"enter": () => editor.escapeMode(),
" ": ()=> editor.pan.startPan(),
};
const modalIsOpen = Object.values(editor.modal).filter((modal) => {
const isHidden = modal.el.classList.contains("hidden");
if (!isHidden && key === "cmd_enter") modal.confirm();
if (!isHidden && key === "escape") modal.close();
return !isHidden;
}).length;
// keyboard shortcut exists
if (keys[key]) {
if (editor.modal.isVisible()) return;
// keyboard shortcut exists for app
if (!modalIsOpen && keys[key]) {
e.preventDefault();
keys[key]();
keys[key].cb();
}
});
@ -85,4 +94,41 @@ MD.Keyboard = function(){
})
// modal shortcuts
const shortcutEl = document.getElementById("shortcuts");
const docFrag = document.createDocumentFragment();
for (const key in keys) {
const name = keys[key].name;
if (!name) continue;
const shortcut = document.createElement("div");
shortcut.classList.add("shortcut")
const chords = key.split("_");
const shortcutKeys = document.createElement("div");
shortcutKeys.classList.add("shortcut-keys")
chords.forEach(key => {
const shortcutKey = document.createElement("div");
shortcutKey.classList.add("shortcut-key");
if (key === "arrowright") key = "→";
if (key === "arrowleft") key = "←";
if (key === "arrowup") key = "↑";
if (key === "arrowdown") key = "↓";
if (key === " ") key = "SPACEBAR";
if (key === "shift") key = "⇧";
if (key === "cmd") key = svgedit.browser.isMac ? "⌘" : "Ctrl";
shortcutKey.textContent = key;
shortcutKeys.appendChild(shortcutKey);
shortcut.appendChild(shortcutKeys);
});
const shortcutName = document.createElement("div");
shortcutName.classList.add("shortcut-name");
shortcutName.textContent = name;
shortcutKeys.appendChild(shortcutName);
docFrag.appendChild(shortcutKeys);
}
shortcutEl.appendChild(docFrag);
}

View File

@ -8,7 +8,9 @@ MD.Menu = function(){
$('#tool_topath').on("click", editor.convertToPath);
$('#tool_group').on("click", editor.groupSelected);
$('#tool_ungroup').on("click", editor.ungroupSelected);
$('#tool_ungroup').on("click", editor.ungroupSelected);
if (window.location.host !== "editor.method.ac")
$('#modal_donate').hide();
// top dropdown menus
$('.menu_title')
.on('mousedown', function() {

View File

@ -1,66 +1,47 @@
MD.Modal = function(){
MD.Modal = function(config){
var orig_source = false;
const el = document.createElement("div");
el.classList.add("modal", "hidden");
$("button.cancel, .overlay").on("click", cancelOverlays);
$("#tool_source").on("click", viewSource);
$("#tool_source_save").on("click", saveSource);
const item = document.createElement("div");
item.innerHTML = config.html;
item.classList.add("modal-item");
el.appendChild(item);
function viewSource(e, forSaving){
editor.menu.flash($('#view_menu'));
$('#save_output_btns').toggle(!!forSaving);
$('#tool_source_back').toggle(!forSaving);
orig_source = svgCanvas.getSvgString();
$('#svg_source_textarea').val(orig_source);
$('#svg_source_editor').fadeIn();
$('#svg_source_textarea').focus().select();
};
el.addEventListener("click", close);
item.addEventListener("click", function(e){
e.stopPropagation();
});
function saveSource(){
var saveChanges = function() {
svgCanvas.clearSelection();
$('#svg_source_editor').hide();
$('#svg_source_textarea').blur();
editor.zoom.multiply(1);
editor.rulers.update();
editor.paintBox.fill.prep();
editor.paintBox.stroke.prep();
}
document.body.appendChild(el);
if (!svgCanvas.setSvgString($('#svg_source_textarea').val())) {
$.confirm("There were parsing errors in your SVG source.\nRevert back to original SVG source?", function(ok) {
if(!ok) return false;
saveChanges();
});
} else {
saveChanges();
}
};
function cancelOverlays() {
$('#dialog_box').hide();
if (orig_source && orig_source !== $('#svg_source_textarea').val()) {
$.confirm("Ignore changes made to SVG source?", function(ok) {
if(ok) {
$('#svg_source_editor').hide();
$('#svg_source_textarea').blur();
};
});
} else {
$('#svg_source_editor').hide();
$('#svg_source_textarea').blur();
}
};
function isVisible(){
return $('#svg_source_editor').is(":visible");
function open(){
el.classList.remove("hidden");
}
this.cancelOverlays = cancelOverlays;
this.isVisible = isVisible;
this.viewSource = viewSource;
this.saveSource = saveSource;
function close(){
el.classList.add("hidden");
}
function confirm(cb){
if (cb) cb();
close();
}
this.open = open;
this.close = close;
this.confirm = confirm;
this.cb = config.cb || function(){};
this.el = el;
if (config.js) {
const el = this.el;
config.js(el);
}
return this
}

View File

@ -7,7 +7,7 @@ const dao = [
label: "Canvas ID",
type: "id",
default: "",
private: false,
private: true,
save: true
},

View File

@ -9,14 +9,14 @@
var box = $('#dialog_box'), btn_holder = $('#dialog_buttons');
var dbox = function(type, msg, callback, defText) {
$('#dialog_content').html('<p>'+msg.replace(/\n/g,'</p><p>')+'</p>')
$('#dialog_content').html(msg)
.toggleClass('prompt',(type==='prompt'));
btn_holder.empty();
var ok = $('<input type="button" value="OK">').appendTo(btn_holder);
if(type != 'alert') {
$('<input type="button" value="Cancel">')
$('<input type="button" class="cancel" value="Cancel">')
.appendTo(btn_holder)
.on("click touchstart", function() { box.hide();callback(false)});
}

View File

@ -9,7 +9,7 @@ MD.Editor = function(){
function clear(){
var dims = state.get("canvasSize");
$.confirm("<strong>Do you want to clear the drawing?</strong>\nThis will also erase your undo history", function(ok) {
$.confirm("<h4>Do you want to clear the drawing?</h4><p>This will also erase your undo history</p>", function(ok) {
if(!ok) return;
state.set("canvasMode", "select")
svgCanvas.clear();
@ -135,6 +135,7 @@ MD.Editor = function(){
};
function escapeMode(){
for (key in editor.modal) editor.modal[key].close();
state.set("canvasMode", "select");
state.set("canvasContent", svgCanvas.getSvgString())
}
@ -310,6 +311,29 @@ MD.Editor = function(){
}
}
function about(){
editor.modal.about.open();
}
function configure(){
//const props = dao.filter
editor.modal.configure.open();
}
function shortcuts(){
editor.modal.shortcuts.open();
}
function donate(){
editor.modal.donate.open();
}
function source(){
const textarea = editor.modal.source.el.querySelector("textarea");
textarea.value = svgCanvas.getSvgString();
editor.modal.source.open();
}
this.selectedChanged = selectedChanged;
this.elementChanged = elementChanged;
this.changeAttribute = changeAttribute;
@ -340,6 +364,12 @@ MD.Editor = function(){
this.toggleWireframe = toggleWireframe;
this.groupSelected = groupSelected;
this.ungroupSelected = ungroupSelected;
this.about = about;
this.configure = configure;
this.shortcuts = shortcuts;
this.donate = donate;
this.source = source;
this.export = function(){
if(window.canvg) {
svgCanvas.rasterExport();

62
src/js/modalbackup.js Normal file
View File

@ -0,0 +1,62 @@
var orig_source = false;
$("button.cancel, .overlay").on("click", cancelOverlays);
$("#tool_source").on("click", viewSource);
$("#tool_source_save").on("click", saveSource);
function viewSource(e, forSaving){
editor.menu.flash($('#view_menu'));
$('#save_output_btns').toggle(!!forSaving);
$('#tool_source_back').toggle(!forSaving);
orig_source = svgCanvas.getSvgString();
$('#svg_source_textarea').val(orig_source);
$('#svg_source_editor').fadeIn();
$('#svg_source_textarea').focus().select();
};
function saveSource(){
var saveChanges = function() {
svgCanvas.clearSelection();
$('#svg_source_editor').hide();
$('#svg_source_textarea').blur();
editor.zoom.multiply(1);
editor.rulers.update();
editor.paintBox.fill.prep();
editor.paintBox.stroke.prep();
}
if (!svgCanvas.setSvgString($('#svg_source_textarea').val())) {
$.confirm("There were parsing errors in your SVG source.\nRevert back to original SVG source?", function(ok) {
if(!ok) return false;
saveChanges();
});
} else {
saveChanges();
}
};
function cancelOverlays() {
$('#dialog_box').hide();
if (orig_source && orig_source !== $('#svg_source_textarea').val()) {
$.confirm("Ignore changes made to SVG source?", function(ok) {
if(ok) {
$('#svg_source_editor').hide();
$('#svg_source_textarea').blur();
};
});
} else {
$('#svg_source_editor').hide();
$('#svg_source_textarea').blur();
}
};
function isVisible(){
return $('#svg_source_editor').is(":visible");
}
this.cancelOverlays = cancelOverlays;
this.isVisible = isVisible;
this.viewSource = viewSource;
this.saveSource = saveSource;

View File

@ -1,6 +1,89 @@
// globals
const svgCanvas = new $.SvgCanvas(document.getElementById("svgcanvas"));
const editor = new MD.Editor();
editor.modal = {
about: new MD.Modal({
html: `
<h1>About this application</h1>
<p>Method Draw is a simple <a href="https://github.com/methodofaction/Method-Draw">open source</a> vector drawing application. Method Draw was forked from <a href="https://github.com/SVG-Edit/svgedit">SVG-Edit</a> several years ago with the goal of improving and modernizing the interface.</p>
<p>At this time (2021), the author (<a href="http://method.ac/writing">Mark MacKay</a>) is working on improving stability and improving the codebase, which contains a lot of legacy practices. The goal is to create a vector editor suitable for simple graphic design tasks.</p>
`
}),
source: new MD.Modal({
html: `
<div id="svg_source_editor">
<div id="svg_source_overlay" class="overlay"></div>
<div id="svg_source_container">
<form>
<textarea id="svg_source_textarea" spellcheck="false"></textarea>
</form>
<div id="tool_source_back" class="toolbar_button">
<button id="tool_source_cancel" class="cancel">Cancel</button>
<button id="tool_source_save" class="ok">Apply Changes</button>
</div>
</div>
</div>`,
js: function(el){
el.children[0].classList.add("modal-item-source");
el.querySelector("#tool_source_save").addEventListener("click", function(){
var saveChanges = function() {
svgCanvas.clearSelection();
$('#svg_source_textarea').blur();
editor.zoom.multiply(1);
editor.rulers.update();
editor.paintBox.fill.prep();
editor.paintBox.stroke.prep();
editor.modal.source.close();
}
if (!svgCanvas.setSvgString($('#svg_source_textarea').val())) {
$.confirm("There were parsing errors in your SVG source.\nRevert back to original SVG source?", function(ok) {
if(!ok) return false;
saveChanges();
});
} else {
saveChanges();
}
})
el.querySelector("#tool_source_cancel").addEventListener("click", function(){
editor.modal.source.close();
});
}
}),
configure: new MD.Modal({
html: `
<h1>Configuration</h1>
<div id="configuration">
<button class="warning">Erase all data</button>
</div>
</div>`,
js: function(el){
const input = el.querySelector("#configuration button.warning");
input.addEventListener("click", function(){
state.clean();
})
}
}),
donate: new MD.Modal({
html: `
<h1>Donate</h1>
<p>Lorem ipsum dolor sit amet</p>`
}),
shortcuts: new MD.Modal({
html: `
<h1>Shortcuts</h1>
<div id="shortcuts"></div>`,
js: function(el){
el.children[0].classList.add("modal-item-wide");
}
})
};
editor.source();
editor.keyboard = new MD.Keyboard();
editor.menu = new MD.Menu();
editor.toolbar = new MD.Toolbar();
editor.rulers = new MD.Rulers();
@ -14,9 +97,8 @@ editor.paintBox = {
canvas: new MD.PaintBox('#canvas_color', 'canvas')
};
editor.palette = new MD.Palette();
editor.keyboard = new MD.Keyboard();
editor.pan = new MD.Pan();
editor.modal = new MD.Modal();
editor.import = new MD.Import();
editor.contextMenu = new MD.ContextMenu();

View File

@ -34,7 +34,7 @@ function State(){
this.clean = (warn = true) => {
if (warn) {
const confirmed = confirm("Deletes all configuration and text, are you sure?");
const confirmed = confirm("Clears all editor configuration and canvas, are you sure?");
if (!confirmed) return;
}

View File

@ -94,9 +94,6 @@ var clearSvgContentElement = canvas.clearSvgContentElement = function() {
"xmlns:xlink": xlinkns
}).appendTo(svgroot);
// TODO: make this string optional and set by the client
var comment = svgdoc.createComment(" Created with Method Draw - http://github.com/duopixel/Method-Draw/ ");
svgcontent.appendChild(comment);
};
clearSvgContentElement();