Some minor progress on the brush

This commit is contained in:
Devine Lu Linvega 2017-11-08 13:12:55 +13:00
parent 806bcfc954
commit 5ec4dedfa0
9 changed files with 129 additions and 73 deletions

View File

@ -13,6 +13,9 @@ Ronin is a simple open-source graphic design tool.
Missing documentation. Missing documentation.
### Methods ### 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 ### Settings
- `size`, default 4 - `size`, default 4
@ -38,8 +41,6 @@ Manager for the canvas size
- `fill:#f00` Fill entire canvas with color - `fill:#f00` Fill entire canvas with color
### Settings ### Settings
- `width`, default 930
- `height`, default 540
### Ports ### Ports
@ -67,7 +68,6 @@ File import/export tools.
- `save:name` Export canvas. - `save:name` Export canvas.
### Settings ### Settings
- `anchor`, default [object Object]
### Ports ### Ports
@ -91,8 +91,8 @@ Trace lines and to draw shapes.
Cursor magnetisation settings, changes are reflected on the grid layer. Cursor magnetisation settings, changes are reflected on the grid layer.
### Methods ### Methods
- `lock:undefined` undefined - `lock:10x10` Magnetize cursor
- `unlock:undefined` undefined - `unlock:` Release cursor
### Settings ### Settings
- `size`, default 0 - `size`, default 0
@ -100,6 +100,17 @@ Cursor magnetisation settings, changes are reflected on the grid layer.
### Ports ### Ports
## filter
Pixel filter
### Methods
- `balance:#ff0033` Filter color balance.
### Settings
### Ports
## License ## License
See the [LICENSE](LICENSE.md) file for license rights and limitations (CC). See the [LICENSE](LICENSE.md) file for license rights and limitations (CC).

View File

@ -1,5 +1,7 @@
<html> <html>
<head> <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/module.js"></script>
<script type="text/javascript" src="scripts/core/method.js"></script> <script type="text/javascript" src="scripts/core/method.js"></script>
<script type="text/javascript" src="scripts/modules/frame.js"></script> <script type="text/javascript" src="scripts/modules/frame.js"></script>

View File

@ -24,6 +24,7 @@ function Commander()
var setting_value = q.settings[setting_id]; var setting_value = q.settings[setting_id];
if(!ronin.modules[q.module].settings[setting_id]){ console.log("Missing setting",setting_id); return; } if(!ronin.modules[q.module].settings[setting_id]){ console.log("Missing setting",setting_id); return; }
ronin.modules[q.module].settings[setting_id] = setting_value; ronin.modules[q.module].settings[setting_id] = setting_value;
console.log(ronin.modules[q.module]);
} }
ronin.modules[q.module].routes = q.routes; ronin.modules[q.module].routes = q.routes;

View File

@ -28,7 +28,7 @@ function Layer()
this.el.style.height = size.height+"px"; 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); return this.context().getImageData(x, y, width * 2, height * 2);
} }

View File

@ -6,75 +6,47 @@ function Brush()
this.pointers = [ this.pointers = [
new Pointer({offset:{x:0,y:0}}), new Pointer({offset:{x:0,y:0}}),
new Pointer({offset:{x:2,y:2}}), new Pointer({offset:{x:0,y:0},mirror:{x:400,y:0}})
new Pointer({offset:{x:4,y:4}}),
]; ];
this.ports = {};
this.ports.speed = new Port(this,"speed",false,true,0,50,"The cursor speed"); 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.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.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.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.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) this.thickness = function(line)
{ {
if(this.ports[this.routes.thickness]){ var t = this.settings.size * this.ports.speed;
return this.ports[this.routes.thickness] * this.settings.size; this.absolute_thickness = t > this.absolute_thickness ? this.absolute_thickness+0.5 : this.absolute_thickness-0.5;
} return this.absolute_thickness * 3;
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;
} }
this.stroke = function(line) this.stroke = function(line)
{ {
ronin.commander.blur(); ronin.commander.blur();
// this.ports.speed = distance_between(line.from,line.to)/15.0; this.ports.speed = 1-distance_between(line.from,line.to)/15.0;
// this.ports.distance += this.ports.speed; this.ports.distance += this.ports.speed;
// this.ports.noise = Math.random(255/255.0); // this.ports.noise = Math.random(255/255.0);
// this.ports.x = line.from.x/2; // this.ports.x = line.from.x/2;
@ -136,13 +108,18 @@ function Pointer(options)
{ {
var ctx = ronin.render.context(); 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.beginPath();
ctx.globalCompositeOperation="source-over"; 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.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 * ronin.brush.offset(line)),(line.to.y * 2) + (this.options.offset.y * ronin.brush.offset(line))); ctx.lineTo((line.to.x * 2) + this.options.offset.x,(line.to.y * 2) + this.options.offset.y);
ctx.lineCap="round"; ctx.lineCap="round";
ctx.lineWidth = this.thickness(line); 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.stroke();
ctx.closePath(); ctx.closePath();
} }

View File

@ -3,8 +3,10 @@ function Filter()
Module.call(this,"filter","Pixel filter"); Module.call(this,"filter","Pixel filter");
this.methods.balance = new Method("balance","#ff0033","Filter color balance.",function(q){ 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; var data = originalData.data;
for(var i = 0; i < data.length; i += 4) { 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); 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);
}); });
} }

View File

@ -2,10 +2,11 @@ function Frame()
{ {
Module.call(this,"frame","Manager for the canvas size"); 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){ 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.render.clear();
ronin.frame.resize_to(q); ronin.frame.resize_to(q);
ronin.render.context().putImageData(data, 0, 0); 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){ this.methods.rescale = new Method("rescale","0.5","Rescale canvas to float.",function(p){
var copy_canvas = document.createElement("canvas"); 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; copy_canvas.height = ronin.frame.settings.height * 2;
var copy_ctx = copy_canvas.getContext("2d"); var copy_ctx = copy_canvas.getContext("2d");
copy_ctx.drawImage(ronin.render.to_img(), 0, 0); 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.render.clear();
ronin.frame.resize_to(new_size); ronin.frame.resize_to(new_size);
@ -42,8 +43,8 @@ function Frame()
this.resize_to = function(size) this.resize_to = function(size)
{ {
ronin.frame.settings.width = size.width; ronin.frame.width = size.width;
ronin.frame.settings.height = size.height; ronin.frame.height = size.height;
const {dialog,app} = require('electron').remote; const {dialog,app} = require('electron').remote;
var win = require('electron').remote.getCurrentWindow(); var win = require('electron').remote.getCurrentWindow();

View File

@ -44,8 +44,8 @@ function Ronin()
{ {
document.body.appendChild(this.el); document.body.appendChild(this.el);
this.frame.settings.width = window.innerWidth; this.frame.width = window.innerWidth;
this.frame.settings.height = window.innerHeight; this.frame.height = window.innerHeight;
this.grid.install(); this.grid.install();
this.guide.install(); this.guide.install();

View 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";
}
}