Skip to content

Instantly share code, notes, and snippets.

@nkint
Last active July 15, 2019 15:00
Show Gist options
  • Save nkint/2141478e535ca0b201d89aac695f4756 to your computer and use it in GitHub Desktop.
Save nkint/2141478e535ca0b201d89aac695f4756 to your computer and use it in GitHub Desktop.
add raf stream
import * as tx from "@thi.ng/transducers";
import { clearDOM } from "@thi.ng/hdom";
import {
stream,
Stream,
sync,
fromRAF,
sidechainToggle
} from "@thi.ng/rstream";
import { updateDOM } from "@thi.ng/transducers-hdom";
import { Transducer, Reducer } from "@thi.ng/transducers";
export const slider = (
value: number,
onChange: (n: number) => void,
min: number,
max: number,
step: number,
label: string
) => {
return [
"div",
["div", label],
[
"input.mr3",
{
type: "range",
value,
min,
max,
step,
oninput: (e: Event) => {
const target = e.target as HTMLInputElement;
const value = target && target.value;
onChange(parseFloat(value));
}
}
]
];
};
export const checkbox = (
value: boolean,
onChange: (n: boolean) => void,
label: string
) => {
return [
"div",
[
"input.mr3",
{
id: label,
type: "checkbox",
checked: value,
oninput: (e: Event) => {
const target = e.target as HTMLInputElement;
const checked = target && target.checked;
onChange(checked);
}
}
],
["label", { for: label }, label]
];
};
const scaleStream = stream<number>();
scaleStream.next(1);
const animationStream = stream<boolean>();
function increment(initialValue: number = 0): Transducer<number, number> {
let frame = initialValue;
return (rfn: Reducer<number, number>) => [
() => rfn[0](),
(acc) => rfn[1](acc),
(acc) => rfn[2](acc, frame++)
];
}
const frameStream = fromRAF();
const frameStreamConditional = frameStream
.subscribe(sidechainToggle<number, boolean>(animationStream))
.transform(increment());
let main = sync<any, any>({
src: {
scaleValue: scaleStream,
animationValue: animationStream,
frameValue: frameStreamConditional
}
});
frameStream.next(0);
animationStream.next(false);
frameStreamConditional.next(10);
type AppState = {
scaleValue: number;
animationValue: boolean;
frameValue: number;
};
const app = (
scaleS: Stream<number>,
animationS: Stream<boolean>,
frameS?: Stream<number>
) => (state: AppState) => {
return appRender(state);
};
main.transform(
tx.map(app(scaleStream, animationStream, frameStream)),
updateDOM()
);
function appRender(state: AppState) {
return [
"div.ma2",
[
"div.mv2",
slider(
state.scaleValue,
(x: number) => scaleStream.next(x),
0,
1.2,
0.01,
"tangent scale factor"
),
checkbox(
state.animationValue,
(x: boolean) => animationStream.next(x),
"animation"
),
state.frameValue
]
];
}
if (process.env.NODE_ENV !== "production") {
const hot = (<any>module).hot;
hot &&
hot.dispose(() => {
const app = document.getElementById("app");
app && clearDOM(app);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment