Skip to content

Commit 76f2051

Browse files
committed
clear raycaster intersections when disabled (fixes #3593)
1 parent 1247785 commit 76f2051

File tree

2 files changed

+71
-18
lines changed

2 files changed

+71
-18
lines changed

src/components/raycaster.js

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ var OBSERVER_CONFIG = {
2020
subtree: true
2121
};
2222

23+
var EVENTS = {
24+
INTERSECT: 'raycaster-intersected',
25+
INTERSECTION: 'raycaster-intersection',
26+
INTERSECT_CLEAR: 'raycaster-intersected-cleared',
27+
INTERSECTION_CLEAR: 'raycaster-intersection-cleared'
28+
};
29+
2330
/**
2431
* Raycaster component.
2532
*
@@ -61,6 +68,7 @@ module.exports.Component = registerComponent('raycaster', {
6168
this.raycaster = new THREE.Raycaster();
6269
this.updateOriginDirection();
6370
this.setDirty = this.setDirty.bind(this);
71+
this.updateLine = this.updateLine.bind(this);
6472
this.observer = new MutationObserver(this.setDirty);
6573
this.dirty = true;
6674
this.lineEndVec3 = new THREE.Vector3();
@@ -108,6 +116,8 @@ module.exports.Component = registerComponent('raycaster', {
108116
: this.removeEventListeners();
109117
}
110118

119+
if (oldData.enabled && !data.enabled) { this.clearAllIntersections(); }
120+
111121
this.setDirty();
112122
},
113123

@@ -123,6 +133,7 @@ module.exports.Component = registerComponent('raycaster', {
123133
if (this.data.showLine) {
124134
this.el.removeAttribute('line');
125135
}
136+
this.clearAllIntersections();
126137
},
127138

128139
addEventListeners: function () {
@@ -186,12 +197,10 @@ module.exports.Component = registerComponent('raycaster', {
186197
var intersectedEls = this.intersectedEls;
187198
var intersection;
188199
var intersections = this.intersections;
189-
var lineLength;
190200
var newIntersectedEls = this.newIntersectedEls;
191201
var newIntersections = this.newIntersections;
192202
var prevIntersectedEls = this.prevIntersectedEls;
193203
var rawIntersections = this.rawIntersections;
194-
var self = this;
195204

196205
if (!this.data.enabled) { return; }
197206

@@ -235,17 +244,17 @@ module.exports.Component = registerComponent('raycaster', {
235244
clearedIntersectedEls.length = 0;
236245
for (i = 0; i < prevIntersectedEls.length; i++) {
237246
if (intersectedEls.indexOf(prevIntersectedEls[i]) !== -1) { continue; }
238-
prevIntersectedEls[i].emit('raycaster-intersected-cleared',
247+
prevIntersectedEls[i].emit(EVENTS.INTERSECT_CLEAR,
239248
this.intersectedClearedDetail);
240249
clearedIntersectedEls.push(prevIntersectedEls[i]);
241250
}
242251
if (clearedIntersectedEls.length) {
243-
el.emit('raycaster-intersection-cleared', this.intersectionClearedDetail);
252+
el.emit(EVENTS.INTERSECTION_CLEAR, this.intersectionClearedDetail);
244253
}
245254

246255
// Emit intersected on intersected entity per intersected entity.
247256
for (i = 0; i < newIntersectedEls.length; i++) {
248-
newIntersectedEls[i].emit('raycaster-intersected', {
257+
newIntersectedEls[i].emit(EVENTS.INTERSECT, {
249258
el: el,
250259
intersection: newIntersections[i]
251260
});
@@ -255,22 +264,28 @@ module.exports.Component = registerComponent('raycaster', {
255264
if (newIntersections.length) {
256265
this.intersectionDetail.els = newIntersectedEls;
257266
this.intersectionDetail.intersections = newIntersections;
258-
el.emit('raycaster-intersection', this.intersectionDetail);
267+
el.emit(EVENTS.INTERSECTION, this.intersectionDetail);
259268
}
260269

261270
// Update line length.
262-
setTimeout(function () {
263-
if (self.data.showLine) {
264-
if (intersections.length) {
265-
if (intersections[0].object.el === el && intersections[1]) {
266-
lineLength = intersections[1].distance;
267-
} else {
268-
lineLength = intersections[0].distance;
269-
}
271+
setTimeout(this.updateLine);
272+
},
273+
274+
updateLine: function () {
275+
var el = this.el;
276+
var intersections = this.intersections;
277+
var lineLength;
278+
279+
if (this.data.showLine) {
280+
if (intersections.length) {
281+
if (intersections[0].object.el === el && intersections[1]) {
282+
lineLength = intersections[1].distance;
283+
} else {
284+
lineLength = intersections[0].distance;
270285
}
271-
self.drawLine(lineLength);
272286
}
273-
});
287+
this.drawLine(lineLength);
288+
}
274289
},
275290

276291
/**
@@ -394,7 +409,19 @@ module.exports.Component = registerComponent('raycaster', {
394409
}
395410
return objects;
396411
};
397-
})()
412+
})(),
413+
414+
clearAllIntersections: function () {
415+
var i;
416+
for (i = 0; i < this.intersectedEls.length; i++) {
417+
this.intersectedEls[i].emit(EVENTS.INTERSECT_CLEAR,
418+
this.intersectedClearedDetail);
419+
}
420+
copyArray(this.clearedIntersectedEls, this.intersectedEls);
421+
this.intersectedEls.length = 0;
422+
this.intersections.length = 0;
423+
this.el.emit(EVENTS.INTERSECTION_CLEAR, this.intersectionClearedDetail);
424+
}
398425
});
399426

400427
/**

tests/components/raycaster.test.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,9 @@ suite('raycaster', function () {
261261
raycasterEl.addEventListener('raycaster-intersection', function () {
262262
// Point raycaster somewhere else.
263263
raycasterEl.setAttribute('rotation', '90 0 0');
264-
raycasterEl.addEventListener('raycaster-intersection-cleared', function (evt) {
264+
raycasterEl.addEventListener('raycaster-intersection-cleared', function cb (evt) {
265265
assert.notEqual(component.clearedIntersectedEls.indexOf(targetEl), -1);
266+
raycasterEl.removeEventListener('raycaster-intersection-cleared', cb);
266267
done();
267268
});
268269
component.tick();
@@ -283,6 +284,31 @@ suite('raycaster', function () {
283284
});
284285
component.tick();
285286
});
287+
288+
test('clears intersections when disabled', function (done) {
289+
targetEl.addEventListener('raycaster-intersected', function () {
290+
targetEl.addEventListener('raycaster-intersected-cleared', function () {
291+
done();
292+
});
293+
assert.equal(component.intersectedEls.length, 2);
294+
assert.equal(component.clearedIntersectedEls.length, 0);
295+
el.setAttribute('raycaster', 'enabled', false);
296+
assert.equal(component.intersectedEls.length, 0);
297+
assert.equal(component.intersections.length, 0);
298+
assert.equal(component.clearedIntersectedEls.length, 2);
299+
});
300+
component.tick();
301+
});
302+
303+
test('emits intersectioncleared when disabled', function (done) {
304+
targetEl.addEventListener('raycaster-intersected', function () {
305+
el.addEventListener('raycaster-intersection-cleared', function () {
306+
done();
307+
});
308+
el.setAttribute('raycaster', 'enabled', false);
309+
});
310+
component.tick();
311+
});
286312
});
287313

288314
suite('non-recursive raycaster', function () {

0 commit comments

Comments
 (0)