diff --git a/LAYOUT.md b/LAYOUT.md new file mode 100644 index 0000000..3cb774b --- /dev/null +++ b/LAYOUT.md @@ -0,0 +1,42 @@ +## default Mode + +### File +- New: `CmdOrCtrl+N` +- Open: `CmdOrCtrl+O` +- Save: `CmdOrCtrl+S` + +### Edit +- Insert: `I` +- Copy: `CmdOrCtrl+C` +- Paste: `CmdOrCtrl+V` +- Undo: `CmdOrCtrl+Z` +- Delete: `Backspace` +- Move Up: `Up` +- Move Down: `Down` +- Move Left: `Left` +- Move Right: `Right` +- Deselect: `Esc` + +### Stroke +- Line: `A` +- Arc: `S` +- Arc Rev: `D` +- Bezier: `F` +- Connect: `Z` + +### Effect +- Thicker: `}` +- Thinner: `{` +- Thicker +5: `]` +- Thinner -5: `[` +- Linecap: `Y` +- Mirror: `Space` +- Fill: `G` + +### View +- Tools: `U` +- Grid: `H` +- Control Points: `J` +- Expert Mode: `:` + + diff --git a/LAYOUT.svg b/LAYOUT.svg index dbd2198..0741e31 100644 --- a/LAYOUT.svg +++ b/LAYOUT.svg @@ -1 +1 @@ -ESCDESELECTDOCUMENT1234567890-+BACKSPACEDELETERESETTABQQUITWERTYUIOOPENP[THINNER]THICKER|CAPSALINESARCSAVEDARC REVFBEZIERGFILLHGRIDHIDEJCONTROLKL;TOOLS'ENTERINSERTFULLSCRESHIFTZCONNECTUNDOXCCOPYVPASTEBNNEWM,ABOUT.INSPECT/LINECAPCAPSLOCKCTRLCMDALTSPACEMIRRORCTRLPNFNALT \ No newline at end of file +ESCDESELECTDOCUMENT1234567890-PLUSBACKSPACEDELETERESETTABQQUITWERTYLINECAPUTOOLSIINSERTOOPENP[THINNER]THICKER|CAPSALINESARCSAVEDARC REVFBEZIERGFILLHGRIDHIDEJCONTROLKL;'ENTERFULLSCRESHIFTZCONNECTUNDOXCCOPYVPASTEBNNEWM,ABOUT.INSPECT/CAPSLOCKCTRLCMDALTSPACEMIRRORCTRLPNFNALT \ No newline at end of file diff --git a/README.md b/README.md index 47382c5..37f369c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,48 @@ Clicking on the canvas will insert control points, up to 3CPs. CPs can be moved ## Controls - +## default Mode + +### File +- New: `CmdOrCtrl+N` +- Open: `CmdOrCtrl+O` +- Save: `CmdOrCtrl+S` + +### Edit +- Insert: `I` +- Copy: `CmdOrCtrl+C` +- Paste: `CmdOrCtrl+V` +- Undo: `CmdOrCtrl+Z` +- Delete: `Backspace` +- Move Up: `Up` +- Move Down: `Down` +- Move Left: `Left` +- Move Right: `Right` +- Deselect: `Esc` + +### Stroke +- Line: `A` +- Arc: `S` +- Arc Rev: `D` +- Bezier: `F` +- Connect: `Z` + +### Effect +- Thicker: `}` +- Thinner: `{` +- Thicker +5: `]` +- Thinner -5: `[` +- Linecap: `Y` +- Mirror: `Space` +- Fill: `G` + +### View +- Tools: `U` +- Grid: `H` +- Control Points: `J` +- Expert Mode: `:` + + ## Extras diff --git a/sources/index.html b/sources/index.html index 1bd18e2..4097e4f 100644 --- a/sources/index.html +++ b/sources/index.html @@ -1,5 +1,8 @@ + + + @@ -9,8 +12,6 @@ - - diff --git a/sources/links/fonts.css b/sources/links/fonts.css index 5740035..b6b11ea 100644 --- a/sources/links/fonts.css +++ b/sources/links/fonts.css @@ -1,20 +1,6 @@ @font-face { - font-family: 'input_mono_regular'; - src: url('../media/fonts/input_mono_regular.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'input_mono_medium'; - src: url('../media/fonts/input_mono_medium.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: 'input_mono_thin'; - src: url('../media/fonts/input_mono_thin.ttf') format('truetype'); - font-weight: normal; - font-style: normal; -} + font-family: 'din_regular'; + src: url('../media/fonts/din_regular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/sources/links/main.css b/sources/links/main.css index 43aec38..38968be 100644 --- a/sources/links/main.css +++ b/sources/links/main.css @@ -1,15 +1,17 @@ -body { padding: 5px; font-family: 'input_mono_regular'; -webkit-user-select: none; overflow: hidden; padding-left:5px;} +body { padding: 5px; font-family: 'din_regular'; -webkit-user-select: none; overflow: hidden; padding-left:5px;} #app { display: flex; flex-direction: column; align-items: center;} -#wrapper { padding: 25px; padding-bottom: 15px; -webkit-app-region: drag;} +#wrapper { padding: 25px; padding-bottom: 15px; -webkit-app-region: drag; padding-left:15px;} #dotgrid { margin:0px auto; position:relative; overflow: hidden; padding:10px;-webkit-app-region: no-drag; width:310px; height:310px; } -#cursor { opacity: 1; transition: all 50ms; width:8px; height:8px; position:absolute; z-index:25; border-radius:5px; border:1px solid black;} -#cursor_coord { font-size:10px; z-index: 10000; margin-left:15px; margin-top:-2px;} -#cursor_coord.left { margin-left:-110px; text-align: right; width:100px; } +#cursor { opacity: 1; transition: all 50ms; width:6px; height:6px; position:absolute; z-index:25; border-radius:5px; border:2px solid black;} + #cursor_from { width:4px; height:4px; margin-top:2px; margin-left:2px; position:absolute; z-index:2500; border-radius:10px; left:-100px;border:1px solid black;} #cursor_to { width:4px; height:4px; margin-top:2px; margin-left:2px; position:absolute; z-index:2500; border-radius:10px; left:-100px; border:1px solid black;} #cursor_end { width:4px; height:4px; margin-top:2px; margin-left:2px; position:absolute; z-index:2500; border-radius:10px; left:-100px; border:1px solid black;} +#cursor_x { position: absolute; top:0px; display: block; width:20px; height:10px; font-size: 11px; text-align: center; margin-left:10px; transition: left 100ms } +#cursor_y { position: absolute; left:-10px; display: block; width:20px; height:10px; font-size: 11px; text-align: right; margin-top:15px; transition: top 100ms } + #guide,#widgets { position: absolute;width: 300px;height: 300px; margin-left: -5px; margin-top: -5px; transition: opacity 250ms} #widgets { z-index: 9000; margin-left: 0; margin-top: 0; } #render { display: none } @@ -19,7 +21,7 @@ body { padding: 5px; font-family: 'input_mono_regular'; -webkit-user-select: non svg.vector { z-index: 1000;position: relative; left:10px; top:10px; width:300px; height:300px; } -#interface { font-size: 11px;line-height: 30px;text-transform: uppercase;-webkit-app-region: no-drag; transition: all 150ms; width: 315px; position:fixed; bottom:20px; left:calc(50vw - 150px);} +#interface { font-size: 11px;line-height: 30px;text-transform: uppercase;-webkit-app-region: no-drag; transition: all 150ms; width: 315px; position:fixed; bottom:20px; left:calc(50vw - 155px);} #interface svg.inactive { opacity: 0.2 } #interface svg:hover { opacity: 0.5 } #interface svg.icon:last-child { margin-right: 0; margin-left: 15px; } diff --git a/sources/media/fonts/input_mono_medium.ttf b/sources/media/fonts/input_mono_medium.ttf deleted file mode 100644 index 0d488bf..0000000 Binary files a/sources/media/fonts/input_mono_medium.ttf and /dev/null differ diff --git a/sources/media/fonts/input_mono_regular.ttf b/sources/media/fonts/input_mono_regular.ttf deleted file mode 100644 index c19c287..0000000 Binary files a/sources/media/fonts/input_mono_regular.ttf and /dev/null differ diff --git a/sources/media/fonts/input_mono_thin.ttf b/sources/media/fonts/input_mono_thin.ttf deleted file mode 100644 index 9622bc3..0000000 Binary files a/sources/media/fonts/input_mono_thin.ttf and /dev/null differ diff --git a/sources/scripts/dotgrid.js b/sources/scripts/dotgrid.js index e532dbb..3212ffa 100644 --- a/sources/scripts/dotgrid.js +++ b/sources/scripts/dotgrid.js @@ -64,10 +64,15 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.cursor.id = "cursor"; this.element.appendChild(this.cursor); - this.cursor_coord = document.createElement("div"); - this.cursor_coord.id = "cursor_coord"; - this.cursor_coord.className = "fl" - this.cursor.appendChild(this.cursor_coord); + this.cursor_x = document.createElement("t"); + this.cursor_x.id = "cursor_x"; + this.cursor_x.className = "fl" + this.element.appendChild(this.cursor_x); + + this.cursor_y = document.createElement("t"); + this.cursor_y.id = "cursor_y"; + this.cursor_y.className = "fl" + this.element.appendChild(this.cursor_y); cursor_from = document.createElement("div"); cursor_from.id = "cursor_from"; @@ -111,7 +116,6 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.preview_el.setAttribute("version","1.1"); this.preview_el.style.width = this.width; this.preview_el.style.height = this.height; - this.preview_el.style.stroke = "#72dec2"; this.preview_el.style.strokeWidth = 2; this.preview_el.style.fill = "none"; this.preview_el.style.strokeLinecap = "round"; @@ -138,7 +142,7 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.controller.add("default","File","Open",() => { dotgrid.open(); },"CmdOrCtrl+O"); this.controller.add("default","File","Save",() => { dotgrid.save(); },"CmdOrCtrl+S"); - this.controller.add("default","Edit","Insert",() => { dotgrid.add_point(); },"Enter"); + this.controller.add("default","Edit","Insert",() => { dotgrid.add_point(); },"I"); this.controller.add("default","Edit","Copy",() => { document.execCommand('copy'); },"CmdOrCtrl+C"); this.controller.add("default","Edit","Paste",() => { document.execCommand('paste'); },"CmdOrCtrl+V"); this.controller.add("default","Edit","Undo",() => { dotgrid.undo(); },"CmdOrCtrl+Z"); @@ -155,16 +159,18 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.controller.add("default","Stroke","Bezier",() => { dotgrid.draw_bezier(); },"F"); this.controller.add("default","Stroke","Connect",() => { dotgrid.draw_close(); },"Z"); - this.controller.add("default","Effect","Thicker",() => { dotgrid.mod_thickness(1) },"]"); - this.controller.add("default","Effect","Thinner",() => { dotgrid.mod_thickness(-1) },"["); - this.controller.add("default","Effect","Linecap",() => { dotgrid.mod_linecap(); },"/"); + this.controller.add("default","Effect","Thicker",() => { dotgrid.mod_thickness(1) },"}"); + this.controller.add("default","Effect","Thinner",() => { dotgrid.mod_thickness(-1) },"{"); + this.controller.add("default","Effect","Thicker +5",() => { dotgrid.mod_thickness(5,true) },"]"); + this.controller.add("default","Effect","Thinner -5",() => { dotgrid.mod_thickness(-5,true) },"["); + this.controller.add("default","Effect","Linecap",() => { dotgrid.mod_linecap(); },"Y"); this.controller.add("default","Effect","Mirror",() => { dotgrid.mod_mirror(); },"Space"); this.controller.add("default","Effect","Fill",() => { dotgrid.toggle_fill(); },"G"); - this.controller.add("default","View","Tools",() => { dotgrid.interface.toggle(); },";"); + this.controller.add("default","View","Tools",() => { dotgrid.interface.toggle(); },"U"); this.controller.add("default","View","Grid",() => { dotgrid.guide.toggle(); },"H"); this.controller.add("default","View","Control Points",() => { dotgrid.guide.toggle_widgets(); },"J"); - this.controller.add("default","View","Expert",() => { dotgrid.interface.toggle_zoom(); },":"); + this.controller.add("default","View","Expert Mode",() => { dotgrid.interface.toggle_zoom(); },":"); this.controller.commit(); @@ -300,7 +306,7 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca { var o = e.target.getAttribute("ar"); - var pos = this.position_in_grid(new Pos(e.clientX,e.clientY)); + var pos = this.position_in_grid(new Pos(e.clientX+5,e.clientY-5)); pos = this.position_on_grid(pos); if(e.altKey){ dotgrid.delete_at(pos); return; } @@ -323,7 +329,7 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.mouse_move = function(e) { - var pos = this.position_in_grid(new Pos(e.clientX,e.clientY)); + var pos = this.position_in_grid(new Pos(e.clientX+5,e.clientY-5)); pos = this.position_on_grid(pos); if(dotgrid.translation){ dotgrid.translation.to = pos; } @@ -337,7 +343,7 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.mouse_up = function(e) { - var pos = this.position_in_grid(new Pos(e.clientX,e.clientY)); + var pos = this.position_in_grid(new Pos(e.clientX+5,e.clientY-5)); pos = this.position_on_grid(pos); if(e.altKey){ return; } @@ -366,12 +372,19 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.cursor.style.visibility = "visible" this.cursor.style.left = Math.floor(-(pos.x-this.grid_width)); this.cursor.style.top = Math.floor(pos.y+this.grid_height); - this.cursor_coord.className = -pos.x > this.width/2 ? "fl left" : "fl" - this.cursor_coord.textContent = parseInt(-pos.x/this.grid_width)+","+parseInt(pos.y/this.grid_height); + this.update_cursor(pos); window.setTimeout(() => dotgrid.cursor.style.transition = "all 50ms", 17 /*one frame*/) } } + this.update_cursor = function(pos) + { + this.cursor_x.style.left = `${-pos.x}px`; + this.cursor_x.textContent = parseInt(-pos.x/this.grid_width) + this.cursor_y.style.top = `${pos.y}px`; + this.cursor_y.textContent = parseInt(pos.y/this.grid_width) + } + this.add_point = function(pos = new Pos(0,0)) { if(from === null){ this.set_from(pos.scale(1/this.scale)); } @@ -471,12 +484,16 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca this.draw(); } - this.mod_thickness = function(mod) + this.mod_thickness = function(mod,step = false) { if(!mod){ mod = 1; this.thickness = this.thickness > 30 ? 1 : this.thickness } + if(step){ + this.thickness = parseInt(this.thickness/5) * 5; + } + this.thickness = Math.max(this.thickness+mod,0); - this.cursor_coord.textContent = this.thickness; + this.cursor_x.textContent = this.thickness; this.draw(); } diff --git a/sources/scripts/interface.js b/sources/scripts/interface.js index 2a1d22a..c4e2e8c 100644 --- a/sources/scripts/interface.js +++ b/sources/scripts/interface.js @@ -21,7 +21,7 @@ function Interface() ["mirror","mirror","M60,60 L240,240 M180,120 L210,90 M120,180 L90,210 "], ["fill","fill","M60,60 L60,150 L150,150 L240,150 L240,240 Z "], - ["export","export (ctrl s)","M150,50 L50,150 L150,250 L250,150 L150,50 Z"] + ["export","export","M150,50 L50,150 L150,250 L250,150 L150,50 Z"] ] path_arr.forEach(function(a) { html += ''+a[1]+'' diff --git a/sources/scripts/controller.js b/sources/scripts/lib/controller.js similarity index 81% rename from sources/scripts/controller.js rename to sources/scripts/lib/controller.js index e11fb58..89dd9ca 100644 --- a/sources/scripts/controller.js +++ b/sources/scripts/lib/controller.js @@ -17,7 +17,14 @@ function Controller() console.log(`${mode}/${cat}/${label} <${accelerator}>`); } - this.set = function(mode) + this.add_role = function(mode,cat,label) + { + if(!this.menu[mode]){ this.menu[mode] = {}; } + if(!this.menu[mode][cat]){ this.menu[mode][cat] = {}; } + this.menu[mode][cat][label] = {role:label}; + } + + this.set = function(mode = "default") { this.mode = mode; this.commit(); @@ -31,7 +38,12 @@ function Controller() var submenu = []; for(name in m[cat]){ var option = m[cat][name]; - submenu.push({label:name,accelerator:option.accelerator,click:option.fn}) + if(option.role){ + submenu.push({role:option.role}) + } + else{ + submenu.push({label:name,accelerator:option.accelerator,click:option.fn}) + } } f.push({label:cat,submenu:submenu}); } @@ -46,15 +58,17 @@ function Controller() this.docs = function() { console.log("Generating docs.."); - var svg = this.generate(this.format()) + var svg = this.generate_svg(this.format()) + var txt = this.documentation(this.format()); dialog.showSaveDialog((fileName) => { if (fileName === undefined){ return; } fileName = fileName.substr(-4,4) != ".svg" ? fileName+".svg" : fileName; fs.writeFile(fileName,svg); + fs.writeFile(fileName.replace(".svg",".md"),txt); }); } - this.generate = function(m) + this.generate_svg = function(m) { var svg_html = ""; @@ -70,13 +84,43 @@ function Controller() return `${svg_html}`; } + this.documentation = function() + { + var txt = ""; + + txt += this.documentation_for_mode("default",this.menu.default); + + for(name in this.menu){ + if(name == "default"){ continue; } + txt += this.documentation_for_mode(name,this.menu[name]); + } + return txt; + } + + this.documentation_for_mode = function(name,mode) + { + var txt = `## ${name} Mode\n\n`; + + for(id in mode){ + if(id == "*"){ continue; } + txt += `### ${id}\n`; + for(name in mode[id]){ + var option = mode[id][name]; + txt += `- ${name}: \`${option.accelerator}\`\n`; + } + txt += "\n" + } + + return txt+"\n"; + } + this.accelerator_for_key = function(key,menu) { var acc = {basic:null,ctrl:null} for(cat in menu){ var options = menu[cat]; for(id in options.submenu){ - var option = options.submenu[id]; + var option = options.submenu[id]; if(option.role){ continue; } acc.basic = (option.accelerator.toLowerCase() == key.toLowerCase()) ? option.label.toUpperCase().replace("TOGGLE ","").substr(0,8).trim() : acc.basic; acc.ctrl = (option.accelerator.toLowerCase() == ("CmdOrCtrl+"+key).toLowerCase()) ? option.label.toUpperCase().replace("TOGGLE ","").substr(0,8).trim() : acc.ctrl; } @@ -97,7 +141,7 @@ function Controller() {x:540, y:0, width:60, height:60, name:"9"}, {x:600, y:0, width:60, height:60, name:"0"}, {x:660, y:0, width:60, height:60, name:"-"}, - {x:720, y:0, width:60, height:60, name:"+"}, + {x:720, y:0, width:60, height:60, name:"plus"}, {x:780, y:0, width:120, height:60, name:"backspace"}, {x:0, y:60, width:90, height:60, name:"tab"}, {x:90, y:60, width:60, height:60, name:"q"}, diff --git a/sources/scripts/theme.js b/sources/scripts/lib/theme.js similarity index 100% rename from sources/scripts/theme.js rename to sources/scripts/lib/theme.js