-
-
Notifications
You must be signed in to change notification settings - Fork 150
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(examples): add pixel-gradients example
- Loading branch information
1 parent
7ecb207
commit 1c0e541
Showing
8 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/// <reference types="vite/client" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": "../tsconfig.json", | ||
"include": ["src/**/*"], | ||
"compilerOptions": { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters