Integrate Konva canvas library

I’m new to aurelia and Konva. Nevertheless I try to use Konva in my Aurelia application.

As a test I try to add a Konva.Stage from the Konva-Tutorial to the Aurelia contact-manager tutorial

So now I have my tree-detail.js (Adapted from Konva tutorial):

import Konva from "konva";
import { Layer } from "konva/lib/Layer";
import { Circle } from "konva/lib/shapes/Circle";
import { Stage } from "konva/lib/Stage";

export class TreeDetail {
    // from https://konvajs.org/docs/overview.html

    stage:Stage;
    layer:Layer;
    circle:Circle;

    constructor() {
        // first we need to create a stage
        this.stage = new Konva.Stage({
            container: 'tree-detail',   // id of container <div>
            width: 500,
            height: 500
        });

        // then create layer
        this.layer = new Konva.Layer();

        // create our shape
        this.circle = new Konva.Circle({
            x: this.stage.width() / 2,
            y: this.stage.height() / 2,
            radius: 70,
            fill: 'red',
            stroke: 'black',
            strokeWidth: 4
        });

        // add the shape to the layer
        this.layer.add(this.circle);

        // add the layer to the stage
        this.stage.add(this.layer);

        // draw the image
        this.layer.draw();
    }
};

tree-detail.html (Konva mentioning it needs a container

with that id):

<template>
    <div id="tree-detail">

    </div>
</template>

app.html (from aurelia contact-manager tutorial, unchanged except for contact → tree)

<template>
  <require from="./styles.css"></require>
  <require from="./tree-list"></require>

  <nav class="navbar navbar-light bg-light border-bottom fixed-top" role="navigation">
    <a class="navbar-brand" href="#">
      <i class="fa fa-user"></i>
      <span>Trees</span>
    </a>
  </nav>

  <div class="container-md">
    <div class="row">
      <tree-list class="col-sm-5 col-md-4"></tree-list>
      <router-view class="col-sm-7 col-md-8"></router-view>
    </div>
  </div>
</template>

app.html (unchanged except for contact → tree)

import {Router, RouterConfiguration} from 'aurelia-router';
import {PLATFORM} from 'aurelia-pal';

export class App {
  router: Router;

  configureRouter(config: RouterConfiguration, router: Router){
    config.title = 'Trees';
    config.options.pushState = true;
    config.options.root = '/';
    config.map([
      { route: '',              moduleId: PLATFORM.moduleName('no-selection'),   title: 'Select' },
      { route: 'trees/:id',  moduleId: PLATFORM.moduleName('tree-detail'), name:'trees' }
    ]);

    this.router = router;
  }
}

When I click on a tree-item in the browser to show the tree-detail I get an error in the JavaScript console:

ERROR [app-router] Error: Error invoking TreeDetail. Check the inner error for details.
------------------------------------------------
Inner Error:
Message: Can not find container in document with id tree-detail
------------------------------------------------
aurelia-logging-console.js:45
    error aurelia-logging-console.js:45
    logFactory aurelia-logging.js:38
    processResult aurelia-router.js:2205
    _dequeueInstruction aurelia-router.js:2165

It seems the template html is not loaded yet when the Konva.Stage is created.

When I put the container

directly into app.html, Konva creates the canvas:

  <div class="container-md">
    <div class="row">
      <tree-list class="col-sm-5 col-md-4"></tree-list>
      <div id="tree-detail">
        <router-view class="col-sm-7 col-md-8"></router-view>
      </div>
    </div>
  </div>

But that doesn’t seem to be the correct way of loading a Konva.Stage in my view. What would be the more elegant aurelia way to achieve that?

Just a thought …
In tree-detail.js - don’t do the work in the constructor.

Maybe try the attached method?
https://aurelia.io/docs/fundamentals/cheat-sheet#creating-components

Hi Stuart,

thanks for the hint! I replaced constructor() with attached()and now it works as expected. :tada: