Skip to content

EmperorJack/visor

Repository files navigation

Visor

Visor visuals screenshot

Creative code real-time visuals in JavaScript or TypeScript.

  • Designed with the aim to be user-friendly, fast, and extensible.
  • Inspired by Processing, Nannou, and other creative coding frameworks.
  • Rust-based engine powered by Deno Core, a secure, sandboxed JavaScript runtime.
  • Is the core engine for the new version of Visor VJ (unreleased).

Disclaimer ⚠️

Visor is still very early in development. The APIs are minimal, likely to change, and documentation is sparse. Please keep this in mind if you use it!

If you think of a feature request, notice any bugs, or have any other feedback, please feel free to submit an issue on Github, or chat on Matrix.

Examples

The following illustrates a simple Visor sketch:

const draw = createDraw();

export function setup() {
  console.log("Hello, world!");
}

export function update() {
  draw.clear();

  for (let i = -5; i <= 5; i++) {
    const x = i * 50;
    const y = Math.sin(time() + i) * 50;

    const hue = map(x, -250, 250, 0, 1);
    const color = hsv(hue, 0.8, 1);

    draw.ellipse().xy(x, y).wh(25, 25).fill(color);
  }
}

And the corresponding visuals:

Visor sketch example

More examples can be found in the examples folder.

Running a Visor sketch

The recommended way to run Visor sketches is with the visor_cli command line interface. At this time, it is only available through cargo, which means you must have Rust installed. Follow the instructions here to install Rust.

With Rust installed, you can install visor_cli using cargo:

cargo install visor_cli

Now, to run a sketch:

visor_cli run ~/path/to/sketch.js

If you clone this repository onto your machine, you can run the examples directly:

visor_cli run ~/path/to/visor/examples/hello-world.js

Use the --help flag to learn more about the visor_cli options or sub-commands:

visor_cli --help
visor_cli run --help

Live coding

You can use the --watch flag with visor_cli to detect saved changes to a sketch file and hot reload it. E.g:

visor_cli run ~/path/to/sketch.js --watch

TypeScript

To best make use of TypeScript in your sketches you can use the the Visor type declarations. These can be generated with visor_cli by running:

visor_cli types ~/output/path/for/visor-types.d.ts

You can then reference these types in your TypeScript code. The recommended development environent for working on Visor sketches is Deno. Follow the instructions here to install Deno.

If you are using Visual Studio Code, you can also use the Deno extension to make use of the Deno language server.

With Deno installed, you can create a deno.json file in your sketch folder to configure the types correctly:

{
  "compilerOptions": {
    "lib": ["deno.ns"],
    "types": ["./visor-types.d.ts"]
  }
}

Please note that none of the Deno standard libraries (such as fetch) are available with Visor by default. Specifying lib in your deno.json like above configures your type checker to understand this.

How it works

The Visor engine is powered by Deno Core, which underpins the Deno JavaScript runtime. For Visor, this means the user can sketch in JavaScript or TypeScript, depsite the engine itself being written in Rust. This makes the engine both fast and reliable, while enabling user-friendly creative coding.

Graphics rendering is enabled by using a mix of APIs from the Nannou creative coding framework and the underlying wgpu graphics API. Windowing is supported by the TAO library.

Crates

Crate Description
visor_cli Command line interface for running Visor sketches.
visor_core Re-exports visor_engine and all of the core plugins.
visor_engine The Visor engine.
visor_plugin_draw Plugin for drawing shapes.
visor_plugin_log Plugin for console logging.
visor_plugin_math Plugin for useful math functions.
visor_plugin_midi Plugin for connecting to MIDI devices and loading mappings.
visor_plugin_state Plugin for persistent sketch state when hot reloading.
visor_plugin_time Plugin for time and frame related functions.

Using the Visor engine in a Rust app

The Visor engine can be called from a Rust program. To see how this works, check out the implementation of visor_cli in the source code. Note that you must provide your own event loop and windows using TAO.

Plugins

Plugins are the best way to extend Visor with your own APIs. Plugins are written in both Rust and JavaScript or TypeScript. Check out the counter_plugin as an example, or look at the core plugins within the crates folder.

Plugins can be built statically into a Rust app that uses the Visor engine, or they can be linked at runtime after building them as dynamic libraries e.g: cdylib. The latter enables custom plugins to be loaded into the visor_cli by passing their paths to the --plugins option.

Contributing

This project is still in early stages and is not ready for code contributions yet. However, hearing your feedback and support is very welcome! The best way to contribute is through feature requests, bug reports, and general feedback. Please feel free to submit an issue on Github, or chat on Matrix. You are also welcome to share anything cool you've made with Visor. ✨

Acknowledgements

This project would not be possible without the hard work and dedication of many amazing open source projects. Notable shout-outs include the creators of Nannou, Deno, and wgpu, to name a few. Thank you!

About

Creative code real-time visuals in JavaScript or TypeScript.

Resources

License

Code of conduct

Stars

Watchers

Forks