Some minor progress on the brush
This commit is contained in:
		
							
								
								
									
										21
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								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). | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| <html> | ||||
|   <head> | ||||
|     <script type="text/javascript" src="scripts/units/color.js"></script> | ||||
|  | ||||
|     <script type="text/javascript" src="scripts/core/module.js"></script> | ||||
|     <script type="text/javascript" src="scripts/core/method.js"></script> | ||||
|     <script type="text/javascript" src="scripts/modules/frame.js"></script> | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
|   | ||||
| @@ -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(); | ||||
|   } | ||||
|   | ||||
| @@ -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); | ||||
|   }); | ||||
| } | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
							
								
								
									
										46
									
								
								sources/scripts/units/color.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								sources/scripts/units/color.js
									
									
									
									
									
										Normal file
									
								
							| @@ -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"; | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user