Search code examples
javascriptcanvasaurelia

Aurelia: resize/layout change event for view?


Is there a way to subscribe to a view in order to observe resize/layout events in Aurelia? I have a canvas I would like to resize. I'm wondering if there is an "aurelia" way to do this?

I tried:

<div ref="canvasContainer" class="widget-dial-container" resize.delegate="doresize()">
  <canvas ref="canvas" class="widget-dial-canvas" />
</div>

but it never calls my doresize() method.

I've tried binding to the DOM offsetWidth and offsetHeight, but this doesn't work either (with and without @bindable canvasContainer; in the vm)


Solution

  • The resize event is only supported on the window itself, as Kruga mentioned. You can attach to it in a cross-platform fashion using the Aurelia Platform Abstraction Layer's PLATFORM object. You'll have to run jspm install aurelia-pal to get it. If you aren't worried about cross-plat, then you can just use the window object.

    The following template and VM work for me. I implemented a throttle on the resize timer:

    HTML

    <template>
      <div style="height: 125px; min-width: 150px; width: 100%;" ref="canvasContainer">
        <canvas ref="canvas" width.one-way="canvasContainer.offsetWidth"></canvas>
      </div>
    </template>
    

    TEMPLATE

    import {PLATFORM} from 'aurelia-pal';
    
    export class App {
      resizeTimer = null;
      resizeEventHandler = () => this.resized();
    
      attached() {
        this.resized();
    
        PLATFORM.global.addEventListener("resize", this.resizeEventHandler);
      }
    
      detached() {
        PLATFORM.global.removeEventListener("resize", this.resizeEventHandler);
      }
    
      resized() {
        clearTimeout(this.resizeTimer);
    
        this.resizeTimer = setTimeout(() => {
          let ctx = this.canvas.getContext("2d");
    
          ctx.fillStyle = "green";
          ctx.font = "30px Arial";
          ctx.fillText(`Width: ${this.canvas.width}`,10,50);
        }, 150);
      }
    }