Skip to content

Commit

Permalink
feat(examples): add rasterize-blend demo
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Sep 27, 2022
1 parent ff0018f commit 58e3189
Show file tree
Hide file tree
Showing 10 changed files with 277 additions and 49 deletions.
Binary file added assets/examples/rasterize-blend.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
97 changes: 49 additions & 48 deletions examples/README.md

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions examples/rasterize-blend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# rasterize-blend

![screenshot](https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/rasterize-blend.jpg)

[Live demo](http://demo.thi.ng/umbrella/rasterize-blend/)

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

## Authors

- Karsten Schmidt

## License

© 2022 Karsten Schmidt // Apache Software License 2.0
21 changes: 21 additions & 0 deletions examples/rasterize-blend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link
rel="icon"
href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">⛱️</text></svg>'
/>
<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>rasterize-blend · @thi.ng/umbrella</title>
<link href="https://unpkg.com/tachyons@4/css/tachyons.min.css" rel="stylesheet">
<style>
</style>
</head>
<body class="sans-serif">
<div id="app"></div>
<div><a class="link" href="https://github.com/thi-ng/umbrella/tree/develop/examples/rasterize-blend">Source code</a></div>
<script type="module" src="/src/index.ts"></script>
</body>
</html>
32 changes: 32 additions & 0 deletions examples/rasterize-blend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@example/rasterize-blend",
"version": "0.0.1",
"private": true,
"description": "Steering behavior drawing with alpha-blended shapes",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <k+npm@thi.ng>",
"license": "Apache-2.0",
"scripts": {
"start": "vite --open",
"build": "tsc && vite build --base='./'",
"preview": "vite preview --host --open"
},
"devDependencies": {
"typescript": "^4.8.3",
"vite": "^3.1.3"
},
"dependencies": {
"@thi.ng/adapt-dpi": "workspace:^",
"@thi.ng/dsp": "workspace:^",
"@thi.ng/pixel": "workspace:^",
"@thi.ng/rasterize": "workspace:^",
"@thi.ng/vectors": "workspace:^"
},
"browser": {
"process": false
},
"thi.ng": {
"readme": true,
"screenshot": "examples/rasterize-blend.jpg"
}
}
65 changes: 65 additions & 0 deletions examples/rasterize-blend/src/agent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {
cartesian2,
direction2,
maddN2,
mixN2,
normalize2,
randMinMax2,
randNorm2,
Vec,
} from "@thi.ng/vectors";

interface AgentOpts {
margin: number;
speed: number;
steerSpeed: number;
spinSpeed: number;
spinRadius: number;
}

export class Agent {
opts: AgentOpts;
pos: Vec = [0.5, 0.5];
globalPos: Vec;
dir: Vec;
targetDir: Vec;
spin = 0;

constructor(opts: Partial<AgentOpts> = {}) {
this.opts = {
margin: 0.02,
speed: 0.001,
steerSpeed: 0.05,
spinSpeed: 0.05,
spinRadius: 0.0,
...opts,
};
this.globalPos = [...this.pos];
this.targetDir = randNorm2([]);
this.dir = [...this.targetDir];
this.spin = 0;
}

update() {
const [x, y] = this.pos;
const { margin, speed, steerSpeed, spinSpeed, spinRadius } = this.opts;
const imargin = 1 - margin;
if (
Math.random() < 0.005 ||
x < margin ||
x > imargin ||
y < margin ||
y > imargin
) {
this.targetDir = direction2(
[],
this.pos,
randMinMax2([], [margin, margin], [imargin, imargin])
);
}
normalize2(null, mixN2(null, this.dir, this.targetDir, steerSpeed));
maddN2(this.pos, this.dir, speed, this.pos);
this.spin += spinSpeed;
return cartesian2(this.globalPos, [spinRadius, this.spin], this.pos);
}
}
73 changes: 73 additions & 0 deletions examples/rasterize-blend/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { adaptDPI } from "@thi.ng/adapt-dpi";
import type { NumericArray } from "@thi.ng/api";
import { osc, sin } from "@thi.ng/dsp";
import { canvas2d, floatBuffer, floatBufferFromCanvas } from "@thi.ng/pixel";
import { defBlendF, drawCircle, drawLine, Shader2D } from "@thi.ng/rasterize";
import { Agent } from "./agent.js";

// create canvas and adapt to screen's DPR
const { canvas } = canvas2d(640, 640, document.body);
adaptDPI(canvas, canvas.width, canvas.height);
// pre-create image data
const data = new ImageData(canvas.width, canvas.height);
// create RGBA floating point pixel buffer for drawing
const img = floatBufferFromCanvas(canvas);

interface Brush {
agent: Agent;
shader: Shader2D<NumericArray>;
}

// define "brushes", each with its own agent & color blend function
// see: https://docs.thi.ng/umbrella/rasterize/modules.html#defBlendF
const brushes: Brush[] = [
{
agent: new Agent({
speed: 1 / canvas.width,
}),
shader: defBlendF([0, 0, 0, 0.05]),
},
{
agent: new Agent({
speed: 1 / canvas.width,
spinRadius: 0.2,
spinSpeed: 0.02,
}),
shader: defBlendF([1, 0, 0.4, 0.05]),
},
];

// create sine oscillator for brush size modulation
const radius = osc(sin, 0.002, 0.05, 0.07);

const update = () => {
for (let i = 0; i < 10; i++) {
brushes.forEach((b, i) => {
const [px, py] = b.agent.pos;
let [x, y] = b.agent.update();
x *= canvas.width;
y *= canvas.height;
if (i === 0) {
// draw 1st agent as circles with modulated radius
drawCircle(img, x, y, radius.next() * canvas.width, b.shader);
} else {
// draw all other agents as line
drawLine(
img,
px * canvas.width,
py * canvas.height,
x,
y,
b.shader
);
}
});
}
// convert floating point image and apply to canvas
img.blitCanvas(canvas, { data });
// ∞-loop
requestAnimationFrame(update);
};

// kick off...
update();
1 change: 1 addition & 0 deletions examples/rasterize-blend/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
6 changes: 6 additions & 0 deletions examples/rasterize-blend/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": ["src/**/*"],
"compilerOptions": {
}
}
16 changes: 15 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,20 @@ __metadata:
languageName: unknown
linkType: soft

"@example/rasterize-blend@workspace:examples/rasterize-blend":
version: 0.0.0-use.local
resolution: "@example/rasterize-blend@workspace:examples/rasterize-blend"
dependencies:
"@thi.ng/adapt-dpi": "workspace:^"
"@thi.ng/dsp": "workspace:^"
"@thi.ng/pixel": "workspace:^"
"@thi.ng/rasterize": "workspace:^"
"@thi.ng/vectors": "workspace:^"
typescript: ^4.8.3
vite: ^3.1.3
languageName: unknown
linkType: soft

"@example/rdom-basics@workspace:examples/rdom-basics":
version: 0.0.0-use.local
resolution: "@example/rdom-basics@workspace:examples/rdom-basics"
Expand Down Expand Up @@ -4020,7 +4034,7 @@ __metadata:
languageName: unknown
linkType: soft

"@thi.ng/rasterize@workspace:packages/rasterize":
"@thi.ng/rasterize@workspace:^, @thi.ng/rasterize@workspace:packages/rasterize":
version: 0.0.0-use.local
resolution: "@thi.ng/rasterize@workspace:packages/rasterize"
dependencies:
Expand Down

0 comments on commit 58e3189

Please sign in to comment.