Skip to content

Commit 1d876bc

Browse files
committed
feat: Add visibilitychange event to Object3D
Emit event when visible property changes. Fixes #32767
1 parent c36ae33 commit 1d876bc

File tree

2 files changed

+77
-8
lines changed

2 files changed

+77
-8
lines changed

src/core/Object3D.js

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ const _childaddedEvent = { type: 'childadded', child: null };
5555
*/
5656
const _childremovedEvent = { type: 'childremoved', child: null };
5757

58+
/**
59+
* Fires when the object's visibility has changed.
60+
*
61+
* @event Object3D#visibilitychange
62+
* @type {Object}
63+
* @property {boolean} visible - The new visibility state.
64+
*/
65+
const _visibilitychangeEvent = { type: 'visibilitychange', visible: null };
66+
5867
/**
5968
* This is the base class for most objects in three.js and provides a set of
6069
* properties and methods for manipulating objects in 3D space.
@@ -141,6 +150,7 @@ class Object3D extends EventDispatcher {
141150
const rotation = new Euler();
142151
const quaternion = new Quaternion();
143152
const scale = new Vector3( 1, 1, 1 );
153+
let visible = true;
144154

145155
function onRotationChange() {
146156

@@ -222,6 +232,34 @@ class Object3D extends EventDispatcher {
222232
*/
223233
normalMatrix: {
224234
value: new Matrix3()
235+
},
236+
/**
237+
* When set to `true`, the 3D object gets rendered.
238+
*
239+
* @name Object3D#visible
240+
* @type {boolean}
241+
* @default true
242+
*/
243+
visible: {
244+
configurable: true,
245+
enumerable: true,
246+
get() {
247+
248+
return visible;
249+
250+
},
251+
set( value ) {
252+
253+
if ( visible !== value ) {
254+
255+
visible = value;
256+
_visibilitychangeEvent.visible = value;
257+
this.dispatchEvent( _visibilitychangeEvent );
258+
_visibilitychangeEvent.visible = null;
259+
260+
}
261+
262+
}
225263
}
226264
} );
227265

@@ -280,14 +318,6 @@ class Object3D extends EventDispatcher {
280318
*/
281319
this.layers = new Layers();
282320

283-
/**
284-
* When set to `true`, the 3D object gets rendered.
285-
*
286-
* @type {boolean}
287-
* @default true
288-
*/
289-
this.visible = true;
290-
291321
/**
292322
* When set to `true`, the 3D object gets rendered into shadow maps.
293323
*

test/unit/src/core/Object3D.tests.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,45 @@ export default QUnit.module( 'Core', () => {
682682

683683
} );
684684

685+
QUnit.test( 'visibilitychange event', ( assert ) => {
686+
687+
const obj = new Object3D();
688+
let eventCount = 0;
689+
let lastEventVisible = null;
690+
691+
obj.addEventListener( 'visibilitychange', function ( event ) {
692+
693+
eventCount ++;
694+
lastEventVisible = event.visible;
695+
696+
} );
697+
698+
// Initial state
699+
assert.strictEqual( obj.visible, true, 'Object starts visible' );
700+
assert.strictEqual( eventCount, 0, 'No events fired initially' );
701+
702+
// Change visibility to false
703+
obj.visible = false;
704+
assert.strictEqual( obj.visible, false, 'Visibility changed to false' );
705+
assert.strictEqual( eventCount, 1, 'Event fired when visibility changed' );
706+
assert.strictEqual( lastEventVisible, false, 'Event contains correct visible value (false)' );
707+
708+
// Set to same value - should not fire event
709+
obj.visible = false;
710+
assert.strictEqual( eventCount, 1, 'No event fired when setting same value' );
711+
712+
// Change visibility back to true
713+
obj.visible = true;
714+
assert.strictEqual( obj.visible, true, 'Visibility changed to true' );
715+
assert.strictEqual( eventCount, 2, 'Event fired when visibility changed back' );
716+
assert.strictEqual( lastEventVisible, true, 'Event contains correct visible value (true)' );
717+
718+
// Set to same value again - should not fire event
719+
obj.visible = true;
720+
assert.strictEqual( eventCount, 2, 'No event fired when setting same value again' );
721+
722+
} );
723+
685724
QUnit.test( 'updateMatrix', ( assert ) => {
686725

687726
const a = new Object3D();

0 commit comments

Comments
 (0)