Question

I have a component that's laid out using polymer-grid-layout which contains a canvas as the main part of the content. I want the canvas to auto resize based on the size that polymer-grid-layout allocates.

I can't put width:100%; height:100% on the canvas as that just stretches the canvas making it distorted and grainy. Instead I wrapped a div around the canvas and manually resize the canvas based on the div size in code.

Code looks somewhat like (note I've left out the boiler plate like etc)

<polymer-grid-layout xnodes="{{xnodes}}" 
     layout="[[1, 2, 3],
              [4, 4, 4]]">
</polymer-grid-layout>

<gauge-slider id='front' label='Front'></gauge-slider>
<panel flex></panel>
<gauge-slider id='back' label='Back'></gauge-slider>

<canvas-view id="canvasView" canvasModel="{{canvasModel}}" flex></canvas-view>

where canvas-view contains

<panel id="canvasContainer" flex>
  <canvas id="canvas"></canvas>
</panel>

In the canvas-view dart code I set the canvas width like so

void _resize() {
  canvas.width = canvasContainer.clientWidth;
  canvas.height = canvasContainer.clientHeight;

  _redraw();
}

which I call from

@override
void ready() {
  canvas = $['canvas'];
  canvasContainer = $['canvasContainer'];

  // doesn't seem to be a resize on anything other than window!?!
  window.onResize.listen((_) => _resize());
}

and from

@published void set canvasModel(CanvasModel m) {
  _canvasModel = m;

  // TODO: need to build in a delay as otherwise the containing div has not been sized properly yet
  new Timer(new Duration(milliseconds: 50), _resize);
}

The problem is in the above code. If I call _resize directly here then the container div doesn't yet know it's proper height. After experimenting I found that 50 millisecs allows the container to be sized correctly by the grid layout on my machine but that seems really dodgy and likely to be problematic on different devices.

How can I avoid that delay? Is there some event I can listen to that tells me when the grid layout has finished sizing components?

Also was there a simpler way to have achieved the canvas resizing in the first place?

Lastly, I had to style the canvasContainer panel to have 0 margins, border etc. Is there a way to have fetched the inner dimensions of that container?

Was it helpful?

Solution

Is there some event I can listen to that tells me when the grid layout has finished sizing components?

The grid layout sends a polymer-grid-layout event after it has finished sizing components.

Also was there a simpler way to have achieved the canvas resizing in the first place?

I don't think so, but maybe a Canvas expert out there will chime in with better advice.

Lastly, I had to style the canvasContainer panel to have 0 margins, border etc. Is there a way to have fetched the inner dimensions of that container?

clientWidth/Height ignores the margins and border, but does count padding. There are other ways of measuring boxes, but it gets complicated quickly (mostly because of x-browser concerns). This can be a difficult topic, here is a starter link: https://developer.mozilla.org/en-US/docs/Determining_the_dimensions_of_elements

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top