-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Using examples/WebGL/Filters_GL-GL.html from master branch (commit c7b6035) and adding the line bmp.hitTest(0,0)
leads to following error (Ubuntu 16.04, Chrome 69.0.3497.42 beta 64-bit):
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'
at BitmapCache.p.draw (easeljs-NEXT.js:15625)
at Bitmap.p.draw (easeljs-NEXT.js:6705)
at Bitmap.p.draw (easeljs-NEXT.js:11883)
at Bitmap.p.hitTest (easeljs-NEXT.js:7016)
at Image.handleImageLoad (Filters_GL-GL.html:68)
The provided value metioned in the error message is of type WebGLTexture
instead. bmp.on('mousedown', ()=>{})
plus clicking causes the same error for same reason.
The general problem as I see it is that currently for the hitTest a 1x1-sized canvas is created, its '2d' context is acquired, the object is drawn on it and the pixel for the test is queried with ctx.getImageData(0,0,1,1)
, as can be seen in the following code references:
EaselJS/src/easeljs/display/DisplayObject.js
Lines 543 to 548 in c7b6035
var canvas = createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"); // prevent errors on load in browsers without canvas. | |
if (canvas.getContext) { | |
DisplayObject._hitTestCanvas = canvas; | |
DisplayObject._hitTestContext = canvas.getContext("2d"); | |
canvas.width = canvas.height = 1; | |
} |
EaselJS/src/easeljs/display/DisplayObject.js
Lines 1083 to 1088 in c7b6035
p.hitTest = function(x, y) { | |
var ctx = DisplayObject._hitTestContext; | |
ctx.setTransform(1, 0, 0, 1, -x, -y); | |
this.draw(ctx); | |
var hit = this._testHit(ctx); |
EaselJS/src/easeljs/display/DisplayObject.js
Lines 1322 to 1325 in c7b6035
p._testHit = function(ctx) { | |
try { | |
var hit = ctx.getImageData(0, 0, 1, 1).data[3] > 1; | |
} catch (e) { |
I guess the problem with webgl-cache is that it is stored on the gpu and not as easy accessible as a getImageData
. I'm basing my guess solely on the following comment:
EaselJS/src/easeljs/filters/BitmapCache.js
Lines 366 to 370 in c7b6035
* When "options.useGL" is set to the parent stage of the target and WebGL, performance is increased by using | |
* "RenderTextures" instead of canvas elements. These are internal Textures on the graphics card stored in the GPU. | |
* Because they are no longer canvases you cannot perform operations you could with a regular canvas. The benefit | |
* is that this avoids the slowdown of copying the texture back and forth from the GPU to a Canvas element. | |
* This means "stage" is the recommended option when available. |
I don't know a solution, imo a solution depends on hitTest's use cases. For my case, as a workaround, I'm planning to override the DisplayObject's hitTest
with a custom function that either uses a context2d-duplicate to do the hitTest or simply checks for the object's bounds in this function.