dsehnal / LiteMol

A library/plugin for handling 3D structural molecular data (not only) in the browser.
Other
157 stars 38 forks source link

Resize canvas after wrapper DOM element resized #52

Open suyang-nju opened 5 years ago

suyang-nju commented 5 years ago

Is there a way to dynamically update the webgl canvas size (not its CSS width/height) after the wrapper DOM element for LiteMol plugin is resized?

dsehnal commented 5 years ago

What do you mean? This should be done automatically. Are you doing the resizing in code? And if so, can you share it? Perhaps I have omitted a use case.

suyang-nju commented 5 years ago

See the screenshot below. Actually, both canvas width/height and CSS width/height stay the same after the wrapper DOM element resizes. Everything other than the canvas resized correctly, e.g., the parent div.lm-viewport-host3d is in the right size.

The wrapper is a relatively positioned div that is inside of an absolutely positioned div container whose location and size can change based on user input. Something along the line of

<div class="container">
  <div class="litemol-wrapper" />
</div>
.container {
  position: absolute;
  left: ???; /*based on user input*/
  top: ???; /*based on user input*/
  width: ???; /*based on user input*/
  height: ???; /*based on user input*/
}

.litemol-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}
const plugin = LiteMol.Plugin.create({
  target: document.getElementsByClassName("litemol-wrapper")[0], 
});

canvas

dsehnal commented 5 years ago

This is strange, because the resize event is bound for the "parent element" (lm-viewport-host3d) https://github.com/dsehnal/LiteMol/blob/master/src/lib/Visualization/Base/Scene.ts#L217

Can you maybe try to remove the litemol-wrapper and use directly the container (the plugin should automatically adjust to 100% size of the parent).

Alternatively, try calling plugin.context.scene.scene.handleResize() after the change to see what happens (might need to do setTimeout(() => handleResize(), 50)).

suyang-nju commented 5 years ago

I see. The 'resize' event is only fired on the window object when the window resizes (quoting MDN below). In my case, the window is not resized, only the wrapper element is, so the event handler is not triggered. I will resort to calling handelResize() manually then.

Window: resize event (MDN link)

In some earlier browsers it was possible to register resize event handlers on any HTML element. It is still possible to set onresize attributes or use addEventListener() to set a handler on any element. However, resize events are only fired on the window object (i.e. returned by document.defaultView). Only handlers registered on the window object will receive resize events.

There is a proposal to allow all elements to be notified of resize changes. See Resize Observer to read the draft document, and GitHub issues to read the on-going discussions.