diff --git a/src/HTMLMesh.js b/src/HTMLMesh.js
index 4baffc3..3a3d709 100644
--- a/src/HTMLMesh.js
+++ b/src/HTMLMesh.js
@@ -29,6 +29,7 @@ class HTMLMesh extends Mesh {
}
+ this.addEventListener( 'mouseleave', onEvent );
this.addEventListener( 'mousedown', onEvent );
this.addEventListener( 'mousemove', onEvent );
this.addEventListener( 'mouseup', onEvent );
@@ -43,6 +44,7 @@ class HTMLMesh extends Mesh {
canvases.delete( dom );
+ this.removeEventListener( 'mouseleave', onEvent );
this.removeEventListener( 'mousedown', onEvent );
this.removeEventListener( 'mousemove', onEvent );
this.removeEventListener( 'mouseup', onEvent );
@@ -73,7 +75,7 @@ class HTMLTexture extends CanvasTexture {
if ( ! this.scheduleUpdate ) {
// ideally should use xr.requestAnimationFrame, here setTimeout to avoid passing the renderer
- this.scheduleUpdate = setTimeout( () => this.update(), 16 );
+ this.scheduleUpdate = setTimeout( () => this.update(), 100 );
}
@@ -121,6 +123,18 @@ class HTMLTexture extends CanvasTexture {
}
+// Those are all css properties we use in this file:
+const USED_CSS_PROPERTIES = [
+ 'backgroundColor', 'color',
+ 'borderRadius',
+ 'borderTopWidth', 'borderTopColor', 'borderTopStyle',
+ 'borderLeftWidth', 'borderLeftColor', 'borderLeftStyle',
+ 'borderBottomWidth', 'borderBottomColor', 'borderBottomStyle',
+ 'borderRightWidth', 'borderRightColor', 'borderRightStyle',
+ 'accentColor', 'fontFamily', 'fontWeight', 'fontSize', 'textTransform',
+ 'paddingLeft', 'paddingTop', 'paddingBottom', 'paddingRight',
+ 'overflow'
+];
//
@@ -243,6 +257,38 @@ function html2canvas( element ) {
}
+ function getStyleForElement( element ) {
+ const style = window.getComputedStyle( element );
+ if ( element instanceof HTMLButtonElement ) {
+ if ( element.dataset.hoverStyleStored !== 'true' ) {
+ // The first time we render, store hover style in data attributes to make
+ // hover style work in VR because style aren't recomputed when we add the
+ // hover class.
+ if ( element.dataset.hoverStyleStored !== 'pending' ) {
+ // The mutation observer won't trigger rerender if we add the class now because we're currently rendering (scheduleUpdate is defined)
+ // Wait end of render before we modify the DOM.
+ element.dataset.hoverStyleStored = 'pending';
+ queueMicrotask( () => {
+ // Disable any css transition to avoir having a
+ // background color in between states when rerender is triggered.
+ element.style.transitionDuration = '0s';
+ element.classList.add( 'hover' );
+ } );
+ } else if ( element.classList.contains( 'hover' ) ){
+ // rerender was called, now store the updated computed style for hover
+ for ( const prop of USED_CSS_PROPERTIES ) {
+ element.dataset[prop] = style[prop];
+ }
+ element.dataset.hoverStyleStored = 'true';
+ queueMicrotask( () => {
+ element.classList.remove( 'hover' );
+ } );
+ }
+ }
+ }
+ return element.classList.contains( 'hover' ) && element.dataset.hoverStyleStored === 'true' ? element.dataset : style;
+ }
+
function drawElement( element, style ) {
let x = 0, y = 0, width = 0, height = 0;
@@ -288,7 +334,7 @@ function html2canvas( element ) {
width = rect.width;
height = rect.height;
- style = window.getComputedStyle( element );
+ style = getStyleForElement( element );
// Get the border of the element used for fill and border
@@ -526,6 +572,16 @@ function htmlevent( element, event, x, y ) {
element.dispatchEvent( new MouseEvent( event, mouseEventInit ) );
+ if ( element instanceof HTMLButtonElement ) {
+ switch ( event ) {
+ case 'mousemove':
+ if ( !element.classList.contains( 'hover' ) ) {
+ element.classList.add('hover');
+ }
+ break;
+ }
+ }
+
if ( element instanceof HTMLInputElement && element.type === 'range' && ( event === 'mousedown' || event === 'click' ) ) {
const [ min, max ] = [ 'min', 'max' ].map( property => parseFloat( element[ property ] ) );
@@ -538,6 +594,10 @@ function htmlevent( element, event, x, y ) {
}
+ } else {
+ if ( element instanceof HTMLButtonElement ) {
+ if ( element.classList.contains( 'hover' ) ) element.classList.remove( 'hover' );
+ }
}
for ( let i = 0; i < element.childNodes.length; i ++ ) {
diff --git a/src/aframe-html.js b/src/aframe-html.js
index ac4cf3d..6a39577 100644
--- a/src/aframe-html.js
+++ b/src/aframe-html.js
@@ -78,6 +78,10 @@ AFRAME.registerComponent('html', {
}
if (type === 'mouseleave' && this.activeRaycaster === raycaster) {
this.activeRaycaster = null;
+ _event.type = type;
+ _event.data.set( -1, -1 );
+ const mesh = this.el.getObject3D('html');
+ mesh.dispatchEvent( _event );
}
if (this.cursor) this.cursor.visible = false;
if (intersection) {