Skip to content

Commit

Permalink
feat(examples): add pixel-gradients example
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Oct 9, 2023
1 parent 7ecb207 commit 1c0e541
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 0 deletions.
Binary file added assets/examples/pixel-gradients.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions examples/pixel-gradients/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# pixel-gradients

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

[Live demo](http://demo.thi.ng/umbrella/pixel-gradients/)

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

## Authors

- Karsten Schmidt

## License

© 2023 Karsten Schmidt // Apache Software License 2.0
29 changes: 29 additions & 0 deletions examples/pixel-gradients/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!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>pixel-gradients · @thi.ng/umbrella</title>
<link
href="https://unpkg.com/tachyons@4/css/tachyons.min.css"
rel="stylesheet"
/>
<style></style>
</head>
<body class="ma3 sans-serif">
<div id="app"></div>
<div>
<a
class="link"
href="https://github.com/thi-ng/umbrella/tree/develop/examples/pixel-gradients"
>Source code</a
>
</div>
<script type="module" src="/src/index.ts"></script>
</body>
</html>
46 changes: 46 additions & 0 deletions examples/pixel-gradients/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@example/pixel-gradients",
"version": "0.0.1",
"private": true,
"description": "Randomized 4-point 2D color gradient image generator",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <[email protected]>",
"license": "Apache-2.0",
"scripts": {
"start": "vite --host --open",
"build": "tsc && vite build --base='./'",
"preview": "vite preview --host --open"
},
"devDependencies": {
"typescript": "^5.2.2",
"vite": "^4.4.9"
},
"dependencies": {
"@thi.ng/api": "workspace:^",
"@thi.ng/arrays": "workspace:^",
"@thi.ng/color": "workspace:^",
"@thi.ng/color-palettes": "workspace:^",
"@thi.ng/dl-asset": "workspace:^",
"@thi.ng/hiccup-html": "workspace:^",
"@thi.ng/pixel": "workspace:^",
"@thi.ng/random": "workspace:^",
"@thi.ng/rdom": "workspace:^",
"@thi.ng/rstream": "workspace:^"
},
"browser": {
"process": false
},
"thi.ng": {
"readme": [
"arrays",
"color",
"color-palettes",
"dl-asset",
"hiccup-html",
"pixel",
"random",
"rdom"
],
"screenshot": "examples/pixel-gradients.jpg"
}
}
127 changes: 127 additions & 0 deletions examples/pixel-gradients/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { typedArrayOfVec } from "@thi.ng/api";
import { shuffle } from "@thi.ng/arrays";
import {
analog,
colorsFromRange,
colorsFromTheme,
convert,
} from "@thi.ng/color";
import { asLCH } from "@thi.ng/color-palettes";
import { downloadCanvas } from "@thi.ng/dl-asset";
import { button, canvas, div, option, select } from "@thi.ng/hiccup-html";
import { FLOAT_RGBA, floatBuffer } from "@thi.ng/pixel";
import { SYSTEM, XsAdd, pickRandom, randomID } from "@thi.ng/random";
import { $compile, $input, $inputTrigger } from "@thi.ng/rdom";
import { stream } from "@thi.ng/rstream";

// default PRNG (aka Math.random wrapper)
const RND = SYSTEM;
// alternatively, use a seedable PRNG:
// const RND = new XsAdd(0xdecafbad);

// selection of color theme IDs from https://thi.ng/color-palettes
// (will be used by `palette` strategy below...)
const THEMES = [46, 54, 100, 126, 139, 145, 184, 187, 191, 218];

// config options for obtaining color themes (see below)
const OPTS = { num: 4, variance: 0.05, rnd: RND };

