add examples page with prerendered swatches

This commit is contained in:
Felix Roos 2022-12-28 14:40:53 +01:00
parent 1dd0ff13d8
commit 9f058bd88a
6 changed files with 380 additions and 6 deletions

332
package-lock.json generated
View File

@ -14,6 +14,7 @@
"devDependencies": {
"@vitest/ui": "^0.25.7",
"c8": "^7.12.0",
"canvas": "^2.11.0",
"eslint": "^8.28.0",
"events": "^3.3.0",
"gh-pages": "^4.0.0",
@ -1717,6 +1718,109 @@
"@lezer/common": "^1.0.0"
}
},
"node_modules/@mapbox/node-pre-gyp": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
"integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
"dev": true,
"dependencies": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.7",
"nopt": "^5.0.0",
"npmlog": "^5.0.1",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.11"
},
"bin": {
"node-pre-gyp": "bin/node-pre-gyp"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/are-we-there-yet": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
"dev": true,
"dependencies": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/detect-libc": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
"dev": true,
"dependencies": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.1",
"object-assign": "^4.1.1",
"signal-exit": "^3.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"dev": true,
"dependencies": {
"abbrev": "1"
},
"bin": {
"nopt": "bin/nopt.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/npmlog": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
"dev": true,
"dependencies": {
"are-we-there-yet": "^2.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^3.0.0",
"set-blocking": "^2.0.0"
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"license": "MIT",
@ -3135,6 +3239,21 @@
],
"license": "CC-BY-4.0"
},
"node_modules/canvas": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.0.tgz",
"integrity": "sha512-bdTjFexjKJEwtIo0oRx8eD4G2yWoUOXP9lj279jmQ2zMnTQhT8C3512OKz3s+ZOaQlLbE7TuVvRDYDB3Llyy5g==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.17.0",
"simple-get": "^3.0.3"
},
"engines": {
"node": ">=6"
}
},
"node_modules/caseless": {
"version": "0.12.0",
"dev": true,
@ -3388,6 +3507,15 @@
"version": "1.1.4",
"license": "MIT"
},
"node_modules/color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true,
"bin": {
"color-support": "bin.js"
}
},
"node_modules/columnify": {
"version": "1.6.0",
"dev": true,
@ -3979,6 +4107,18 @@
"node": ">=0.10"
}
},
"node_modules/decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"dev": true,
"dependencies": {
"mimic-response": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/dedent": {
"version": "0.7.0",
"dev": true,
@ -7610,6 +7750,18 @@
"node": ">=6"
}
},
"node_modules/mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
"dev": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/min-indent": {
"version": "1.0.1",
"dev": true,
@ -7863,6 +8015,12 @@
"dev": true,
"license": "ISC"
},
"node_modules/nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"dev": true
},
"node_modules/nanoid": {
"version": "3.3.4",
"dev": true,
@ -10205,6 +10363,37 @@
"dev": true,
"license": "ISC"
},
"node_modules/simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/simple-get": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"dev": true,
"dependencies": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"node_modules/sirv": {
"version": "2.0.2",
"dev": true,
@ -12273,6 +12462,7 @@
"version": "0.5.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@strudel.cycles/core": "^0.5.0",
"acorn": "^8.8.1",
"escodegen": "^2.0.0",
"estree-walker": "^3.0.1"
@ -12301,6 +12491,7 @@
"version": "0.5.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@strudel.cycles/core": "^0.5.0",
"WebDirt": "github:dktr0/WebDirt"
}
},
@ -13506,6 +13697,90 @@
"@lezer/common": "^1.0.0"
}
},
"@mapbox/node-pre-gyp": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
"integrity": "sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==",
"dev": true,
"requires": {
"detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0",
"make-dir": "^3.1.0",
"node-fetch": "^2.6.7",
"nopt": "^5.0.0",
"npmlog": "^5.0.1",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"tar": "^6.1.11"
},
"dependencies": {
"are-we-there-yet": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
"dev": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^3.6.0"
}
},
"detect-libc": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
"integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
"dev": true
},
"gauge": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
"dev": true,
"requires": {
"aproba": "^1.0.3 || ^2.0.0",
"color-support": "^1.1.2",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.1",
"object-assign": "^4.1.1",
"signal-exit": "^3.0.0",
"string-width": "^4.2.3",
"strip-ansi": "^6.0.1",
"wide-align": "^1.1.2"
}
},
"nopt": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
"dev": true,
"requires": {
"abbrev": "1"
}
},
"npmlog": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
"dev": true,
"requires": {
"are-we-there-yet": "^2.0.0",
"console-control-strings": "^1.1.0",
"gauge": "^3.0.0",
"set-blocking": "^2.0.0"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
}
}
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"requires": {
@ -13882,6 +14157,7 @@
"@strudel.cycles/transpiler": {
"version": "file:packages/transpiler",
"requires": {
"@strudel.cycles/core": "^0.5.0",
"acorn": "^8.8.1",
"escodegen": "^2.0.0",
"estree-walker": "^3.0.1"
@ -13901,6 +14177,7 @@
"@strudel.cycles/webdirt": {
"version": "file:packages/webdirt",
"requires": {
"@strudel.cycles/core": "^0.5.0",
"WebDirt": "github:dktr0/WebDirt"
}
},
@ -14650,6 +14927,17 @@
"version": "1.0.30001430",
"dev": true
},
"canvas": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.0.tgz",
"integrity": "sha512-bdTjFexjKJEwtIo0oRx8eD4G2yWoUOXP9lj279jmQ2zMnTQhT8C3512OKz3s+ZOaQlLbE7TuVvRDYDB3Llyy5g==",
"dev": true,
"requires": {
"@mapbox/node-pre-gyp": "^1.0.0",
"nan": "^2.17.0",
"simple-get": "^3.0.3"
}
},
"caseless": {
"version": "0.12.0",
"dev": true
@ -14817,6 +15105,12 @@
"color-name": {
"version": "1.1.4"
},
"color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true
},
"columnify": {
"version": "1.6.0",
"dev": true,
@ -15234,6 +15528,15 @@
"version": "0.2.0",
"dev": true
},
"decompress-response": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
"dev": true,
"requires": {
"mimic-response": "^2.0.0"
}
},
"dedent": {
"version": "0.7.0",
"dev": true
@ -17579,6 +17882,12 @@
"version": "2.1.0",
"dev": true
},
"mimic-response": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
"dev": true
},
"min-indent": {
"version": "1.0.1",
"dev": true
@ -17738,6 +18047,12 @@
"version": "0.0.8",
"dev": true
},
"nan": {
"version": "2.17.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
"integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==",
"dev": true
},
"nanoid": {
"version": "3.3.4",
"dev": true
@ -19278,6 +19593,23 @@
"version": "3.0.7",
"dev": true
},
"simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
"dev": true
},
"simple-get": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"dev": true,
"requires": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"sirv": {
"version": "2.0.2",
"dev": true,

View File

@ -48,6 +48,7 @@
"devDependencies": {
"@vitest/ui": "^0.25.7",
"c8": "^7.12.0",
"canvas": "^2.11.0",
"eslint": "^8.28.0",
"events": "^3.3.0",
"gh-pages": "^4.0.0",

View File

@ -56,9 +56,6 @@ Pattern.prototype.pianoroll = function ({
from = 0;
to = timeframeProp;
}
if (!autorange && fold) {
console.warn('disabling autorange has no effect when fold is enabled');
}
const timeAxis = vertical ? h : w;
const valueAxis = vertical ? w : h;
let timeRange = vertical ? [timeAxis, 0] : [0, timeAxis]; // pixel range for time
@ -190,9 +187,6 @@ export function pianoroll({
from = 0;
to = timeframeProp;
}
if (!autorange && fold) {
console.warn('disabling autorange has no effect when fold is enabled');
}
const timeAxis = vertical ? h : w;
const valueAxis = vertical ? w : h;
let timeRange = vertical ? [timeAxis, 0] : [0, timeAxis]; // pixel range for time

View File

@ -0,0 +1,18 @@
---
import * as tunes from '../../../src/repl/tunes.mjs';
---
<body class="bg-slate-800">
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-2 p-2 select-none">
{
Object.entries(tunes).map(([name, tune]) => (
<a class="rounded-md bg-slate-900 hover:bg-slate-700 cursor-pointer relative" href={`/#${btoa(tune)}`}>
<div class="absolute w-full h-full flex justify-center items-center">
<span class="bg-slate-800 p-2 rounded-md text-white">{name}</span>
</div>
<img src={`/img/example-${name}.png`} />
</a>
))
}
</div>
</body>

View File

@ -0,0 +1,27 @@
import { createCanvas } from 'canvas';
import { pianoroll } from '@strudel.cycles/core';
import { evaluate } from '@strudel.cycles/transpiler';
import '../../../../test/runtime.mjs';
import * as tunes from '../../repl/tunes.mjs';
export async function get({ params, request }) {
const { name } = params;
const tune = tunes[name];
const { pattern } = await evaluate(tune);
const haps = pattern.queryArc(0, 4);
const canvas = createCanvas(800, 800);
const ctx = canvas.getContext('2d');
pianoroll({ time: 4, haps, ctx, playhead: 1, fold: 1, background: 'transparent', playheadColor: 'transparent' });
const buffer = canvas.toBuffer('image/png');
return {
body: buffer,
encoding: 'binary',
};
}
export function getStaticPaths() {
return Object.keys(tunes).map((name) => ({
params: {
name,
},
}));
}

View File

@ -42,6 +42,8 @@ This interactive tutorial will guide you through the basics of Strudel.
To see and hear what Strudel can do, visit the [Strudel REPL](https://strudel.tidalcycles.org/) and click the Shuffle icon in the top menu bar.
You can get a feel for Strudel by browsing and editing these examples and clicking the Refresh icon to update.
You can also browse through the examples [here](/examples).
Alternatively, you can get a taste of what Strudel can do by clicking play on this track:
<MiniRepl