Improved shortcuts and drag/drop

This commit is contained in:
Devine Lu Linvega 2017-11-14 07:52:53 +13:00
parent 66a34a6814
commit 16ddcfb27a
7 changed files with 50 additions and 28 deletions

View File

@ -6,37 +6,40 @@ Dotgrid is a simple vector drawing application.
## Guide ## Guide
It works by adding control points and selecting a stroke type. So clicking the canvas a few times will place up to 3 control points. Clicking one of the icons, or pressing one of the shortcuts, will draw a stroke. Clicking on the canvas will insert control points, up to 3CPs. CPs can be moved with the arrows. Clicking one of the path icons, or pressing one of the shortcuts, will draw a stroke between them. The newly created segment's handles can be moved by clicking and dragging them.
## Controls ## Controls
### Layer 1 ### Segments
- `q` Erase control points.
- `w` Erase last segment.
- `e` Export SVG file.
- `r` Close Path.
### Layer 2
- `a` Draw Arc(counter-clockwise). - `a` Draw Arc(counter-clockwise).
- `s` Draw Arc(clockwise). - `s` Draw Arc(clockwise).
- `d` Draw Line. - `d` Draw Line.
- `f` Draw Bezier. - `f` Draw Bezier.
- `g` Close Path.
### Parametric ### Parametric
- `+` Increase stroke size. - `]` Increase stroke size.
- `-` Reduce stroke size. - `[` Reduce stroke size.
- `/` Toggle linecap. - `/` Toggle linecap.
### Commands
- `space` Mirror.
- `escape` Remove control points.
- `arrows` Move last control point.
### Shortcuts ### Shortcuts
- `ctrl+n` New canvas. - `ctrl+n` New canvas.
- `ctrl+s` Export canvas.
- `ctrl+z` Delete last segment.
- `ctrl+enter` Toggle Fullscreen. ## Mouse
- `alt+click` Erase target control point.
- `ctrl+click` Translate target control point. - `click/drag` Translate target control point.
- `click+alt` Erase target control point.
## License ## License

View File

