diff --git a/README.md b/README.md index 1045a83..c7f3f25 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ Ronin is a simple open-source graphic design tool. Missing documentation. ### Methods +- `add:x,y&mirror_x,mirror_y` Add a new pointer to the brush +- `remove:` Remove last pointer +- `pick:x,y` Set brush color to a position's pixel. ### Settings - `size`, default 4 @@ -38,8 +41,6 @@ Manager for the canvas size - `fill:#f00` Fill entire canvas with color ### Settings -- `width`, default 930 -- `height`, default 540 ### Ports @@ -67,7 +68,6 @@ File import/export tools. - `save:name` Export canvas. ### Settings -- `anchor`, default [object Object] ### Ports @@ -91,8 +91,8 @@ Trace lines and to draw shapes. Cursor magnetisation settings, changes are reflected on the grid layer. ### Methods -- `lock:undefined` undefined -- `unlock:undefined` undefined +- `lock:10x10` Magnetize cursor +- `unlock:` Release cursor ### Settings - `size`, default 0 @@ -100,6 +100,17 @@ Cursor magnetisation settings, changes are reflected on the grid layer. ### Ports +## filter + +Pixel filter + +### Methods +- `balance:#ff0033` Filter color balance. + +### Settings + +### Ports + ## License See the [LICENSE](LICENSE.md) file for license rights and limitations (CC). diff --git a/sources/index.html b/sources/index.html index f1933b2..8ffc81a 100644 --- a/sources/index.html +++ b/sources/index.html @@ -1,5 +1,7 @@ + + diff --git a/sources/scripts/core/commander.js b/sources/scripts/core/commander.js index 4a9a8d9..25b40e9 100644 --- a/sources/scripts/core/commander.js +++ b/sources/scripts/core/commander.js @@ -24,6 +24,7 @@ function Commander() 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; + console.log(ronin.modules[q.module]); } ronin.modules[q.module].routes = q.routes; diff --git a/sources/scripts/core/layer.js b/sources/scripts/core/layer.js index 678e2ab..705f042 100644 --- a/sources/scripts/core/layer.js +++ b/sources/scripts/core/layer.js @@ -28,7 +28,7 @@ function Layer() this.el.style.height = size.height+"px"; } - this.select = function(x = 0,y = 0,width = ronin.frame.settings.width,height = ronin.frame.settings.width) + this.select = function(x = 0,y = 0,width = ronin.frame.width,height = ronin.frame.width) { return this.context().getImageData(x, y, width * 2, height * 2); } diff --git a/sources/scripts/modules/brush.js b/sources/scripts/modules/brush.js index c16115e..8710259 100644 --- a/sources/scripts/modules/brush.js +++ b/sources/scripts/modules/brush.js @@ -6,75 +6,47 @@ function Brush() this.pointers = [ new Pointer({offset:{x:0,y:0}}), - new Pointer({offset:{x:2,y:2}}), - new Pointer({offset:{x:4,y:4}}), + new Pointer({offset:{x:0,y:0},mirror:{x:400,y:0}}) ]; - this.ports = {}; - this.ports.speed = new Port(this,"speed",false,true,0,50,"The cursor speed"); this.ports.distance = new Port(this,"distance",false,true,0,9999,"The cursor distance"); this.ports.red = new Port(this,"red",true,true,0,255,"The brush color value(red)"); this.ports.green = new Port(this,"green",true,true,0,255,"The brush color value(green)"); this.ports.blue = new Port(this,"blue",true,true,0,255,"The brush color value(blue)"); + this.methods.add = new Method("add","x,y&mirror_x,mirror_y","Add a new pointer to the brush",function(q){ + var offset = q.length ? q[0] : q; + var mirror = q.length ? q[1] : null; + ronin.brush.pointers.push(new Pointer({offset:offset,mirror:mirror})); + }) + + this.methods.remove = new Method("remove","","Remove last pointer",function(q){ + ronin.brush.pointers.pop(); + }) + + this.methods.pick = new Method("pick","x,y","Set brush color to a position's pixel.",function(q){ + var pixel = ronin.render.context().getImageData(q.x*2, q.y*2, 1, 1).data; + var c = new Color().rgb_to_hex(pixel); + var color = new Color(c); + ronin.brush.settings.color = color.hex; + }) + + this.absolute_thickness = 0; + this.thickness = function(line) { - if(this.ports[this.routes.thickness]){ - return this.ports[this.routes.thickness] * this.settings.size; - } - return this.settings.size; - } - - this.offset = function(line) - { - if(this.ports[this.routes.offset]){ - return this.ports[this.routes.offset]; - } - return 1; - } - - this.red = function(line) - { - return 255; - if(this.ports[this.routes.red]){ - return this.ports[this.routes.red] * 255; - } - return this.ports.red; - } - - this.green = function(line) - { - return 0; - if(this.ports[this.routes.green]){ - return this.ports[this.routes.green] * 255; - } - return this.ports.green; - } - - this.blue = function(line) - { - return 0; - if(this.ports[this.routes.blue]){ - return this.ports[this.routes.blue] * 255; - } - return this.ports.blue; - } - - this.alpha = function(line) - { - if(this.ports[this.routes.alpha]){ - return this.ports[this.routes.alpha]; - } - return this.ports.alpha; + var t = this.settings.size * this.ports.speed; + this.absolute_thickness = t > this.absolute_thickness ? this.absolute_thickness+0.5 : this.absolute_thickness-0.5; + return this.absolute_thickness * 3; } this.stroke = function(line) { ronin.commander.blur(); - // this.ports.speed = distance_between(line.from,line.to)/15.0; - // this.ports.distance += this.ports.speed; + this.ports.speed = 1-distance_between(line.from,line.to)/15.0; + this.ports.distance += this.ports.speed; // this.ports.noise = Math.random(255/255.0); // this.ports.x = line.from.x/2; @@ -136,13 +108,18 @@ function Pointer(options) { var ctx = ronin.render.context(); + if(this.options.mirror){ + line.from.x = this.options.mirror.x - line.from.x; + line.to.x = this.options.mirror.x - line.to.x; + } + ctx.beginPath(); ctx.globalCompositeOperation="source-over"; - ctx.moveTo((line.from.x * 2) + (this.options.offset.x * ronin.brush.offset(line)),(line.from.y * 2) + (this.options.offset.y * ronin.brush.offset(line))); - ctx.lineTo((line.to.x * 2) + (this.options.offset.x * ronin.brush.offset(line)),(line.to.y * 2) + (this.options.offset.y * ronin.brush.offset(line))); + ctx.moveTo((line.from.x * 2) + this.options.offset.x,(line.from.y * 2) + this.options.offset.y); + ctx.lineTo((line.to.x * 2) + this.options.offset.x,(line.to.y * 2) + this.options.offset.y); ctx.lineCap="round"; ctx.lineWidth = this.thickness(line); - ctx.strokeStyle = "rgba("+clamp(parseInt(ronin.brush.red()),0,255)+","+clamp(parseInt(ronin.brush.green()),0,255)+","+clamp(parseInt(ronin.brush.blue()),0,255)+","+ronin.brush.alpha()+")"; + ctx.strokeStyle = ronin.brush.settings.color; ctx.stroke(); ctx.closePath(); } diff --git a/sources/scripts/modules/filter.js b/sources/scripts/modules/filter.js index 767e64e..1a98f5e 100644 --- a/sources/scripts/modules/filter.js +++ b/sources/scripts/modules/filter.js @@ -3,8 +3,10 @@ function Filter() Module.call(this,"filter","Pixel filter"); this.methods.balance = new Method("balance","#ff0033","Filter color balance.",function(q){ - var color = {r:1,g:0,b:0.5}; - var originalData = ronin.render.context().getImageData(0, 0, ronin.frame.settings.width*2, ronin.frame.settings.height*2); + + var color = new Color(q).floats(); + + var originalData = ronin.render.context().getImageData(0, 0, ronin.frame.width*2, ronin.frame.height*2); var data = originalData.data; for(var i = 0; i < data.length; i += 4) { @@ -13,6 +15,22 @@ function Filter() data[i + 2] = data[i + 2] * (color.b + 0.5); } - ronin.preview.context().putImageData(originalData, 0, 0); + ronin.render.context().putImageData(originalData, 0, 0); + }); + + this.methods.balance = new Method("balance","#ff0033","Filter color balance.",function(q){ + + var color = new Color(q).floats(); + + var originalData = ronin.render.context().getImageData(0, 0, ronin.frame.width*2, ronin.frame.height*2); + var data = originalData.data; + + for(var i = 0; i < data.length; i += 4) { + data[i] = data[i] * (color.r + 0.5); + data[i + 1] = data[i + 1] * (color.g + 0.5); + data[i + 2] = data[i + 2] * (color.b + 0.5); + } + + ronin.render.context().putImageData(originalData, 0, 0); }); } \ No newline at end of file diff --git a/sources/scripts/modules/frame.js b/sources/scripts/modules/frame.js index 33cd173..60c9b65 100644 --- a/sources/scripts/modules/frame.js +++ b/sources/scripts/modules/frame.js @@ -2,10 +2,11 @@ function Frame() { Module.call(this,"frame","Manager for the canvas size"); - this.settings = {width:400,height:400}; + this.width = 400; + this.height = 400; this.methods.resize = new Method("resize","WxH","Resize canvas to size.",function(q){ - var data = ronin.render.select(0,0,ronin.frame.settings.width,ronin.frame.settings.height); + var data = ronin.render.select(0,0,ronin.frame.width,ronin.frame.height); ronin.render.clear(); ronin.frame.resize_to(q); ronin.render.context().putImageData(data, 0, 0); @@ -13,12 +14,12 @@ function Frame() this.methods.rescale = new Method("rescale","0.5","Rescale canvas to float.",function(p){ var copy_canvas = document.createElement("canvas"); - copy_canvas.width = ronin.frame.settings.width * 2; + copy_canvas.width = ronin.frame.width * 2; copy_canvas.height = ronin.frame.settings.height * 2; var copy_ctx = copy_canvas.getContext("2d"); copy_ctx.drawImage(ronin.render.to_img(), 0, 0); - var new_size = {width:ronin.frame.settings.width * p,height:ronin.frame.settings.height * p}; + var new_size = {width:ronin.frame.width * p,height:ronin.frame.height * p}; ronin.render.clear(); ronin.frame.resize_to(new_size); @@ -42,8 +43,8 @@ function Frame() this.resize_to = function(size) { - ronin.frame.settings.width = size.width; - ronin.frame.settings.height = size.height; + ronin.frame.width = size.width; + ronin.frame.height = size.height; const {dialog,app} = require('electron').remote; var win = require('electron').remote.getCurrentWindow(); diff --git a/sources/scripts/ronin.js b/sources/scripts/ronin.js index a4fbbe7..5a6a2b4 100644 --- a/sources/scripts/ronin.js +++ b/sources/scripts/ronin.js @@ -44,8 +44,8 @@ function Ronin() { document.body.appendChild(this.el); - this.frame.settings.width = window.innerWidth; - this.frame.settings.height = window.innerHeight; + this.frame.width = window.innerWidth; + this.frame.height = window.innerHeight; this.grid.install(); this.guide.install(); diff --git a/sources/scripts/units/color.js b/sources/scripts/units/color.js new file mode 100644 index 0000000..da16279 --- /dev/null +++ b/sources/scripts/units/color.js @@ -0,0 +1,46 @@ +function Color(hex = '#000000') +{ + this.example = "#ff0000"; + this.hex = hex; + + this.rgb = function() + { + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(this.hex); + return result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; + } + + this.rgba = function() + { + return "rgba("+this.rgb().r+","+this.rgb().g+","+this.rgb().b+",1)"; + } + + this.floats = function() + { + var rgb = this.rgb(); + return { r:rgb.r/255, g:rgb.g/255, b:rgb.b/255 } + } + + this.render = function() + { + return this.hex; + } + + this.rgb_to_hex = function(rgb) + { + return "#"+("0" + parseInt(rgb[0],10).toString(16)).slice(-2)+("0" + parseInt(rgb[1],10).toString(16)).slice(-2)+("0" + parseInt(rgb[2],10).toString(16)).slice(-2); + } + + this.brightness = function() + { + return this.rgb() ? (this.rgb().r + this.rgb().g + this.rgb().b)/3 : 0; + } + + this.style = function() + { + return this.brightness() > 150 ? "bright" : "dark"; + } +} \ No newline at end of file