I'm trying to add support for web components in general and the model-viewer in particular to Panel. Panel is a framework for creating awesome analytics apps in Python.
It's pretty easy to do, except I cannot trigger a resize of the model-viewer to 100% of the width and height of the parentElement. I need to do this after the layout of the parentElement.
I've tried to find this functionality without luck.
Please guide me to what function on the model-viewer to run in order to resize the element. Or if it does not exist please add this functionality.
Thanks
.Git video of model-viewer in Jupyter Notebook using Panel.

I need this too for resizing on ios. I've added resize-observer-polyfill to my page, but as the app (universalviewer.io) can load a variety of content types it would be nice to use the recommended ponyfill pattern in the modelviewer extension to call a modelviewer.resize() method. Otherwise all other extensions load the polyfill unnecessarily and suffer a performance hit.
@edsilv @MarcSkovMadsen thank you for the request and the feedback.
Before I launch into my short essay below, here is a quick suggestion to address the stated problem:
Per our documentation on polyfills, you can dispatch a global "fake" resize event in order to force a resize of <model-viewer> without using the polyfill. To offer some pseudocode:
function forceResize() {
var event = new CustomEvent('resize');
self.dispatchEvent(event); // Dispatch "fake" resize event on window
}
// When something happens and you know you need to resize <model-viewer>:
forceResize();
Wherever possible, <model-viewer> relies on native web platform constructs in order to achieve its design goals. Resize Observer is a standards-track solution for monitoring the realtime layout changes of an HTML element. At this point, it is implemented in most major browsers, with significant exceptions including Safari and IE11. In browsers where it is implemented, no polyfill is required.
I strongly recommend taking the path of including the Resize Observer polyfill in the page. Resize Observer will cover a lot of layout changes you may not be considering, and also will be more efficient than manual resizing in a lot of cases (because of timing details related to how it notifies of resize).
In many cases, the cost of using the Resize Observer polyfill is low. Where performance is a concern, I like to look at performance traces before jumping to conclusions about the cost of something. If you have an example site I could look at, I would be happy to do a performance analysis to gauge what the practical impact of the Resize Observer might be.
Your docs say this about performance:
However, it is important to note that Resize Observer is optional because the polyfill is known to have performance consequences that might be considered unacceptable for some use cases (it uses a Mutation Observer that observes the whole document tree).
It also recommends to use a ponyfill instead of a global on the resize-observer-polyfill readme:
https://github.com/que-etc/resize-observer-polyfill#usage-example
Based on that, I thought the above comments were well founded, but you're right, it's always better to test yourself.
Forcing another window.resize is suboptimal for us as it will trigger a full resize throughout the app, and we're trying to keep these to a minimum.
Happy to include the polyfill though if that's your recommendation :-)
We are open to amendments to our recommendations pending a performance
analysis. If the analysis shows that you are in between a rock and a hard
place, we will move to make things easier to the extent that we can. I'm
happy to help analyze a performance-related test case if you have one.
On Mon, Mar 16, 2020, 11:28 AM Edward Silverton notifications@github.com
wrote:
Your docs say this about performance:
However, it is important to note that Resize Observer is optional because
the polyfill is known to have performance consequences that might be
considered unacceptable for some use cases (it uses a Mutation Observer
that observes the whole document tree).It also recommends to use a ponyfill instead of a global on the
resize-observer-polyfill readme:https://github.com/que-etc/resize-observer-polyfill#usage-example
Based on that, I thought the above comments were well founded, but you're
right, it's always better to test yourself.Forcing another window.resize is suboptimal for us as it will trigger a
full resize throughout the app, and we're trying to keep these to a minimum.Happy to include the polyfill though if that's your recommendation :-)
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/google/model-viewer/issues/1088#issuecomment-599694110,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAB2TUYCE3IT5XWYC4N45J3RHZVU5ANCNFSM4LLDSEDA
.
Hi @cdata and @edsilv
Thanks for your comments. What you write is not within my area of expertise. It will take some time to understand and digest.
I will try raising the resize event. But my current understanding is that everything has just resized (The function I normally have to run an resize function in is called after_layout). So raising a new resize event will just cause everything to resize again. I could be afraid I would end up in an infinite cycle. But thats up for me to test.
The use case is based on Bokeh/ Panel. And Bokeh comes with it's own layout engine. It does not use the browsers layout engine (as far I understand). So in my understanding thats why I need to manually trigger a resize of the model-viewer. I had a similar problem with ECharts but running echart.resize() solved the problem and made it so easy to integrate with Python/ Panel. See https://github.com/holoviz/panel/pull/1122#issuecomment-599179666
I have yet to understand how the ResizeObserver can be of use. As far as I understand it just observes for things resizing. And I already know things have resized. But the model-viewer has not. So I need some kind of functionality to trigger that.
Sorry if this does not make sense. Again. It's outside my area of expertise. I actually looked into the model-viewer in the hope to provide it to python users so that we/ they can avoid diving into the world of JavaScript and front end development.
Thanks for taking the time to put together quality feedback.
@MarcSkovMadsen if you did, in fact, just "react" to a resize even (in after_layout), then <model-viewer> will have also observed that "true" resize event and updated its size accordingly. Unfortunately, it can be difficult to coordinate layout resizing when multiple libraries are on the page at the same time. This is why ResizeObserver is the recommended approach: it fixes the coordination problem by allowing every user to know their latest layout dimensions regardless of when the layout changed last.
To speak to @edsilv 's question about using it as a ponyfill, if you are building an end-user-facing app or website (and not a re-distributable library) then I think that using it as a ponyfill is acceptable. However, it is not acceptable for a library like <model-viewer> to bundle a polyfill like ResizeObserver because the extra byte size will not be desired or needed by some of our users. In principle, polyfills should only be used when they are called for by the final usage scenario.
@MarcSkovMadsen the practical performance cost of using ResizeObserver for you is likely to be quite low. I would recommend that you try putting this script on your site just to give it a shot:
<script src="https://unpkg.com/browse/[email protected]/dist/ResizeObserver.js"></script>
That's all you would need to do, no further intervention needed. LMK if you can give it a shot and how it goes!
Hi
Thanks for your help.
I now got it working...and without the polyfill. I had to change some Panel code instead.
For the record the below code works for me
import panel as pn
js = """
<script src="https://unpkg.com/@webcomponents/[email protected]/webcomponents-loader.js"></script>
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.js"></script>
<script nomodule src="https://unpkg.com/@google/model-viewer/dist/model-viewer-legacy.js"></script>
"""
js_pane = pn.pane.HTML(js)
html="""
<model-viewer src="https://modelviewer.dev/shared-assets/models/Astronaut.glb" alt="A 3D model of an astronaut"
auto-rotate camera-controls style="height:100%;width:100%;">
</model-viewer>
"""
model_viewer_pane = pn.pane.HTML(html, height=800, width=500)
app = pn.Column(
js_pane,
model_viewer_pane,
background="grey",
)
app.servable()