// various implementations to choose base colors for the gradient
// all of the strategies return colors in LCH format
const STRATEGIES = {
// pick randomized colors from predefined color range descriptors
// see https://thi.ng/color readme for list of available options (and results)
range1: () => [...colorsFromRange("weak", OPTS)],
range2: () => [...colorsFromRange("cool", OPTS)],
range3: () => [...colorsFromRange("light", OPTS)],

// pick randomized colors based on given weighted set of theme part specs.
// each part can specify a base CSS color and optionally a color range to
// modify/tint that color, as well as a weight to control how often colors
// from this theme part will be picked. weights are always relative to each
// other and do not need to sum to 1.0
declarative: () => [
// this theme will statistically contain 2x more aliceblue and mintcream
// than orange. shades of hotpink are 5x less likely to be picked...
// https://docs.thi.ng/umbrella/color/functions/colorsFromTheme.html
...colorsFromTheme(
[
["cool", "aliceblue", 0.5],
["soft", "mintcream", 0.5],
["bright", "orange", 0.25],
["hotpink", 0.1],
],
OPTS
),
],

// choose a random color theme, shuffle it and create slight variations of
// each color...
palette: () =>
shuffle(asLCH(pickRandom(THEMES, RND)), 6, RND)
.slice(0, 4)
.map((x) => analog([], x, 0.1, RND)),
};

type Strategy = keyof typeof STRATEGIES;

// reactive state vars (initially empty/valueless)
const strategy = stream<Strategy>();
const download = stream<boolean>();

// add gradient image generation as subscription. each time a new value is
// pushed into the `strategy` stream, this subscription will run and generate a
// new image...
strategy.subscribe({
next(id) {
const canvas = <HTMLCanvasElement>document.getElementById("main");
// prettier-ignore
// pick new colors via chosen strategy, convert LCH -> sRGB
// (still all colors in floating point format)
const theme = STRATEGIES[id]().map((x) => convert([], x, "srgb", "lch"));
// prettier-ignore
// create a 2x2 float RGBA image, all (4) pixels pre-initialized w/ theme colors
// then resize image to canvas size using bicubic interpolation
// then copy pixels to canvas (incl. format conversion)
floatBuffer(2, 2, FLOAT_RGBA, typedArrayOfVec("f32", theme))
.resize(canvas.width, canvas.height, "cubic")
.blitCanvas(canvas);
},
});

// subscription for download trigger stream to, well... download the canvas
download.subscribe({
next() {
downloadCanvas(
<HTMLCanvasElement>document.getElementById("main"),
`gradient-${randomID(4)}`
);
},
});

// compile & mount UI/DOM
$compile(
div(
{},
div(
".mb3",
{},
// dropdown menu for theme strategies
select(
{ onchange: $input(strategy), value: strategy },
...Object.keys(STRATEGIES).map((x) => option({ value: x }, x))
),
// prettier-ignore
// when clicked, simply retrigger with current strategy
// (deref() obtains the stream's current value)
button(".ml3", { onclick: () => strategy.next(strategy.deref()!) }, "Generate"),
// prettier-ignore
// $inputTrigger is a event handler to emit `true` on given stream
button(".ml3",{ onclick: $inputTrigger(download) }, "Download")
),
canvas("#main", { width: 960, height: 540 })
)
).mount(document.getElementById("app")!);

// trigger generation of first gradient image
strategy.next("range1");
1 change: 1 addition & 0 deletions examples/pixel-gradients/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/pixel-gradients/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../tsconfig.json",
"include": ["src/**/*"],
"compilerOptions": {
}
}
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,25 @@ __metadata:
languageName: unknown
linkType: soft

"@example/pixel-gradients@workspace:examples/pixel-gradients":
version: 0.0.0-use.local
resolution: "@example/pixel-gradients@workspace:examples/pixel-gradients"
dependencies:
"@thi.ng/api": "workspace:^"
"@thi.ng/arrays": "workspace:^"
"@thi.ng/color": "workspace:^"
"@thi.ng/color-palettes": "workspace:^"
"@thi.ng/dl-asset": "workspace:^"
"@thi.ng/hiccup-html": "workspace:^"
"@thi.ng/pixel": "workspace:^"
"@thi.ng/random": "workspace:^"
"@thi.ng/rdom": "workspace:^"
"@thi.ng/rstream": "workspace:^"
typescript: ^5.2.2
vite: ^4.4.9
languageName: unknown
linkType: soft

"@example/pixel-indexed@workspace:examples/pixel-indexed":
version: 0.0.0-use.local
resolution: "@example/pixel-indexed@workspace:examples/pixel-indexed"
Expand Down

0 comments on commit 1c0e541

Please sign in to comment.