Skip to content

Commit

Permalink
feat(examples): add poly-spline example
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jul 12, 2019
1 parent cc3af3f commit 64693d3
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 22 deletions.
45 changes: 23 additions & 22 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,26 @@ in touch via PR, issue tracker, email or twitter!
| 34 | [markdown](./markdown) | Markdown parser & editor w/ live preview | fsm, rstream, transducers-hdom | advanced |
| 35 | [package-stats](./package-stats) | CLI util to visualize umbrella pkg stats | hiccup-svg, transducers | intermediate |
| 36 | [pointfree-svg](./pointfree-svg) | Generate SVG using pointfree DSL | hiccup, hiccup-svg, pointfree-lang | intermediate |
| 37 | [router-basics](./router-basics) | Complete mini SPA | atom, hdom, interceptors, router | advanced |
| 38 | [rstream-dataflow](./rstream-dataflow) | Dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate |
| 39 | [rstream-grid](./rstream-grid) | Dataflow graph SVG grid | atom, hdom, hiccup-svg, interceptors, rstream-graph, transducers | advanced |
| 40 | [rstream-hdom](./rstream-hdom) | rstream based UI updates & state handling | hdom, rstream, transducers | intermediate |
| 41 | [shader-ast-canvas2d](shader-ast-canvas2d) | 2D canvas shader emulation | shader-ast | basic |
| 42 | [shader-ast-noise](shader-ast-noise) | HOF shader function composition | shader-ast, webgl | basic |
| 43 | [shader-ast-raymarch](shader-ast-raymarch) | WebGL & Canvas2D raymarch shader | shader-ast, webgl | intermediate |
| 44 | [shader-ast-sdf2d](shader-ast-sdf2d) | WebGL & Canvas2D SDF | shader-ast, webgl | basic |
| 45 | [shader-ast-tunnel](shader-ast-tunnel) | WebGL & Canvas2D textured tunnel shader | shader-ast, webgl | basic |
| 46 | [svg-barchart](./svg-barchart) | hdom SVG barchart component | hdom, transducers | basic |
| 47 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic |
| 48 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate |
| 49 | [talk-slides](./talk-slides) | Presentation slides from ClojureX 2018 | hdom, rstream, transducers-hdom | intermediate |
| 50 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate |
| 51 | [transducers-hdom](./transducers-hdom) | Transducer & rstream based hdom UI updates | hdom, rstream, transducers-hdom | basic |
| 52 | [triple-query](./triple-query) | Triple store query results & sortable table | atom, hdom, hdom-components, rstream-query, transducers | intermediate |
| 53 | [webgl-cubemap](./webgl-cubemap) | WebGL cubemap, async texture loading | hdom, webgl, shader-ast | intermediate |
| 54 | [webgl-gpgpu-basics](./webgl-gpgpu-basics) | Minimal GPGPU example | webgl, shader-ast | basic |
| 55 | [webgl-grid](./webgl-grid) | WebGL instancing | webgl, hdom | intermediate |
| 56 | [webgl-msdf](./webgl-msdf) | WebGL MSDF font rendering & particle system | webgl, webgl-msdf, shader-ast, hdom | intermediate |
| 57 | [webgl-ssao](./webgl-ssao) | WebGL screenspace ambient occlusion | webgl, shader-ast, rstream, hdom | advanced |
| 58 | [xml-converter](./xml-converter) | XML/HTML/SVG to hiccup conversion as you type | rstream, sax, transducers, transducers-hdom | advanced |
| 37 | [poly-spline](./poly-spline) | Polygon to cubic curve conversion & visualization | geom, hiccup-svg, hdom, rstream | intermediate |
| 38 | [router-basics](./router-basics) | Complete mini SPA | atom, hdom, interceptors, router | advanced |
| 39 | [rstream-dataflow](./rstream-dataflow) | Dataflow graph | atom, hdom, rstream, rstream-gestures, rstream-graph, transducers | intermediate |
| 40 | [rstream-grid](./rstream-grid) | Dataflow graph SVG grid | atom, hdom, hiccup-svg, interceptors, rstream-graph, transducers | advanced |
| 41 | [rstream-hdom](./rstream-hdom) | rstream based UI updates & state handling | hdom, rstream, transducers | intermediate |
| 42 | [shader-ast-canvas2d](shader-ast-canvas2d) | 2D canvas shader emulation | shader-ast | basic |
| 43 | [shader-ast-noise](shader-ast-noise) | HOF shader function composition | shader-ast, webgl | basic |
| 44 | [shader-ast-raymarch](shader-ast-raymarch) | WebGL & Canvas2D raymarch shader | shader-ast, webgl | intermediate |
| 45 | [shader-ast-sdf2d](shader-ast-sdf2d) | WebGL & Canvas2D SDF | shader-ast, webgl | basic |
| 46 | [shader-ast-tunnel](shader-ast-tunnel) | WebGL & Canvas2D textured tunnel shader | shader-ast, webgl | basic |
| 47 | [svg-barchart](./svg-barchart) | hdom SVG barchart component | hdom, transducers | basic |
| 48 | [svg-particles](./svg-particles) | hdom SVG generation / animation | hdom, transducers | basic |
| 49 | [svg-waveform](./svg-waveform) | hdom SVG generation / undo history | atom, hdom, hiccup-svg, interceptors, iterators | intermediate |
| 50 | [talk-slides](./talk-slides) | Presentation slides from ClojureX 2018 | hdom, rstream, transducers-hdom | intermediate |
| 51 | [todo-list](./todo-list) | Canonical Todo list with undo/redo | atom, hdom, transducers | intermediate |
| 52 | [transducers-hdom](./transducers-hdom) | Transducer & rstream based hdom UI updates | hdom, rstream, transducers-hdom | basic |
| 53 | [triple-query](./triple-query) | Triple store query results & sortable table | atom, hdom, hdom-components, rstream-query, transducers | intermediate |
| 54 | [webgl-cubemap](./webgl-cubemap) | WebGL cubemap, async texture loading | hdom, webgl, shader-ast | intermediate |
| 55 | [webgl-gpgpu-basics](./webgl-gpgpu-basics) | Minimal GPGPU example | webgl, shader-ast | basic |
| 56 | [webgl-grid](./webgl-grid) | WebGL instancing | webgl, hdom | intermediate |
| 57 | [webgl-msdf](./webgl-msdf) | WebGL MSDF font rendering & particle system | webgl, webgl-msdf, shader-ast, hdom | intermediate |
| 58 | [webgl-ssao](./webgl-ssao) | WebGL screenspace ambient occlusion | webgl, shader-ast, rstream, hdom | advanced |
| 59 | [xml-converter](./xml-converter) | XML/HTML/SVG to hiccup conversion as you type | rstream, sax, transducers, transducers-hdom | advanced |
5 changes: 5 additions & 0 deletions examples/poly-spline/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.cache
out
node_modules
yarn.lock
*.js
13 changes: 13 additions & 0 deletions examples/poly-spline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# poly-spline

