diff --git a/README.md b/README.md index 4a1d92b..3a081da 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,13 @@ The library updates is constantly revealing new applications to Ronin, you can s Learn more by reading the manual, or have a look at some experiments on twitter. If you need help, visit the Community, follow the [workshop](https://github.com/hundredrabbits/Ronin/blob/master/WORKSHOP.md) or watch the [video tutorial](https://www.youtube.com/watch?v=SgAWGh1s9zg). ```lisp -; draw a red square +; clear screen +(clear) +; draw red square (stroke (rect 30 30 100 100) "red" 2) +; download result +(export) ``` ## Install & Run @@ -36,8 +40,23 @@ Ronin helpers are keywords that facilitates adding coordinates from the canvas i (fill $circle "red") ``` +## Importing an image + +To save an image in memory, open an image file with Ronin, or drag an image file on the window. You will then be able to import it by using the file image's name. If the image file is `preview.png`, you can import it as follow: + +```lisp +; import image at position +(import "preview.jpg" + (pos 100 100)) + +; import image at position, with size +(import "preview.jpg" + (rect 100 100 400 400)) +``` + ## Library +- `(import ~name ~shape)` Imports a graphic file with format. - `(export ~name ~format ~quality)` Exports a graphic file with format. - `(pos ~x ~y)` Returns a position shape. - `(line ax ay bx by)` Returns a line shape. @@ -133,19 +152,6 @@ Ronin helpers are keywords that facilitates adding coordinates from the canvas i - `(test name a b)` - `(benchmark fn)` Logs time taken to execute a function. -### In Development - -- `(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. -- `(exit ~force)` Exits Ronin. -- `(dir ~path)` Returns the content of a directory. -- `(file ~path)` Returns the content of a file. -- `(dirpath ~path)` Returns the path of a directory. -- `(filepath ~path)` Returns the path of a file. -- `(dirname ~path)` Returns the name of a folder. -- `(filename ~path)` Returns the name of a file. - diff --git a/desktop/sources/links/main.css b/desktop/sources/links/main.css index 729c14b..d70e743 100644 --- a/desktop/sources/links/main.css +++ b/desktop/sources/links/main.css @@ -6,7 +6,7 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_regular #ronin #wrapper { overflow: hidden; position: relative; } #ronin #wrapper #commander { z-index: 9000;position: relative;width: calc(50vw - 30px);height: calc(100vh - 60px);-webkit-app-region: no-drag;padding-right: 30px;transition: margin-left 250ms;} #ronin #wrapper #commander textarea { background: none; width: 100%; height: calc(100vh - 105px); resize: none; font-size: 12px;line-height: 15px; padding-right: 15px} -#ronin #wrapper #commander #status { position: absolute; bottom: 0px; text-transform: lowercase; line-height: 15px; height: 30px; overflow: hidden; width: calc(100% - 75px); padding-left:45px;} +#ronin #wrapper #commander #status { position: absolute; bottom: 0px; line-height: 15px; height: 30px; overflow: hidden; width: calc(100% - 75px); padding-left:45px;} #ronin #wrapper #commander #status #run { display: block; width: 26px; height: 26px; position: absolute; top: 0px; border-radius: 15px; left:0px; cursor: pointer; border:2px solid #fff; transition: background-color 250ms, border-color 250ms} #ronin.expand #wrapper #commander { width:100%; } #ronin #surface, #ronin #guide { position: absolute; top:0px; -webkit-user-select: none;-webkit-app-region: no-drag; background-image: url("data:image/svg+xml;utf8,"); background-size: 10px 10px; background-position: -4px -4px; width:100%; height:100%; transition: left 250ms, opacity 250ms; opacity: 1; } diff --git a/desktop/sources/scripts/lib/source.js b/desktop/sources/scripts/lib/source.js index cffa6ea..cd10a99 100644 --- a/desktop/sources/scripts/lib/source.js +++ b/desktop/sources/scripts/lib/source.js @@ -18,12 +18,14 @@ function Source () { this.cache = {} } - this.open = (callback) => { + this.open = (ext, callback) => { console.log('Source', 'Open file..') const input = document.createElement('input') input.type = 'file' input.onchange = (e) => { - this.cache = e.target.files[0] + const file = e.target.files[0] + if (file.name.indexOf(ext) < 0) { console.warn('Source', 'File is not ' + ext); return } + this.cache = file this.load(this.cache, callback) } input.click() diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 0d580fd..44cb5a6 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -3,19 +3,17 @@ /* global Image */ function Library (ronin) { - // Modularity: Write simple parts connected by clean interfaces. - // Composition: Design programs to be connected to other programs. - // Parsimony: Write a big program only when it is clear by demonstration that nothing else will do. - // IO - this.import = async (path, shape, alpha = 1) => { // Imports a graphic file with format. - // const img = new Image() - // img.src = path - // return ronin.surface.draw(img, shape, alpha) + this.import = async (name, shape, alpha = 1) => { // Imports a graphic file with format. + const src = ronin.cache.get(name) + if (!src) { ronin.log('No data for ' + name); return } + const img = new Image() + img.src = src + return ronin.surface.draw(img, shape, alpha) } - this.export = (name = 'export', type = 'image/png', quality = 1.0) => { // Exports a graphic file with format. + this.export = async (name = 'export', type = 'image/png', quality = 1.0) => { // Exports a graphic file with format. const base64 = ronin.surface.el.toDataURL(type, quality) const link = document.createElement('a') link.setAttribute('href', base64) @@ -23,14 +21,6 @@ function Library (ronin) { link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })) } - this.open = async (path, ratio = 1) => { // Imports a graphic file and resizes the frame. - return ronin.surface.open(path, ratio) - } - - this.exit = (force = false) => { // Exits Ronin. - ronin.source.quit(force) - } - // Shapes this.pos = (x = 0, y = 0) => { // Returns a position shape. diff --git a/desktop/sources/scripts/ronin.js b/desktop/sources/scripts/ronin.js index 2c48f6b..7494e4c 100644 --- a/desktop/sources/scripts/ronin.js +++ b/desktop/sources/scripts/ronin.js @@ -39,7 +39,7 @@ function Ronin () { this.acels.set('File', 'New', 'CmdOrCtrl+N', () => { this.source.new(); this.surface.clear(); this.commander.clear() }) this.acels.set('File', 'Save', 'CmdOrCtrl+S', () => { this.source.save('export.lisp', this.commander._input.value, 'text/plain') }) this.acels.set('File', 'Save As', 'CmdOrCtrl+Shift+S', () => { this.source.saveAs() }) - this.acels.set('File', 'Open', 'CmdOrCtrl+O', () => { this.source.open(this.whenOpen) }) + this.acels.set('File', 'Open', 'CmdOrCtrl+O', () => { this.source.open('lisp', this.whenOpen) }) this.acels.set('File', 'Revert', 'CmdOrCtrl+W', () => { this.source.revert() }) this.acels.set('View', 'Toggle Guides', 'CmdOrCtrl+Shift+H', () => { this.surface.toggleGuides() }) this.acels.set('View', 'Toggle Commander', 'CmdOrCtrl+K', () => { this.commander.toggle() }) @@ -174,7 +174,29 @@ function Ronin () { this.onDrop = (e) => { e.preventDefault() e.stopPropagation() - this.source.load(e.dataTransfer.files[0], this.whenOpen) + const file = e.dataTransfer.files[0] + + if (file.name.indexOf('.lisp') > -1) { + this.source.load(e.dataTransfer.files[0], this.whenOpen) + } + if (file.type === 'image/jpeg' || file.type === 'image/png') { + const img = new Image() + img.onload = () => { + this.cache.set(file.name, img.src) + } + img.src = URL.createObjectURL(file) + } + } + + this.cache = { + data: {}, + set: (key, content) => { + this.log((this.cache.data[key] ? 'Updated ' : 'Stored ') + key) + this.cache.data[key] = content + }, + get: (key) => { + return this.cache.data[key] + } } this.mouseShape = (position, type) => {