dev-docs/RFCs/v6.3/event-handling-rfc.md
This RFC proposes an extensible system where layers can specify callbacks to additional pointer events beyond onHover and onClick.
In the context of creating "editable" layers, it is desirable to package event listeners inside a custom layer. In the current system, where old layer instances are disposed each rendering cycle, event listeners created inside a layer must be unbound and bound every time the layer updates. See example in nebula.
Another issue in editable layers is that in the current system, event handlers can only be supplied to the props object at layer construction. This makes it difficult for a custom layer to encapsulate event handling code as part of the class.
The goal of this proposal is to support callback for any of the mjolnir.js events.
A layer accepts additional props in the form of on<CamelCaseEventName>. For example:
new ScatterplotLayer({
...
onPanStart: this._onPanStart,
onPanMove: this._onPanMove,
onPanCancel: this._onPanEnd
onPanEnd: this._onPanEnd
});
Each callback will be invoked with a PickingInfo object if the specified event is fired over the layer's rendered content.
Deck accepts additional props in the form of onLayer<CamelCaseEventName>. For example:
new Deck({
...
onLayerPanStart: this._onLayerPanStart,
onLayerPanMove: this._onLayerPanMove,
onLayerPanCancel: this._onLayerPanEnd
onLayerPanEnd: this._onLayerPanEnd
});
Each callback will be invoked with a PickingInfo object if the specified event is fired on the canvas.
Allow layers to override default event handling using on* methods:
class MyLayer extends CompositeLayer {
onClick(...args) {
// do something
if (this.props.onClick) {
this.props.onClick(...args);
}
}
onDrag(...args) {
// do something
if (this.props.onDrag) {
this.props.onDrag(...args);
}
}
}
Deck currently executes pickLayers on hover (pointer move without button down) and click regardless whether they are being listened to. The most recent result of hover is saved in layerManager.context.lastPickingInfo.
In the proposed new event system, during each update cycle, LayerManager will produce a list of events that are being listened to by any of the current layers/sublayers. Deck then merges this list with the list of events that are being listened to by top-level props. Event listeners are added/removed from EventManager if events are added/removed from the list. This ensures that only the event that have handlers will be fired.
To avoid additional perf hit, picking should not be performed on every event. Other than hover, no event will invoke picking. Instead, they use the last-picked object stored in lastPickingInfo.
The proposal will require the following changes:
mjolnir.js: new utility to validate a list of eventsLayerManager class: a new method that returns a list of events that are being listened toDeck class: a new method that diffs lists of events and update EventManager, executed after each setProps; a new method that handles any new eventIf implemented: