Adding support for Canvas in ChakraBridge

Last week, I announced the beginning of ChakraBridge: https://blogs.msdn.com/b/eternalcoding/archive/2015/10/21/using-javascript-frameworks-from-your-c-uwp-application.aspx

One of the problem I mentioned was that the JavaScript framework that you want to use has to be independent of the DOM.

But today, thanks to the great contribution of Koen Zwikstra (Developer of XAML Spy), I’m thrilled to announce that you can also use JavaScript frameworks that use the HTML5 canvas!

You can now find a demo of paper.js running inside a Win2D canvas:

Paper.js is an open source vector graphics scripting framework that runs on top of the HTML5 Canvas. It offers a clean Scene Graph / Document Object Model and a lot of powerful functionality to create and work with vector graphics and bezier curves, all neatly wrapped up in a well designed, consistent and clean programming interface.

How it works?

Basically, ChakraBridge provides an API surface identical to the HTML5 Canvas and routes all order to a Win2D canvas. To achieve this, weprojected new elements to JavaScript space:

 

For instance the interface implemented by our canvas implementation is the following:

public interface ICanvasRenderingContext2D
    {
        IHTMLCanvasElement canvas { get; }
        string fillStyle { get; set; }
        float lineWidth { get; set; }
        string strokeStyle { get; set; }
        void beginPath();
        void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
        void clearRect(float x, float y, float width, float height);
        void closePath();
        void fill();
        void fillRect(float x, float y, float width, float height);
        IImageData getImageData(float sx, float sy, float sw, float sh);
        void lineTo(float x, float y);
        void moveTo(float x, float y);
        void restore();
        void save();
        void stroke();
        void transform(float a, float b, float c, float d, float e, float f);
    }

The idea is then to map these methods to the same Win2D feature like for instance for the fillRect function:

public void fillRect(float x, float y, float width, float height)
{
    this.window.Session.FillRectangle(x, y, width, height, this.state.Fill);
}

this.window.Session is a Win2D CanvasDrawingSession and so, we are just using the FillRectangle method.

To display the result, you just have to add a Win2D CanvasControl on your page:

<canvas:CanvasControl x:Name="canvasCtrl" Draw="canvasCtrl_Draw" Width="500" Height="500"/>

Simple, isn’t it?

Managing render frequency

From JavaScript point of view, the rendering is done by a single function:

function drawScene() {
    paper.view.onFrame();
    paper.view.draw();
}

From C# world, the idea is just to call this function every 1/60 second:

this.timer = new DispatcherTimer {
    Interval = TimeSpan.FromMilliseconds(1000d / 60)
};
this.timer.Tick += (o, e) => {
    host.CallFunction("drawScene");
    this.canvasCtrl.Invalidate();
};

The Wind2D canvas is then invalidate and redrawn using this code:

 private void canvasCtrl_Draw(CanvasControl sender, CanvasDrawEventArgs args)
 {
     var target = (CanvasRenderTarget)this.host.Window.Render();

     args.DrawingSession.DrawImage(target);
 }

Going further

Paper.js is now fully usable from your C# project! And that’s just the beginning. We are looking for more contributor to add more features to ChakraBridge! Feel free to join us at https://github.com/deltakosh/JsBridge