Skip to content

Add resize to Renderable.js #374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ build/
*.py[cod]
node_modules/
.vscode
.venv

# Compiled javascript
pythreejs/static/
Expand Down
48 changes: 47 additions & 1 deletion js/src/_base/Renderable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var _ = require('underscore');
var widgets = require('@jupyter-widgets/base');
var $ = require('jquery');
var Promise = require('bluebird');
var THREE = require('three');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import isn't used, so is probably not needed here.

Suggested change
var THREE = require('three');


var pkgName = require('../../package.json').name;
var EXTENSION_SPEC_VERSION = require('../version').EXTENSION_SPEC_VERSION;
Expand Down Expand Up @@ -55,6 +56,7 @@ var RenderableModel = widgets.DOMWidgetModel.extend({

this.createPropertiesArrays();
ThreeModel.prototype.setupListeners.call(this);

},

createPropertiesArrays: function() {
Expand Down Expand Up @@ -185,6 +187,9 @@ var RenderableView = widgets.DOMWidgetView.extend({
this.isFrozen = true;
this.id = Math.floor(Math.random() * 1000000);
this._ticking = false;
if (this.model.get('autoResize')) {
window.addEventListener('resize', this.resize.bind(this), false);
}
},

remove: function() {
Expand All @@ -196,6 +201,7 @@ var RenderableView = widgets.DOMWidgetView.extend({
}
},

// This allows dynamic messages from jupyterlab
processPhosphorMessage: function(msg) {
widgets.DOMWidgetView.prototype.processPhosphorMessage.call(this, msg);
switch (msg.type) {
Expand All @@ -205,6 +211,11 @@ var RenderableView = widgets.DOMWidgetView.extend({
case 'before-detach':
this.el.removeEventListener('contextmenu', this, true);
break;
case 'resize':
if (this.model.get('autoResize')) {
this.resize();
}
break;
}
},

Expand Down Expand Up @@ -240,7 +251,6 @@ var RenderableView = widgets.DOMWidgetView.extend({

doRender: function() {
this.el.className = 'jupyter-widget jupyter-threejs';

this.unfreeze();

this.lazyRendererSetup();
Expand Down Expand Up @@ -454,6 +464,38 @@ var RenderableView = widgets.DOMWidgetView.extend({

},

// Get the size of the container, or if that doesn't exist, the window
getSize: function() {
try {
const { width, height } = this.el.getBoundingClientRect();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also use window.getComputedStyle() for both the container (this.el) and the rendered element (this.renderer.domElement and or this.$frozenRenderer if this.isFrozen is true) to substract the margins and paddings from these sizes. That should hopefully avoid the magic "4.4" below, as the actual size of this padding will depend on the context (e.g. the margin is a CSS variable set by the theme in JupyterLab).

console.log("bounding client size");
return [width, height];
} catch (error) {
// Not using a container for the renderer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about this. When does this happen?

console.log("Window size");
return [window.innerWidth, window.innerHeight]
}
},

// resize the renderer
resize: function() {
let size = this.getSize();
const width = size[0],
height = size[1];

if (width === 0){
return;
}
this.renderer.setSize(width, height - 4.4); // Seems to grow by 4.4 px on each resize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you set the size on the model (this.model.set({"_width": width, "_height": height})), then the update would happen automatically via the existing updateSize method, and the sizes would also persist through a freeze/thaw cycle.

this.camera.aspect = width / height;
this.camera.updateProjectionMatrix();

// finally render if not frozen
if (!this.isFrozen) {
this.render()
}
},

teardownViewer: function() {

this.$renderer.off('mouseenter');
Expand Down Expand Up @@ -494,11 +536,15 @@ var RenderableView = widgets.DOMWidgetView.extend({
});
},

// Permit custom calls from pythreejs
onCustomMessage: function(content, buffers) {
switch(content.type) {
case 'freeze':
this.freeze();
break;
case 'resize':
this.resize();
break;
default:
}
},
Expand Down
1 change: 1 addition & 0 deletions pythreejs/_base/renderable.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class RenderableWidget(DOMWidget):
_alpha = Bool(False).tag(sync=True)
_webgl_version = Int(2).tag(sync=True)

autoResize = Bool(False).tag(sync=True)
autoClear = Bool(True).tag(sync=True)
autoClearColor = Bool(True).tag(sync=True)
autoClearDepth = Bool(True).tag(sync=True)
Expand Down
7 changes: 5 additions & 2 deletions pythreejs/core/Renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from contextlib import contextmanager
from ipywidgets import widget_serialization
from traitlets import (
Unicode, CInt, Instance, Float, Tuple, Undefined, link)
Unicode, CInt, Instance, Float, Tuple, Undefined, link, Bool)

from ..traits import *

Expand All @@ -27,24 +27,27 @@ class Renderer(RenderableWidget):

width = CInt(200)
height = CInt(200)

scene = Instance(Scene).tag(sync=True, **widget_serialization)
camera = Instance(Camera).tag(sync=True, **widget_serialization)
controls = List(Instance(Controls)).tag(sync=True, **widget_serialization)
#effect = Instance(Effect, allow_none=True).tag(sync=True, **widget_serialization)
background = Color('black', allow_none=True).tag(sync=True)
background_opacity = Float(1.0, min=0.0, max=1.0).tag(sync=True)

def __init__(self, scene, camera, controls=None, antialias=False, alpha=False, webgl_version=2, **kwargs):
def __init__(self, scene, camera, controls=None, antialias=False, alpha=False, webgl_version=2, auto_resize=False, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def __init__(self, scene, camera, controls=None, antialias=False, alpha=False, webgl_version=2, auto_resize=False, **kwargs):

The users can pass autoResize here, and it will be passed along to the super's init method via the kwargs. The other args that are listed here explicitly are there because:

  • They are required (scene and camera)
  • They are hidden traits (name start with an underscore).

The autoResize trait does not need the same logic.

super(Renderer, self).__init__(
scene=scene,
camera=camera,
controls=controls or [],
_antialias=antialias,
_alpha=alpha,
_webgl_version=webgl_version,
auto_resize=False,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
auto_resize=False,

**kwargs)
link((self, 'width'), (self, '_width'))
link((self, 'height'), (self, '_height'))
self.autoResize = auto_resize
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we pass along the trait to the super's init, we won't need to set it here.

Suggested change
self.autoResize = auto_resize


def render(self, scene, camera):
content = {
Expand Down
4 changes: 2 additions & 2 deletions pythreejs/renderers/WebGLRenderer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from ipywidgets import widget_serialization
from traitlets import Unicode, CInt, link
from traitlets import Unicode, CInt, link, Bool

from .._base.renderable import RenderableWidget

Expand All @@ -18,6 +18,7 @@ class WebGLRenderer(RenderableWidget):

width = CInt(200)
height = CInt(200)
autoResize = Bool(False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already declared on the base class, so should not need to be redeclared here.

Suggested change
autoResize = Bool(False)


def __init__(self, antialias=False, alpha=False, webgl_version=2, **kwargs):
super(WebGLRenderer, self).__init__(
Expand All @@ -41,4 +42,3 @@ def freeze(self):
"type": "freeze"
}
self.send(content)

3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
'nbval',
'pytest-check-links',
'numpy>=1.14',
'matplotlib',
'ipywebrtc',
'scikit-image',
],
'examples': [
'scipy',
Expand Down