From c23b96ca3a6f30cef5cc6e2c375d823a5a94a62d Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Tue, 26 Sep 2017 09:50:08 +1300 Subject: [PATCH] Implemented basic brush --- sources/index.html | 3 +++ sources/links/main.css | 5 +++-- sources/scripts/brush.js | 36 ++++++++++++++++++++++++++++++++++++ sources/scripts/commander.js | 31 ++++++++++++++++++++++++++++--- sources/scripts/cursor.js | 29 +++++++++++++++-------------- sources/scripts/eraser.js | 21 +++++++++++++++++++++ sources/scripts/hint.js | 25 +++++++++++++++++++++++++ sources/scripts/keyboard.js | 17 +++++++++++++++-- sources/scripts/query.js | 18 ++++++++++++++---- sources/scripts/ronin.js | 9 +++++++-- 10 files changed, 167 insertions(+), 27 deletions(-) create mode 100644 sources/scripts/brush.js create mode 100644 sources/scripts/eraser.js create mode 100644 sources/scripts/hint.js diff --git a/sources/index.html b/sources/index.html index 4cdacd2..b415981 100644 --- a/sources/index.html +++ b/sources/index.html @@ -4,6 +4,9 @@ + + + diff --git a/sources/links/main.css b/sources/links/main.css index 4e15a59..ff66a5e 100644 --- a/sources/links/main.css +++ b/sources/links/main.css @@ -4,5 +4,6 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_medium" yu { display:block; } #ronin { background:#444; height: 100vh; width:100vw; } -#commander { position: fixed; bottom:0px; left:0px; width:100vw; height:30px; line-height: 30px; -webkit-user-select: none;-webkit-app-region: drag; } -#commander input { background: transparent;width: calc(100vw - 30px);padding: 0px 15px;display: block;line-height: 30px;font-size: 11px;color: white; margin-left:30px; } +#commander { position: fixed; bottom:15px; left:5px; width:100vw; height:20px; line-height: 20px; -webkit-user-select: none;-webkit-app-region: drag; z-index:900;} +#commander input { background: transparent;width: calc(100vw - 30px);display: block;line-height: 20px;font-size: 11px;color: white; margin-left:20px; } +#hint { position: fixed; bottom:15px; left:5px; width:100vw; height:20px; line-height: 20px; font-size: 11px;color: white; margin-left:20px; } \ No newline at end of file diff --git a/sources/scripts/brush.js b/sources/scripts/brush.js new file mode 100644 index 0000000..b9d6caf --- /dev/null +++ b/sources/scripts/brush.js @@ -0,0 +1,36 @@ +function Brush() +{ + this.settings = {size:10,color:"#f00"}; + + this.thickness = function(line) + { + var ratio = 1 - (distance_between(line.from,line.to)/15.0); + return this.settings.size * ratio; + } + + this.stroke = function(line) + { + ronin.commander.blur(); + var ctx = ronin.render.context(); + + ctx.beginPath(); + ctx.globalCompositeOperation="source-over"; + ctx.moveTo(line.from.x * 2,line.from.y * 2); + ctx.lineTo(line.to.x * 2,line.to.y * 2); + ctx.lineCap="round"; + ctx.lineWidth = this.thickness(line); + ctx.strokeStyle = this.settings.color; + ctx.stroke(); + ctx.closePath(); + } + + this.mod_size = function(mod) + { + this.settings.size += mod; + } + + function distance_between(a,b) + { + return Math.sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) ); + } +} \ No newline at end of file diff --git a/sources/scripts/commander.js b/sources/scripts/commander.js index 321965d..80fd4a9 100644 --- a/sources/scripts/commander.js +++ b/sources/scripts/commander.js @@ -3,7 +3,7 @@ function Commander() this.el = document.createElement('yu'); this.el.id = "commander"; this.input_el = document.createElement('input'); - this.input_el.value = "rescale s:0.5 rect:300x300"; + this.input_el.value = ""; this.install = function() { @@ -16,8 +16,33 @@ function Commander() { var q = new Query(query_str); - if(!ronin.modules[q.module]){ console.log("Unknown module"); return; } + if(!ronin.modules[q.module]){ console.log("Unknown module",q); return; } - ronin.modules[q.module].run(q) + // Update settings + for(setting_id in q.settings){ + var setting_value = q.settings[setting_id]; + if(!ronin.modules[q.module].settings[setting_id]){ console.log("Missing setting",setting_id); return; } + ronin.modules[q.module].settings[setting_id] = setting_value; + } + + // Run methods + for(method_id in q.methods){ + var method_param = q.methods[method_id]; + if(!ronin.modules[q.module][method_id]){ console.log("Missing method",method_id); return; } + ronin.modules[q.module][method_id].run(method_param); + } + + ronin.commander.input_el.value = ""; + ronin.hint.update(); + } + + this.on_input = function(e) + { + ronin.hint.update(); + } + + this.blur = function() + { + this.input_el.blur(); } } \ No newline at end of file diff --git a/sources/scripts/cursor.js b/sources/scripts/cursor.js index 440c484..9844b13 100644 --- a/sources/scripts/cursor.js +++ b/sources/scripts/cursor.js @@ -1,37 +1,38 @@ function Cursor(rune) { + this.line = {from:null,to:null}; this.is_down = false; this.mouse_down = function(e) { e.preventDefault(); - ronin.cursor.is_down = true; - - var ctx = ronin.render.context(); - ctx.beginPath(); - ctx.rect(e.clientX * 2, e.clientY * 2, 5, 5); - ctx.fillStyle = "red"; - ctx.fill(); + ronin.cursor.line.from = {x:e.clientX,y:e.clientY}; } this.mouse_move = function(e) { e.preventDefault(); - if(!ronin.cursor.is_down){ return; } + if(!ronin.cursor.line.from){ return; } - var ctx = ronin.render.context(); - ctx.beginPath(); - ctx.rect(e.clientX * 2, e.clientY * 2, 5, 5); - ctx.fillStyle = "red"; - ctx.fill(); + ronin.cursor.line.to = {x:e.clientX,y:e.clientY}; + + if(e.altKey){ + ronin.eraser.stroke(ronin.cursor.line); + } + else{ + ronin.brush.stroke(ronin.cursor.line); + } + + ronin.cursor.line.from = {x:e.clientX,y:e.clientY}; } this.mouse_up = function(e) { e.preventDefault(); - ronin.cursor.is_down = false; + ronin.cursor.is_down = false; + ronin.cursor.line = {}; } } \ No newline at end of file diff --git a/sources/scripts/eraser.js b/sources/scripts/eraser.js new file mode 100644 index 0000000..32beb91 --- /dev/null +++ b/sources/scripts/eraser.js @@ -0,0 +1,21 @@ +function Eraser() +{ + this.thickness = function(line) + { + return ronin.brush.thickness(line); + } + + this.stroke = function(line) + { + var ctx = ronin.render.context(); + + ctx.beginPath(); + ctx.globalCompositeOperation="destination-out"; + ctx.moveTo(line.from.x * 2,line.from.y * 2); + ctx.lineTo(line.to.x * 2,line.to.y * 2); + ctx.lineCap="round"; + ctx.lineWidth = this.thickness(line); + ctx.stroke(); + ctx.closePath(); + } +} \ No newline at end of file diff --git a/sources/scripts/hint.js b/sources/scripts/hint.js new file mode 100644 index 0000000..e1e543f --- /dev/null +++ b/sources/scripts/hint.js @@ -0,0 +1,25 @@ +function Hint() +{ + this.el = document.createElement('yu'); + this.el.id = "hint"; + + this.install = function() + { + ronin.el.appendChild(this.el); + this.el.innerHTML = ""; + } + + this.update = function(e = null) + { + this.el.innerHTML = this.pad(ronin.commander.input_el.value)+"brush:"+ronin.brush.settings.size+"&"+ronin.brush.settings.color+""; + } + + this.pad = function(input) + { + var s = ""; + for (i = 0; i < input.length+1; i++){ + s += "_"; + } + return ""+s+""; + } +} \ No newline at end of file diff --git a/sources/scripts/keyboard.js b/sources/scripts/keyboard.js index 48eb866..01913c6 100644 --- a/sources/scripts/keyboard.js +++ b/sources/scripts/keyboard.js @@ -1,8 +1,8 @@ function Keyboard() { - this.key_up = function() + this.key_up = function(e) { - + ronin.hint.update(e); } this.key_down = function(e) @@ -10,5 +10,18 @@ function Keyboard() if(e.key == "Enter"){ ronin.commander.validate(); } + + if(e.key == "Escape"){ + ronin.commander.input_el.blur();; + } + + if(e.key == "]"){ + ronin.brush.mod_size(1); + } + if(e.key == "["){ + ronin.brush.mod_size(-1); + } + + ronin.hint.update(e); } } \ No newline at end of file diff --git a/sources/scripts/query.js b/sources/scripts/query.js index ca4e7c1..8ae4a63 100644 --- a/sources/scripts/query.js +++ b/sources/scripts/query.js @@ -2,11 +2,21 @@ function Query(query_str) { this.module = query_str.split(" ")[0]; var parts = query_str.split(" ").splice(1); - this.parameters = {all:parts.join(" ")}; + this.raw = parts.join(" "); + this.methods = {}; + this.settings = {}; + for(part_id in parts){ var part = parts[part_id]; - var key = part.indexOf(":") > -1 ? part.split(":")[0] : "any"; - var value = part.indexOf(":") > -1 ? part.split(":")[1] : part; - this.parameters[key] = value; + if(part.indexOf(":") > -1){ + var key = part.indexOf(":") > -1 ? part.split(":")[0] : "any"; + var value = part.indexOf(":") > -1 ? part.split(":")[1] : part; + this.methods[key] = value; + } + if(part.indexOf("=") > -1){ + var key = part.indexOf("=") > -1 ? part.split("=")[0] : "any"; + var value = part.indexOf("=") > -1 ? part.split("=")[1] : part; + this.settings[key] = value; + } } } \ No newline at end of file diff --git a/sources/scripts/ronin.js b/sources/scripts/ronin.js index 8a429cd..81bb4aa 100644 --- a/sources/scripts/ronin.js +++ b/sources/scripts/ronin.js @@ -8,9 +8,13 @@ function Ronin() this.commander = new Commander(); this.cursor = new Cursor(); this.render = new Render(); + this.brush = new Brush(); + this.eraser = new Eraser(); + this.hint = new Hint(); this.modules = { - rescale : new Rescale() + rescale : new Rescale(), + brush : this.brush, }; this.install = function() @@ -19,6 +23,7 @@ function Ronin() this.render.install(); this.commander.install(); + this.hint.install(); this.start(); } @@ -30,8 +35,8 @@ function Ronin() ronin.render.el.addEventListener('mousedown', ronin.cursor.mouse_down); ronin.render.el.addEventListener('mousemove', ronin.cursor.mouse_move); ronin.render.el.addEventListener('mouseup', ronin.cursor.mouse_up); - window.addEventListener('keydown', ronin.keyboard.key_down); + ronin.commander.input_el.addEventListener('input', ronin.commander.on_input); console.log("Ronin","Started"); this.render.update();