diff --git a/.gitignore b/.gitignore index 3819313..4a6a205 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.swp *.swo +assets/ \ No newline at end of file diff --git a/README.md b/README.md index 26c9bc2..e8752ea 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,91 @@ -#Ronin - - - -#Starting - -Ronin is a web based drawing application and visual language. Launch index.html and press **:**(colon) to display the command prompt. Input the commands below to interface with the different tools. Headings with a star are features in development. - +# Ronin +## Basics +Ronin is a web based drawing application and visual language. Launch index.html and press **:**(colon) to display the command prompt. Input the commands below to interface with the different tools. ``` : ``` +### Loading/Saving +Requires you to run Ronin through localhost. Navigate to the Ronin folder, and run the simple http server. +``` +cd /path/to/ronin/ ; Navigate to Ronin through the terminal +python -m SimpleHTTPServer 8000 ; Start localhost +http://localhost:8000/ ; Enjoy Ronin +``` +### Controls +``` +ctrl ; Draw Overlays +alt ; Drag Surface +shift ; Erase +shift+ctrl ; Eyedrop +shift+alt ; Move Layer +``` +## Modules +### # Surface +Missing documentation. +- Parameters: `Rect` `Color` `Bang` +- Variables: `layer` -#Modules -##Canvas -``` -@ 600x400 ; New canvas of size 600w and 400h -@ 100x100 #ff0000 ; New canvas of size 100w and 100h with red background -@ ! ; Clear canvas -``` +### / FileLoad +Missing documentation. +- Parameters: `Filepath` `Position` `Rect` +- Variables: -##Save File -``` -$ new_name ; Create a new file with name -$ 3 ; Save to temporary storage, accessible with Load -$ ! ; Clear temporary storage -``` +### $ FileSave +Missing documentation. +- Parameters: `Any` +- Variables: -##Load File -``` -/ dir/file_name.jpg 10,10 100x100 ; Load image, at 10,10 with size 100x100 -/ dir/file_name.jpg 10,10 100x ; Load image, at 10,10 with size 100w and auto height -/ 3 ; Load temporary storage id -``` +### ^ History +Missing documentation. +- Parameters: +- Variables: -##Brush(Pointers) -``` -> 10 ; Size 10 -> -4 ; Eraser, Size 4 -> 10,0 ; Add pointer at pos -> 400x0 ; Add mirror pointer, at 400x -> 4 #ff0000 ; Red brush, Size 4 -> 100,100 45' ; Radial brush from position x,y and 45 degrees -> ! ; Remove all pointers -``` +### | Overlay +Missing documentation. +- Parameters: `Position` `Rect` +- Variables: -##Guides -``` -| 10,10 100x100 ; Draw a guide -| -100,0 ; Draw a grid at every 100px -| ! ; Remove all guides -``` +### % Render +Missing documentation. +- Parameters: `Any` +- Variables: -##Vector(SVG) -``` -+ M10 10 h 80 v 80 h -80 Z ; Draw a square outline -+ M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80 ; Draw a bezier -+ M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 ; Draw a circle -``` +### > Brush +Missing documentation. +- Parameters: `Position` `Rect` `Angle` `Color` `Value` `Bang` +- Variables: `natural` `banking` -##Stroke* -``` -- 0,0 0,10 10,10 10,0 0,0 ; Draw a square -``` +### . Eraser +Missing documentation. +- Parameters: `Value` +- Variables: -##Filters* -``` -: saturation 0.5 ; Set image saturation to 0.5 -: balance red 0.9 0.4 0.7 ; Set color balance red to 0.9 0.4 0.7 -: balance white 0.7 0.7 0.7 ; Set color balance white to 0.7 0.7 0.7 -: sharpen 0.5 ; Sharpen image to 50% -: chromatic 10 ; Shifts, from center, pixels red value by 10, green by 5, blue by 0 -: chromatic 8 0 16 ; Shifts, from center, pixels red value by 8, green by 0, blue by 16 -``` +### * Eye +Missing documentation. +- Parameters: +- Variables: -##Translate* -``` -^ 0,10 ; Translate 10px vertically -^ 20,20 100x100 40,40 ; Translate a specific portion to a specific location -^ -1280x800 ; Flip image horizontally -``` +### & Typographe +Missing documentation. +- Parameters: `Position` `Color` `Value` +- Variables: `text` -##Zoom* -``` -= 75 ; Zoom factor of 75% -= ! ; Zoom 100% -``` +### _ Stroke +Missing documentation. +- Parameters: `Any` +- Variables: -#Units +### + Vector +Missing documentation. +- Parameters: `Any` `Position` +- Variables: + +### ? Help +Missing documentation. +- Parameters: +- Variables: + +## Units ``` 5 ; value: 5 5,7 ; position: 5x 7y @@ -93,35 +93,24 @@ $ ! ; Clear temporary storage #ff0000 ; color: red 0..5 ; random: 0.0-5.0 45' ; degree: 45/365 -rate:10 ; variable: rate = 10 -"foo" ; string: foo -{40w} ; constant: 120px, 40% canvas width +rate=10 ; variable: rate = 10 ``` - -#Constants -``` -w ; percentage of canvas width -h ; percentage of canvas height -``` - -#Presets -##Radial Brush +## Presets +### Radial Brush ``` # 8 strands > 600,400 45';> 600,400 90';> 600,400 135';> 600,400 180';> 600,400 225';> 600,400 270';> 600,400 315' # 6 strands > 600,400 60';> 600,400 120';> 600,400 180';> 600,400 240';> 600,400 300' ``` - -##Symmetry Brush +### Symmetry Brush ``` # XY > 400x 3 # Angular brushes > 400x 1,1;> 400x 2,2;> 400x 3,3; > 1,1;> 2,2;> 3,3; ``` - -##Angular Brush +### Angular Brush ``` # Light > 1,1;> 2,2;> 3,3;> 4,4 @@ -130,3 +119,8 @@ h ; percentage of canvas height # Symmetric Light > 1,1 600x;> 2,2 600x;> 3,3 600x;> 4,4 600x ``` + +### Twitter export & Watermark +``` +# 1280x800 ; / assets/photo.jpg 1280x 0,0 ; / assets/hundredrabbits.png 60x60 20,720 +``` diff --git a/index.html b/index.html index d0c950c..6bba1c8 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,6 @@ - + @@ -9,34 +9,62 @@ + + - - - + - - + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + Ronin
- - +
+ +
+
Loading..
- + - \ No newline at end of file + diff --git a/links/fonts.css b/links/fonts.css new file mode 100644 index 0000000..93a9790 --- /dev/null +++ b/links/fonts.css @@ -0,0 +1,15 @@ +/* Input Mono */ + +@font-face { + font-family: 'input_mono_regular'; + src: url('../media/fonts/input_mono_regular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'input_mono_medium'; + src: url('../media/fonts/input_mono_medium.ttf') format('truetype'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/links/main.css b/links/main.css index 76ddfe1..cb22a84 100644 --- a/links/main.css +++ b/links/main.css @@ -1,20 +1,33 @@ -body { margin:0px; padding:0px; overflow:hidden;} +body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_medium",courier,monospace;} *:focus {outline: none; } canvas:hover { cursor: crosshair;} -#overlay { position:fixed; z-index:1000;} +#ronin { width:100%; height:100%; overflow:hidden; background:#ccc; background-image:url(../media/grid_20.png); background-position: center center; } +#surface { width:50vw; height:50vh; overflow:hidden; position:fixed; left:50%; top:50%; background:#efefef; border-radius:3px;} +#surface .layer { position:absolute; top:0px; left:0px; width:100%; height:100%;} +#overlay { position:absolute; z-index:1000;} +#widget { color:#fff; position:absolute; font-size:10px; padding-top:10px;} +#widget .module { float:left; margin-right:10px; } +#widget .module .highlight { color:#e7fff8; } +#widget .cursor { float:right; text-align: right} +#widget .layer:hover { cursor:pointer;} #commander { display:none; z-index: 2000; position:fixed; } #commander.visible { display:block; } #commander.hidden { display:none; } -#commander input { background:black; padding:5px 15px; position:fixed; bottom:0; color:white; font-size:14px; left:0; border:0; width:calc(100vw); font-family:courier; cursor:pointer; display:block;} +#commander input { background:none; padding:10px; position:fixed; bottom:0; color:white; font-size:11px; left:0; border:0; width:calc(100vw); cursor:pointer; display:block; height:35px;} +#commander input:before { content:"input"; color:e7fff8;} -#commander_hint { background: black;position: fixed;bottom: 27px;padding: 5px 15px 0 15px;line-height: 17px;font-family: courier;font-size: 14px;width: 100vw;color: #999;} -#commander_hint .module { color:#ffffff; display:inline-block; margin-right:10px;} +#commander_hint { background: #000;position: fixed;bottom: 0px;left:0px;padding: 10px;font-size: 11px;width: calc(100vw - 20px);color: #999; height:15px;} +#commander_hint .rune { color:#e7fff8; display:inline-block; margin-right:10px;} +#commander_hint .module { color:#ccc; display:inline-block; margin-right:10px;} +#commander_hint .command { color:#fff; display:inline-block; margin-right:10px;} #commander_hint .param { font-style: italic;} -#commander_hint .param:after { content:", "; } +#commander_hint .param:after { content:" "; } #commander_hint .param:last-child:after { content:"";} -#commander_hint .value { color:#ff0000;} -#commander_hint .value:after { content:", "; color:#999; } -#commander_hint .value:last-child:after { content:"";} \ No newline at end of file +#commander_hint .value { color:#e7fff8;} +#commander_hint .value:after { content:" "; color:#999; } +#commander_hint .value:last-child:after { content:"";} +#commander_hint .variable_key { color:#aaa; font-weight:bold;} +#commander_hint .variable_value { color:#aaa;} \ No newline at end of file diff --git a/links/reset.css b/links/reset.css new file mode 100644 index 0000000..9f57584 --- /dev/null +++ b/links/reset.css @@ -0,0 +1 @@ +* { margin:0;padding:0;border:0;outline:0;text-decoration:none;font-weight:inherit;font-style:inherit;color:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;list-style:none;border-collapse:collapse;border-spacing:0; -webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;} \ No newline at end of file diff --git a/main.js b/main.js deleted file mode 100644 index 18d4515..0000000 --- a/main.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Listens for the app launching then creates the window - * - * @see http://developer.chrome.com/apps/app.runtime.html - * @see http://developer.chrome.com/apps/app.window.html - */ -chrome.app.runtime.onLaunched.addListener(function() { - // Center window on screen. - var screenWidth = screen.availWidth; - var screenHeight = screen.availHeight; - var width = 500; - var height = 300; - - chrome.app.window.create('index.html', { - id: "helloWorldID", - outerBounds: { - width: width, - height: height, - left: Math.round((screenWidth-width)/2), - top: Math.round((screenHeight-height)/2) - } - }); -}); \ No newline at end of file diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 99b774d..0000000 --- a/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "manifest_version": 2, - "name": "Ronin", - "version": "1.1", - "minimum_chrome_version": "23", - "icons": { - "16": "media/icon_16.png", - "128": "media/icon_128.png" - }, - "app": { - "background": { - "scripts": ["main.js"] - } - } -} \ No newline at end of file diff --git a/media/fonts/input_mono_medium.ttf b/media/fonts/input_mono_medium.ttf new file mode 100644 index 0000000..c19c287 Binary files /dev/null and b/media/fonts/input_mono_medium.ttf differ diff --git a/media/fonts/input_mono_regular.ttf b/media/fonts/input_mono_regular.ttf new file mode 100644 index 0000000..0d488bf Binary files /dev/null and b/media/fonts/input_mono_regular.ttf differ diff --git a/media/grid_20.png b/media/grid_20.png new file mode 100644 index 0000000..0e6c281 Binary files /dev/null and b/media/grid_20.png differ diff --git a/media/icon_128.png b/media/icon_128.png deleted file mode 100644 index 6cfd7fe..0000000 Binary files a/media/icon_128.png and /dev/null differ diff --git a/media/icon_16.png b/media/icon_16.png deleted file mode 100644 index aed5233..0000000 Binary files a/media/icon_16.png and /dev/null differ diff --git a/scripts/commander.js b/scripts/commander.js deleted file mode 100644 index 1f23198..0000000 --- a/scripts/commander.js +++ /dev/null @@ -1,140 +0,0 @@ -function Commander(element,element_input) -{ - this.element = element; - this.element_input = element_input; - this.cmd = null; - this.storage = []; - this.storage_index = 0; - this.always_show = false; - - this.show = function() - { - this.element.setAttribute('class','visible'); - this.element_input.focus(); - } - - this.always = function() { - this.always_show = !this.always_show; - } - - this.hide = function() - { - if (!this.always_show) { - this.element.setAttribute('class','hidden'); - } - this.element_input.value = ""; - } - - this.clear = function() - { - this.element_input.value = ""; - } - - this.next_cmd = function() - { - this.storage_index += this.storage_index < this.storage.length ? 1 : 0; - this.element_input.value = this.storage[this.storage_index] ? this.storage[this.storage_index] : ""; - } - - this.prev_cmd = function() - { - this.storage_index -= this.storage_index < 1 ? 0 : 1; - this.element_input.value = this.storage[this.storage_index]; - } - - this.active = function(content) - { - this.storage.push(content.join(" ")); - this.storage_index = this.storage.length; - - var key = content[0]; - content.shift(); - var cmd = new Command(content); - - switch(key) { - case "~": - this.always(); - break; - case "@": - ronin.canvas.active(cmd); - break; - case "$": - ronin.file.save(cmd); - break; - case "/": - ronin.file.active(cmd); - break; - case ">": - ronin.brush.active(cmd); - break; - case "|": - ronin.overlay.active(cmd); - break; - case "-": - ronin.stroke.active(cmd); - break; - case "^": // TODO - ronin.translate.active(cmd); - break; - case "=": // TODO - ronin.zoom.active(cmd); - break; - case "#": // TODO - ronin.layers.active(cmd); - break; - case ":": - ronin.filter.active(cmd); - break; - case "+": - ronin.vector.active(cmd); - break; - } - this.hide(); - } - - this.passive = function(content) - { - var key = content[0]; - content.shift(); - this.cmd = new Command(content); - ronin.module = null; - - switch(key) { - case "@": - ronin.canvas.passive(this.cmd); - ronin.module = ronin.canvas; - break; - case "/": - ronin.file.passive(this.cmd); - ronin.module = ronin.file; - break; - case ">": - ronin.brush.passive(this.cmd); - ronin.module = ronin.brush; - break; - case "|": - ronin.overlay.passive(this.cmd); - ronin.module = ronin.overlay; - break; - case "^": // TODO - ronin.translate.passive(this.cmd); - ronin.module = ronin.translate; - break; - case "=": // TODO - ronin.zoom.passive(this.cmd); - ronin.module = ronin.zoom; - break; - case "$": - ronin.module = ronin.file; - break; - case ":": - ronin.filter.passive(this.cmd); - ronin.module = ronin.filter; - break; - case "+": - ronin.vector.passive(this.cmd); - ronin.module = ronin.vector; - break; - } - } -} diff --git a/scripts/command.js b/scripts/core/command.js similarity index 64% rename from scripts/command.js rename to scripts/core/command.js index 12eea57..27903dc 100644 --- a/scripts/command.js +++ b/scripts/core/command.js @@ -1,39 +1,6 @@ function Command(content) { - this.content = raster(content); - - // Raster - - function raster(array) // @ {50w}x100 - { - var str = array.join(" "); - - var m = str.replace(/(\{(.*)\})/g, function(a) { - var parts = a.split(/[{}]/); - for(var e = 0; e < parts.length; e++) { - if(str.indexOf("{"+parts[e]+"}") == -1){ continue; } - str = str.replace("{"+parts[e]+"}",converter(parts[e])); - } - }); - return str.split(" "); - } - - function converter(str) - { - var unit = str.charAt(str.length - 1); - var value = parseFloat(str.replace(unit,'')); - - switch(unit) { - case "w": - return ronin.canvas.element.width * (value/100); - break; - case "h": - return ronin.canvas.element.height * (value/100); - break; - } - - return str; - } + this.content = content; // Parser @@ -46,7 +13,7 @@ function Command(content) this.rect = function() { for (i = 0; i < this.content.length; i++) { - if(this.content[i].indexOf("x") >= 0){ return new Rect(this.content[i]); } + if(this.content[i].indexOf("x") >= 0 && this.content[i].indexOf("/") < 0){ return new Rect(this.content[i]); } } return null; } @@ -111,7 +78,12 @@ function Command(content) this.variable = function(name) { for (i = 0; i < this.content.length; i++) { - if(this.content[i].indexOf(name+":") >= 0){ return Variable(this.content[i]); } + if(this.content[i].indexOf("=") >= 0){ + var parts = this.content[i].split("="); + if(parts[0] == name){ + return new Variable(parts[0],parts[1]); + } + } } return null; } diff --git a/scripts/core/commander.hint.js b/scripts/core/commander.hint.js new file mode 100644 index 0000000..edb5974 --- /dev/null +++ b/scripts/core/commander.hint.js @@ -0,0 +1,38 @@ +function Hint(element) +{ + Module.call(this); + + this.element = element; + + this.update = function(module,cmd) + { + if(module){ + this.element.innerHTML = this.message(module,cmd); + this.element.style.display = "block"; + } + else if(commander && commander.element_input.value != ""){ + this.element.innerHTML = commander.element_input.value; + this.element.style.display = "block"; + } + else{ + this.element.innerHTML = this.default(); + this.element.style.display = "block"; + } + } + + this.message = function(module,cmd) + { + return module.hint(cmd); + } + + this.default = function() + { + var s = "Modules"; + + for (var key in ronin.modules){ + s += " "+key+" "+ronin.modules[key].constructor.name.substr(0,2)+" "; + } + + return s; + } +} \ No newline at end of file diff --git a/scripts/core/commander.js b/scripts/core/commander.js new file mode 100644 index 0000000..c517738 --- /dev/null +++ b/scripts/core/commander.js @@ -0,0 +1,99 @@ +function Commander(element,element_input) +{ + this.element = element; + this.element_input = element_input; + this.hint = new Hint(); + this.storage = []; + this.storage_index = 0; + this.always_show = false; + + var queue = []; + + this.query = function(input_str) + { + if(input_str.indexOf(";") > 0){ + queue = input_str.split(";"); + } + else{ + queue.push(input_str) + } + run(); + this.hide(); + } + + function run() + { + console.log("~ "+queue[0].trim()); + active(queue[0].trim()); + + queue.shift(); + if(queue.length > 0){ + setTimeout(function(){ run(); }, 100); + } + } + + function active(content) + { + var key = content[0]; + var cmd = new Command(content.substring(1).trim().split(" ")); + + if(ronin.modules[key]){ + ronin.modules[key].active(cmd); + } + + ronin.history.add(content); + } + + this.passive = function(content) + { + var key = content[0]; + var cmd = new Command(content.substring(1).split(" ")); + + ronin.module = null; + + if(ronin.modules[key]){ + ronin.modules[key].passive(cmd); + ronin.module = ronin.modules[key]; + } + this.hint.update(ronin.module,cmd); + } + + // + + this.show = function() + { + this.element.setAttribute('class','visible'); + this.element_input.focus(); + this.element_input.value = ""; + } + + this.always = function() { + this.always_show = !this.always_show; + } + + this.hide = function() + { + if (!this.always_show) { + this.element.setAttribute('class','hidden'); + } + this.element_input.value = ""; + } + + this.clear = function() + { + this.element_input.value = ""; + } + + this.next_cmd = function() + { + this.storage_index += this.storage_index < this.storage.length ? 1 : 0; + this.element_input.value = this.storage[this.storage_index] ? this.storage[this.storage_index] : ""; + } + + this.prev_cmd = function() + { + this.storage_index -= this.storage_index < 1 ? 0 : 1; + this.element_input.value = this.storage[this.storage_index]; + } + +} diff --git a/scripts/core/cursor.js b/scripts/core/cursor.js new file mode 100644 index 0000000..427010c --- /dev/null +++ b/scripts/core/cursor.js @@ -0,0 +1,45 @@ +function Cursor() +{ + this.mode = null; + this.position = new Position(); + + this.update = function(event) + { + if(event.ctrltKey === true && event.altKey === true && event.shiftKey === true){ /* */ } + else if(event.shiftKey === true && event.ctrlKey === true){ this.set_mode(ronin.eye); } + else if(event.shiftKey === true && event.altKey === true){ this.set_mode(ronin.surface.active_layer); } + else if(event.ctrltKey === true && event.altKey === true){ this.set_mode(ronin.overlay.compositor); } + else if(event.ctrlKey === true){ this.set_mode(ronin.overlay); } + else if(event.altKey === true){ this.set_mode(ronin.surface); } + else if(event.shiftKey === true){ this.set_mode(ronin.eraser); } + else{ this.set_mode(ronin.brush); } + } + + this.set_mode = function(mode) + { + if(this.mode == mode){ return; } + this.mode = mode; + document.body.setAttribute("class",this.mode.constructor.name); + ronin.widget.update(); + } + + this.mouse_down = function(position) + { + this.position = position; + this.mode.mouse_down(position); + ronin.widget.update(); + } + + this.mouse_move = function(position) + { + this.position = position; + this.mode.mouse_move(position); + } + + this.mouse_up = function(position) + { + this.position = position; + this.mode.mouse_up(position); + ronin.widget.update(); + } +} \ No newline at end of file diff --git a/scripts/core/init.js b/scripts/core/init.js new file mode 100644 index 0000000..4dff0ae --- /dev/null +++ b/scripts/core/init.js @@ -0,0 +1,42 @@ +var ronin = new Ronin(); +ronin.element = document.getElementById('ronin'); +ronin.overlay.element = document.getElementById('overlay'); +ronin.surface.element = document.getElementById('surface'); +ronin.widget.element = document.getElementById('widget'); +ronin.cursor.mode = ronin.brush; + +var commander = new Commander(document.getElementById("commander"),document.getElementById("commander_input")); +commander.hint.element = document.getElementById('commander_hint'); + +// Cursor + +document.addEventListener('mousedown', function(e){ ronin.cursor.mouse_down(ronin.position_in_canvas(e));}, false); +document.addEventListener('mousemove', function(e){ ronin.cursor.mouse_move(ronin.position_in_canvas(e));}, false); +document.addEventListener('mouseup', function(e){ ronin.cursor.mouse_up(ronin.position_in_canvas(e));}, false); +document.addEventListener('contextmenu', function(ev){ ev.preventDefault(); return false;}, false); +window.addEventListener('resize', function(){ ronin.on_resize(); }, true); + +// Keyboard + +var keyboard = new Keyboard(); +document.onkeyup = function myFunction(){ keyboard.listen_onkeyup(event); }; +document.onkeydown = function myFunction(){ keyboard.listen_onkeydown(event); }; + +// Canvas +var starting_canvas = new Rect(); +starting_canvas.width = window.innerWidth - 200; +starting_canvas.height = window.innerHeight - 200; + +// Clamp + +starting_canvas.width = parseInt(starting_canvas.width/40) * 40; +starting_canvas.height = parseInt(starting_canvas.height/40) * 40; + +commander.query("~ "+ronin.timestamp()); +commander.query("# "+starting_canvas.render()); +commander.query("# layer=background"); +commander.query("# #efefef"); +commander.query("# layer=main"); +commander.query("> 1 0,0 #000000"); +commander.query("> 1 1,0 #000000"); +commander.query("> 1 0,1 #000000"); \ No newline at end of file diff --git a/scripts/core/keyboard.js b/scripts/core/keyboard.js new file mode 100644 index 0000000..be3ee61 --- /dev/null +++ b/scripts/core/keyboard.js @@ -0,0 +1,80 @@ +function Keyboard() +{ + this.listen_onkeyup = function(event) + { + switch (event.key) { + case "Enter": this.key_enter(); break; + case "ArrowUp": this.key_arrow_up(); break; + case "ArrowDown": this.key_arrow_down(); break; + case "ArrowLeft": this.key_arrow_left(); break; + case "ArrowRight": this.key_arrow_right(); break; + // case ":": this.key_colon(); break; + case "Escape": this.key_escape(); break; + } + + switch(event.which) + { + case 13: this.key_enter(); break; + case 186: if(event.shiftKey){this.key_colon();} break; + case 27: this.key_escape(); break; + case 219: ronin.brush.size_up(); break; + case 221: ronin.brush.size_down(); break; + case 38: ronin.surface.layer_up(); break; + case 40: ronin.surface.layer_down(); break; + } + + // Passive + commander.passive(commander.element_input.value); + + ronin.cursor.set_mode(ronin.brush); + ronin.widget.update(); + }; + + this.listen_onkeydown = function(event) + { + ronin.cursor.update(event); + } + + this.key_tab = function() + { + } + + this.key_enter = function() + { + commander.query(commander.element_input.value); + } + + this.key_space = function() + { + } + + this.key_arrow_up = function() + { + commander.prev_cmd(); + } + + this.key_arrow_down = function() + { + commander.next_cmd(); + } + + this.key_arrow_left = function() + { + } + + this.key_arrow_right = function() + { + } + + this.key_colon = function() + { + commander.show(); + return false; + } + + this.key_escape = function() + { + commander.hide(); + ronin.overlay.clear(); + } +} diff --git a/scripts/core/ronin.js b/scripts/core/ronin.js new file mode 100644 index 0000000..35cd75b --- /dev/null +++ b/scripts/core/ronin.js @@ -0,0 +1,66 @@ +function Ronin() +{ + this.modules = {}; + this.element = null; + this.widget = new Widget(); + + this.surface = new Surface("#"); + this.fileload = new FileLoad("/"); + this.filesave = new FileSave("$"); + this.history = new History("^"); + this.overlay = new Overlay("|"); + this.brush = new Brush(">"); + this.eraser = new Eraser("."); + this.eye = new Eye("*"); + this.render = new Render("%"); + this.stroke = new Stroke("_"); + this.vector = new Vector("+"); + this.help = new Help("?"); + this.typo = new Typographe("&"); + + this.cursor = new Cursor(); + + this.modules[this.surface.rune] = this.surface; + this.modules[this.fileload.rune] = this.fileload; + this.modules[this.filesave.rune] = this.filesave; + this.modules[this.history.rune] = this.history; + this.modules[this.overlay.rune] = this.overlay; + this.modules[this.render.rune] = this.render; + this.modules[this.brush.rune] = this.brush; + this.modules[this.eraser.rune] = this.eraser; + this.modules[this.eye.rune] = this.eye; + this.modules[this.typo.rune] = this.typo; + this.modules[this.stroke.rune] = this.stroke; + this.modules[this.vector.rune] = this.vector; + this.modules[this.help.rune] = this.help; + + this.cursors = []; + + this.position_in_canvas = function(e) + { + var x = e.clientX; + x -= (window.innerWidth - this.surface.size.width)/2; + x -= parseInt(this.surface.element.style.marginLeft) + (this.surface.size.width/2); + var y = e.clientY; + y -= (window.innerHeight - this.surface.size.height)/2; + y -= parseInt(this.surface.element.style.marginTop) + parseInt(this.surface.size.height/2); + return new Position(x,y); + } + + this.position_in_window = function(p) + { + return new Position(p.x + parseInt(this.surface.element.style.marginLeft),p.y + parseInt(this.surface.element.style.marginTop)); + } + + this.timestamp = function() + { + var currentdate = new Date(); + var date = currentdate.getFullYear()+""+(currentdate.getMonth()+1)+""+currentdate.getDate(); + return date+" "+currentdate.getHours()+":"+currentdate.getMinutes()+":"+currentdate.getSeconds(); + } + + this.on_resize = function() + { + this.widget.on_resize(); + } +} \ No newline at end of file diff --git a/scripts/core/widget.js b/scripts/core/widget.js new file mode 100644 index 0000000..e01c271 --- /dev/null +++ b/scripts/core/widget.js @@ -0,0 +1,26 @@ +function Widget() +{ + this.element = null; + + this.update = function() + { + var s = ""; + + for (var key in ronin.modules){ + s += ronin.modules[key].widget() ? "
"+ronin.modules[key].widget()+"
" : ""; + } + + s += "
"+ronin.cursor.mode.widget_cursor()+"
"; + + this.element.innerHTML = s; + } + + this.on_resize = function() + { + this.element.style.left = (window.innerWidth/2)-(ronin.surface.size.width/2); + this.element.style.top = (window.innerHeight/2)+(ronin.surface.size.height/2); + this.element.style.width = ronin.surface.size.width+"px"; + + this.update(); + } +} \ No newline at end of file diff --git a/scripts/filters/_balance.js b/scripts/filters/_balance.js new file mode 100644 index 0000000..6bfc559 --- /dev/null +++ b/scripts/filters/_balance.js @@ -0,0 +1,46 @@ +Filter.prototype.filter_balance = function(pixels = this.pixels(),p = null) +{ + // / media/filter.color.jpg + // : balance 0.5 2.4 1.2 + + p[0] = parseFloat(p[0]); + p[1] = p[1] ? parseFloat(p[1]) : parseFloat(p[0]); + p[2] = p[2] ? parseFloat(p[2]) : parseFloat(p[0]); + + var data = pixels.data; + + // Multiply + if(p[0] % 1 !== 0 && p[1] % 1 !== 0 && p[2] % 1 !== 0){ + console.log("Multi"); + for (var i = 0; i < data.length; i += 4) { + data[i] = data[i] * p[0]; // red + data[i + 1] = data[i + 1] * p[1]; // green + data[i + 2] = data[i + 2] * p[2]; // blue + + // Clamp + data[i] = data[i] < 255 ? data[i] : 255; + data[i + 1] = data[i + 1] < 255 ? data[i + 1] : 255; + data[i + 2] = data[i + 2] < 255 ? data[i + 2] : 255; + } + } + // Add + else{ + p[0] = parseInt(p[0]); + p[1] = p[1] ? parseInt(p[1]) : parseInt(p[0]); + p[2] = p[2] ? parseInt(p[2]) : parseInt(p[0]); + + for (i = 0; i < data.length; i += 4) { + data[i] = data[i] + p[0]; // red + data[i + 1] = data[i + 1] + p[1]; // green + data[i + 2] = data[i + 2] + p[2]; // blue + + // Clamp + data[i] = data[i] < 255 ? data[i] : 255; + data[i + 1] = data[i + 1] < 255 ? data[i + 1] : 255; + data[i + 2] = data[i + 2] < 255 ? data[i + 2] : 255; + } + } + + ronin.canvas.clear(); + ronin.surface.context().putImageData(pixels, 0, 0, 0, 0, pixels.width, pixels.height); +} \ No newline at end of file diff --git a/scripts/filters/_offset.js b/scripts/filters/_offset.js new file mode 100644 index 0000000..72b0d07 --- /dev/null +++ b/scripts/filters/_offset.js @@ -0,0 +1,19 @@ +Filter.prototype.filter_offset = function(pixels = this.pixels(),p = null) +{ + var v = 255; // defaults to 255 if no parameter specified + if (p.length > 0 && p[0]) { + v = parseInt(p[0]); + // permissible range is 0 <= v <= 255 + if (v > 255) { v = 255;} + if (v < 0) { v = 0;} + } + var d = pixels.data; + + for (var i=0; i 0){ - var cmds = val.split(";"); - var vals = []; - for (i = 0; i < cmds.length; i++) { - val = cmds[i].replace(/^\s+|\s+$/g, ''); - vals.push(val.split(" ")); - } - return vals; - } - else{ - return [val.split(" ")]; - } - } - - this.lock = function() - { - this.is_locked = true; - interface.actions_panel.style.color = "red"; - } - - this.unlock = function() - { - this.is_locked = false; - interface.actions_panel.style.color = "black"; - } - - this.listen = function(event) - { - if(this.is_locked === true){ return; } - - switch (event.keyCode) - { - case 9: this.key_tab(); break; - case 13: this.key_enter(); break; - case 32: this.key_space(); break; - case 38: this.key_arrow_up(); break; - case 40: this.key_arrow_down(); break; - case 37: this.key_arrow_left(); break; - case 39: this.key_arrow_right(); break; - case 186: this.key_colon(); break; - case 190: if (event.shiftKey) this.key_colon(); break; - case 27: this.key_escape(); break; - } - - // Passive - var cmd = commander.element_input.value; - commander.passive(cmd.split(" ")); - ronin.hint.update(); - }; - - this.key_tab = function() - { - } - - this.key_enter = function() - { - var cmd = commander.element_input.value; - - if(cmd.indexOf(";") > 0){ - var multi = cmd.split(";"); - var i = 0; - while(i < 100){ - if(multi[i]){commander.active(multi[i].split(" "));} - else{ break; } - i += 1; - } - } - else{ - commander.active(cmd.split(" ")); - } - } - - this.key_space = function() - { - } - - this.key_arrow_up = function() - { - commander.prev_cmd(); - } - - this.key_arrow_down = function() - { - commander.next_cmd(); - } - - this.key_arrow_left = function() - { - } - - this.key_arrow_right = function() - { - } - - this.key_colon = function() - { - commander.show(); - return false; - } - - this.key_escape = function() - { - commander.hide(); - ronin.overlay.clear(); - } -} diff --git a/scripts/module.js b/scripts/module.js deleted file mode 100644 index d9b3496..0000000 --- a/scripts/module.js +++ /dev/null @@ -1,19 +0,0 @@ -function Module() -{ - this.parameters = []; - - this.active = function(cmd) - { - console.log("Nothing to do."); - } - - this.passive = function(cmd) - { - console.log("Nothing to do."); - } - - this.hint = function(cmd) - { - return "unknown"; - } -} \ No newline at end of file diff --git a/scripts/modules/brush.js b/scripts/modules/brush.js index 43d6646..d0c3de1 100644 --- a/scripts/modules/brush.js +++ b/scripts/modules/brush.js @@ -1,12 +1,11 @@ -function Brush() +function Brush(rune) { - Module.call(this); + Module.call(this,rune); this.parameters = [Position,Rect,Angle,Color,Value,Bang]; - this.pointers = [new Pointer(new Position())]; + this.variables = {"natural" : false,"banking" : false}; + this.pointers = []; - this.position = new Position(); - this.is_drawing = false; this.size = 1; this.opacity = 1; this.color = new Color(); @@ -17,30 +16,20 @@ function Brush() { if(cmd.bang()){ this.pointers = []; } - var pointer = new Pointer(); + // Pointer + if(cmd.rect() || cmd.position() || cmd.angle()){ + this.add_pointer(cmd); + } - if(cmd.position()){ - pointer.offset = cmd.position(); - } - if(cmd.rect()){ - pointer.mirror = cmd.rect(); - } - if(cmd.variable("osc_scale") && cmd.variable("osc_rate")){ - pointer.osc_rate = parseFloat(cmd.variable("osc_rate")); - pointer.osc_scale = parseFloat(cmd.variable("osc_scale")); - } - if(cmd.angle()){ - pointer.angle = cmd.angle(); - } - if(cmd.rect() || cmd.position() || cmd.variable("osc_rate") || cmd.angle()){ - this.add_pointer(pointer); - } + // Global if(cmd.color()){ this.color = cmd.color(); } if(cmd.value()){ this.size = cmd.value().float; } + + this.update_variables(cmd); } this.passive = function(cmd) @@ -55,41 +44,83 @@ function Brush() ronin.overlay.draw(cmd.position()); } } - - this.add_pointer = function(pointer) + + this.size_up = function() { + this.size -= this.size > 1 ? 1 : 0; + ronin.widget.update(); + } + + this.size_down = function() + { + this.size += 1; + ronin.widget.update(); + } + + this.add_pointer = function(cmd) + { + var pointer = new Pointer(); + + if(cmd.position()){ + pointer.offset = cmd.position(); + } + if(cmd.rect()){ + pointer.mirror = cmd.rect(); + } + if(cmd.angle()){ + pointer.angle = cmd.angle(); + } + this.pointers.push(pointer); } - // Draw - - this.draw = function(e) + this.widget_cursor = function() { - if(this.is_drawing === false){return;} - - this.position = new Position(e.clientX,e.clientY); - - for (i = 0; i < this.pointers.length; i++) { - this.pointers[i].draw(); + + var s = "> "+this.size+"
"; + + for (i = 0; i < ronin.brush.pointers.length; i++) { + s += ronin.brush.pointers[i].widget(); } + return s; + + return this.pointers.length > 0 ? "Brush "+this.size+", "+this.pointers.length+" pointers" : "No Pointers"; } - this.draw_start = function(e) + // Cursor + + this.is_drawing = false; + + this.mouse_down = function(position) { this.is_drawing = true; - for (i = 0; i < this.pointers.length; i++) { - this.pointers[i].start(); + for (i = 0; i < ronin.brush.pointers.length; i++) { + ronin.brush.pointers[i].start(); } + + ronin.stroke.new_stroke(); } - this.draw_stop = function(e) + this.mouse_move = function(position) + { + if(this.is_drawing === false){ return; } + + for (i = 0; i < ronin.brush.pointers.length; i++) { + ronin.brush.pointers[i].draw(); + } + + ronin.stroke.append_stroke(position); + } + + this.mouse_up = function(position) { this.is_drawing = false; - for (i = 0; i < this.pointers.length; i++) { - this.pointers[i].stop(); + for (i = 0; i < ronin.brush.pointers.length; i++) { + ronin.brush.pointers[i].stop(); } + + ronin.stroke.save_stroke("brush"); } - } \ No newline at end of file diff --git a/scripts/modules/brush.pointer.js b/scripts/modules/brush.pointer.js index bb1302b..1e8c990 100644 --- a/scripts/modules/brush.pointer.js +++ b/scripts/modules/brush.pointer.js @@ -6,67 +6,105 @@ function Pointer(offset = new Position(), color = new Color('000000')) this.angle = null; this.distance = 0; - this.osc_scale = null; - this.osc_rate = null; - - this.draw = function() - { - if(!this.position_prev){this.position_prev = this.position(); } - if(ronin.brush.size < 0){ this.erase(); return; } - - var position = this.position(); - - this.distance += position.distance_to(this.position_prev); - - // Osc experiment - if(this.osc_rate && this.osc_scale){ - // position.x += (Math.sin(this.distance/(25 * this.osc_rate)) * this.osc_scale) - (this.osc_scale/2); - position.y += (Math.sin(this.distance/(25 * this.osc_rate)) * this.osc_scale) - (this.osc_scale/2); - } - - ronin.canvas.context().beginPath(); - ronin.canvas.context().moveTo(this.position_prev.x,this.position_prev.y); - ronin.canvas.context().lineTo(position.x,position.y); - ronin.canvas.context().lineCap="round"; - ronin.canvas.context().lineWidth = this.thickness(); - ronin.canvas.context().strokeStyle = ronin.brush.color.rgba(); - ronin.canvas.context().stroke(); - ronin.canvas.context().closePath(); - - this.position_prev = position; - } - - this.erase = function() - { - ronin.canvas.context().clearRect(this.position().x - (ronin.brush.size/2), this.position().y - (ronin.brush.size/2), ronin.brush.size, ronin.brush.size); - } - + // Parameters + this.thickness = function() { - var ratio = 10/this.position().distance_to(this.position_prev); + var ratio = 10/this.position().distance_to(this.position_prev[0]); ratio = ratio > 1 ? 1 : ratio; return ronin.brush.size * ratio; } + // + + this.draw = function() + { + if(!this.position_prev){this.position_prev = [this.position()]; return; } + + var position = this.position(); + var position_prev = this.position_prev[0]; + + //remove stale previous positions + if (this.position_prev.length > 3) this.position_prev.pop(); + + this.distance += position.distance_to(position_prev); + + ronin.surface.context().beginPath(); + + ronin.surface.context().globalCompositeOperation="source-over"; + ronin.surface.context().moveTo(position_prev.x,position_prev.y); + + //Choose direct line or curve line based on how many samples available + if(this.position_prev.length > 1 && position.distance_to(position_prev) > 13){ + + var d = + position.distance_to(position_prev)/ + position_prev.distance_to(this.position_prev[1]); + + //caluclate a control point for the quad curve + var ppx = position_prev.x - (this.position_prev[1].x - position_prev.x); + var ppy = position_prev.y - (this.position_prev[1].y - position_prev.y); + var px = (position.x + position_prev.x)/2; + var py = (position.y + position_prev.y)/2; + var tx = px + (ppx - px) * 0.2 * d; + var ty = py + (ppy - py) * 0.2 * d; + + ronin.surface.context().quadraticCurveTo(tx,ty,position.x,position.y); + } + else { + ronin.surface.context().lineTo(position.x,position.y); + } + + ronin.surface.context().lineCap="round"; + ronin.surface.context().lineWidth = this.thickness(); + ronin.surface.context().strokeStyle = ronin.brush.color.rgba(); + ronin.surface.context().stroke(); + ronin.surface.context().closePath(); + + this.position_prev.unshift(position); + } + this.position = function() { - if(this.angle){ - var angle_radian = this.angle.degrees * Math.PI / 180; - var deltaX = ronin.brush.position.x - this.offset.x; - var deltaY = ronin.brush.position.y - this.offset.y; - var t = Math.atan2(deltaY, deltaX) + angle_radian; - var radius = ronin.brush.position.distance_to(this.offset); - var x = Math.cos(t) * radius; - var y = Math.sin(t) * radius; - return new Position(x + this.offset.x,y + this.offset.y); + if(this.angle && this.offset){ + return this.position_rotation(); } else if(this.mirror && this.mirror.width > 0){ - return new Position((2 * this.mirror.width) - (ronin.brush.position.x + this.offset.x), 0 + (ronin.brush.position.y + this.offset.y)); + return this.position_mirror_x(); } else if(this.mirror && this.mirror.height > 0){ - return new Position((ronin.brush.position.x + this.offset.x), (2 * this.mirror.height) - (ronin.brush.position.y + this.offset.y)); + return this.position_mirror_y(); } - return new Position(ronin.brush.position.x + this.offset.x, ronin.brush.position.y + this.offset.y); + return this.position_default(); + } + + // Effects + + this.position_default = function() + { + return ronin.cursor.position.add(this.offset); + } + + this.position_mirror_x = function() + { + return new Position((2 * this.mirror.width) - (ronin.cursor.position.x + this.offset.x), 0 + (ronin.cursor.position.y + this.offset.y)); + } + + this.position_mirror_y = function() + { + return new Position((ronin.cursor.position.x + this.offset.x), (2 * this.mirror.height) - (ronin.cursor.position.y + this.offset.y)); + } + + this.position_rotation = function() + { + var angle_radian = this.angle.degrees * Math.PI / 180; + var deltaX = ronin.cursor.position.x - this.offset.x; + var deltaY = ronin.cursor.position.y - this.offset.y; + var t = Math.atan2(deltaY, deltaX) + angle_radian; + var radius = ronin.cursor.position.distance_to(this.offset); + var x = Math.cos(t) * radius; + var y = Math.sin(t) * radius; + return new Position(x + this.offset.x,y + this.offset.y); } this.start = function() @@ -77,4 +115,9 @@ function Pointer(offset = new Position(), color = new Color('000000')) { this.position_prev = null; } + + this.widget = function() + { + return this.offset.render()+"
"; + } } \ No newline at end of file diff --git a/scripts/modules/canvas.js b/scripts/modules/canvas.js deleted file mode 100644 index de5d546..0000000 --- a/scripts/modules/canvas.js +++ /dev/null @@ -1,49 +0,0 @@ -function Canvas(element) -{ - Module.call(this); - - this.parameters = [Rect,Color,Bang]; - this.element = element; - - this.active = function(cmd) - { - if(cmd.bang()){ this.clear(); } - - if(cmd.rect()){ - this.resize(cmd.rect()); - ronin.overlay.resize(cmd.rect()); - } - - if(cmd.color()){ - this.context().beginPath(); - this.context().rect(0, 0, this.element.width, this.element.height); - this.context().fillStyle = cmd.color().hex; - this.context().fill(); - } - } - - this.passive = function(cmd) - { - if(cmd.rect()){ - ronin.overlay.show_guide(null,cmd.rect()); - } - } - - // - - this.resize = function(rect) - { - this.element.setAttribute('width',rect.width+"px"); - this.element.setAttribute('height',rect.height+"px"); - } - - this.context = function() - { - return this.element.getContext('2d'); - } - - this.clear = function() - { - this.context().clearRect(0, 0, this.element.width, this.element.height); - } -} \ No newline at end of file diff --git a/scripts/modules/eraser.js b/scripts/modules/eraser.js new file mode 100644 index 0000000..973ccf4 --- /dev/null +++ b/scripts/modules/eraser.js @@ -0,0 +1,79 @@ +function Eraser(rune) +{ + Module.call(this,rune); + + this.parameters = [Value]; + this.size = 5; + + // Module + + this.position_prev = null; + + this.draw = function() + { + if(!this.position_prev){this.position_prev = ronin.cursor.position; } + if(ronin.brush.size < 0){ this.erase(); return; } + + var position = ronin.cursor.position; + + this.distance += position.distance_to(this.position_prev); + + ronin.surface.context().beginPath(); + ronin.surface.context().globalCompositeOperation="destination-out"; + ronin.surface.context().moveTo(this.position_prev.x,this.position_prev.y); + ronin.surface.context().lineTo(position.x,position.y); + ronin.surface.context().lineCap="round"; + ronin.surface.context().lineWidth = this.size; + ronin.surface.context().strokeStyle = new Color("#ff0000").rgba(); + ronin.surface.context().stroke(); + ronin.surface.context().closePath(); + + this.position_prev = position; + } + + this.active = function(cmd) + { + if(cmd.value()){ + this.size = cmd.value().float; + } + } + + this.passive = function(cmd) + { + + } + + this.widget_cursor = function() + { + return ". "+this.size; + } + + // Cursor + + this.is_drawing = false; + + this.mouse_down = function(position) + { + this.is_drawing = true; + this.position_prev = null; + + ronin.stroke.new_stroke(); + } + + this.mouse_move = function(position) + { + if(this.is_drawing === false){ return; } + + this.draw(); + + ronin.stroke.append_stroke(position); + } + + this.mouse_up = function(position) + { + this.is_drawing = false; + this.position_prev = null; + + ronin.stroke.save_stroke("eraser"); + } +} \ No newline at end of file diff --git a/scripts/modules/eye.js b/scripts/modules/eye.js new file mode 100644 index 0000000..61c3045 --- /dev/null +++ b/scripts/modules/eye.js @@ -0,0 +1,45 @@ +function Eye(rune) +{ + Module.call(this,rune); + + // Module + + this.active = function(cmd) + { + } + + this.passive = function(cmd) + { + } + + this.widget_cursor = function() + { + return "Eye"; + } + + this.color_picker = function(position) + { + var imgData = ronin.surface.context().getImageData(position.x, position.y, 1, 1).data; + var c = new Color(); + commander.show(); + commander.element_input.focus(); + commander.element_input.value = "> "+(c.rgb_to_hex(imgData)); + } + + // Cursor + + this.mouse_down = function(position) + { + this.color_picker(position); + } + + this.mouse_move = function(position) + { + this.color_picker(position); + } + + this.mouse_up = function(position) + { + this.color_picker(position); + } +} \ No newline at end of file diff --git a/scripts/modules/file.js b/scripts/modules/file.load.js similarity index 59% rename from scripts/modules/file.js rename to scripts/modules/file.load.js index 6eea27d..089dcd8 100644 --- a/scripts/modules/file.js +++ b/scripts/modules/file.load.js @@ -1,14 +1,11 @@ -function File() +function FileLoad(rune) { - Module.call(this); + Module.call(this,rune); - this.parameters = [Filepath,Position,Rect,Bang]; - this.storage = []; + this.parameters = [Filepath,Position,Rect]; this.active = function(cmd) { - if(cmd.bang()){ this.storage = []; } - ronin.overlay.clear(); if(!cmd.filepath() && !cmd.value()){ return; } @@ -16,7 +13,7 @@ function File() var position = cmd.position() ? cmd.position() : new Position(); base_image = new Image(); - base_image.src = cmd.value() && this.storage[cmd.value().int] ? this.storage[cmd.value().int] : cmd.filepath().path; + base_image.src = cmd.filepath().path; base_image.src += '?' + new Date().getTime(); base_image.crossOrigin = "Anonymous"; @@ -32,7 +29,7 @@ function File() width = isNaN(width) && height > 0 ? (height*base_image.naturalWidth)/base_image.naturalHeight : width; height = isNaN(height) && width > 0 ? (width*base_image.naturalHeight)/base_image.naturalWidth : height; - ronin.canvas.context().drawImage(base_image, position.x, position.y, width, height); + ronin.surface.context().drawImage(base_image, position.x, position.y, width, height); } } @@ -49,16 +46,4 @@ function File() ronin.overlay.draw(position); } } - - this.save = function(cmd) - { - if(cmd.value() && cmd.value().int > 0){ - this.storage[cmd.value().int] = ronin.canvas.element.toDataURL("image/png"); - } - else{ - var d = ronin.canvas.element.toDataURL("image/png"); - var w = window.open('about:blank','image from canvas'); - w.document.write(""+(cmd.content[0] ? cmd.content[0] : "Untitled")+"from canvas"); - } - } } \ No newline at end of file diff --git a/scripts/modules/file.save.js b/scripts/modules/file.save.js new file mode 100644 index 0000000..ad647a0 --- /dev/null +++ b/scripts/modules/file.save.js @@ -0,0 +1,22 @@ +function FileSave(rune) +{ + Module.call(this,rune); + + this.parameters = [Any]; + + this.active = function(cmd) + { + var n = "Ronin Export"; + var f = cmd.variable("format"); + var d = ronin.surface.merge(); + d = ronin.surface.active_layer.element.toDataURL('image/png'); + // // ronin.surface.layers["render"].clear(); + var w = window.open('about:blank','image from canvas'); + // w.document.write("hello") + w.document.write(""+(n ? n : "Untitled")+""); + } + + this.passive = function(cmd) + { + } +} \ No newline at end of file diff --git a/scripts/modules/filter.js b/scripts/modules/filter.js deleted file mode 100644 index c52ef3e..0000000 --- a/scripts/modules/filter.js +++ /dev/null @@ -1,121 +0,0 @@ -function Filter(element) -{ - Module.call(this); - - this.parameters = [Text,Value]; - - this.active = function(cmd) - { - if(cmd.content.length < 1){ return; } - - var p = cmd.content; - var filter_name = p[0]; - p.shift(); - - switch(filter_name) { - case "saturation": - this.filter_saturation(this.pixels(),p); - break; - case "chromatic": - this.filter_chromatic(this.pixels(),p); - break; - } - } - - this.passive = function(cmd) - { - } - - // Filters - - this.filter_saturation = function(pixels = this.pixels(),p = null) - { - var d = pixels.data; - for (var i=0; iHelp
"+html+"
"); + } + + // + + this.view_intro = function() + { + var html = "# Ronin\n## Basics\nRonin is a web based drawing application and visual language. Launch index.html and press **:**(colon) to display the command prompt. Input the commands below to interface with the different tools. \n```\n:\n```\n"; + + html += "### Loading/Saving\nRequires you to run Ronin through localhost. Navigate to the Ronin folder, and run the simple http server.\n"; + html += "```\ncd /path/to/ronin/ ; Navigate to Ronin through the terminal\npython -m SimpleHTTPServer 8000 ; Start localhost\nhttp://localhost:8000/ ; Enjoy Ronin\n```\n"; + html += "### Controls\n"; + html += "```\nctrl ; Draw Overlays\nalt ; Drag Surface\nshift ; Erase\nshift+ctrl ; Eyedrop\nshift+alt ; Move Layer\n```\n"; + return html; + } + + this.view_modules = function() + { + html = "## Modules\n"; + Object.keys(ronin.modules).forEach(function (key) { + html += "### "+key+" "+ronin.modules[key].constructor.name+"\n"; + html += ronin.modules[key].docs+"\n"; + html += "- Parameters: "; + for (i = 0; i < ronin.modules[key].parameters.length; i++) { + html += "`"+ronin.modules[key].parameters[i].name+"` "; + } + html += "\n"; + html += "- Variables: "; + for (var key in ronin.modules[key].variables){ + html += "`"+key+"` "; + } + html += "\n\n"; + }); + + return html; + } + + this.view_units = function() + { + html = "## Units\n"; + html += "```\n5 ; value: 5\n5,7 ; position: 5x 7y\n7x9 ; rect: 7w 9h\n#ff0000 ; color: red\n0..5 ; random: 0.0-5.0\n45' ; degree: 45/365\nrate=10 ; variable: rate = 10\n```\n"; + return html; + } + + this.view_presets = function() + { + html = "## Presets\n"; + html += "### Radial Brush\n"; + html += "```\n# 8 strands\n> 600,400 45';> 600,400 90';> 600,400 135';> 600,400 180';> 600,400 225';> 600,400 270';> 600,400 315'\n# 6 strands\n> 600,400 60';> 600,400 120';> 600,400 180';> 600,400 240';> 600,400 300'\n```\n" + html += "### Symmetry Brush\n"; + html += "```\n# XY\n> 400x 3\n# Angular brushes\n> 400x 1,1;> 400x 2,2;> 400x 3,3; > 1,1;> 2,2;> 3,3;\n```\n" + html += "### Angular Brush\n"; + html += "```\n# Light\n> 1,1;> 2,2;> 3,3;> 4,4\n# Hard\n> 2,2;> 4,4;> 6,6;> 8,8\n# Symmetric Light\n> 1,1 600x;> 2,2 600x;> 3,3 600x;> 4,4 600x\n```\n"; + + return html; + } + + function pad(s,length) + { + if(!s){ return s; } + + var new_string = s; + while(new_string.length < length){ + new_string += " "; + } + return new_string; + } +} \ No newline at end of file diff --git a/scripts/modules/hint.js b/scripts/modules/hint.js deleted file mode 100644 index 13be6eb..0000000 --- a/scripts/modules/hint.js +++ /dev/null @@ -1,32 +0,0 @@ -function Hint(element) -{ - Module.call(this); - - this.element = element; - - this.update = function() - { - if(ronin.module){ - this.element.innerHTML = this.message(ronin.module,commander.cmd); - this.element.style.display = "block"; - } - else{ - this.element.style.display = "none"; - } - } - - this.message = function(module,cmd) - { - var s = ""+module.constructor.name+""; - - var e = 0; - while(e < 10){ - if(!module.parameters[e]){ break; } - var param_name = module.parameters[e].name; - s += cmd[param_name.toLowerCase()]() ? ""+cmd[param_name.toLowerCase()]().render()+"" : ""+param_name+""; - e += 1; - } - - return s; - } -} \ No newline at end of file diff --git a/scripts/modules/history.js b/scripts/modules/history.js new file mode 100644 index 0000000..7962bf7 --- /dev/null +++ b/scripts/modules/history.js @@ -0,0 +1,30 @@ +function History(rune) +{ + Module.call(this,rune); + + this.cmds = []; + + this.active = function(cmd) + { + var w = window.open('about:blank','source'); + var html = ""; + + for (i = 0; i < this.cmds.length; i++) { + if(this.cmds[i][0] == this.rune){ continue; } + html += this.cmds[i]+";
"; + } + w.document.write("Source"+html+""); + } + + this.add = function(content) + { + this.cmds.push(content); + } + + this.widget = function() + { + if(this.cmds.length === 0){ return "";} + + return "^ "+this.cmds.length+" "; + } +} \ No newline at end of file diff --git a/scripts/modules/module.js b/scripts/modules/module.js new file mode 100644 index 0000000..defa29e --- /dev/null +++ b/scripts/modules/module.js @@ -0,0 +1,86 @@ +function Module(rune) +{ + this.rune = rune; + this.element = null; + this.parameters = []; + this.variables = {}; + + this.docs = "Missing documentation."; + + this.active = function(cmd) + { + console.log("Nothing to do."); + } + + this.passive = function(cmd) + { + console.log("Nothing to do."); + } + + this.update_variables = function(cmd) + { + for (var key in this.variables){ + if(!cmd.variable(key)){ continue; } + this.variables[key] = cmd.variable(key).value; + } + } + + this.hint = function(cmd) + { + var s = this.pad(cmd.content.join(" ")); + + s += cmd.content.join(" ").length == 0 ? ""+this.constructor.name+"" : ""; + + // Params + + var e = 0; + while(e < 10){ + if(!this.parameters[e]){ break; } + var param_name = this.parameters[e].name; + s += cmd[param_name.toLowerCase()]() ? "" : ""+param_name+""; + e += 1; + } + + // Variables + if(this.variables){ + for (var key in this.variables){ + if(cmd.variable(key)){continue;} + s += ""+key+"="+this.variables[key]+" "; + } + } + + return s; + } + + this.pad = function(input) + { + var s = ""; + for (i = 0; i < input.length+2; i++){ + s += "_"; + } + + return ""+s+""; + } + + this.widget = function() + { + return ""; + } + + this.widget_cursor = function() + { + return "Missing"; + } + + this.mouse_down = function(position) + { + } + + this.mouse_move = function(position) + { + } + + this.mouse_up = function(position) + { + } +} \ No newline at end of file diff --git a/scripts/modules/overlay.js b/scripts/modules/overlay.js index 91ce5d2..d86634f 100644 --- a/scripts/modules/overlay.js +++ b/scripts/modules/overlay.js @@ -1,9 +1,8 @@ -function Overlay(element) +function Overlay(rune) { - Module.call(this); + Module.call(this,rune); this.parameters = [Position,Rect]; - this.element = element; // Module @@ -23,7 +22,7 @@ function Overlay(element) { this.clear(); - if(!position){ return; } + if(!position){ position = new Position("0,0"); } if(rect){ this.draw_rect(position,rect); @@ -104,26 +103,11 @@ function Overlay(element) this.resize = function(rect) { - this.element.setAttribute('width',rect.width+"px"); - this.element.setAttribute('height',rect.height+"px"); - } - - this.show_guide = function(position,rect) - { - this.clear(); - this.context().beginPath(); - - this.context().moveTo(0,0); - this.context().lineTo(rect.width,0); - this.context().lineTo(rect.width,rect.height); - this.context().lineTo(0,rect.height); - this.context().lineTo(0,0); - - this.context().lineCap="round"; - this.context().lineWidth = 1; - this.context().strokeStyle = "#ff0000"; - this.context().stroke(); - this.context().closePath(); + this.element.width = rect.width * 2; + this.element.height = rect.height * 2; + this.element.style.width = rect.width+"px"; + this.element.style.height = rect.height+"px"; + this.context().scale(2,2); } this.context = function() @@ -133,6 +117,47 @@ function Overlay(element) this.clear = function() { - this.context().clearRect(0, 0, ronin.canvas.element.width, ronin.canvas.element.height); + this.context().clearRect(0, 0, ronin.surface.size.width, ronin.surface.size.height); + } + + // Cursor + + this.live_draw_from = null; + + this.mouse_down = function(position) + { + ronin.overlay.clear(); + ronin.overlay.draw_pointer(position); + this.live_draw_from = position; + commander.show(); + commander.element_input.focus(); + commander.element_input.value = "| "+this.live_draw_from.render(); + } + + this.mouse_move = function(position) + { + if(this.live_draw_from === null){ return; } + + ronin.overlay.clear(); + + var rect = new Rect(); + rect.width = position.x - this.live_draw_from.x; + rect.height = position.y - this.live_draw_from.y; + + ronin.overlay.draw_rect(this.live_draw_from,rect); + commander.element_input.value = "| "+this.live_draw_from.render()+" "+rect.render(); + } + + this.mouse_up = function(position) + { + this.live_draw_from = null; + commander.element_input.focus(); + } + + // Widget + + this.widget_cursor = function() + { + return "Guide"; } } \ No newline at end of file diff --git a/scripts/modules/render.js b/scripts/modules/render.js new file mode 100644 index 0000000..4eec86e --- /dev/null +++ b/scripts/modules/render.js @@ -0,0 +1,30 @@ +function Render(rune) +{ + Module.call(this,rune); + + this.parameters = [Any]; + this.collection = {}; + + this.collection["stencil"] = new Filter_Stencil(); + this.collection["rotate"] = new Filter_Rotate(); + this.collection["invert"] = new Filter_Invert(); + this.collection["chromatic"] = new Filter_Chromatic(); + + this.active = function(cmd) + { + var name = cmd.content[0]; + + if(!this.collection[name]){ return; } + + return this.collection[name].render(cmd); + } + + this.passive = function(cmd) + { + var name = cmd.content[0]; + if(!this.collection[name]){ return; } + + return this.collection[name].preview(cmd); + } + +} diff --git a/scripts/modules/stroke.js b/scripts/modules/stroke.js index 4a87cf0..d83a090 100644 --- a/scripts/modules/stroke.js +++ b/scripts/modules/stroke.js @@ -1,9 +1,33 @@ -function Stroke(element) +function Stroke(rune) { - Module.call(this); + Module.call(this,rune); this.parameters = [Any]; + // Create a stroke + + this.positions = null; + + this.new_stroke = function() + { + this.positions = []; + } + + this.append_stroke = function(p) + { + this.positions.push(p); + } + + this.save_stroke = function(mode) + { + s = "_ module="+mode+" "; + for (i = 0; i < this.positions.length; i++) { + s += this.positions[i].render()+" "; + } + if(this.positions.length > 0){ ronin.history.add(s); } + this.positions = null; + } + // Module this.passive = function(cmd) @@ -12,23 +36,26 @@ function Stroke(element) this.active = function(cmd) { - // TODO - - var origin = new Position(cmd.content[0]); - var destination = new Position(cmd.content[1]); - - var e = {}; - e.clientX = origin.x; - e.clientY = origin.y; - - ronin.brush.is_drawing = true; - ronin.brush.draw(e); - - e.clientX = destination.x; - e.clientY = destination.y; - - ronin.brush.draw(e); - ronin.brush.is_drawing = false; + var prev = null + for (i = 1; i < cmd.content.length; i++) { + var p = new Position(cmd.content[i]); + if(prev){ + this.draw(prev,p); + } + prev = p; + } + } + + this.draw = function(pos1,pos2) + { + ronin.surface.context().beginPath(); + ronin.surface.context().moveTo(pos1.x,pos1.y); + ronin.surface.context().lineTo(pos2.x,pos2.y); + ronin.surface.context().lineCap="round"; + ronin.surface.context().lineWidth = 10; + ronin.surface.context().strokeStyle = ronin.brush.color.rgba(); + ronin.surface.context().stroke(); + ronin.surface.context().closePath(); } } \ No newline at end of file diff --git a/scripts/modules/surface.js b/scripts/modules/surface.js new file mode 100644 index 0000000..8f2455f --- /dev/null +++ b/scripts/modules/surface.js @@ -0,0 +1,187 @@ +function Surface(rune) +{ + Module.call(this,rune); + + this.element = null; + this.parameters = [Rect,Color,Bang]; + this.variables = {"layer" : "main"}; + + this.layers = {}; + this.active_layer = null; + this.render_layer = null; + + this.size = null; + + this.active = function(cmd) + { + if(cmd.rect()){ + this.resize(cmd.rect(),cmd.position()); + ronin.overlay.resize(cmd.rect()); + } + + if(cmd.color()){ + this.context().beginPath(); + this.context().rect(0, 0, this.active_layer.element.width, this.active_layer.element.height); + this.context().fillStyle = cmd.color().hex; + this.context().fill(); + } + + if(cmd.bang() && Object.keys(ronin.surface.layers).length > 1){ + delete this.layers[this.active_layer.name]; + this.select_any_layer(); + ronin.widget.update(); + } + + if(cmd.variable("layer")){ + var name = cmd.variable("layer").value; + if(!this.layers[name]){ + this.add_layer(new Layer(name,this.size)); + } + this.select_layer(this.layers[name]); + } + } + + this.select_layer = function(layer) + { + console.log("Selecting layer:"+layer.name); + this.active_layer = layer; + } + + this.select_any_layer = function() + { + var layer_name = Object.keys(ronin.surface.layers)[0]; + this.select_layer(ronin.surface.layers[layer_name]); + } + + this.add_layer = function(layer) + { + console.log("Creating layer:"+layer.name); + + this.layers[layer.name] = layer; + this.active_layer = layer; + this.element.appendChild(layer.element); + this.active_layer.resize(this.size); + } + + this.passive = function(cmd) + { + if(cmd.rect()){ + ronin.overlay.draw(cmd.position(),cmd.rect()); + } + } + + this.resize = function(rect, position = null) + { + this.size = rect; + + Object.keys(ronin.surface.layers).forEach(function (key) { + ronin.surface.layers[key].resize(rect); + }); + + ronin.surface.element.width = rect.width * 2; + ronin.surface.element.height = rect.height * 2; + ronin.surface.element.style.width = rect.width+"px"; + ronin.surface.element.style.height = rect.height+"px"; + ronin.surface.element.style.marginLeft = -(rect.width/2); + ronin.surface.element.style.marginTop = -(rect.height/2); + + ronin.on_resize(); + } + + this.widget = function() + { + if(!this.active_layer){ return ""; } + + var s = ""; + + Object.keys(ronin.surface.layers).forEach(function (key) { + s = ronin.surface.layers[key].widget()+s; + }); + return "# "+this.size.render()+"
"+s; + } + + this.widget_cursor = function() + { + return "Drag"; + } + + // Commands + + this.layer_up = function() + { + var keys = Object.keys(ronin.surface.layers); + var loc = keys.indexOf(this.active_layer.name); + + if(loc >= keys.length-1){ console.log("Reached end"); return false; } + + if(keys[loc+1] != null){this.select_layer(ronin.surface.layers[keys[loc+1]]);} + } + + this.layer_down = function() + { + var keys = Object.keys(ronin.surface.layers); + var loc = keys.indexOf(this.active_layer.name); + + if(keys[loc-1] != null){this.select_layer(ronin.surface.layers[keys[loc-1]]);} + } + + // Layers + + this.context = function() + { + return this.active_layer.context(); + } + + this.merge = function() + { + // this.render_layer = this.layers["render"]; + + // var a = []; + // Object.keys(ronin.surface.layers).forEach(function (key) { + // if(key != "render"){ + // a.push(ronin.surface.layers[key]); + // } + // }); + // for (i = a.length; i > 0 ; i--) { + // ronin.surface.render_layer.context().drawImage(a[i-1].context().canvas,0,0,this.size.width,this.size.height); + // } + return this.context(); + } + + // Cursor + + this.drag_from = null; + this.drag_offset_x = 0; + this.drag_offset_y = 0; + + this.mouse_down = function(position) + { + this.drag_from = ronin.position_in_window(position); + } + + this.mouse_move = function(position) + { + if(this.drag_from === null){ return; } + + position = ronin.position_in_window(position); + + var offset_x = this.drag_from.x - position.x; + var offset_y = this.drag_from.y - position.y; + this.drag_offset_x -= offset_x; + this.drag_offset_y -= offset_y; + + ronin.surface.element.style.marginLeft = -(this.size.width/2) + this.drag_offset_x; + ronin.surface.element.style.marginTop = -(this.size.height/2) + this.drag_offset_y; + + ronin.element.style.backgroundPosition = ((this.drag_offset_x/8))-(window.innerWidth % 20)+"px "+((this.drag_offset_y/8)-(window.innerWidth % 20))+"px"; + ronin.widget.element.style.marginLeft = this.drag_offset_x; + ronin.widget.element.style.marginTop = this.drag_offset_y; + + this.drag_from = new Position(position.x,position.y); + } + + this.mouse_up = function(event) + { + this.drag_from = null; + } +} \ No newline at end of file diff --git a/scripts/modules/surface.layer.js b/scripts/modules/surface.layer.js new file mode 100644 index 0000000..ee2d422 --- /dev/null +++ b/scripts/modules/surface.layer.js @@ -0,0 +1,82 @@ +function Layer(name,host = "user") +{ + this.name = name; + this.host = host; + this.element = document.createElement("canvas"); + this.element.setAttribute("id","_"+name); + this.element.setAttribute("class","layer"); + + this.resize = function(rect) + { + console.log("Resize "+this.name+" to "+rect.render()); + + var pixels_rect = new Rect(this.element.width+"x"+this.element.height); + + this.element.width = rect.width * 2; + this.element.height = rect.height * 2; + this.element.style.width = rect.width+"px"; + this.element.style.height = rect.height+"px"; + + this.context().scale(2,2); + } + + this.clear = function() + { + this.context().clearRect(0, 0, this.element.width, this.element.height); + } + + this.context = function() + { + return this.element.getContext('2d'); + } + + this.image = function() + { + return this.element.toDataURL('image/png'); + } + + // + + this.widget_cursor = function() + { + return "Move"; + } + + this.widget = function() + { + return (ronin.surface.active_layer.name == this.name) ? "- ("+this.name+")
" : "- "+this.name+"
"; + } + + this.move_from = null; + + this.mouse_down = function(position) + { + this.move_from = ronin.position_in_window(position); + ronin.stroke.new_stroke(); + } + + this.mouse_move = function(position) + { + if(this.move_from === null){ return; } + + ronin.stroke.append_stroke(position); // Save to stroke + + position = ronin.position_in_window(position); + + var offset_x = this.move_from.x - position.x; + var offset_y = this.move_from.y - position.y; + + var imageData = this.context().getImageData(0, 0, ronin.surface.size.width * 2, ronin.surface.size.height * 2); + this.clear(); + this.context().putImageData(imageData, -offset_x * 2, -offset_y * 2); + + this.move_from = new Position(position.x,position.y); + + } + + this.mouse_up = function(event) + { + this.move_from = null; + ronin.stroke.save_stroke("move"); + } +} \ No newline at end of file diff --git a/scripts/modules/typographe.js b/scripts/modules/typographe.js new file mode 100644 index 0000000..5cc1280 --- /dev/null +++ b/scripts/modules/typographe.js @@ -0,0 +1,39 @@ +function Typographe(rune) +{ + Module.call(this,rune); + + this.parameters = [Position,Color,Value]; + this.variables = {"text" : null}; + + this.active = function(cmd) + { + var target = ronin.surface.active_layer; + target.clear(); + if(cmd.variable("text")){ + this.add_text(target.context(),cmd); + } + } + + this.passive = function(cmd) + { + var target = ronin.overlay; + target.clear(); + if(cmd.variable("text")){ + this.add_text(target.context(),cmd); + } + } + + this.add_text = function(context,cmd) + { + var ctx = context; + + var text = cmd.variable("text").value; + var position = cmd.position() ? cmd.position() : new Position(20,40); + var color = cmd.color() ? cmd.color() : new Color("#000000"); + var size = cmd.value() ? cmd.value().int : 20; + + ctx.font = size+"px Georgia"; + ctx.fillStyle = color.hex; + ctx.fillText(text,position.x,position.y); + } +} \ No newline at end of file diff --git a/scripts/modules/vector.js b/scripts/modules/vector.js index d1912cd..3fa5cba 100644 --- a/scripts/modules/vector.js +++ b/scripts/modules/vector.js @@ -1,6 +1,6 @@ -function Vector() +function Vector(rune) { - Module.call(this); + Module.call(this,rune); this.parameters = [Any,Position]; @@ -18,10 +18,10 @@ function Vector() this.active = function(cmd) { ronin.overlay.clear(); - ronin.canvas.context().lineCap="round"; - ronin.canvas.context().lineWidth = ronin.brush.size; - ronin.canvas.context().strokeStyle = ronin.brush.color.rgba(); - ronin.canvas.context().stroke(new Path2D(cmd.content.join(" "))); + ronin.surface.context().lineCap="round"; + ronin.surface.context().lineWidth = ronin.brush.size; + ronin.surface.context().strokeStyle = ronin.brush.color.rgba(); + ronin.surface.context().stroke(new Path2D(cmd.content.join(" "))); } // + M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 ; Draw a circle diff --git a/scripts/ronin.js b/scripts/ronin.js deleted file mode 100644 index 9cca5d8..0000000 --- a/scripts/ronin.js +++ /dev/null @@ -1,11 +0,0 @@ -function Ronin() -{ - this.canvas = new Canvas(); - this.overlay = new Overlay(); - this.brush = new Brush(); - this.file = new File(); - this.hint = new Hint(); - this.filter = new Filter(); - this.stroke = new Stroke(); - this.vector = new Vector(); -} \ No newline at end of file diff --git a/scripts/unit.js b/scripts/unit.js deleted file mode 100644 index ace87e1..0000000 --- a/scripts/unit.js +++ /dev/null @@ -1,7 +0,0 @@ -function Unit() -{ - this.render = function() - { - return "HEY!"; - } -} \ No newline at end of file diff --git a/scripts/units/angle.js b/scripts/units/angle.js index d15345a..578e258 100644 --- a/scripts/units/angle.js +++ b/scripts/units/angle.js @@ -1,7 +1,9 @@ -function Angle(angle_str) +function Angle(angle_str = "0'") { Unit.call(this); + this.example = "45'"; + this.degrees = parseFloat(angle_str.replace('\'','')); this.render = function() diff --git a/scripts/units/any.js b/scripts/units/any.js index 0c8725d..3e2428f 100644 --- a/scripts/units/any.js +++ b/scripts/units/any.js @@ -2,6 +2,7 @@ function Any(str) { Unit.call(this); + this.example = ""; this.string = str; this.render = function() diff --git a/scripts/units/bang.js b/scripts/units/bang.js index 6671eae..127a44e 100644 --- a/scripts/units/bang.js +++ b/scripts/units/bang.js @@ -2,6 +2,8 @@ function Bang() { Unit.call(this); + this.example = ""; + this.render = function() { return "BANG"; diff --git a/scripts/units/color.js b/scripts/units/color.js index b2fe1a1..9cf1d67 100644 --- a/scripts/units/color.js +++ b/scripts/units/color.js @@ -2,6 +2,7 @@ function Color(hex = '#000000') { Unit.call(this); + this.example = "#ff0000"; this.hex = hex; this.rgb = function() @@ -23,4 +24,9 @@ function Color(hex = '#000000') { 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); + } } \ No newline at end of file diff --git a/scripts/units/filepath.js b/scripts/units/filepath.js index 3aca1dc..d856346 100644 --- a/scripts/units/filepath.js +++ b/scripts/units/filepath.js @@ -2,6 +2,7 @@ function Filepath(path_str) { Unit.call(this); + this.example = "assets/demo.png"; this.path = path_str; this.render = function() diff --git a/scripts/units/position.js b/scripts/units/position.js index 9cd7606..4203e78 100644 --- a/scripts/units/position.js +++ b/scripts/units/position.js @@ -2,10 +2,16 @@ function Position(position_str = "0,0",y = null) { Unit.call(this); + this.example = "100,150"; this.position_str = position_str; - this.x = y ? position_str : parseFloat(this.position_str.split(",")[0]); - this.y = y ? y : parseFloat(this.position_str.split(",")[1]); + this.x = y != null ? position_str : parseFloat(this.position_str.split(",")[0]); + this.y = y != null ? y : parseFloat(this.position_str.split(",")[1]); + + this.add = function(position) + { + return new Position(this.x + position.x, this.y + position.y); + } this.is_equal = function(target) { diff --git a/scripts/units/range.js b/scripts/units/range.js new file mode 100644 index 0000000..3dc3d38 --- /dev/null +++ b/scripts/units/range.js @@ -0,0 +1,15 @@ +function Range(range_str) +{ + Unit.call(this); + + this.example = "10..50"; + this.range_str = range_str; + + this.from = parseFloat(this.range_str.split("..")[0]); + this.to = parseFloat(this.range_str.split("..")[1]); + + this.render = function() + { + return this.from+".."+this.to; + } +} \ No newline at end of file diff --git a/scripts/units/rect.js b/scripts/units/rect.js index 27daeba..c0b3c12 100644 --- a/scripts/units/rect.js +++ b/scripts/units/rect.js @@ -2,10 +2,11 @@ function Rect(rect_str) { Unit.call(this); + this.example = "200x300"; this.rect_str = rect_str; - this.width = parseFloat(this.rect_str.split("x")[0]); - this.height = parseFloat(this.rect_str.split("x")[1]); + this.width = rect_str ? parseFloat(this.rect_str.split("x")[0]) : 0; + this.height = rect_str ? parseFloat(this.rect_str.split("x")[1]) : 0; this.render = function() { diff --git a/scripts/units/unit.js b/scripts/units/unit.js new file mode 100644 index 0000000..58c3d21 --- /dev/null +++ b/scripts/units/unit.js @@ -0,0 +1,9 @@ +function Unit() +{ + this.example = "unknown"; + + this.render = function() + { + return "[MISSING]"; + } +} \ No newline at end of file diff --git a/scripts/units/value.js b/scripts/units/value.js index a6b98e5..3bb7e26 100644 --- a/scripts/units/value.js +++ b/scripts/units/value.js @@ -2,6 +2,7 @@ function Value(value_str) { Unit.call(this); + this.example = "20"; this.value = value_str; this.float = parseFloat(this.value); this.int = parseInt(this.value); diff --git a/scripts/units/variable.js b/scripts/units/variable.js new file mode 100644 index 0000000..2d59f7f --- /dev/null +++ b/scripts/units/variable.js @@ -0,0 +1,16 @@ +function Variable(key,value) +{ + Unit.call(this); + + this.candidates = []; + this.key = key; + + if(value == "true"){ this.value = true; } + else if(value == "false"){ this.value = false; } + else{ this.value = value; } + + this.render = function() + { + return this.key+"="+this.value; + } +} \ No newline at end of file