This commit is contained in:
neauoire 2020-02-10 09:42:55 -05:00
parent e98b0f8df7
commit 80ead7eabf
14 changed files with 451 additions and 119 deletions

View File

@ -6,7 +6,7 @@ Ronin is a <b>procedural graphics tool</b> designed to automate simple graphical
The library updates is constantly revealing new applications to Ronin, you can see the list of available functions <a href="https://github.com/hundredrabbits/Ronin#library" target="_blank" rel="noreferrer" class="external ">here</a>. Most of our iconography and designs were created with both <a href="https://hundredrabbits.itch.io/Ronin" target="_blank">Ronin</a> and <a href="https://hundredrabbits.itch.io/dotgrid">Dotgrid</a>.
Learn more by reading the <a href="https://github.com/Hundredrabbits/Ronin" target="_blank" rel="noreferrer" class="external ">manual</a>, or have a look at some experiments on <a href="https://twitter.com/neauoire/status/1152481692193419267" target="_blank" rel="noreferrer" class="external ">twitter</a>. If you need <b>help</b>, visit the <a href="https://hundredrabbits.itch.io/ronin/community" target="_blank" rel="noreferrer" class="external ">Community</a>, follow the [workshop](https://github.com/hundredrabbits/Ronin/blob/master/WORKSHOP.md) or watch the [video tutorial](https://www.youtube.com/watch?v=SgAWGh1s9zg).
Learn more by reading the <a href="https://github.com/Hundredrabbits/Ronin" target="_blank" rel="noreferrer" class="external ">manual</a>, or have a look at some experiments on <a href="https://twitter.com/neauoire/status/1152481692193419267" target="_blank" rel="noreferrer" class="external ">twitter</a>. If you need <b>help</b>, visit the <a href="https://hundredrabbits.itch.io/ronin/community" target="_blank" rel="noreferrer" class="external ">Community</a>, follow the [workshop](https://github.com/hundredrabbits/Ronin/blob/master/resources/WORKSHOP.md) or watch the [video tutorial](https://www.youtube.com/watch?v=SgAWGh1s9zg).
```lisp
; clear screen
@ -29,7 +29,7 @@ npm install
npm start
```
<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/PREVIEW.jpg' width='600'/>
<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/resources/PREVIEW.jpg' width='600'/>
## Helpers
@ -152,9 +152,9 @@ To save an image in memory, open an image file with Ronin, or drag an image file
- `(test name a b)`
- `(benchmark fn)` Logs time taken to execute a function.
<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/PREVIEW2.jpg' width='600'/>
<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/resources/PREVIEW2.jpg' width='600'/>
<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/PREVIEW3.jpg' width='600'/>
<img src='https://raw.githubusercontent.com/hundredrabbits/Ronin/master/resources/PREVIEW3.jpg' width='600'/>
## Extras

View File

@ -1,4 +1,6 @@
<svg class="vector" width="300px" height="300px" xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" style="width: 300px; height: 300px; stroke: rgb(0, 0, 0); stroke-width: 0; fill: none; stroke-linecap: square;">
<svg class="vector" width="300px" height="300px" xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" style="width: 300px; height: 300px; stroke: rgb(0, 0, 0); stroke-width: 0; fill: none; stroke-linecap: round; background:black">
<rect width="300" height="300" style="fill:rgb(0,0,0)" />
<path d="M60,60 l120,0 a60,60 0 0,1 60,60 a-60,60 0 0,1 -60,60 l-120,0 M180,180 a60,60 0 0,1 60,60" stroke='white' stroke-width='15'></path>
<g transform="translate(48 48) scale(0.675)">
<path d="M60,60 l120,0 a60,60 0 0,1 60,60 a-60,60 0 0,1 -60,60 l-120,0 M180,180 a60,60 0 0,1 60,60" style="stroke-width: 12; stroke-linecap: round; stroke-linejoin: round; stroke: rgb(255, 255, 255); fill: none;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 439 B

After

Width:  |  Height:  |  Size: 586 B

View File

@ -5,9 +5,9 @@
"requires": true,
"dependencies": {
"@electron/get": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.6.0.tgz",
"integrity": "sha512-xuvAzbN9iBApfAMvW0hKUpxHR5wPVbG9RaoSTbpu/WaHISDu0MVfMWYhfeU0X730CpBV0G2RkLgwAs9WDan3GA==",
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/@electron/get/-/get-1.7.2.tgz",
"integrity": "sha512-LSE4LZGMjGS9TloDx0yO44D2UTbaeKRk+QjlhWLiQlikV6J4spgDCjb6z4YIcqmPAwNzlNCnWF4dubytwI+ATA==",
"dev": true,
"requires": {
"debug": "^4.1.1",
@ -17,7 +17,7 @@
"global-tunnel-ng": "^2.7.1",
"got": "^9.6.0",
"sanitize-filename": "^1.6.2",
"sumchecker": "^3.0.0"
"sumchecker": "^3.0.1"
}
},
"@sindresorhus/is": {
@ -36,15 +36,15 @@
}
},
"@types/node": {
"version": "12.12.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.5.tgz",
"integrity": "sha512-KEjODidV4XYUlJBF3XdjSH5FWoMCtO0utnhtdLf1AgeuZLOrRbvmU/gaRCVg7ZaQDjVf3l84egiY0mRNe5xE4A==",
"version": "12.12.26",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.26.tgz",
"integrity": "sha512-UmUm94/QZvU5xLcUlNR8hA7Ac+fGpO1EG/a8bcWVz0P0LqtxFmun9Y2bbtuckwGboWJIT70DoWq1r3hb56n3DA==",
"dev": true
},
"asar": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/asar/-/asar-2.0.1.tgz",
"integrity": "sha512-Vo9yTuUtyFahkVMFaI6uMuX6N7k5DWa6a/8+7ov0/f8Lq9TVR0tUjzSzxQSxT1Y+RJIZgnP7BVb6Uhi+9cjxqA==",
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/asar/-/asar-2.0.3.tgz",
"integrity": "sha512-QdHKO+HOYVtE4B/M3up3i4LSJeJgsa2CTVBrjBf9GgLUPGGUFZowcdJ5yE4gOJuRAHNdqB9JFeRfFfaOu5x8Rw==",
"dev": true,
"requires": {
"chromium-pickle-js": "^0.2.0",
@ -75,15 +75,15 @@
"dev": true
},
"bluebird": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz",
"integrity": "sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==",
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
"boolean": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-2.0.3.tgz",
"integrity": "sha512-iHzXeFCXWrpjYE7DToXGCBPGZf0eVISqzL+4sgrOSYEKXnb59WHPFvGTTyCj6zJ/MuuLAxEn8zPkrTHHzlt3IA==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.0.tgz",
"integrity": "sha512-OElxJ1lUSinuoUnkpOgLmxp0DC4ytEhODEL6QJU0NpxE/mI4rUSh8h1P1Wkvfi3xQEBcxXR2gBIPNYNuaFcAbQ==",
"dev": true,
"optional": true
},
@ -220,9 +220,9 @@
}
},
"core-js": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.3.6.tgz",
"integrity": "sha512-u4oM8SHwmDuh5mWZdDg9UwNVq5s1uqq6ZDLLIs07VY+VJU91i3h4f3K/pgFvtUQPGdeStrZ+odKyfyt4EnKHfA==",
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz",
"integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==",
"dev": true,
"optional": true
},
@ -233,18 +233,18 @@
"dev": true
},
"cross-zip": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-2.1.6.tgz",
"integrity": "sha512-xLIETNkzRcU6jGRzenJyRFxahbtP4628xEKMTI/Ql0Vu8m4h8M7uRLVi7E5OYHuJ6VQPsG4icJumKAFUvfm0+A==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-3.0.0.tgz",
"integrity": "sha512-cm+l8PJ6WiSQmKZ/x8DGvUm2u/3FX2JFs1AFd18gdHaVhP5Lf4oE6Jrj2Jd05JYSioz5x+nIRVp0zBQuzuCRcQ==",
"dev": true,
"requires": {
"rimraf": "^3.0.0"
},
"dependencies": {
"rimraf": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
"integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
@ -283,9 +283,9 @@
}
},
"defer-to-connect": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.0.tgz",
"integrity": "sha512-WE2sZoctWm/v4smfCAdjYbrfS55JiMRdlY9ZubFhsYbteCK9+BvAx4YV7nPjYM6ZnX5BcoVKwfmyx9sIFTgQMQ==",
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
"integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
"dev": true
},
"define-properties": {
@ -312,9 +312,9 @@
"dev": true
},
"electron": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-7.0.1.tgz",
"integrity": "sha512-eMFoZIO0+eOAE9FyNC/f0Vp8l/sJziTMK+axEt2XIpGCagom1IZgUKPGwmHUcftZCX5lNKh+Tv53T0GcNnNTKQ==",
"version": "7.1.11",
"resolved": "https://registry.npmjs.org/electron/-/electron-7.1.11.tgz",
"integrity": "sha512-YDXfnovKY+8iZ5ISQh1kRqYIRKbpOSxGXCx2WVxPFPutEQ7Q/Xzr3h4GePEY25/NXMytMfhKaAZAYjtWUm3r9Q==",
"dev": true,
"requires": {
"@electron/get": "^1.0.1",
@ -323,19 +323,19 @@
}
},
"electron-notarize": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.1.1.tgz",
"integrity": "sha512-TpKfJcz4LXl5jiGvZTs5fbEx+wUFXV5u8voeG5WCHWfY/cdgdD8lDZIZRqLVOtR3VO+drgJ9aiSHIO9TYn/fKg==",
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz",
"integrity": "sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"fs-extra": "^8.0.1"
"fs-extra": "^8.1.0"
}
},
"electron-osx-sign": {
"version": "0.4.14",
"resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.14.tgz",
"integrity": "sha512-72vtrz9I3dOeFDaNvO5thwIjrimDiXMmYEbN0hEBqnvcSSMOWugjim2wiY9ox3dhuBFUhxp3owmuZCoH3Ij08A==",
"version": "0.4.15",
"resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.15.tgz",
"integrity": "sha512-1QtPNpjIji9bGZ0VRFwtJUyU1uHi7q3XUAOG0qFsvAUfs5H0T8hbgUfyg3xvPzmF1ruV8T8pQmQ86vNfLrcRiA==",
"dev": true,
"requires": {
"bluebird": "^3.5.0",
@ -370,16 +370,16 @@
}
},
"electron-packager": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-14.1.0.tgz",
"integrity": "sha512-4oGtQYYjSA/M4BGOwG0NBqEtThBf7aCV76C2AZsD71eGocYqZNvtvfzeeMnKkc3EW1nPq7iJ4Wge+GXma0kwIA==",
"version": "14.2.1",
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-14.2.1.tgz",
"integrity": "sha512-g6y3BVrAOz/iavKD+VMFbehrQcwCWuA3CZvVbmmbQuCfegGA1ytwWn0BNIDDrEdbuz31Fti7mnNHhb5L+3Wq9A==",
"dev": true,
"requires": {
"@electron/get": "^1.6.0",
"asar": "^2.0.1",
"cross-zip": "^2.1.5",
"cross-zip": "^3.0.0",
"debug": "^4.0.1",
"electron-notarize": "^0.1.1",
"electron-notarize": "^0.2.0",
"electron-osx-sign": "^0.4.11",
"fs-extra": "^8.1.0",
"galactus": "^0.2.1",
@ -392,6 +392,14 @@
"sanitize-filename": "^1.6.0",
"semver": "^6.0.0",
"yargs-parser": "^16.0.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"encodeurl": {
@ -526,13 +534,6 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true,
"optional": true
},
"galactus": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz",
@ -605,9 +606,9 @@
}
},
"glob": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz",
"integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==",
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@ -619,18 +620,18 @@
}
},
"global-agent": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.5.tgz",
"integrity": "sha512-pYJjCxxNBzYxo6iNO62JZn8iCFVbvpiM0zE4w/G5hBNIvLjnvzIeCVQPMKc3aK8ju5L7Q8NNI/oBSosU0eeSYw==",
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz",
"integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==",
"dev": true,
"optional": true,
"requires": {
"boolean": "^2.0.2",
"core-js": "^3.3.3",
"boolean": "^3.0.0",
"core-js": "^3.6.4",
"es6-error": "^4.1.1",
"matcher": "^2.0.0",
"roarr": "^2.14.2",
"semver": "^6.3.0",
"matcher": "^2.1.0",
"roarr": "^2.15.2",
"semver": "^7.1.2",
"serialize-error": "^5.0.0"
}
},
@ -648,15 +649,13 @@
}
},
"globalthis": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.0.tgz",
"integrity": "sha512-vcCAZTJ3r5Qcu5l8/2oyVdoFwxKgfYnMTR2vwWeux/NAVZK3PwcMaWkdUIn4GJbmKuRK7xcvDsLuK+CKcXyodg==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz",
"integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==",
"dev": true,
"optional": true,
"requires": {
"define-properties": "^1.1.2",
"function-bind": "^1.1.1",
"object-keys": "^1.0.12"
"define-properties": "^1.1.3"
}
},
"got": {
@ -827,9 +826,9 @@
"dev": true
},
"matcher": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.0.0.tgz",
"integrity": "sha512-nlmfSlgHBFx36j/Pl/KQPbIaqE8Zf0TqmSMjsuddHDg6PMSVgmyW9HpkLs0o0M1n2GIZ/S2BZBLIww/xjhiGng==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz",
"integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==",
"dev": true,
"optional": true,
"requires": {
@ -1089,9 +1088,9 @@
}
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@ -1104,9 +1103,9 @@
}
},
"resolve": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
"integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
@ -1131,15 +1130,15 @@
}
},
"roarr": {
"version": "2.14.3",
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.14.3.tgz",
"integrity": "sha512-D4BpKVruUDCJ9DJWcC7T+fx4o10IUYJ7MdmjM4Skx1aqc42CE7LGzPDUAfczibhavNGcnY1IHqJdq16NmiG4rQ==",
"version": "2.15.2",
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.2.tgz",
"integrity": "sha512-jmaDhK9CO4YbQAV8zzCnq9vjAqeO489MS5ehZ+rXmFiPFFE6B+S9KYO6prjmLJ5A0zY3QxVlQdrIya7E/azz/Q==",
"dev": true,
"optional": true,
"requires": {
"boolean": "^2.0.2",
"boolean": "^3.0.0",
"detect-node": "^2.0.4",
"globalthis": "^1.0.0",
"globalthis": "^1.0.1",
"json-stringify-safe": "^5.0.1",
"semver-compare": "^1.0.0",
"sprintf-js": "^1.1.2"
@ -1161,10 +1160,11 @@
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz",
"integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==",
"dev": true,
"optional": true
},
"semver-compare": {
"version": "1.0.0",
@ -1238,9 +1238,9 @@
"dev": true
},
"sumchecker": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.0.tgz",
"integrity": "sha512-yreseuC/z4iaodVoq07XULEOO9p4jnQazO7mbrnDSvWAU/y2cbyIKs+gWJptfcGu9R+1l27K8Rkj0bfvqnBpgQ==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
"dev": true,
"requires": {
"debug": "^4.1.0"
@ -1350,9 +1350,9 @@
"dev": true
},
"xmldom": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
"integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=",
"version": "0.1.31",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
"dev": true
},
"yargs-parser": {

View File

@ -3,13 +3,14 @@
"version": "0.1.0",
"main": "main.js",
"scripts": {
"start": "electron .",
"start": "electron . --disable-gpu",
"fix": "standard --fix",
"clean": "rm -r ~/Documents/Ronin-darwin-x64/ ; rm -r ~/Documents/Ronin-linux-x64/ ; rm -r ~/Documents/Ronin-win32-x64/ ; echo 'cleaned build location'",
"build_osx": "electron-packager . Ronin --platform=darwin --arch=x64 --out ~/Documents/ --overwrite --icon=icon.icns ; echo 'Built for OSX'",
"build_linux": "electron-packager . Ronin --platform=linux --arch=x64 --out ~/Documents/ --overwrite --icon=icon.ico ; echo 'Built for LINUX'",
"build_win": "electron-packager . Ronin --platform=win32 --arch=x64 --out ~/Documents/ --overwrite --icon=icon.ico ; echo 'Built for WIN'",
"build": "npm run clean ; npm run build_osx ; npm run build_linux ; npm run build_win",
"build": "npm run clean ; npm run build_osx ; npm run build_linux ; npm run build_win ; npm run add_manual",
"add_manual": "cp ../resources/MANUAL.txt ~/Documents/Ronin-darwin-x64/MANUAL.txt ; cp ../resources/MANUAL.txt ~/Documents/Ronin-linux-x64/MANUAL.txt ; cp ../resources/MANUAL.txt ~/Documents/Ronin-win32-x64/MANUAL.txt",
"push_osx": "~/Applications/butler push ~/Documents/Ronin-darwin-x64/ hundredrabbits/ronin:osx-64",
"push_linux": "~/Applications/butler push ~/Documents/Ronin-linux-x64/ hundredrabbits/ronin:linux-64",
"push_win": "~/Applications/butler push ~/Documents/Ronin-win32-x64/ hundredrabbits/ronin:windows-64",
@ -17,8 +18,8 @@
"push": "npm run build ; npm run push_osx ; npm run push_linux ; npm run push_win ; npm run clean ; npm run status"
},
"devDependencies": {
"electron": "^7.1.5",
"electron-packager": "^14.1.1"
"electron": "^7.1.11",
"electron-packager": "^14.2.1"
},
"standard": {
"globals": [

View File

@ -39,8 +39,8 @@ function Client () {
window.addEventListener('drop', this.onDrop)
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.download('ronin', 'lisp', this.commander._input.value, 'text/plain') })
this.acels.set('File', 'Export Image', 'CmdOrCtrl+E', () => { this.source.download('ronin', 'png', this.surface.el.toDataURL('image/png', 1.0), 'image/png') })
this.acels.set('File', 'Save', 'CmdOrCtrl+S', () => { this.source.write('ronin', 'lisp', this.commander._input.value, 'text/plain') })
this.acels.set('File', 'Export Image', 'CmdOrCtrl+E', () => { this.source.write('ronin', 'png', this.surface.el.toDataURL('image/png', 1.0), 'image/png') })
this.acels.set('File', 'Open', 'CmdOrCtrl+O', () => { this.source.open('lisp', this.whenOpen) })
this.acels.add('Edit', 'undo')

View File

@ -37,10 +37,10 @@ function Acels (client) {
if ((event.ctrlKey || event.metaKey) && event.shiftKey) {
return `CmdOrCtrl+Shift+${accelerator}`
}
if (event.shiftKey) {
if (event.shiftKey && event.key.toUpperCase() !== event.key) {
return `Shift+${accelerator}`
}
if (event.altKey) {
if (event.altKey && event.key.length !== 1) {
return `Alt+${accelerator}`
}
if (event.ctrlKey || event.metaKey) {
@ -73,7 +73,7 @@ function Acels (client) {
for (const cat in cats) {
text += `\n### ${cat}\n\n`
for (const item of cats[cat]) {
text += item.accelerator ? `- \`${item.accelerator}\`: ${item.info}\n` : ''
text += item.accelerator ? `- \`${item.accelerator.replace('`', 'tilde')}\`: ${item.name}\n` : ''
}
}
return text.trim()
@ -83,8 +83,9 @@ function Acels (client) {
const cats = this.sort()
let text = ''
for (const cat in cats) {
text += `\n${cat}\n\n`
for (const item of cats[cat]) {
text += item.accelerator ? `${cat}: ${item.name} | ${item.accelerator}\n` : ''
text += item.accelerator ? `${item.name.padEnd(25, '.')} ${item.accelerator}\n` : ''
}
}
return text.trim()
@ -105,13 +106,13 @@ function Acels (client) {
submenu: [
{ label: 'Download Themes', click: () => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Themes') } },
{ label: 'Open Theme', click: () => { client.theme.open() } },
{ label: 'Reset Theme', click: () => { client.theme.reset() } }
{ label: 'Reset Theme', accelerator: 'CmdOrCtrl+Escape', click: () => { client.theme.reset() } }
]
},
{ label: 'Fullscreen', accelerator: 'CmdOrCtrl+Enter', click: () => { app.toggleFullscreen() } },
{ label: 'Hide', accelerator: 'CmdOrCtrl+H', click: () => { app.toggleVisible() } },
{ label: 'Toggle Menubar', accelerator: 'Alt+H', click: () => { app.toggleMenubar() } },
{ label: 'Inspect', accelerator: 'CmdOrCtrl+.', click: () => { app.inspect() } },
{ label: 'Inspect', accelerator: 'CmdOrCtrl+Tab', click: () => { app.inspect() } },
{ role: 'quit' }
]
})

View File

@ -18,14 +18,14 @@ function Source (client) {
this.cache = {}
}
this.open = (ext, callback) => {
this.open = (ext, callback, store = false) => {
console.log('Source', 'Open file..')
const input = document.createElement('input')
input.type = 'file'
input.onchange = (e) => {
const file = e.target.files[0]
if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); return }
this.read(file, callback)
this.read(file, callback, store)
}
input.click()
}
@ -37,7 +37,7 @@ function Source (client) {
input.setAttribute('multiple', 'multiple')
input.onchange = (e) => {
for (const file of e.target.files) {
if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); return }
if (file.name.indexOf('.' + ext) < 0) { console.warn('Source', `Skipped ${file.name}`); continue }
this.read(file, this.store)
}
}
@ -60,11 +60,12 @@ function Source (client) {
// I/O
this.read = (file, callback) => {
this.read = (file, callback, store = false) => {
const reader = new FileReader()
reader.onload = (event) => {
const res = event.target.result
if (callback) { callback(file, res) }
if (store) { this.store(file, res) }
}
reader.readAsText(file, 'UTF-8')
}

View File

@ -1,5 +1,6 @@
'use strict'
/* global Image */
/* global Image */
function Library (client) {
@ -11,12 +12,9 @@ function Library (client) {
return shape || this.rect(0, 0, img.width, img.height)
}
this.export = async (name = 'export', type = 'image/png', quality = 1.0) => { // Exports a graphic file with format.
const base64 = client.surface.el.toDataURL(type, quality)
const link = document.createElement('a')
link.setAttribute('href', base64)
link.setAttribute('download', type === 'image/png' ? name + '.png' : name + '.jpg')
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }))
this.export = async (name = 'ronin', type = 'image/png', quality = 1.0) => { // Exports a graphic file with format.
const ext = type === 'image/png' ? name + '.png' : name + '.jpg'
client.source.write(name, ext, client.surface.el.toDataURL(type, 1.0), type)
}
// Shapes

22
resources/MANUAL.txt Normal file
View File

@ -0,0 +1,22 @@
File
New...................... CmdOrCtrl+N
Save..................... CmdOrCtrl+S
Export Image............. CmdOrCtrl+E
Open..................... CmdOrCtrl+O
Edit
View
Toggle Guides............ CmdOrCtrl+Shift+H
Toggle Commander......... CmdOrCtrl+K
Expand Commander......... CmdOrCtrl+Shift+K
Project
Run...................... CmdOrCtrl+R
Reload Run............... CmdOrCtrl+Shift+R
Re-Indent................ CmdOrCtrl+Shift+I
Clean.................... Escape

46
resources/PRELUDE.md Normal file
View File

@ -0,0 +1,46 @@
# Prelude
## Colors
### Compare two Colors
Use: `(if (color-eq (255 200 0) (200 255 0)) "yes" "no")`.
```
(defn color-eq
(a b)
(and
(eq a:0 b:0)
(eq a:1 b:1)
(eq a:2 b:2)))
```
## Pixels
### Erase all pixels of a specific color
Use: `(pixels erase-color (255 0 0))`.
```
(defn erase-color
(a b)
(a:0 a:1 a:2
(if
(and
(eq a:0 b:0)
(eq a:1 b:1)
(eq a:2 b:2)) 0 255)))
```
### Posterize
Use: `(pixels posterize 40)`.
```
(defn posterize
(a q)
(
(step a:0 q)
(step a:1 q)
(step a:2 q) a:3))
```

BIN
resources/PREVIEW.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 KiB

BIN
resources/PREVIEW2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 KiB

BIN
resources/PREVIEW3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

261
resources/WORKSHOP.md Normal file
View File

@ -0,0 +1,261 @@
# Workshop
<img src="https://raw.githubusercontent.com/hundredrabbits/100r.co/master/media/content/characters/ronin.pose.png" width="300"/>
This workshop is designed to go over the **most commonly used functions** with [Ronin](https://github.com/hundredrabbits/Ronin). The list of all available functions and their usage is located [here](https://github.com/hundredrabbits/Ronin/#library). You can also follow along our [video tutorial](https://youtu.be/SgAWGh1s9zg).
- **Part 1**: [Images](#Images) `(import)`, `(crop)`, `(export)`
- **Part 2**: [Draw](#Draw) `(stroke)`, `(fill)`, `(gradient)`, `(clear)`
- **Part 3**: [Filters](#Filters) `(pixels)`, `(saturation)`, `(convolve)`, `(sharpen)`
- **Part 4**: [Events](#Events) `(echo)`, `(on "mouse-down")`, `(on "animate")`, `(on "/a")`
## Images
This section will teach the basics of opening, cropping and saving an image file. You can use the `$path` helper to quickly get an image's path into Ronin, by writing `$path` and dragging a file onto the Ronin window.
### Import
To import an image onto the current canvas, type the following text, drag an image file onto the Ronin window, trace a shape in the canvas and press `cmd+r`:
```lisp
(import $path
(guide $rect))
```
The previous code will import an image, and preserve its ratio. Alternatively, you could use a `$line` to stretch the image, or a `$pos` to simply draw the image at its original size.
```lisp
(import $path
(guide $line))
```
### Crop
To crop the canvas, type the following text, drag an image file onto the Ronin window press `cmd+r`:
```lisp
(import $path
(pos 0 0))
(crop
(rect 50 50 300 300))
```
### Export
To export the resulting image, type the following text, drag an image file onto the Ronin window, then drag a folder and add the new file's name, and press `cmd+r`:
```lisp
(import $path)
(export $path)
```
For example, a version of that same code with file paths, might look something like the following:
```lisp
(import "~/Desktop/photo.jpg")
(export "~/Desktop/export.png")
```
You could also **generate the export path from the import path**. To import `~/Desktop/photo.jpg`, and automatically generate the export path `~/Desktop/photo-export.jpg`, use this:
```lisp
(def import-path $path)
(def export-path
(concat
(dirpath import-path) "/"
(filename import-path) "-export.jpg"))
(import import-path)
(export export-path)
```
## Draw
This section will teach you how to draw some basic shapes and colorize them.
### Stroke
In Ronin, a shape is either a `(rect)`, a `(line)`, a `(circle)` or a `(pos)`. To draw the outline of any shape, wrap the shape inside of a `(stroke shape width color)` function, like:
```lisp
(stroke
(rect 100 100 300 200) "red" 10)
```
Or, if you would like to trace the shape with your mouse:
```lisp
(stroke
$rect "red" 10)
```
### Fill
To fill the inside of any shape, wrap it inside of a `(fill shape color)` function, like:
```lisp
(fill
(rect 100 100 300 200) "orange")
```
### Gradient
To colorize a stroke or a fill, with a gradient, use the `(gradient line colors)` where the colors is a list of colors like `("blue" "red" "yellow")`:
```lisp
(clear)
(fill
(circle 300 300 200)
(gradient
(line 0 0 500 500)
("white" "black")))
```
To better understand how the `(line)` affects the coloring of the circle, wrap the `$line` inside a `(guide)`, as follows to preserve the guide interface:
```lisp
(clear)
(fill
(circle 300 300 200)
(gradient
(guide $line)
("white" "black")))
```
### Clear
In the previous example, we used the `(clear)` function, which clears the canvas, but it can also be used to clear only a part of the canvas:
```lisp
(clear)
(fill
frame "red")
(clear
(rect 100 100 300 300))
```
## Filters
This section will cover how to manipulate the pixels of an image.
### Pixels
First let's open an image, ideally one in color, and change every pixel of a selected area at `(rect 100 100 200 200)`:
```lisp
(import $path)
(pixels saturation 10
(rect 100 100 200 200))
```
The `(pixels)` function expects a function that returns 4 values(r,g,b,a), and so you can define a custom filter like:
```
(defn invert
(pixel)
(
(sub 255 pixel:0)
(sub 255 pixel:1)
(sub 255 pixel:2) pixel:3))
(pixels invert)
```
### saturation
In the previous example, we increased the saturation of a region of the image, to desaturate an entire image, you can simply omit the `(rect)` which will select the entire canvas, and set the pixel filter to `saturation` and the value to `0.5`(50% saturation):
```lisp
(import $path)
(pixels saturation 0.5)
```
### convolve
Effects which use the surrounding pixels, or convolution matrix, are used with the `(convolve)` function, you can learn more about this family of filters [here](https://en.wikipedia.org/wiki/Kernel_(image_processing)).
### sharpen
```lisp
(import $path)
(convolve (sharpen) $rect)
```
Custom convolve kernels can also be created like this:
```lisp
(import $path)
(def (blur)
(
(-1 -1 -1)
(-1 5 -1)
(-1 -1 -1)))
(convolve (blur))
```
<img src="https://raw.githubusercontent.com/hundredrabbits/100r.co/master/media/content/characters/ronin.idle.png" width="300"/>
## Events
This section will demonstrate how to use events in Ronin to create interactive scripts.
### Echo
You can print some content to the screen in Ronin, by using the `(echo)` function, for example, the following script will write the word `hello` at the bottom left of the interface:
```lisp
(echo "hello")
```
### MouseDown
Let's use the `(debug)` function to display the position of the mouse cursor in the interface.
```lisp
(on "mouse-down" echo)
```
We can define a function that triggers when the `mouse-down` event is detected, or when you click on the canvas:
```lisp
; define the function
(defn draw-rect
(e)
(fill e:circle "red"))
; use the function
(on "mouse-move" draw-rect)
```
For more examples of functions, see the [examples](https://github.com/hundredrabbits/Ronin/tree/master/examples).
You can find a more elaborate version of this example [here](https://github.com/hundredrabbits/Ronin/blob/master/examples/events/on-mouse.lisp).
### Animate
The `animate` event fires around 30 times per second, and is a perfect tool to create animations. Following the previous example, and the pattern of creating a function and binding it to the event, let's make a function that will use the `(time)` to animate a box:
```lisp
; define the function
(defn wob-rect
()
(
(clear)
(def rect-x 300)
(def rect-y (add (mul (sin (time 0.005)) 50) 300))
(fill
(rect rect-x rect-y 100 100) "red")))
; use the function
(on "animate" wob-rect)
```
You can find a more elaborate version of this example [here](https://github.com/hundredrabbits/Ronin/blob/master/examples/events/on-animate.lisp).
### OSC
Other programs can communicate with Ronin via OSC with the previous pattern. For example, if you send OSC data to the port `49162`, at the path `/a`, the event can be used in Ronin to trigger a function:
```lisp
(on "/a" echo)
```
You can find a more elaborate version of this example [here](https://github.com/hundredrabbits/Ronin/blob/master/examples/events/on-osc.lisp).
I hope this workshop has been enlightening, if you have questions or suggestions, please visit the [community](https://hundredrabbits.itch.io/ronin/community). Enjoy!