Merge branch 'master' into convolution
This commit is contained in:
commit
aea4184168
27
README.md
27
README.md
@ -25,6 +25,8 @@ npm start
|
|||||||
|
|
||||||
## Library
|
## Library
|
||||||
|
|
||||||
|
Additional functions can be found in the [includes](https://github.com/hundredrabbits/Ronin/tree/master/desktop/sources/lisp), you can also look at the [examples](https://github.com/hundredrabbits/Ronin/tree/master/examples) to see them in action.
|
||||||
|
|
||||||
- `(import path rect)` Imports a graphic file with format.
|
- `(import path rect)` Imports a graphic file with format.
|
||||||
- `(export path ~format ~quality)` Exports a graphic file with format.
|
- `(export path ~format ~quality)` Exports a graphic file with format.
|
||||||
- `(open path)` Imports a graphic file and resizes the frame.
|
- `(open path)` Imports a graphic file and resizes the frame.
|
||||||
@ -38,6 +40,17 @@ npm start
|
|||||||
- `(stroke ~shape)` Strokes a shape.
|
- `(stroke ~shape)` Strokes a shape.
|
||||||
- `(fill ~rect)` Fills a shape.
|
- `(fill ~rect)` Fills a shape.
|
||||||
- `(clear ~rect)` Clears a rect.
|
- `(clear ~rect)` Clears a rect.
|
||||||
|
- `(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.
|
||||||
|
- `(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)`
|
||||||
|
- `(theme variable ~el)`
|
||||||
|
- `(gradient [x1 y1 x2 y2] ~colors 'black'])`
|
||||||
|
- `(pixels rect fn q)`
|
||||||
|
- `(saturation pixel ~q)`
|
||||||
|
- `(contrast pixel ~q)`
|
||||||
- `(concat ...items)` Concat multiple strings.
|
- `(concat ...items)` Concat multiple strings.
|
||||||
- `(add ...args)` Adds values.
|
- `(add ...args)` Adds values.
|
||||||
- `(sub ...args)` Subtracts values.
|
- `(sub ...args)` Subtracts values.
|
||||||
@ -71,17 +84,8 @@ npm start
|
|||||||
- `(get item key)` Gets an object's parameter with name.
|
- `(get item key)` Gets an object's parameter with name.
|
||||||
- `(set item key val)` Sets an object's parameter with name as value.
|
- `(set item key val)` Sets an object's parameter with name as value.
|
||||||
- `(of h ...keys)` Gets object parameters with names.
|
- `(of h ...keys)` Gets object parameters with names.
|
||||||
- `(frame)` Returns a rect of the frame.
|
- `(keys item)` Returns a list of the object's keys
|
||||||
- `(center)` Returns a position of the center of the frame.
|
- `(values item)` Returns a list of the object's values
|
||||||
- `(resize w h ~fit)` 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)`
|
|
||||||
- `(theme variable ~el)`
|
|
||||||
- `(gradient [x1 y1 x2 y2] ~colors 'black'])`
|
|
||||||
- `(pixels rect fn q)`
|
|
||||||
- `(saturation pixel ~q)`
|
|
||||||
- `(contrast pixel ~q)`
|
|
||||||
- `(dir ~path)` Returns the content of a directory.
|
- `(dir ~path)` Returns the content of a directory.
|
||||||
- `(file ~path)` Returns the content of a file.
|
- `(file ~path)` Returns the content of a file.
|
||||||
- `(dirpath ~path)` Returns the path of a directory.
|
- `(dirpath ~path)` Returns the path of a directory.
|
||||||
@ -93,6 +97,7 @@ npm start
|
|||||||
- `(js)` Javascript interop.
|
- `(js)` Javascript interop.
|
||||||
- `(test name a b)`
|
- `(test name a b)`
|
||||||
- `(benchmark fn)` logs time taken to execute a function.
|
- `(benchmark fn)` logs time taken to execute a function.
|
||||||
|
- `(osc ~address)` returns the last received osc msg on port 12940
|
||||||
|
|
||||||
## Extras
|
## Extras
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const { app, BrowserWindow, webFrame, Menu } = require('electron')
|
const { app, BrowserWindow, webFrame, Menu } = require('electron')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const url = require('url')
|
const url = require('url')
|
||||||
|
const osc = require('osc')
|
||||||
const shell = require('electron').shell
|
const shell = require('electron').shell
|
||||||
|
|
||||||
let isShown = true
|
let isShown = true
|
||||||
|
1262
desktop/package-lock.json
generated
1262
desktop/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,7 @@
|
|||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron .",
|
"start": "electron .",
|
||||||
|
"install": "electron-rebuild",
|
||||||
"clean": "rm -r ~/Desktop/Ronin-darwin-x64/ ; rm -r ~/Desktop/Ronin-linux-x64/ ; rm -r ~/Desktop/Ronin-win32-x64/ ; echo 'cleaned build location'",
|
"clean": "rm -r ~/Desktop/Ronin-darwin-x64/ ; rm -r ~/Desktop/Ronin-linux-x64/ ; rm -r ~/Desktop/Ronin-win32-x64/ ; echo 'cleaned build location'",
|
||||||
"build_osx": "electron-packager . Ronin --platform=darwin --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.icns ; echo 'Built for OSX'",
|
"build_osx": "electron-packager . Ronin --platform=darwin --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.icns ; echo 'Built for OSX'",
|
||||||
"build_linux": "electron-packager . Ronin --platform=linux --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.ico ; echo 'Built for LINUX'",
|
"build_linux": "electron-packager . Ronin --platform=linux --arch=x64 --out ~/Desktop/ --overwrite --icon=icon.ico ; echo 'Built for LINUX'",
|
||||||
@ -16,8 +17,12 @@
|
|||||||
"push_status": "~/butler status hundredrabbits/ronin",
|
"push_status": "~/butler status hundredrabbits/ronin",
|
||||||
"push": "npm run build ; npm run push_theme ; npm run push_osx ; npm run push_linux ; npm run push_win ; npm run clean ; npm run push_status"
|
"push": "npm run build ; npm run push_theme ; npm run push_osx ; npm run push_linux ; npm run push_win ; npm run clean ; npm run push_status"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"osc": "^2.3.1"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^5.0.6",
|
"electron": "^5.0.6",
|
||||||
"electron-packager": "^13.1.1"
|
"electron-packager": "^13.1.1",
|
||||||
|
"electron-rebuild": "^1.8.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
<script type="text/javascript" src="scripts/surface.js"></script>
|
<script type="text/javascript" src="scripts/surface.js"></script>
|
||||||
<script type="text/javascript" src="scripts/lisp.js"></script>
|
<script type="text/javascript" src="scripts/lisp.js"></script>
|
||||||
<script type="text/javascript" src="scripts/library.js"></script>
|
<script type="text/javascript" src="scripts/library.js"></script>
|
||||||
|
<script type="text/javascript" src="scripts/osc.js"></script>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="links/reset.css"/>
|
<link rel="stylesheet" type="text/css" href="links/reset.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="links/fonts.css"/>
|
<link rel="stylesheet" type="text/css" href="links/fonts.css"/>
|
||||||
<link rel="stylesheet" type="text/css" href="links/main.css"/>
|
<link rel="stylesheet" type="text/css" href="links/main.css"/>
|
||||||
@ -18,10 +20,10 @@
|
|||||||
<body>
|
<body>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
const {dialog,app} = require('electron').remote;
|
const {dialog,app} = require('electron').remote;
|
||||||
const fs = require('fs');
|
const fs = require('fs')
|
||||||
const app_path = app.getAppPath();
|
const ronin = new Ronin()
|
||||||
const ronin = new Ronin();
|
|
||||||
ronin.controller = new Controller();
|
ronin.controller = new Controller()
|
||||||
ronin.controller.add("default","*","About",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Dotgrid'); },"CmdOrCtrl+,");
|
ronin.controller.add("default","*","About",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Dotgrid'); },"CmdOrCtrl+,");
|
||||||
ronin.controller.add("default","*","Fullscreen",() => { app.toggleFullscreen() },"CmdOrCtrl+Enter");
|
ronin.controller.add("default","*","Fullscreen",() => { app.toggleFullscreen() },"CmdOrCtrl+Enter");
|
||||||
ronin.controller.add("default","*","Hide",() => { app.toggleVisible() },"CmdOrCtrl+H");
|
ronin.controller.add("default","*","Hide",() => { app.toggleVisible() },"CmdOrCtrl+H");
|
||||||
@ -53,9 +55,10 @@
|
|||||||
ronin.controller.add("default","Theme","Reset Theme",() => { ronin.theme.reset() },"CmdOrCtrl+Shift+Backspace")
|
ronin.controller.add("default","Theme","Reset Theme",() => { ronin.theme.reset() },"CmdOrCtrl+Shift+Backspace")
|
||||||
ronin.controller.addSpacer('default', 'Theme', 'Download')
|
ronin.controller.addSpacer('default', 'Theme', 'Download')
|
||||||
ronin.controller.add("default","Theme","Download Themes..",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Themes') })
|
ronin.controller.add("default","Theme","Download Themes..",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Themes') })
|
||||||
ronin.controller.commit();
|
ronin.controller.commit()
|
||||||
ronin.install(document.body);
|
|
||||||
window.addEventListener('load', () => { ronin.start(); })
|
ronin.install(document.body)
|
||||||
|
window.addEventListener('load', () => { ronin.start() })
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -14,4 +14,4 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_regular
|
|||||||
#ronin canvas#guide { background:none; }
|
#ronin canvas#guide { background:none; }
|
||||||
#ronin canvas#surface { border-radius: 2px }
|
#ronin canvas#surface { border-radius: 2px }
|
||||||
|
|
||||||
#ronin.hidden canvas#surface, #ronin.hidden canvas#guide { left:10px; }
|
#ronin.hidden canvas#surface, #ronin.hidden canvas#guide { left:0px; }
|
34
desktop/sources/lisp/prelude.lisp
Normal file
34
desktop/sources/lisp/prelude.lisp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
;
|
||||||
|
(echo "Loading prelude.lisp")
|
||||||
|
; translate
|
||||||
|
(defn translate
|
||||||
|
(r p)
|
||||||
|
(clone r
|
||||||
|
(rect
|
||||||
|
(of p :x)
|
||||||
|
(of p :y)
|
||||||
|
(of r :w)
|
||||||
|
(of r :h))))
|
||||||
|
; times
|
||||||
|
(defn times
|
||||||
|
(v f)
|
||||||
|
(
|
||||||
|
(f v)
|
||||||
|
(if
|
||||||
|
(gt v 1)
|
||||||
|
(times
|
||||||
|
(sub v 1) f))))
|
||||||
|
; convert deg to radians
|
||||||
|
(defn deg-rad
|
||||||
|
(deg)
|
||||||
|
(mul deg
|
||||||
|
(div PI 180)))
|
||||||
|
; position on a circle from angle
|
||||||
|
(defn circle-pos
|
||||||
|
(cx cy r a) {:x
|
||||||
|
(add cx
|
||||||
|
(mul r
|
||||||
|
(cos a))) :y
|
||||||
|
(add cy
|
||||||
|
(mul r
|
||||||
|
(sin a)))})
|
@ -31,11 +31,21 @@ function Commander (ronin) {
|
|||||||
this.hide()
|
this.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.cache = ''
|
||||||
|
|
||||||
this.run = (txt = this._input.value) => {
|
this.run = (txt = this._input.value) => {
|
||||||
if (txt.indexOf('$') > -1) { ronin.log('Present: $'); return }
|
if (txt.indexOf('$') > -1) { ronin.log('Present: $'); return }
|
||||||
const inter = new Lisp(txt, ronin.library)
|
this.cache = txt
|
||||||
inter.toPixels()
|
if (ronin.always !== true) {
|
||||||
ronin.always === true && requestAnimationFrame(() => this.run(txt))
|
ronin.surface.maximize()
|
||||||
|
ronin.interpreter.run(this.cache)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loop = () => {
|
||||||
|
ronin.surface.maximize()
|
||||||
|
ronin.interpreter.run(this.cache)
|
||||||
|
ronin.always === true && requestAnimationFrame(() => this.loop())
|
||||||
}
|
}
|
||||||
|
|
||||||
this.load = function (txt) {
|
this.load = function (txt) {
|
||||||
@ -47,6 +57,10 @@ function Commander (ronin) {
|
|||||||
this.reindent = function () {
|
this.reindent = function () {
|
||||||
let val = this._input.value.replace(/\n/g, '').replace(/ +(?= )/g, '').replace(/\( \(/g, '((').replace(/\) \)/g, '))').trim()
|
let val = this._input.value.replace(/\n/g, '').replace(/ +(?= )/g, '').replace(/\( \(/g, '((').replace(/\) \)/g, '))').trim()
|
||||||
let depth = 0
|
let depth = 0
|
||||||
|
if (val.split('(').length !== val.split(')').length) {
|
||||||
|
ronin.log('Uneven number of parens.')
|
||||||
|
return
|
||||||
|
}
|
||||||
for (let i = 0; i < val.length; i++) {
|
for (let i = 0; i < val.length; i++) {
|
||||||
const c = val.charAt(i)
|
const c = val.charAt(i)
|
||||||
if (c === '(') { depth++ } else if (c === ')') { depth-- }
|
if (c === '(') { depth++ } else if (c === ')') { depth-- }
|
||||||
@ -68,7 +82,7 @@ function Commander (ronin) {
|
|||||||
// Logs
|
// Logs
|
||||||
if (msg && msg !== this._log.textContent) {
|
if (msg && msg !== this._log.textContent) {
|
||||||
this._log.textContent = `${msg}`
|
this._log.textContent = `${msg}`
|
||||||
console.log(msg)
|
// console.log(msg)
|
||||||
}
|
}
|
||||||
// Source
|
// Source
|
||||||
const _source = `${ronin.source} ${this._input.value.split('\n').length} lines`
|
const _source = `${ronin.source} ${this._input.value.split('\n').length} lines`
|
||||||
|
@ -7,7 +7,7 @@ function Library (ronin) {
|
|||||||
|
|
||||||
this.export = (path, format = 'image/png', quality = 1.0) => { // Exports a graphic file with format.
|
this.export = (path, format = 'image/png', quality = 1.0) => { // Exports a graphic file with format.
|
||||||
if (!path) { console.warn('Missing export path'); return path }
|
if (!path) { console.warn('Missing export path'); return path }
|
||||||
var dataUrl = ronin.surface.el.toDataURL(format, quality)
|
const dataUrl = ronin.surface.el.toDataURL(format, quality)
|
||||||
const data = dataUrl.replace(/^data:image\/png;base64,/, '').replace(/^data:image\/jpeg;base64,/, '')
|
const data = dataUrl.replace(/^data:image\/png;base64,/, '').replace(/^data:image\/jpeg;base64,/, '')
|
||||||
fs.writeFileSync(path, data, 'base64')
|
fs.writeFileSync(path, data, 'base64')
|
||||||
return path
|
return path
|
||||||
@ -31,8 +31,8 @@ function Library (ronin) {
|
|||||||
return { x, y, w, h, t }
|
return { x, y, w, h, t }
|
||||||
}
|
}
|
||||||
|
|
||||||
this.circle = (x, y, r, t = 'circle') => { // Returns a circle shape.
|
this.circle = (cx, cy, r, t = 'circle') => { // Returns a circle shape.
|
||||||
return { x, y, r, t }
|
return { cx, cy, r, t }
|
||||||
}
|
}
|
||||||
|
|
||||||
this.line = (a, b, t = 'line') => { // Returns a line shape.
|
this.line = (a, b, t = 'line') => { // Returns a line shape.
|
||||||
@ -64,6 +64,83 @@ function Library (ronin) {
|
|||||||
return rect
|
return rect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Frame
|
||||||
|
|
||||||
|
this.frame = () => { // Returns a rect of the frame.
|
||||||
|
return ronin.surface.getFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.center = () => { // Returns a position of the center of the frame.
|
||||||
|
const rect = this.frame()
|
||||||
|
return this.pos(rect.w / 2, rect.h / 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resize = async (w, h, fit = true) => { // Resizes the canvas to target w and h, returns the rect.
|
||||||
|
const rect = { x: 0, y: 0, w, h }
|
||||||
|
const a = document.createElement('img')
|
||||||
|
const b = document.createElement('img')
|
||||||
|
a.src = ronin.surface.el.toDataURL()
|
||||||
|
await ronin.surface.resizeImage(a, b)
|
||||||
|
ronin.surface.resize(rect, fit)
|
||||||
|
return ronin.surface.draw(b, rect)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rescale = async (w, h) => { // Rescales the canvas to target ratio of w and h, returns the rect.
|
||||||
|
const rect = { x: 0, y: 0, w: this.frame().w * w, h: this.frame().h * h }
|
||||||
|
const a = document.createElement('img')
|
||||||
|
const b = document.createElement('img')
|
||||||
|
a.src = ronin.surface.el.toDataURL()
|
||||||
|
await ronin.surface.resizeImage(a, b)
|
||||||
|
ronin.surface.resize(rect, true)
|
||||||
|
return ronin.surface.draw(b, rect)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.crop = async (rect) => { // Crop canvas to rect.
|
||||||
|
return ronin.surface.crop(rect)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clone = (a, b) => {
|
||||||
|
ronin.surface.clone(a, b)
|
||||||
|
return [a, b]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.theme = (variable, el = document.documentElement) => {
|
||||||
|
// ex. (theme "f_main") -> :root { --f_main: "#fff" }
|
||||||
|
return getComputedStyle(el).getPropertyValue(`--${variable}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gradients
|
||||||
|
|
||||||
|
this.gradient = ([x1, y1, x2, y2], colors = ['white', 'black']) => {
|
||||||
|
return ronin.surface.linearGradient(x1, y1, x2, y2, colors)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pixels
|
||||||
|
|
||||||
|
this.pixels = (rect, fn, q) => {
|
||||||
|
const img = ronin.surface.context.getImageData(0, 0, rect.w, rect.h)
|
||||||
|
for (let i = 0, loop = img.data.length; i < loop; i += 4) {
|
||||||
|
const pixel = { r: img.data[i], g: img.data[i + 1], b: img.data[i + 2], a: img.data[i + 3] }
|
||||||
|
const processed = fn(pixel, q)
|
||||||
|
img.data[i] = processed[0]
|
||||||
|
img.data[i + 1] = processed[1]
|
||||||
|
img.data[i + 2] = processed[2]
|
||||||
|
img.data[i + 3] = processed[3]
|
||||||
|
}
|
||||||
|
ronin.surface.context.putImageData(img, 0, 0)
|
||||||
|
return rect
|
||||||
|
}
|
||||||
|
|
||||||
|
this.saturation = (pixel, q = 1) => {
|
||||||
|
const color = 0.2126 * pixel.r + 0.7152 * pixel.g + 0.0722 * pixel.b
|
||||||
|
return [(color * (1 - q)) + (pixel.r * q), (color * (1 - q)) + (pixel.g * q), (color * (1 - q)) + (pixel.b * q), pixel.a]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contrast = (pixel, q = 1) => {
|
||||||
|
const intercept = 128 * (1 - q)
|
||||||
|
return [pixel.r * q + intercept, pixel.g * q + intercept, pixel.b * q + intercept, pixel.a]
|
||||||
|
}
|
||||||
|
|
||||||
// Strings
|
// Strings
|
||||||
|
|
||||||
this.concat = function (...items) { // Concat multiple strings.
|
this.concat = function (...items) { // Concat multiple strings.
|
||||||
@ -233,78 +310,12 @@ function Library (ronin) {
|
|||||||
}, h)
|
}, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Frame
|
this.keys = (item) => { // Returns a list of the object's keys
|
||||||
|
return Object.keys(item)
|
||||||
this.frame = () => { // Returns a rect of the frame.
|
|
||||||
return ronin.surface.getFrame()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.center = () => { // Returns a position of the center of the frame.
|
this.values = (item) => { // Returns a list of the object's values
|
||||||
const rect = this.frame()
|
return Object.values(item)
|
||||||
return this.pos(rect.w / 2, rect.h / 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resize = async (w, h, fit = true) => { // Resizes the canvas to target w and h, returns the rect.
|
|
||||||
const rect = { x: 0, y: 0, w, h }
|
|
||||||
const a = document.createElement('img')
|
|
||||||
const b = document.createElement('img')
|
|
||||||
a.src = ronin.surface.el.toDataURL()
|
|
||||||
await ronin.surface.resizeImage(a, b)
|
|
||||||
ronin.surface.resize(rect, fit)
|
|
||||||
return ronin.surface.draw(b, rect)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.rescale = async (w, h) => { // Rescales the canvas to target ratio of w and h, returns the rect.
|
|
||||||
const rect = { x: 0, y: 0, w: this.frame().w * w, h: this.frame().h * h }
|
|
||||||
const a = document.createElement('img')
|
|
||||||
const b = document.createElement('img')
|
|
||||||
a.src = ronin.surface.el.toDataURL()
|
|
||||||
await ronin.surface.resizeImage(a, b)
|
|
||||||
ronin.surface.resize(rect, true)
|
|
||||||
return ronin.surface.draw(b, rect)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.crop = async (rect) => { // Crop canvas to rect.
|
|
||||||
return ronin.surface.crop(rect)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.clone = (a, b) => {
|
|
||||||
ronin.surface.clone(a, b)
|
|
||||||
return [a, b]
|
|
||||||
}
|
|
||||||
|
|
||||||
this.theme = (variable, el = document.documentElement) => {
|
|
||||||
// ex. (theme "f_main") -> :root { --f_main: "#fff" }
|
|
||||||
return getComputedStyle(el).getPropertyValue(`--${variable}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gradients
|
|
||||||
|
|
||||||
this.gradient = ([x1, y1, x2, y2], colors = ['white', 'black']) => {
|
|
||||||
return ronin.surface.linearGradient(x1, y1, x2, y2, colors)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pixels
|
|
||||||
|
|
||||||
this.pixels = (rect, fn, q) => {
|
|
||||||
const img = ronin.surface.context.getImageData(rect.x, rect.y, rect.w, rect.h)
|
|
||||||
for (let i = 0, loop = img.data.length; i < loop; i += 4) {
|
|
||||||
const pixel = { r: img.data[i], g: img.data[i + 1], b: img.data[i + 2], a: img.data[i + 3] }
|
|
||||||
const processed = fn(pixel, q)
|
|
||||||
img.data.set(processed, i);
|
|
||||||
}
|
|
||||||
ronin.surface.context.putImageData(img, rect.x, rect.y)
|
|
||||||
return rect
|
|
||||||
}
|
|
||||||
|
|
||||||
this.saturation = (pixel, q = 1) => {
|
|
||||||
const color = 0.2126 * pixel.r + 0.7152 * pixel.g + 0.0722 * pixel.b * (1 - q)
|
|
||||||
return [color + (pixel.r * q), color + (pixel.g * q), color + (pixel.b * q), pixel.a]
|
|
||||||
}
|
|
||||||
|
|
||||||
this.contrast = (pixel, q = 1) => {
|
|
||||||
const intercept = 128 * (1 - q)
|
|
||||||
return [pixel.r * q + intercept, pixel.g * q + intercept, pixel.b * q + intercept, pixel.a]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convolve
|
// Convolve
|
||||||
@ -370,6 +381,16 @@ function Library (ronin) {
|
|||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.table = (arg) => {
|
||||||
|
console.table(arg)
|
||||||
|
return arg
|
||||||
|
}
|
||||||
|
|
||||||
|
this.debug = (arg) => {
|
||||||
|
console.log(arg)
|
||||||
|
return arg
|
||||||
|
}
|
||||||
|
|
||||||
this.time = (rate = 1) => { // Returns timestamp in milliseconds.
|
this.time = (rate = 1) => { // Returns timestamp in milliseconds.
|
||||||
return (Date.now() * rate)
|
return (Date.now() * rate)
|
||||||
}
|
}
|
||||||
@ -397,4 +418,10 @@ function Library (ronin) {
|
|||||||
console.log(`time taken: ${Date.now() - start}ms`)
|
console.log(`time taken: ${Date.now() - start}ms`)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IO
|
||||||
|
|
||||||
|
this.osc = (path) => { // Returns the latest osc message at path
|
||||||
|
return path ? ronin.osc.msg[path] : ronin.osc.msg
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
function Lisp (input, lib) {
|
function Lisp (lib = {}, includes = []) {
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|
||||||
const TYPES = { identifier: 0, number: 1, string: 2, bool: 3 }
|
const TYPES = { identifier: 0, number: 1, string: 2, bool: 3 }
|
||||||
|
|
||||||
const Context = function (scope, parent) {
|
const Context = function (scope, parent) {
|
||||||
this.scope = scope
|
this.scope = scope
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
|
|
||||||
this.get = function (identifier) {
|
this.get = function (identifier) {
|
||||||
if (identifier in this.scope) {
|
if (identifier in this.scope) {
|
||||||
return this.scope[identifier]
|
return this.scope[identifier]
|
||||||
@ -20,9 +20,9 @@ function Lisp (input, lib) {
|
|||||||
|
|
||||||
const special = {
|
const special = {
|
||||||
include: (input, context) => {
|
include: (input, context) => {
|
||||||
if (!input[1].value || !fs.existsSync(input[1].value)) { console.warn('Source', input[1].value); return [] }
|
if (!input[1].value || !fs.existsSync(input[1].value)) { console.warn('Lisp', 'No file: ' + input[1].value); return [] }
|
||||||
const file = fs.readFileSync(input[1].value, { encoding: 'utf-8' })
|
const file = fs.readFileSync(input[1].value, { encoding: 'utf-8' })
|
||||||
return interpret(this.parse(file), context)
|
return interpret(this.parse(`(${file})`), context)
|
||||||
},
|
},
|
||||||
let: function (input, context) {
|
let: function (input, context) {
|
||||||
const letContext = input[1].reduce(function (acc, x) {
|
const letContext = input[1].reduce(function (acc, x) {
|
||||||
@ -60,21 +60,32 @@ function Lisp (input, lib) {
|
|||||||
return interpret(input[2], new Context(lambdaScope, context))
|
return interpret(input[2], new Context(lambdaScope, context))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
__fn: function (input, context) {
|
|
||||||
return async function () {
|
|
||||||
const lambdaArguments = arguments
|
|
||||||
const lambdaScope = [].reduce(function (acc, x, i) {
|
|
||||||
acc[x.value] = lambdaArguments[i]
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
return interpret(input.slice(1), new Context(lambdaScope, context))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
if: async function (input, context) {
|
if: async function (input, context) {
|
||||||
if (await interpret(input[1], context)) {
|
if (await interpret(input[1], context)) {
|
||||||
return interpret(input[2], context)
|
return interpret(input[2], context)
|
||||||
}
|
}
|
||||||
return input[3] ? interpret(input[3], context) : []
|
return input[3] ? interpret(input[3], context) : []
|
||||||
|
},
|
||||||
|
__fn: function (input, context) {
|
||||||
|
return async function () {
|
||||||
|
const lambdaArguments = arguments
|
||||||
|
const keys = [...new Set(input.slice(2).flat(100).filter(i =>
|
||||||
|
i.type === TYPES.identifier &&
|
||||||
|
i.value[0] === '%'
|
||||||
|
).map(x => x.value).sort())]
|
||||||
|
const lambdaScope = keys.reduce(function (acc, x, i) {
|
||||||
|
acc[x] = lambdaArguments[i]
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
return interpret(input.slice(1), new Context(lambdaScope, context))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
__obj: async function (input, context) {
|
||||||
|
const obj = {}
|
||||||
|
for (let i = 1; i < input.length; i += 2) {
|
||||||
|
obj[await interpret(input[i], context)] = await interpret(input[i + 1], context)
|
||||||
|
}
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +101,7 @@ function Lisp (input, lib) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const interpret = async function (input, context) {
|
const interpret = async function (input, context) {
|
||||||
if (!input) { console.warn('error', context.scope); return null }
|
if (!input) { console.warn('Lisp', 'error', context.scope); return null }
|
||||||
|
|
||||||
if (context === undefined) {
|
if (context === undefined) {
|
||||||
return interpret(input, new Context(lib))
|
return interpret(input, new Context(lib))
|
||||||
@ -108,6 +119,8 @@ function Lisp (input, lib) {
|
|||||||
return { type: TYPES.number, value: parseFloat(input) }
|
return { type: TYPES.number, value: parseFloat(input) }
|
||||||
} else if (input[0] === '"' && input.slice(-1) === '"') {
|
} else if (input[0] === '"' && input.slice(-1) === '"') {
|
||||||
return { type: TYPES.string, value: input.slice(1, -1) }
|
return { type: TYPES.string, value: input.slice(1, -1) }
|
||||||
|
} else if (input[0] === ':') {
|
||||||
|
return { type: TYPES.string, value: input.slice(1) }
|
||||||
} else if (input === 'true' || input === 'false') {
|
} else if (input === 'true' || input === 'false') {
|
||||||
return { type: TYPES.bool, value: input === 'true' }
|
return { type: TYPES.bool, value: input === 'true' }
|
||||||
} else {
|
} else {
|
||||||
@ -124,10 +137,14 @@ function Lisp (input, lib) {
|
|||||||
input.unshift('__fn')
|
input.unshift('__fn')
|
||||||
list.push(parenthesize(input, []))
|
list.push(parenthesize(input, []))
|
||||||
return parenthesize(input, list)
|
return parenthesize(input, list)
|
||||||
|
} else if (token === '{') {
|
||||||
|
input.unshift('__obj')
|
||||||
|
list.push(parenthesize(input, []))
|
||||||
|
return parenthesize(input, list)
|
||||||
} else if (token === '(') {
|
} else if (token === '(') {
|
||||||
list.push(parenthesize(input, []))
|
list.push(parenthesize(input, []))
|
||||||
return parenthesize(input, list)
|
return parenthesize(input, list)
|
||||||
} else if (token === ')') {
|
} else if (token === ')' || token === '}') {
|
||||||
return list
|
return list
|
||||||
} else {
|
} else {
|
||||||
return parenthesize(input, list.concat(categorize(token)))
|
return parenthesize(input, list.concat(categorize(token)))
|
||||||
@ -135,21 +152,35 @@ function Lisp (input, lib) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tokenize = function (input) {
|
const tokenize = function (input) {
|
||||||
const i = input.replace(/^\;.*\n?/gm, '').split('"')
|
const i = input.replace(/^\;.*\n?/gm, '').replace('λ', 'lambda ').split('"')
|
||||||
return i.map(function (x, i) {
|
return i.map(function (x, i) {
|
||||||
return i % 2 === 0 ?
|
return i % 2 === 0
|
||||||
x.replace(/\(/g, ' ( ').replace(/\)/g, ' ) ').replace(/' \( /g, ' \'( ')
|
? x.replace(/\(/g, ' ( ')
|
||||||
: x.replace(/ /g, '!whitespace!')
|
.replace(/\)/g, ' ) ')
|
||||||
|
.replace(/' \( /g, ' \'( ') // '()
|
||||||
|
.replace(/\{/g, ' { ') // {}
|
||||||
|
.replace(/\}/g, ' } ') // {}
|
||||||
|
: x.replace(/ /g, '!whitespace!')
|
||||||
})
|
})
|
||||||
.join('"').trim().split(/\s+/)
|
.join('"').trim().split(/\s+/)
|
||||||
.map(function (x) { return x.replace(/!whitespace!/g, ' ') })
|
.map(function (x) { return x.replace(/!whitespace!/g, ' ') })
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inc = function () {
|
||||||
|
return includes.reduce((acc, item) => {
|
||||||
|
const p = path.join(__dirname, `lisp/${item}.lisp`)
|
||||||
|
if (!fs.existsSync(p)) { console.warn('Lisp', `Missing include: ${p}`); return acc }
|
||||||
|
return `${acc}(include "${p}") `
|
||||||
|
}, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parse = function (input) {
|
this.parse = function (input) {
|
||||||
return parenthesize(tokenize(`(${input})`))
|
return parenthesize(tokenize(input))
|
||||||
}
|
}
|
||||||
|
|
||||||
this.toPixels = async function () {
|
this.run = async function (input) {
|
||||||
return interpret(this.parse(input))
|
return interpret(this.parse(`(
|
||||||
|
${this.inc()}
|
||||||
|
${input})`))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
desktop/sources/scripts/osc.js
Normal file
23
desktop/sources/scripts/osc.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
function Osc (ronin) {
|
||||||
|
const osc = require('osc')
|
||||||
|
|
||||||
|
this.msg = {}
|
||||||
|
|
||||||
|
this.start = function () {
|
||||||
|
const udpPort = new osc.UDPPort({
|
||||||
|
localAddress: '0.0.0.0',
|
||||||
|
localPort: 49162,
|
||||||
|
metadata: true
|
||||||
|
})
|
||||||
|
udpPort.on('message', this.onMsg)
|
||||||
|
udpPort.open()
|
||||||
|
ronin.log('OSC', 'Started.')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onMsg = (msg, timeTag, info) => {
|
||||||
|
this.msg[msg.address] = msg.args
|
||||||
|
// ronin.log(`${info.address}:${info.port} > ${msg.args}`, info)
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,8 @@ function Ronin () {
|
|||||||
b_inv: '#ffb545'
|
b_inv: '#ffb545'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.includes = ['prelude']
|
||||||
|
|
||||||
this.el = document.createElement('div')
|
this.el = document.createElement('div')
|
||||||
this.el.id = 'ronin'
|
this.el.id = 'ronin'
|
||||||
|
|
||||||
@ -19,7 +21,8 @@ function Ronin () {
|
|||||||
this.commander = new Commander(this)
|
this.commander = new Commander(this)
|
||||||
this.surface = new Surface(this)
|
this.surface = new Surface(this)
|
||||||
this.library = new Library(this)
|
this.library = new Library(this)
|
||||||
|
this.interpreter = new Lisp(this.library, this.includes)
|
||||||
|
this.osc = new Osc(this)
|
||||||
// Parameters
|
// Parameters
|
||||||
|
|
||||||
this.always = false
|
this.always = false
|
||||||
@ -43,7 +46,7 @@ function Ronin () {
|
|||||||
this.source.start()
|
this.source.start()
|
||||||
this.commander.start()
|
this.commander.start()
|
||||||
this.surface.start()
|
this.surface.start()
|
||||||
console.log('Ronin', 'Started')
|
this.osc.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.reset = function () {
|
this.reset = function () {
|
||||||
@ -61,7 +64,7 @@ function Ronin () {
|
|||||||
this.animate = (b = true) => {
|
this.animate = (b = true) => {
|
||||||
if (this.always === b) { return }
|
if (this.always === b) { return }
|
||||||
this.always = b
|
this.always = b
|
||||||
this.commander.run()
|
this.commander.loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zoom
|
// Zoom
|
||||||
|
@ -126,12 +126,6 @@ function Source (ronin) {
|
|||||||
return `${str}`
|
return `${str}`
|
||||||
}
|
}
|
||||||
|
|
||||||
this.locate = function (name) {
|
|
||||||
if (!this.path) { return }
|
|
||||||
const loc = path.join(this.folder(), name)
|
|
||||||
return fs.existsSync(loc) ? loc : null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Etc
|
// Etc
|
||||||
|
|
||||||
this.name = function () {
|
this.name = function () {
|
||||||
|
@ -100,7 +100,7 @@ function Surface (ronin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.traceCircle = function (circle, context) {
|
this.traceCircle = function (circle, context) {
|
||||||
context.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI)
|
context.arc(circle.cx, circle.cy, circle.r, 0, 2 * Math.PI)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.traceText = function (text, context) {
|
this.traceText = function (text, context) {
|
||||||
@ -185,7 +185,7 @@ function Surface (ronin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.maximize = function () {
|
this.maximize = function () {
|
||||||
this.resize({ x: 0, y: 0, w: (window.innerWidth * this.ratio) - 60, h: (window.innerHeight * this.ratio) - 60, t: 'rect' })
|
this.resize({ x: 0, y: 0, w: ((window.innerWidth - 60) * this.ratio), h: ((window.innerHeight - 60) * this.ratio), t: 'rect' })
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onResize = function () {
|
this.onResize = function () {
|
||||||
|
@ -1,17 +1,50 @@
|
|||||||
; animate
|
;
|
||||||
|
(clear)
|
||||||
(clear)
|
;
|
||||||
(def t
|
(def seg-count 50)
|
||||||
(sin
|
;
|
||||||
(div
|
(def frame-middle
|
||||||
(time) 100)))
|
(div
|
||||||
(def pos
|
(of
|
||||||
(add 200 30
|
(frame) :h) 2))
|
||||||
(mul 30 t)))
|
;
|
||||||
(defn square
|
(def seg-width
|
||||||
(a)
|
(div
|
||||||
(rect a a a a))
|
(of
|
||||||
(stroke
|
(frame) :w) seg-count))
|
||||||
(square pos) 1 "red")
|
;
|
||||||
; set false to stop
|
(defn elevation
|
||||||
(animate true)
|
(i)
|
||||||
|
(add
|
||||||
|
(mul
|
||||||
|
(sin
|
||||||
|
(add
|
||||||
|
(time 0.001)
|
||||||
|
(div i 5)))
|
||||||
|
(div
|
||||||
|
(of
|
||||||
|
(frame) :h) 5)) frame-middle))
|
||||||
|
;
|
||||||
|
(defn draw-dash
|
||||||
|
(i)
|
||||||
|
(
|
||||||
|
(def x
|
||||||
|
(mul
|
||||||
|
(sub i 1) seg-width))
|
||||||
|
(def y
|
||||||
|
(elevation i))
|
||||||
|
(stroke
|
||||||
|
(line
|
||||||
|
(pos x
|
||||||
|
(elevation
|
||||||
|
(sub i 1)))
|
||||||
|
(pos
|
||||||
|
(add x seg-width)
|
||||||
|
(elevation i))) 4
|
||||||
|
(gradient
|
||||||
|
(50 0
|
||||||
|
(of
|
||||||
|
(frame) :w) 0)
|
||||||
|
("rgba(255,255,255,0)" "white" "#72dec2" "red")))))
|
||||||
|
;
|
||||||
|
(times seg-count draw-dash)
|
@ -1,25 +1,26 @@
|
|||||||
(echo (map (lambda (a) (add a 1)) (1 2 3)))
|
(echo (map '(add %1 1) (1 2 3)))
|
||||||
|
|
||||||
(echo (first (1 2 3)))
|
(echo (first (1 2 3)))
|
||||||
(echo (rest (1 2 3)))
|
(echo (rest (1 2 3)))
|
||||||
|
|
||||||
(echo
|
(echo
|
||||||
(filter
|
(filter
|
||||||
(lambda (a) (eq 0 (mod a 2)))
|
'(eq 0 (mod %1 2))
|
||||||
(1 2 3 4 5))
|
(1 2 3 4 5))
|
||||||
)
|
)
|
||||||
|
|
||||||
(clear)
|
(clear)
|
||||||
(map (lambda (a)
|
(map
|
||||||
(stroke (rect (mul a 30) 20 50 50)
|
'(stroke (rect (mul a 30) 20 50 50)
|
||||||
1 "red"))
|
1 "red")
|
||||||
(range 0 20 5))
|
(range 0 20 5))
|
||||||
|
|
||||||
(map (lambda (a)
|
(map
|
||||||
(stroke
|
'(stroke
|
||||||
(rect
|
(rect
|
||||||
(mul a 10)
|
(mul %1 10)
|
||||||
(add 50 (mul (sin a) 40))
|
(add 250 (mul (sin %1) 250))
|
||||||
a
|
(mul 4 %1)
|
||||||
(add 20 (mul (cos a) 50))) 1 "red"))
|
(add 20 (mul (cos %1) 50))) 1 "red")
|
||||||
(range 0 200 5))
|
(range 0 200 5))
|
||||||
|
|
||||||
|
@ -6,4 +6,8 @@
|
|||||||
|
|
||||||
; define a function
|
; define a function
|
||||||
(defn add-two (a) (add 2 a))
|
(defn add-two (a) (add 2 a))
|
||||||
(echo (add-two 4))
|
(echo (add-two 4))
|
||||||
|
|
||||||
|
; use a lambda
|
||||||
|
(times 5
|
||||||
|
(λ (a) (echo (concat "time:" a))))
|
@ -35,14 +35,14 @@
|
|||||||
(test "range simple" (range 0 4) (0 1 2 3 4))
|
(test "range simple" (range 0 4) (0 1 2 3 4))
|
||||||
(test "range with step" (range 0 4 2) (0 2 4))
|
(test "range with step" (range 0 4 2) (0 2 4))
|
||||||
(test "range with negative step" (range 0 -4 -1) (0 -1 -2 -3 -4))
|
(test "range with negative step" (range 0 -4 -1) (0 -1 -2 -3 -4))
|
||||||
(test "map" (map (lambda (a) (add 1 a)) (1 2 3)) (2 3 4))
|
(test "map" (map (λ (a) (add 1 a)) (1 2 3)) (2 3 4))
|
||||||
(test "filter" (filter (lambda (a) (eq 0 (mod a 2))) (2 3 4 5 6)) (2 4 6))
|
(test "filter" (filter (λ (a) (eq 0 (mod a 2))) (2 3 4 5 6)) (2 4 6))
|
||||||
(test "reduce" (reduce (lambda (acc val) (add acc val)) (1 2 3) 4) 10)
|
(test "reduce" (reduce (λ (acc val) (add acc val)) (1 2 3) 4) 10)
|
||||||
|
|
||||||
; Scope
|
; Scope
|
||||||
|
|
||||||
(def aaa 123)
|
(def aaa 123)
|
||||||
(def addOne (lambda (a) (add a 1)))
|
(def addOne (λ (a) (add a 1)))
|
||||||
(test "def - value" aaa 123)
|
(test "def - value" aaa 123)
|
||||||
(test "def - func" (addOne 4) 5)
|
(test "def - func" (addOne 4) 5)
|
||||||
(defn addTwo (a) (add 2 a))
|
(defn addTwo (a) (add 2 a))
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
(defn dejong (r a b c d)
|
(defn dejong (r a b c d)
|
||||||
(reduce
|
(reduce
|
||||||
(lambda (acc val)
|
(λ (acc val)
|
||||||
(first (
|
(first (
|
||||||
(_dejong (first acc) (last acc) a b c d)
|
(_dejong (first acc) (last acc) a b c d)
|
||||||
)))
|
)))
|
||||||
|
@ -5,12 +5,11 @@
|
|||||||
(defn glitch
|
(defn glitch
|
||||||
(rec)
|
(rec)
|
||||||
(if (gt rec 1)
|
(if (gt rec 1)
|
||||||
((clone
|
(
|
||||||
(rect (random 400) (random 400) 2 2)
|
(translate
|
||||||
(rect (random 400) (random 400)
|
(rect (random 400) (random 400) (random 10) (random 10))
|
||||||
(random 10) (random 30)))
|
(pos (random 400) (random 400)))
|
||||||
(glitch (sub rec 1))))
|
(glitch (sub rec 1)))))
|
||||||
)
|
|
||||||
|
|
||||||
(import
|
(import
|
||||||
"../static/crystal.jpg"
|
"../static/crystal.jpg"
|
||||||
|
@ -1,6 +1 @@
|
|||||||
(
|
(echo (map '(add %1 2) (4 5 6))
|
||||||
|
|
||||||
(echo (map '(add 1 2) (4 5 6))
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
|
15
examples/objects.lisp
Normal file
15
examples/objects.lisp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
; objects
|
||||||
|
|
||||||
|
(test "symbols" :a "a")
|
||||||
|
|
||||||
|
(def ob {:a "fantastic" :b 2})
|
||||||
|
|
||||||
|
((of (js) :console :log) ob)
|
||||||
|
|
||||||
|
(echo (of ob :a))
|
||||||
|
|
||||||
|
(echo (keys ob))
|
||||||
|
(echo (values ob))
|
||||||
|
|
||||||
|
(set ob :a 4)
|
||||||
|
(echo (of ob :a))
|
1
examples/orca.lisp
Normal file
1
examples/orca.lisp
Normal file
@ -0,0 +1 @@
|
|||||||
|
(debug (of (osc "/a") :0 :value))
|
11
examples/osc.lisp
Normal file
11
examples/osc.lisp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
(clear)
|
||||||
|
(def x (of (osc "/test") "args" "0" "value"))
|
||||||
|
(def y (of (osc "/test") "args" "1" "value"))
|
||||||
|
(def r (of (osc "/test") "args" "2" "value"))
|
||||||
|
|
||||||
|
(fill
|
||||||
|
(circle x y r)
|
||||||
|
"red")
|
||||||
|
(stroke
|
||||||
|
(circle x y r)
|
||||||
|
5 "white")
|
37
examples/stars.lisp
Normal file
37
examples/stars.lisp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
; stars
|
||||||
|
(clear)
|
||||||
|
;
|
||||||
|
(defn draw-spoke
|
||||||
|
(cx cy r a)
|
||||||
|
(
|
||||||
|
(stroke
|
||||||
|
(line
|
||||||
|
(pos cx cy)
|
||||||
|
(circle-pos cx cy r a)) 2 "white")))
|
||||||
|
;
|
||||||
|
(defn draw-star
|
||||||
|
(cx cy r c)
|
||||||
|
(
|
||||||
|
(times c
|
||||||
|
(λ
|
||||||
|
(i)
|
||||||
|
(
|
||||||
|
(draw-spoke cx cy r
|
||||||
|
(deg-rad
|
||||||
|
(mul i
|
||||||
|
(div 360 c)))))))))
|
||||||
|
; main
|
||||||
|
(times 100
|
||||||
|
(λ
|
||||||
|
()
|
||||||
|
(
|
||||||
|
(draw-star
|
||||||
|
(random 100
|
||||||
|
(of
|
||||||
|
(frame) :w))
|
||||||
|
(random 100
|
||||||
|
(of
|
||||||
|
(frame) :h))
|
||||||
|
(random 10 100)
|
||||||
|
(floor
|
||||||
|
(random 3 32))))))
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
(clear)
|
(clear)
|
||||||
(def col
|
(def col
|
||||||
(lambda
|
(λ
|
||||||
(i)
|
(i)
|
||||||
(of
|
(of
|
||||||
(
|
(
|
||||||
@ -16,7 +16,7 @@
|
|||||||
(theme "b_inv"))
|
(theme "b_inv"))
|
||||||
(mod i 8))))
|
(mod i 8))))
|
||||||
(def rec
|
(def rec
|
||||||
(lambda
|
(λ
|
||||||
(v i)
|
(v i)
|
||||||
(if
|
(if
|
||||||
(gt v 0)
|
(gt v 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user