[Live demo](http://demo.thi.ng/umbrella/poly-spline/)

Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki.

## Authors

- Karsten Schmidt

## License

© 2018 Karsten Schmidt // Apache Software License 2.0
16 changes: 16 additions & 0 deletions examples/poly-spline/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>poly-spline</title>
<link href="https://unpkg.com/tachyons@4/css/tachyons.min.css" rel="stylesheet">
<style>
</style>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./src/index.ts"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions examples/poly-spline/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "poly-spline",
"version": "0.0.1",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"clean": "rm -rf .cache build out",
"build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting",
"build:webpack": "../../node_modules/.bin/webpack --mode production",
"start": "parcel index.html -p 8080 --open"
},
"devDependencies": {
"parcel-bundler": "^1.12.3",
"terser": "^3.17.0",
"typescript": "^3.4.1"
},
"dependencies": {
"@thi.ng/api": "latest",
"@thi.ng/rstream": "latest",
"@thi.ng/transducers-hdom": "latest"
},
"browserslist": [
"last 3 Chrome versions"
],
"browser": {
"process": false
}
}
202 changes: 202 additions & 0 deletions examples/poly-spline/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import { sin } from "@thi.ng/dsp";
import {
asCubic,
circle,
group,
line,
pathFromCubics,
star,
svgDoc,
withAttribs
} from "@thi.ng/geom";
import { convertTree } from "@thi.ng/hiccup-svg";
import {
fromRAF,
stream,
Stream,
sync
} from "@thi.ng/rstream";
import {
comp,
iterator,
map,
mapcat,
partition,
reducer,
scan
} from "@thi.ng/transducers";
import { updateDOM } from "@thi.ng/transducers-hdom";

