Seems good to me, let see what @Deltakosh thinks about this.
I think it may be a little more complicated, however, as the cache may have to be invalidated when the picture is updated / the width/height are not the same than when the cache was created.
In some situations, there may be the following scenario: Control.contains method may be called BEFORE the image is drawn on canvas. In this way, context.getImageData(0, 0, width, height).data returns an array with zeros only. As a result, events like onPointerEnterObservable will not work anymore.
This situation may be reproduced if you are moving a cursor above the place where an image will be shown while the web page is loading. I can record a video with this bug if you need.
If not, I don’t see how it can fail because _workingCanvas is initialized in _prepareWorkingCanvasForOpaqueDetection which is called as part of the draw function.
So, as soon as _workingCanvas is initialized it is updated with the image data without context switches, so it’s not possible to process a contains in-between. And before draw is called, _workingCanvas is uninitialized, meaning that:
if (!this._detectPointerOnOpaqueOnly || !this._workingCanvas) {
return true;
}
will return early in the contains function, meaning we won’t update the cache.
So, in your stream of events, it should normally be:
Image._onImageLoaded calls. But the image has not been drawn on the canvas yet.
Control.contains calls. The cache is not filled with zeros from the canvas because _workingCanvas is unitialized and so contains returns early
Image draws on the canvas. _workingCanvas is now initialized as part of the drawing function
contains is called : Image class does update the cache because _workingCanvas is initialized and the cache is currently empty