We will show how to move 3D cone display scene in two different canvases on the same tab page with VTK WebAssembly project.

Let’s define two canvas on the page. One is at the left-top area, the other is at the right-top part. It will change canvas binding with wasm module after we click on the left-bottom button update.
We had knew that VTK start to find canvas object in rendering process after starting event loop and the canvas is must be ‘canvas’.
Relevant post: Why Does The Canvas Id On HTML Page Have To Be canvas For VTK WebAssembly?.

So we have to terminate the loop firstly, then rewrite the id of target canvas to ‘canvas’. Finally, restart the loop event and rendering.

      <!-- Load WebAssembly module -->
      <script type="text/javascript" src="wasmTester.js"></script>
      <canvas id="canvas" style="position: absolute; left: 0; top: 0; width:500px; height:500px"></canvas>
      <canvas id="canvas1" style="position: absolute; right: 0; top: 0; width:500px; height:500px"></canvas>

      <button id="button" style="position: absolute; left: 0; bottom: 0;"> update </button>

        function $(id){ return document.getElementById(id); }

        var workerObj = null;
        var Module = {
         canvas: (function () {
           var canvas = document.getElementById('canvas');
             function (e) {
               console.error('WebGL context lost. You will need to reload the page.');
           return canvas;
         onRuntimeInitialized: function () {
            workerObj = new Module.Worker();
            console.log( "StartWork!" );

        var app = tester(Module);
        console.log('App created');

        // change left and right canvases.
        $('button').onclick = function()

          $('canvas').id = "canvas2";
          $('canvas1').id = "canvas";
          Module.canvas = $('canvas');

          workerObj = new Module.Worker();
          console.log( "StartWork!" );

The relevant interfaces:

* Run the event loop (does not return until TerminateApp is called).
virtual void StartEventLoop() {}

void vtkSDL2RenderWindowInteractor::TerminateApp(void)
  this->Done = true;

#ifdef __EMSCRIPTEN__
  // Only post a quit message if Start was called...
  if (this->StartedMessageLoop)

* Render the scene. Just pass the render call on to the
* associated vtkRenderWindow.
virtual void Render();

* Prepare for handling events and set the Enabled flag to true.
* This will be called automatically by Start() if the interactor
* is not initialized, but it can be called manually if you need
* to perform any operations between initialization and the start
* of the event loop.
virtual void Initialize();
void ReInitialize()
    this->Initialized = 0;
    this->Enabled = 0;

Fortunately, the memory in browser heap is not growing after we click on update.

Project on GitHub:

The functions list about registering events and bind canvas for SDL window in vtkRenderWindowInteractor::Start:

void vtkRenderWindowInteractor::Start()
void vtkSDL2RenderWindowInteractor::Initialize()
void vtkOpenGLRenderWindow::Start()
void vtkSDL2OpenGLRenderWindow::Initialize()
void vtkSDL2OpenGLRenderWindow::CreateAWindow()
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
device->CreateSDLWindow = Emscripten_CreateWindow;
Emscripten_CreateWindow(_THIS, SDL_Window * window)
Emscripten_RegisterEventHandlers(SDL_WindowData *data)

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments

Computer Number Terms
: You can use the tool to get different expressions of color, disk space and number.

A prohibited operation
Would love your thoughts, please comment.x