npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

toogl

v1.0.8

Published

2D WEBGL library

Downloads

3

Readme

toogl: 2D WEBGL made easy

toogl is a JavaScript library that enables easily rendering 2D canvases with WebGL. It hides away all the messiness of the WEBGL API such as dealing with programs and vertex shaders/buffers and lets you focus on your fragment shaders.

Installation

npm install toogl

Use

The most basic example to get you started:

import { TooGL } from "toogl";

//get webgl context -> assumes there's a canvas with the id of "c"
const gl = document.getElementById("c").getContext("webgl");
const size = [400, 300]; // [width,height] of the canvas

//fragment shader, outputs the color red
const shader = `
precision mediump float;
void main(){
	gl_FragColor = vec4(1,0,0,1);
}
`;

//create a new TooGL instance
const app = new TooGL({ gl, size, shader }); // All three params are required.
app.render(); //Renders the scene

Helpers

Showing the color red is not too exciting, but fortunately, toogl exposes more useful things for you to use.

Coordinates

Internally, toogl manages a vertex shader which defines a rectangle that covers the whole canvas screen. The most common thing you would need from the vertex shader inside of the fragment shader are the coordinates at which each run of the fragment shader is performed at.

There is a variable called v_coords which is passed from the vertex shader which you can make use of in your fragment shader:

precision mediump float;
varying vec2 v_coords; //vec2 since it holds x and y
void main(){
	gl_FragColor = vec4(v_coords,0,1); //v_coords go from 0 -> 1 on both axes
}

Output of the shader:

Uniforms

It is very easy to send variables to your shaders. For this, there are 2 functions exposed by toogl:

addUniform

Add uniform is a function which accepts 2 arguments:

  • name - unique string identifier

  • glFunction - a webgl function for updating the uniform value

    There are 2 ways to pass down this function. Let's take the case of passing a float.

    1. Through your gl context

      app.addUniform("myFloat", gl.uniform1f);

    2. Through uniform types exposed by the TooGL instance

      app.addUniform("myFloat", app.UTYPES.f1);

    They are both equivalent.

updateUniform

Once a uniform was added, you can update it through this function.

app.updateUniform("myFloat", 2);

Full example:

import { TooGL } from "toogl";
const gl = document.getElementById("c").getContext("webgl");
const size = [400, 300];

const shader = `
precision mediump float;
uniform vec2 u_mouse;
void main(){
	gl_FragColor = vec4(u_mouse,0,1);
}
`;

const app = new TooGL({ gl, size, shader });
app.addUniform("u_mouse", app.UTYPES.f2);

window.addEventListener("mousemove", e => {
  //Normalizing coordinates to be between 0 and 1.
  const normalizedX = e.clientX / window.innerWidth;
  const normalizedY = e.clientY / window.innerHeight;
  app.updateUniform("u_mouse", normalizedX, normalizedY); //Updating vec2 float with 2 values

  //Render everytime there is an update
  app.render();
});
app.render();

Textures

toogl also makes it easy to load images as textures through the function addTexture

It accepts a name string and any ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | OffscreenCanvas

import { TooGL } from "toogl";
const gl = document.getElementById("c").getContext("webgl");
const size = [400, 400];
const shader = `
precision mediump float;
varying vec2 v_coords;
uniform sampler2D u_myTexture;

void main() {
    //shader will display the texture stretched fully onto the canvas
    gl_FragColor = texture2D(u_myTexture, v_coords); 
}
`;
const app = new TooGL({
  gl,
  size,
  shader
});
//Load image
const image = new Image();
image.crossOrigin = "";
image.addEventListener("load", () => {
  app.addTexture("u_myTexture", image); //loaded image is added as a texture
  app.render(); //Don't forget to render
});
image.src = "https://webglfundamentals.org/webgl/resources/f-texture.png";

Multiple textures can be loaded and you can also overwrite textures.

Structs

Structs are the glsl (or C++) equivalent of JavaScript objects. Since it is useful to sometimes bundle uniforms together into objects, toogl provides an easy way to define and update your structs.

On the JavaScript side you can use the method addStruct which accepts a name and a config object:

app.addStruct("u_modifiers", {
  contrast: app.UTYPES.f1,
  brightness: app.UTYPES.f1
});

The config object should contain keys that define the properties of the struct, and the values of the keys should be gl uniform values (the same as when adding a uniform). In this case both contrast and brighness are floats.

To update the values there are 2 ways you can do it.

  1. Update the whole object

    app.updateStruct("u_modifiers", {
      contrast: 2,
      brightness: 0.5
    });
  2. Update one property at a time

    app.updateUniform("u_modifiers.contrast", 1.2);

On the shader side, you need to define the struct, and also the uniform which will use the struct type.

precision mediump float;

varying vec2 v_coords;

//The struct type
struct ModifiersStruct {
	float contrast;
	float brightness;
};

//The uniform which contains the values being passed
uniform ModifiersStruct u_modifiers

void main() {
    //shader will display the texture stretched fully onto the canvas
    vec2 modified = v_coords * vec2(u_modifiers.contrast); //accessing the contrast
    gl_FragColor = vec4(modified, 0, 1)
}

Done

That's it. If you feel like something is missing from the library's API you have the option to use the gl rendering context to do custom stuff manually. Or you could make a pull request with the changes to this repo.