Open iwoplaza opened 2 months ago
Good point, we have to think about this. We could try Svelte's approach of exporting values.
Before
// -- Hooks into the example environment
import {
addElement,
addSliderParam,
onCleanup,
onFrame,
} from '@typegpu/example-toolkit';
// --
import { createRuntime, wgsl } from 'typegpu';
const xSpanPlum = addSliderParam('x span', 16, { min: 1, max: 16, step: 1 });
const ySpanPlum = addSliderParam('y span', 16, { min: 1, max: 16, step: 1 });
const canvas = await addElement('canvas', { aspectRatio: 1 });
const runtime = await createRuntime();
onFrame((deltaTime) => {
// ...
runtime.flush();
});
onCleanup(() => {
runtime.dispose();
});
After
import { createRuntime, wgsl } from 'typegpu';
/** @slider { min: 1, max: 16, step: 1 } */
export const xSpanPlum = wgsl.plum(16).$name('x span');
/** @slider { min: 1, max: 16, step: 1 } */
export const ySpanPlum = wgsl.plum(16).$name('y span');
const canvas = document.createElement('canvas');
canvas.style.setProperty('--aspect-ratio', 1);
const runtime = await createRuntime();
let lastTime = Date.now();
function loop() {
const now = Date.now();
const deltaTime = now - lastTime;
lastTime = now;
// ...
runtime.flush();
requestAnimationFrame(loop);
}
loop();
We can try to add the Canvas and any other non-control elements in a separate HTML file, and keep the parameters as exported values.
import { createRuntime, wgsl } from 'typegpu';
/** @slider { min: 1, max: 16, step: 1 } */
export const xSpanPlum = wgsl.plum(16).$name('x span');
/** @slider { min: 1, max: 16, step: 1 } */
export const ySpanPlum = wgsl.plum(16).$name('y span');
const canvas = document.getElementById('canvas');
const runtime = await createRuntime();
let lastTime = Date.now();
function loop() {
const now = Date.now();
const deltaTime = now - lastTime;
lastTime = now;
// ...
runtime.flush();
requestAnimationFrame(loop);
}
loop();
<div class="row">
<canvas id="canvas" class="aspect-1"></canvas>
</div>
@mhawryluk @reczkok Thoughts? 👀
I really like this approach, I have no notes. I assume dropdowns, toggles and buttons would be defined just like the slider? then dropdowns and toggles could have the plum support like sliders, but buttons (in the control panel) would be defined without plums I assume?
Exported functions could become button on-click handlers.
/** @slider { min: 1, max: 16, step: 1 } */
export const fooPlum = wgsl.plum(16).$name('foo');
/** @select ['a', 'b', 'c'] */
export const barPlum = wgsl.plum('a').$name('bar');
/** @toggle */
export const zonkPlum = wgsl.plum(false).$name('zonk');
/** @button "Recompute" */
export function recompute() {
// do something
}
(written by @mhawryluk)
As noticed by @piaskowyk currently the examples use our special example-toolkit functionalities which aren't available outside the page. Therefore users cannot copy paste our examples into their projects and expect them to work. We could let examples define their html template alongside the typescript, but while it could definitely work well for canvas and video elements, the gui controlls are more tricky to do this way.