tentone / escher.js

2D graphics canvas framework for easier interactive web graphics.
https://tentone.github.io/escher.js/
MIT License
20 stars 6 forks source link
canvas css3d diagram graphs

escher.js

npm versionGitHub versionGitHub stars

graph

Examples / Documentation

Getting Started

<div style="width: 100%; height: 100%; position: absolute; top: 0px; left: 0px">
    <canvas id="canvas" style="width: 100%; height: 100%;"></canvas>
</div>
var canvas = document.getElementById(canvas);
document.body.onresize = function()
{
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
};

graph

var group = new Escher.Object2D();

var text = new Escher.Text();
text.position.set(0, -100);
text.text = "Hello World!"
group.add(text);

var box = new Escher.Box();
box.position.set(-100, 0);
group.add(box);

var circle = new Escher.Circle();
circle.position.set(100, 0);
circle.radius = 50;
group.add(circle);

var viewport = new Escher.Viewport(canvas);

var renderer = new Escher.Renderer(canvas);

renderer.createRenderLoop(group, viewport);

graph

var renderer = new Escher.Renderer(canvas);
var controls = new ViewportControls(viewport);

var timer = new AnimationTimer(function()
{
    controls.update(renderer.pointer);
    renderer.update(group, viewport);
});
timer.start();
function preventDefault(event)
{
    event.preventDefault();
    return false;
}

var event = new EventManager();
event.add(canvas, 'DOMMouseScroll', preventDefault);
event.add(canvas, 'wheel', preventDefault);
event.add(canvas, 'mousewheel', preventDefault);
event.add(canvas, 'contextmenu', preventDefault);
event.create();

Viewport

graph

Node Graph

registerSockets()
{
    this.a = this.addInput("number", "a");
    this.b = this.addInput("number", "b");

    this.r = this.addOutput("number", "r");
    this.r.getValue = () =>
    {
        // Add input A and input B
        return this.a.getValue() + this.b.getValue();
    };
}

graph

Custom Objects

var object = new Escher.Object2D();
object.draw = function(context, viewport, canvas)
{
    // Create gradient
    var grd = context.createLinearGradient(0, 0, 70, 0);
    grd.addColorStop(0, "#FF0000");
    grd.addColorStop(1, "#FFFFFF");

    // Fill with gradient
    context.fillStyle = grd;
    context.fillRect(-70, 70, 140, 140);
};

Data Serialization

class CustomObject extends Escher.Node
{
    constructor(operation)
    {
        super();

        this.type = "CustomObject";
        this.something = 2;
    }

    serialize(recursive)
    {
        var data = super.serialize(recursive);
        data.something = this.something;
        return data;
    }

    parse(data, root)
    {
        super.parse(data, root);
        this.something = data.something;
    }
}

Escher.Object2D.register(CustomObject, "CustomObject");
constructor()
{
    super();
    this.text = new Escher.Text();
    this.text.serializable = false;
    this.add(this.text);
}
parse(data, root)
{
    this.someObject = root.getChildByUUID(data.someObject);
}

Pointer events

// Called when the pointer enters the object.
onPointerEnter(pointer, viewport);

// Called when the was inside of the object and leaves the object.
onPointerLeave(pointer, viewport);

// Called while the pointer is over (inside) of the object.
onPointerOver(pointer, viewport);

// Called when the object is dragged across the screen, only works if the object has the property draggable set true.
// Delta is the movement of the pointer already translated into local object coordinates.
onPointerDrag(pointer, viewport, delta);

// Called while the pointer button is pressed.
onButtonPressed(pointer, viewport);

// Called when the pointer button is pressed down.
onButtonDown(pointer, viewport);

// Called after the pointer button gets released.
onButtonUp(pointer, viewport);

DOM Objects

var dom = new Escher.DOM(division);
dom.size.set(100, 50);
dom.origin.set(50, 25);
group.add(dom);

// Re-enable DOM pointer events
dom.element.style.pointerEvents = "auto";

// Attach a new DOM element to the DOM object
var text = document.createElement("div");
text.style.fontFamily = "Arial";
text.style.textAlign = "center";
text.innerHTML = "DOM text!";
dom.element.appendChild(text);

Integrating external libraries

// Read the tiff data as arraybuffer from file
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
xhr.open("GET", "images/kofax.tif");
xhr.onload = function (e)
{
    // Decode the image using tiffjs
    var tiff = new Tiff({buffer: xhr.response});
    var tiffCanvas = tiff.toCanvas();
    if(tiffCanvas)
    {
        // Create the object to draw
        var tiffImage = new Escher.Object2D();
        tiffImage.draw = function(context, viewport, canvas)
        {   
            // Copy the content of the tiff canvas
            context.drawImage(tiffCanvas, 0, 0);
        };

        // Add object to the group
        group.add(tiffImage);
    }
};
xhr.send();

License