Skip to content

Commit

Permalink
Update HTMLMesh to observe DOM mutation and support Canvas elements (m…
Browse files Browse the repository at this point in the history
…rdoob#23386)

* Update HTMLMesh to observe DOM mutation and support Canvas elements

- enable html2canvas updates to be made automatically based on dom updates
- also add Stats.js to VR Sandbox

* Switch raf to setTimeout in HTMLMesh, also fix repeat notes in haptics
  • Loading branch information
zz85 authored and donmccurdy committed Mar 10, 2022
1 parent f93892b commit 725bbe0
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
51 changes: 49 additions & 2 deletions examples/jsm/interactive/HTMLMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,32 @@ class HTMLTexture extends CanvasTexture {
this.minFilter = LinearFilter;
this.magFilter = LinearFilter;

// Create an observer on the DOM, and run html2canvas update in the next loop
const observer = new MutationObserver( () => {

if ( ! this.scheduleUpdate ) {

// ideally should use xr.requestAnimationFrame, here setTimeout to avoid passing the renderer
this.scheduleUpdate = setTimeout( () => this.update(), 16 );

}

} );

const config = { attributes: true, childList: true, subtree: true, characterData: true };
observer.observe( dom, config );

this.observer = observer;

}

dispatchDOMEvent( event ) {

htmlevent( this.dom, event.type, event.data.x, event.data.y );
if ( event.data ) {

htmlevent( this.dom, event.type, event.data.x, event.data.y );

this.update();
}

}

Expand All @@ -75,10 +94,27 @@ class HTMLTexture extends CanvasTexture {
this.image = html2canvas( this.dom );
this.needsUpdate = true;

this.scheduleUpdate = null;

}

dispose() {

if ( this.observer ) {

this.observer.disconnect();

}

this.scheduleUpdate = clearTimeout( this.scheduleUpdate );

super.dispose();

}

}


//

const canvases = new WeakMap();
Expand Down Expand Up @@ -202,6 +238,17 @@ function html2canvas( element ) {

drawText( style, x, y, element.nodeValue.trim() );

} else if ( element instanceof HTMLCanvasElement ) {

// Canvas element
if ( element.style.display === 'none' ) return;

context.save();
const dpr = window.devicePixelRatio;
context.scale(1/dpr, 1/dpr);
context.drawImage(element, 0, 0 );
context.restore();

} else {

if ( element.style.display === 'none' ) return;
Expand Down
2 changes: 1 addition & 1 deletion examples/webxr_vr_haptics.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
let audioCtx = null;

// minor pentatonic scale, so whichever notes is striked would be more pleasant
const musicScale = [ 0, 3, 5, 7, 10, 12 ];
const musicScale = [ 0, 3, 5, 7, 10 ];

init();
animate();
Expand Down
21 changes: 21 additions & 0 deletions examples/webxr_vr_sandbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@
import { XRControllerModelFactory } from './jsm/webxr/XRControllerModelFactory.js';

import { GUI } from './jsm/libs/lil-gui.module.min.js';
import Stats from './jsm/libs/stats.module.js';

let camera, scene, renderer;
let reflector;
let stats, statsMesh;

const parameters = {
radius: 0.6,
Expand Down Expand Up @@ -193,6 +195,21 @@
mesh.scale.setScalar( 2 );
group.add( mesh );


// Add stats.js
stats = new Stats();
stats.dom.style.width = '80px';
stats.dom.style.height = '48px';
document.body.appendChild( stats.dom );

statsMesh = new HTMLMesh( stats.dom );
statsMesh.position.x = - 0.75;
statsMesh.position.y = 2;
statsMesh.position.z = - 0.6;
statsMesh.rotation.y = Math.PI / 4;
statsMesh.scale.setScalar( 2.5 );
group.add( statsMesh );

}

function onWindowResize() {
Expand All @@ -218,6 +235,10 @@
torus.rotation.y = time * 5;

renderer.render( scene, camera );
stats.update();

// Canvas elements doesn't trigger DOM updates, so we have to update the texture
statsMesh.material.map.update();

}

Expand Down

0 comments on commit 725bbe0

Please sign in to comment.