diff --git a/README.md b/README.md index 39914ab..054398a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Ronin helpers are keywords that facilitates adding coordinates from the canvas i ## Library -- `(import path shape)` Imports a graphic file with format. +- `(import path shape ~alpha)` Imports a graphic file with format. - `(export path ~format ~quality)` Exports a graphic file with format. - `(open path ~ratio)` Imports a graphic file and resizes the frame. - `(move x y)` @@ -55,6 +55,7 @@ Ronin helpers are keywords that facilitates adding coordinates from the canvas i - `(circle cx cy r)` Returns a circle shape. - `(ellipse cx cy rx ry)` Returns a ellipse shape. - `(line ax ay bx by)` Returns a line shape. +- `(poly ...pos)` Returns a poly shape. - `(text x y p t ~a ~f)` Returns a text shape. - `(svg x y d)` Returns a svg shape. - `(color r g b ~a)` Returns a color object. @@ -68,7 +69,7 @@ Ronin helpers are keywords that facilitates adding coordinates from the canvas i - `(hsla h s l ~a)` Defines a color h from 0 to 360, s and l from 0 to 100, a from 0 to 1 - `(frame)` Returns a rect of the frame. - `(center)` Returns a position of the center of the frame. -- `(resize w h ~fit)` Resizes the canvas to target w and h, returns the rect. +- `(resize ~w)` Resizes the canvas to target w and h, returns the rect. - `(rescale w h)` Rescales the canvas to target ratio of w and h, returns the rect. - `(crop rect)` Crop canvas to rect. - `(clone a b)` @@ -126,9 +127,9 @@ Ronin helpers are keywords that facilitates adding coordinates from the canvas i - `(keys item)` Returns a list of the object's keys - `(values item)` Returns a list of the object's values - `(convolve kernel ~rect)` -- `(blur)` -- `(sharpen)` -- `(edge)` +- `(blur)` Returns the blur kernel. +- `(sharpen)` Returns the sharpen kernel. +- `(edge)` Returns the edge kernel. - `(dir ~path)` Returns the content of a directory. - `(file ~path)` Returns the content of a file. - `(dirpath ~path)` Returns the path of a directory. diff --git a/desktop/sources/index.html b/desktop/sources/index.html index e36fe26..f9e649f 100644 --- a/desktop/sources/index.html +++ b/desktop/sources/index.html @@ -43,6 +43,7 @@ ronin.controller.addRole('default', 'Edit', 'delete') ronin.controller.addRole('default', 'Edit', 'selectall') ronin.controller.add("default","Edit","Re-Indent",() => { ronin.commander.reindent() },"CmdOrCtrl+Shift+I") + ronin.controller.add("default","Edit","Clean",() => { ronin.commander.cleanup() },"Escape") ronin.controller.add("default","View","Zoom In",() => { ronin.modZoom(0.25) },"CmdOrCtrl+=") ronin.controller.add("default","View","Zoom Out",() => { ronin.modZoom(-0.25) },"CmdOrCtrl+-") ronin.controller.add("default","View","Zoom Reset",() => { ronin.modZoom(1,true) },"CmdOrCtrl+0") diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index da36906..1ad3858 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -36,7 +36,7 @@ function Commander (ronin) { } this.run = (txt = this._input.value) => { - if (this._input.value.indexOf('$') > -1) { console.warn('$ is present.'); return } + if (this._input.value.indexOf('$') > -1) { txt = this.clean(txt) } ronin.bindings = {} if (this._input.value.trim() === '') { ronin.surface.maximize() @@ -77,6 +77,20 @@ function Commander (ronin) { this._input.value = val.trim() } + this.clean = function (input) { + const keywords = ['$pos+', '$pos', '$rect', '$line', '$x', '$y', '$xy'] + for (word of keywords) { + input = input.replace(word, '').trim() + } + return input + } + + this.cleanup = function () { + this._input.value = this.clean(this._input.value) + this.reindent() + this.run() + } + this.setStatus = function (msg) { // Logs if (msg && msg !== this._log.textContent) { @@ -137,34 +151,26 @@ function Commander (ronin) { this.commit = function (shape, end = false, run = false) { if (this.cache.indexOf('$') < 0) { return } const segs = this.cache.split('$') - const seg = segs[1] - const words = seg.split(' ') - const word = words[0] - if (word.substr(0, 4) === 'rect' && shape.rect) { - const rect = shape.rect - this._input.value = this.cache.replace('$rect', `(rect ${rect.x} ${rect.y} ${rect.w} ${rect.h})`) - } else if (word.substr(0, 3) === 'pos' && shape.pos) { - const pos = shape.pos - this._input.value = this.cache.replace('$pos', `(pos ${pos.x} ${pos.y})`) - } else if (word.substr(0, 4) === 'line' && shape.line) { - const line = shape.line - this._input.value = this.cache.replace('$line', `(line ${line.a.x} ${line.a.y} ${line.b.x} ${line.b.y})`) - } else if (word.substr(0, 6) === 'circle' && shape.circle) { - const circle = shape.circle - this._input.value = this.cache.replace('$circle', `(circle ${circle.cx} ${circle.cy} ${circle.r.toFixed(2)})`) - } else if (word.substr(0, 4) === 'drag' && shape.line) { - const rect = shape.rect - this._input.value = this.cache.replace('$drag', `(drag (rect ${rect.x} ${rect.y} ${rect.w} ${rect.h}) $line)`) - } else if (word.substr(0, 4) === 'view' && shape.line) { - const rect = shape.rect - this._input.value = this.cache.replace('$view', `(view (rect ${rect.x} ${rect.y} ${rect.w} ${rect.h}) $rect)`) - } else if (word.substr(0, 2) === 'xy' && shape.x) { - this._input.value = this.cache.replace('$xy', `${shape.x} ${shape.y}`) - } else if (word.substr(0, 1) === 'x' && shape.x) { - this._input.value = this.cache.replace('$x', `${shape.x}`) - } else if (word.substr(0, 1) === 'y' && shape.y) { - this._input.value = this.cache.replace('$y', `${shape.y}`) + const words = segs[1].split(' ') + const word = words[0].replace(/[^0-9a-z]/gi, '') + const append = words[0].indexOf('+') > -1 + + if (word === 'drag') { + this.cache = this.cache.replace('$drag', `(drag $rect $line)`) + } else if (word === 'view') { + this.cache = this.cache.replace('$view', `(drag $rect $rect)`) + } else if (word === 'poly') { + this.cache = this.cache.replace('$poly', `(poly $pos+)`) } + + if (shape[word]) { + if (append) { + this._input.value = this.cache.replace('$' + word + '+', this.template(shape[word], word) + ' $' + word + '+') + } else { + this._input.value = this.cache.replace('$' + word, this.template(shape[word], word)) + } + } + if (end === true) { this.cache = this._input.value } @@ -173,6 +179,15 @@ function Commander (ronin) { } } + this.template = function (shape, word) { + if (word === 'rect') { return `(rect ${shape.x} ${shape.y} ${shape.w} ${shape.h})` } + if (word === 'pos') { return `(pos ${shape.x} ${shape.y})` } + if (word === 'line') { return `(line ${shape.a.x} ${shape.a.y} ${shape.b.x} ${shape.b.y})` } + if (word === 'circle') { return `(circle ${shape.cx} ${shape.cy} ${shape.r})` } + if (word === 'x' || word === 'y' || word === 'xy') { return `${shape}` } + return '' + } + // Display this.show = function (expand = false) { @@ -237,7 +252,7 @@ function Commander (ronin) { // Splash - this.splash = `; welcome to ronin - v2.23 + this.splash = `; welcome to ronin - v2.24 (clear) (def frame-rect (frame)) diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index e26530a..0bbbbeb 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -63,7 +63,7 @@ function Library (ronin) { } this.rect = (x, y, w, h) => { // Returns a rect shape. - return { x, y, w, h } + return { x, y, w, h, pos: { x, y }, size: { w, h } } } this.circle = (cx, cy, r) => { // Returns a circle shape. @@ -78,6 +78,10 @@ function Library (ronin) { return { a: this.pos(ax, ay), b: this.pos(bx, by) } } + this.poly = (...pos) => { // Returns a poly shape. + return pos + } + this.text = (x, y, p, t, a = 'left', f = 'Arial') => { // Returns a text shape. return { x, y, p, t, a, f } } @@ -88,7 +92,7 @@ function Library (ronin) { this.color = (r, g, b, a = 1) => { // Returns a color object. const hex = '#' + ('0' + parseInt(r, 10).toString(16)).slice(-2) + ('0' + parseInt(g, 10).toString(16)).slice(-2) + ('0' + parseInt(b, 10).toString(16)).slice(-2) - return { r, g, b, a, hex, toString: () => { return hex }, 0: r, 1: g, 2: b, 3: a } + return { r, g, b, a, hex, toString: () => { return `rgba(${r},${g},${b},${a})` }, 0: r, 1: g, 2: b, 3: a } } this.offset = (a, b) => { // Offsets pos a with pos b, returns a. @@ -488,17 +492,23 @@ function Library (ronin) { return rect } - this.blur = [[1, 2, 1], - [2, 4, 2], - [1, 2, 2]] + this.blur = () => { // Returns the blur kernel. + return [[1, 2, 1], + [2, 4, 2], + [1, 2, 2]] + } - this.sharpen = [[ 0, -1, 0], - [-1, 5, -1], - [ 0, -1, 0]] + this.sharpen = () => { // Returns the sharpen kernel. + return [[ 0, -1, 0], + [-1, 5, -1], + [ 0, -1, 0]] + } - this.edge = [[-1, -1, -1], - [-1, 9, -1], - [-1, -1, -1]] + this.edge = () => { // Returns the edge kernel. + return [[-1, -1, -1], + [-1, 9, -1], + [-1, -1, -1]] + } // File System diff --git a/desktop/sources/scripts/ronin.js b/desktop/sources/scripts/ronin.js index 8e7da6f..550157d 100644 --- a/desktop/sources/scripts/ronin.js +++ b/desktop/sources/scripts/ronin.js @@ -144,6 +144,7 @@ function Ronin () { if (!this.mouseOrigin) { return } const x = position.x const y = position.y + const xy = x + ' ' + y const pos = { x, y } const rect = { x: this.mouseOrigin.x, @@ -159,10 +160,10 @@ function Ronin () { const circle = { cx: this.mouseOrigin.x, cy: this.mouseOrigin.y, - r: d, + r: d.toFixed(2), edge: { x: rect.x - rect.w, y: rect.y - rect.h, w: rect.w * 2, h: rect.h * 2 } } - return { x, y, d, line, rect, pos, circle, type, 'is-down': type !== 'mouse-up' ? true : null } + return { x, y, xy, d, line, rect, pos, circle, type, 'is-down': type !== 'mouse-up' ? true : null } } // Zoom diff --git a/desktop/sources/scripts/surface.js b/desktop/sources/scripts/surface.js index 9fe2363..7c6edb1 100644 --- a/desktop/sources/scripts/surface.js +++ b/desktop/sources/scripts/surface.js @@ -111,8 +111,12 @@ function Surface (ronin) { } this.traceLine = function (line, context) { - context.moveTo(line.a.x, line.a.y) - context.lineTo(line.b.x, line.b.y) + const positions = Object.values(line) + const origin = positions.pop() + context.moveTo(origin.x, origin.y) + for (pos of positions) { + context.lineTo(pos.x, pos.y) + } } this.tracePos = function (pos, context, radius = 7.5) { @@ -315,7 +319,8 @@ function Surface (ronin) { return !isNaN(shape.x) && !isNaN(shape.y) && shape.p && shape.t && shape.f && shape.a } function isLine (shape) { - return shape.a && !isNaN(shape.a.x) && !isNaN(shape.a.y) && shape.b && !isNaN(shape.b.x) && !isNaN(shape.b.y) + const positions = Object.values(shape) + return !isNaN(positions[0].x) && !isNaN(positions[0].y) && !isNaN(positions[1].x) && !isNaN(positions[1].y) } function fitRect (image, container) {