const BUTTONS = {
blue: "bg-blue white hover-bg-light-blue hover-navy",
green: "bg-green white hover-bg-light-green hover-dark-green"
};

// HOF event listener to emit a value on given stream
const emitOnStream = (stream: Stream<any>, val: any) => () => stream.next(val);

// button UI component
const button = (
_: any,
clazz: string,
onclick: EventListener,
label: string
) => [
"a",
{
href: "#",
onclick,
class: "dib w4 mr2 pa2 link " + clazz
},
label
];

// slider UI component
const slider = (
_: any,
attribs: any,
stream: Stream<number>,
label: string
) => [
"div.mv3",
["span.dib.w4.mr2", label],
[
"input.mr3",
{
type: "range",
value: stream.deref(),
oninput: (e: any) => stream.next(parseFloat(e.target.value)),
...attribs
}
],
stream.deref().toFixed(1)
];

// main app component / stream transformer
// attached to `main` stream sync and responsible to build full UI
// from current stream values
const app = (
_mode: Stream<boolean>,
_uniform: Stream<boolean>,
_scale: Stream<number>,
_uniScale: Stream<number>
) => ({ poly, mode, uniform, scale, uniScale }: any) => {
// reconstruct poly as cubic curve segments
const cubics = asCubic(poly, {
breakPoints: mode,
scale: scale * (uniform ? uniScale : 1),
uniform
});
// visualize control points as circles
const controlPoints = iterator(
comp(mapcat((x) => x.points), map((p) => circle(p, 0.75))),
cubics
);
// visualize control point handles
const handles = iterator(
comp(mapcat((x) => x.points), partition(2), map(line)),
cubics
);
return [
"div.sans-serif.ma3",
// user controls
[
"div",
[
button,
BUTTONS.blue,
emitOnStream(_mode, true),
mode ? "break points" : "control points"
],
[
button,
BUTTONS.green,
emitOnStream(_uniform, true),
uniform ? "uniform" : "non-uniform"
],
[
slider,
{ min: -1.3, max: 1.3, step: 0.1 },
_scale,
"tangent scale"
],
[
slider,
{ min: 0, max: 100, step: 1, disabled: !uniform },
_uniScale,
"uniform scale"
]
],
[
"div",
// all @thi.ng/geom shapes implement the `IToHiccup`
// interface and so can be used directly in
// @thi.ng/hdom-canvas visualizations. However, here we're
// using SVG and hence will need to call `convertTree()` to
// transform the hiccup format into a SVG compatible format
// see:
// https://github.com/thi-ng/umbrella/blob/master/packages/hiccup-svg/src/convert.ts#L34
convertTree(
svgDoc(
{
width: 480,
height: 480,
viewBox: "-150 -150 300 300",
fill: "none",
stroke: "#ccc",
"stroke-width": 0.25
},
poly,
withAttribs(pathFromCubics(cubics), {
stroke: mode ? "blue" : "red",
"stroke-width": 1
}),
group({ stroke: "#333" }, [...controlPoints, ...handles])
)
)
]
];
};

// stream of animated polygons
const poly = fromRAF().transform(
map((t) => star(100, 6, [sin(t, 0.01, 0.5, 0.8), 1]))
);

// poly spline mode flag (control points vs break points)
const mode = stream<boolean>();
// flag for uniform tangent scaling
const uniform = stream<boolean>();
// tangent scale
const scale = stream<number>();
// uniform scale factor (only used if uniform scaling is enabled)
const uniScale = stream<number>();

// re-usable transducer implementing a toggle switch
const toggle = scan(reducer(() => true, (acc) => !acc));

// main stream combinator
const main = sync<any, any>({
src: {
poly,
mode: mode.transform(toggle),
uniform: uniform.transform(toggle),
scale,
uniScale
}
});

// transform to create & apply UI
main.transform(map(app(mode, uniform, scale, uniScale)), updateDOM());

// seed all input streams to kick off
mode.next(false);
uniform.next(false);
scale.next(0.5);
uniScale.next(25);

// HMR handling (dev builds only)
if (process.env.NODE_ENV !== "production") {
const hot = (<any>module).hot;
hot && hot.dispose(() => main.done());
}
11 changes: 11 additions & 0 deletions examples/poly-spline/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": ".",
"target": "es6",
"sourceMap": true
},
"include": [
"./src/**/*.ts"
]
}

0 comments on commit 64693d3

Please sign in to comment.