A graphics library to enable the real-time rendering of 2D signed distance fields on the web. http://schmelczer.dev/sdf-2d/
Find a file
schmelczerandras a9d167927c Bump version
2020-09-27 17:34:07 +02:00
src Fix Insights.measure this handling 2020-09-27 16:11:30 +02:00
static Add logo 2020-09-20 11:25:47 +02:00
.eslintignore Add files 2020-09-15 10:08:16 +02:00
.eslintrc.json Add files 2020-09-15 10:08:16 +02:00
.gitignore Remove clutter 2020-09-16 14:21:28 +02:00
.npmignore Add more options 2020-09-17 17:51:45 +02:00
.prettierrc Add files 2020-09-15 10:08:16 +02:00
custom.d.ts Improve API 2020-09-16 11:31:26 +02:00
package.json Bump version 2020-09-27 17:34:07 +02:00
README.md Add some examples 2020-09-27 17:33:58 +02:00
tsconfig.json Fix lights 2020-09-20 20:08:19 +02:00
webpack.config.js Fix lights 2020-09-20 20:08:19 +02:00

SDF-2D logo SDF-2D library

A graphics library to enable the rendering of 2D signed distance fields (SDF-s) on web.

View it in action!

Further documentation will be provided by the end of September 2020.

Minimal example using Webpack

Certainly, other build tools can be used as well.

Instructions

A tutorial for installing Webpack is also included below, for more information about Webpack visit their getting started page.

  • Install Node.js

  • Create a directory called sdf-2d-example and open a terminal inside it

  • Run the following commands

    npm init -y
    npm install webpack webpack-cli sdf-2d --save-dev
    
  • Create a directory called src, and a new file inside of it named index.html

  • Copy the following code into sdf-2d-example/dist/index.html

    <!DOCTYPE html>
    <html>
      <body>
        <canvas width="600" height="300"></canvas>
        <script src="main.js"></script>
      </body>
    </html>
    
  • Create a directory called src, and a new file inside of it named index.js

  • Copy the following code into sdf-2d-example/src/index.js

    import { compile, Circle, CircleLight } from 'sdf-2d';
    
    const main = async () => {
      const canvas = document.querySelector('canvas');
      const renderer = await compile(canvas, [Circle.descriptor, CircleLight.descriptor]);
    
      renderer.addDrawable(new Circle([200, 200], 50));
      renderer.addDrawable(new CircleLight([500, 300], [1, 0.5, 0], 0.5));
    
      renderer.renderDrawables();
    };
    
    main();
    
  • Inside sdf-2d-example, execute the command npx webpack, this will generate a new file in your dist folder.

  • You're finished, open sdf-2d-example/dist/index.html

End result

The result of the above instructions can also be found in this repository and the finished website is available here.

More complex example

Instructions

We'll be using the files and directory structure created in the minimal example.

  • Paste the following HTML into the <head> of index.html

    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      html,
      body,
      canvas {
        margin: 0;
        width: 100%;
        height: 100%;
      }
    </style>
    
  • Install gl-matrix by running npm install gl-matrix --save-dev

  • Copy the following code into index.js

    import { vec2, vec3 } from 'gl-matrix';
    import { compile, Circle, CircleLight } from 'sdf-2d';
    
    const main = async () => {
      const canvas = document.querySelector('canvas');
    
      const renderer = await compile(canvas, [Circle.descriptor, CircleLight.descriptor]);
    
      renderer.setRuntimeSettings({
        colorPalette: [
          vec3.create(),
          vec3.create(),
          vec3.fromValues(0.5, 0.2, 1), // By default, Circle has a colorIndex of 2
        ],
      });
    
      let aspectRatio;
      const setViewArea = () => {
        const canvasSize = renderer.canvasSize;
        aspectRatio = canvasSize.x / canvasSize.y;
    
        // The view area is given in a coordinate system
        // originated from the bottom (!) left edge of the canvas
        renderer.setViewArea(vec2.fromValues(0, 1), vec2.fromValues(aspectRatio, 1));
      };
    
      setViewArea();
      onresize = setViewArea;
    
      const circle = new Circle(vec2.fromValues(0.5, 0.5), 0.1);
      const light = new CircleLight(vec2.create(), vec3.fromValues(1, 0.5, 0.1), 0.0005);
    
      const animate = (currentTime) => {
        vec2.set(circle.center, aspectRatio / 2, 0.5);
        vec2.set(light.center, ((Math.sin(currentTime / 1000) + 1) / 2) * aspectRatio, 1);
    
        renderer.addDrawable(circle);
        renderer.addDrawable(light);
        renderer.renderDrawables();
    
        console.log(renderer.insights);
    
        requestAnimationFrame(animate);
      };
    
      requestAnimationFrame(animate);
    };
    
    main();
    
  • Run npx webpack

  • You're finished, open index.html

End result

The result of the above instructions can also be found in this repository and the finished website is available here.

Real life example

The source code for the demo page of this library is available here, on GitHub.