Skip to content

Extra Topics

Daeinc edited this page Dec 13, 2023 · 10 revisions

Extra Topics

Render-On-Demand

Some sketches may not need to run and update constantly and only need to update based on a condition. In this case, you can use the render function prop to render on-demand.

const sketch = ({ wrap, render }) => {
  // when this object changes, it renders a new frame
  someObject.addEventListener("change", render);

  // run render() for each mouse click
  window.addEventListener("click", () => {
    render();
  });

  wrap.render = () => {
    // place rendering code here
  };

  wrap.resize = () => {
    // render a new frame when resized
    render();
  };
};

const settings = {
  // animation is disabled, but you can still use render() prop to render on-demand
  animate: false,
};

ssam(sketch, settings);

Asynchronous Operation

Sometimes, you need to run an asynchronous operation such as loading image or texture. In that case, add the async keyword to your sketch function and/or render method. This is especially useful if you want to reliably export a video/GIF frames.

const sketch = async ({ wrap }) => {
  // 3d libraries may have async methods like this:
  const texture = await TextureLoader.load("/texture.png");

  wrap.render = async ({ width, height }) => {
    await TextureLoader.update(texture);
  };
};

Multiple Sketches On The Same Page

To create multiple sketches on the same page, you can adjust the sketch settings like below:

const settings = {
  centered: false, // disable default css style
  id: "unique-canvas-id", // provide a unique ID for each canvas
}

ssam(sketch, settings)

You will also need to update CSS styles in index.html to meet your needs.

Multiple Sketches On The Same Folder

If you have multiple sketches within the same src folder and want to choose one of them to load, there are a few strategies. Let's say your project structure is as below:

.
├── index.html
├── src
│   ├── index.js
│   └── sketchbook
│       ├── sketch1.js
│       ├── sketch2.js
│       ├── ...
├── ...

1. Manual Import

// src/index.js
import { sketch as sk1, settings as st1 } from "./sketchbook/sketch1";
import { sketch as sk2, settings as st2 } from "./sketchbook/sketch2";

ssam(sk1, st1);

2. Load Modules As Array

// src/index.js
const moduleArray = Object.entries(import.meta.glob("./sketchbook/*.js"));

const idx = 0; // change sketch index
const importedModule = moduleArray[idx][1];

ssam((await importedModule()).sketch, {});

3. CLI Option

Update your code as below:

// src/index.js
try {
  const importedModule = await import(
    // defined in env via CLI
    `./sketchbook/${window.SKETCH}.js`
  );
  ssam(importedModule.sketch, importedModule.settings);
} catch {
  console.error(`module import error`);
}

// vite.config.js
export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), "");

  return {
    base: "./",
    plugins: [/** .. */],
    build: { /** .. */ },
    define: {
      SKETCH: JSON.stringify(env.SKETCH),
    },
  };
});

Run the sketch with the CLI command below:

$ SKETCH=sketch1 npm run dev

✋ Currently, hot reload doesn't work with this method.

Maintain Random States

TODO

  • use seeded random function instead of Math.random
  • use the seed as the suffix to a filename
Clone this wiki locally