@ -19,3 +19,8 @@ body { background:#fff; padding: 5px; font-family: 'input_mono_regular'; -webkit
.icon:hover { cursor: pointer; opacity: 1 } .icon:hover { cursor: pointer; opacity: 1 }
svg.vector { z-index: 1000;position: relative } svg.vector { z-index: 1000;position: relative }
#dotgrid #guide { opacity: 0; transition: all 500ms; }
#dotgrid #widgets { opacity: 0; transition: all 150ms; }
#dotgrid:hover #guide { opacity: 1 }
#dotgrid:hover #widgets { opacity: 1 }

View File

@ -123,7 +123,9 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca
var pos = this.position_in_grid(new Pos(e.clientX,e.clientY)); var pos = this.position_in_grid(new Pos(e.clientX,e.clientY));
pos = this.position_on_grid(pos); pos = this.position_on_grid(pos);
if(e.ctrlKey){ dotgrid.translation = {from:pos,to:pos}; }
if(e.altKey){ dotgrid.delete_at(pos); return; }
if(dotgrid.handle_at(pos)){ dotgrid.translation = {from:pos,to:pos}; return; }
if(!o){ return; } if(!o){ return; }
@ -141,7 +143,7 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca
var pos = this.position_in_grid(new Pos(e.clientX,e.clientY)); var pos = this.position_in_grid(new Pos(e.clientX,e.clientY));
pos = this.position_on_grid(pos); pos = this.position_on_grid(pos);
if(e.ctrlKey && dotgrid.translation){ dotgrid.translation.to = pos; } if(dotgrid.translation){ dotgrid.translation.to = pos; }
this.cursor.style.left = Math.floor(-(pos.x-this.grid_width)); this.cursor.style.left = Math.floor(-(pos.x-this.grid_width));
this.cursor.style.top = Math.floor(pos.y+this.grid_height); this.cursor.style.top = Math.floor(pos.y+this.grid_height);
@ -156,12 +158,13 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca
var pos = this.position_in_grid(new Pos(e.clientX,e.clientY)); var pos = this.position_in_grid(new Pos(e.clientX,e.clientY));
pos = this.position_on_grid(pos); pos = this.position_on_grid(pos);
if(e.altKey){ return; }
if(dotgrid.translation){ if(dotgrid.translation){
dotgrid.translate(dotgrid.translation); dotgrid.translate(dotgrid.translation);
return; return;
} }
if(e.altKey){ dotgrid.delete_at(pos); return; }
if(pos.x>0) return; if(pos.x>0) return;
if(from === null){ this.set_from(pos.scale(1/this.scale)); } if(from === null){ this.set_from(pos.scale(1/this.scale)); }
@ -170,6 +173,17 @@ function Dotgrid(width,height,grid_x,grid_y,block_x,block_y,thickness = 3,lineca
this.draw(); this.draw();
} }
this.handle_at = function(pos)
{
for(id in dotgrid.segments){
var segment = dotgrid.segments[id];
if(segment.from && segment.from.is_equal(pos)){ return true; }
if(segment.to && segment.to.is_equal(pos)){ return true; }
if(segment.end && segment.end.is_equal(pos)){ return true; }
}
return false;
}
this.translate = function(t) this.translate = function(t)
{ {
for(id in dotgrid.segments){ for(id in dotgrid.segments){

View File

@ -29,7 +29,7 @@ function Guide()
this.clear = function() this.clear = function()
{ {
this.widgets.getContext('2d').clearRect(0, 0, 600, 600); this.widgets.getContext('2d').clearRect(0, 0, 1280, 1280);
} }
this.update = function() this.update = function()

View File

@ -28,24 +28,19 @@ function Keyboard()
} }
switch (e.keyCode) { switch (e.keyCode) {
case 83 : dotgrid.draw_arc(e.shiftKey ? "1,1" : "0,1"); break; // 'S' case 65 : dotgrid.draw_arc(e.shiftKey ? "1,0" : "0,0"); break; // 'a/A'
case 65 : dotgrid.draw_arc(e.shiftKey ? "1,0" : "0,0"); break; // 'a' case 83 : dotgrid.draw_arc(e.shiftKey ? "1,1" : "0,1"); break; // 's/S'
case 68 : dotgrid.draw_line(); break; // 'd' case 68 : dotgrid.draw_line(); break; // 'd'
case 70 : dotgrid.draw_bezier(); break; // 'f' case 70 : dotgrid.draw_bezier(); break; // 'f'
case 82 : dotgrid.draw_close(); break; // 'r' case 71 : dotgrid.draw_close(); break; // 'g'
case 187 : dotgrid.mod_thickness(1); break; // '+'
case 189 : dotgrid.mod_thickness(-1); break; // '-'
case 221 : dotgrid.mod_thickness(1); break; // ']' case 221 : dotgrid.mod_thickness(1); break; // ']'
case 219 : dotgrid.mod_thickness(-1); break; // '[' case 219 : dotgrid.mod_thickness(-1); break; // '['
case 191 : dotgrid.mod_linecap(1); break; // '/' case 191 : dotgrid.mod_linecap(1); break; // '/'
case 32 : dotgrid.mod_mirror(); break; // 'space' case 32 : dotgrid.mod_mirror(); break; // 'space'
case 81 : dotgrid.reset(); break; // 'Q'
case 27 : dotgrid.reset(); break; // 'ESC' case 27 : dotgrid.reset(); break; // 'ESC'
case 87 : dotgrid.erase(); break; // 'W'
case 8 : dotgrid.erase(); break; // 'Backspace' case 8 : dotgrid.erase(); break; // 'Backspace'
case 69 : dotgrid.export(); break; // 'e'
case 13 : dotgrid.export(); break; // 'Enter' case 13 : dotgrid.export(); break; // 'Enter'
case 9 : dotgrid.toggle_fill(); e.preventDefault(); break; // 'tab' case 9 : dotgrid.toggle_fill(); e.preventDefault(); break; // 'tab'

View File

@ -6,4 +6,9 @@ function Path_Close()
{ {
return "Z "; return "Z ";
} }
this.handles = function()
{
return [];
}
} }

View File

@ -12,7 +12,7 @@ function Render()
var b64Start = 'data:image/svg+xml;base64,'; var b64Start = 'data:image/svg+xml;base64,';
var image64 = b64Start + svg64; var image64 = b64Start + svg64;
this.img.src = image64; this.img.src = image64;
this.el.getContext('2d').clearRect(0, 0, 512, 512); this.el.getContext('2d').clearRect(0, 0, 1280, 1280);
this.el.getContext('2d').drawImage(this.img, 0, 0, 512, 512); this.el.getContext('2d').drawImage(this.img, 0, 0, 512, 512);
} }