I would like to know if there is existing equivalent methods in JavaScript (for HTML5 supported browsers) that can evaluate a bitmap-on-bitmap hitTest like Flash does.
Also, how could a "blur-filter" be achieved?
Can existing DIV / SPAN tags be "drawn" (like Flash's BitmapData.draw() method) into a bitmap object, so it can be used for "hitTest" purpose on the canvas?
I think I may have the HTML5 jargon all wrong here, but hopefully this makes somewhat some sense.
Are there any built-in methods to check if bitmaps touch eachother, at pixel-level evaluation?
Thanks!
No, there are no methods in HTML Canvas or Context to determine if two regions overlap. No tests for non-square regions of non-transparent pixels overlapping, no tests for transformed bounding boxes overlapping, no tests even for overlapping axis-aligned bounding boxes. Any such hit testing will need to be done by you or a higher-level API tracking individual bitmaps. The Canvas/Context is a non-retained low-level pixel blitting and drawing API.
No, you cannot serialize the rendering of HTML elements into a canvas image (other than using drawImage() to copy images and/or canvases). This includes attempting to capture content that is drawn underneath a transparent/semi-transparent canvas. There are security problems if this is allowed, and so it is not.
However, you can 'blur' content already drawn to the canvas by using getImageData() to get the raw pixels, then manipulating the pixel values, and then using putImageData() to push the modified pixels back to the canvas.
PlayMyCode has a great step-by-step explanation of a Javascript per-pixel collision detection function that works very much like Actionscript's hitTest.
Related
The setup
As part of a web vector editing tool written in Javascript, I'm implementing hit testing using a hit canvas strategy similar to that of Concrete.js.
For most of it, it works pretty well: I'm drawing my shapes twice (once on the display canvas, and once on a hit canvas).
When querying the canvas, I check the hovered pixel of the hit canvas and extract interaction information (i.e. which object id is stored there).
The problem
This works well inside shapes, but is painfully flawed at the boundaries where anti-aliasing makes the stored data invalid (it gets mixed with whatever background data was there before).
Are there good strategies for dealing with this data boundary problem?
Without disabling anti-aliasing for canvas methods, then we're bound to have some boundary regions across overlapping regions that will store merged data from multiple regions.
The simple scenario
In a binary scenario (some foreground vs the background), then this can be mitigated as we can assume the background to have no value, and any value becomes some foreground.
The real scenario
However, in a general scenario with multiple shapes overlapping each other on top of the background, is there any reasonable strategy for error detection? (or error correction, but I assume that's harder)
If I can tell that the data is invalid (i.e. it consists of perturbed data due to anti-aliasing), then I can use a different strategy for those few pixels at the boundaries. But I feel that it's impossible to tell whether the data I'm extracting is valid in the general scenario where we can have many overlapping shapes.
Of course, one solution is to NOT use a hit canvas. But I was wondering whether people had found a solution using hit canvases since they seem great for dealing with complex geometries.
Anti-aliasing
The ideal solution would be to disable anti-aliasing, which I don't think is possible for canvas methods [*].
[*] I know we can disable filtering when rendering images (e.g. that question) such as with imageSmoothingEnabled=false or rescaling with image-rendering: pixelated, but those don't solve the problem of anti-aliasing when drawing shapes / paths.
I am working with fTelnet.js - I have gotten down to the this_Font.GetChar() code and have found all characters are from a Font Sprite, it getItemData(....) changes the color where The pixel is 0x80 and colors it foreground [r][g][b][alpha], or colors it background [r][g][b][alpha].
Since Unicode goes outside what is in its 40+ fonts - I need to cheat and .createElement("div"), .innerHTML = "\u#####"; then somehow take that as ImageData so I can patch the above logic and introduce unicode support to fTelnet's canvas routine.
Does anyone know what command(s) I am needed to do this? e.g. I have spent hours trying to resolve this via Google, HTML5 Context docs, without success... mainly not knowing what I am searching for ;-)
or as I re-read this... maybe a hidden canvas, do the ctx.strokeText("\u#####", 25, 50); and then copy from that CTX as a IMAGEDATA to the displayed? (what command would I look up then?)... I normally do not dabble in 2D/3D graphics world (obviously)...
Regards,
Generally, rendering HTML to canvas is not possible - and that seems to be by design (it would make issues like tainting much harder to navigate).
But stamping one canvas on top of another is simple - you can just use the standard #drawImage call, same as with any other image you would draw on canvas.
Actually, if you look at the API documentation and click through the definitions you will see that you can use drawImage to "stamp" any instance of svg or html image, a bitmap, offscreen canvas, video or audio tags.
I'm presently implementing a few features into a vector editor based off of fabric.js and have hit a bump in the road with how best to handle this scenario:
In order to resize/scale the canvas smaller and larger via scaling grippies/controls, I've begun the task of implementing a "fake canvas" that stays in the middle of the real canvas (the real canvas is resized to fill it's DOM parent at all times. This presents several issues, the biggest being, dealing with objects on the canvas, ensuring their coordinate are always relative to my "fake canvas" (which is just a Rect with some restrictions applied, e.g. locking movement, rotation, etc).
So I'm really just looking for strategies/suggestions at how to go about doing this. For instance, I know I'd be dealing with newly added objects, moving objects and preventing them to be moved outside of the boundaries of my fake canvas. Among other considerations.
Thanks for the input and suggestions. I'm not looking for code, I'm more just looking for suggestions of how best to handle all the canvas related things, transferred to a fake canvas. I see that the Shutterstock Editor does some of this too, so I guess it doesn't seem like it's out of the realm of possibilities.
I'm playing around with the idea of modifying my game development IDE to produce HTML5 versions of the games created with it. One of the features of the IDE is the ability to define frames, which not only define how a graphics cell is transformed (rotated, stretched, etc), but also how it is colored when it is drawn. So if I wanted green hills and brown hills and uphills and downhills, I would only need 1 graphic defined for all of those, simply transformed and colored differently.
I can see how an HTML5 canvas context will allow me to transform drawImage results, but I don't see a practical way to modulate the colors. I want to be able to say, for example, R=255, G=255, B=0, A=127 and have none of the blue channel come through (a yellow-tinted version of the graphic) drawn at 50% translucency (keeping in mind that portions of the graphic cell may already be translucent or transparent).
Is this possible? Or will I need to getImageData and manipulate the pixels and cache manipulated copies? If I need to cache manipulated copies, what's the best JavaScript data structure to accomplish this? I think I'd want some kind of dictionary where the key is an image index and an RGBA composed as a single value somehow. Look-ups would have to be very fast because it would potentially be done for a majority of the tiles being drawn.
Sadly I don't think you can do it without the help of getImageData.
Here's an example of tinting an image using getImageData:
http://jsfiddle.net/3eUBk/2/
It was something I made to answer this question, which has an explanation of everything thats going on: How can I use a gradient map to tone a HTML5 canvas with an image in the canvas.
Let me know if you need more information.
Javascript CANVAS is amazing: it allows us to draw something like lines, polygons on the browser screen.
I wonder how does Javascript CANVAS works. For example to draw a line, does it use a series aligned tiny images to simulate the line or some other approach?
Thanks in advance.
Any reasonable implementer would just use a bitmap (stored internally in the browser), and draw to that using OS native drawing commands.
Why does it matter? It's not at all related to HTML+CSS, if that's what you're wondering.
More detail, for detail's sake:
When the browser's HTML parser sees a canvas element (of a given width & height) it needs to allocate an onscreen pixmap to cover that area. It either does this manually (i.e. malloc()) or it calls into some OS native drawing API to create a surface to draw on. The OS native API could be Windows, Gtk, Kde, Qt, or any other drawing library that the implementer of the browser chose. Also, it's highly dependent on the operating system. Internet Explorer probably calls into some Windows native library (i.e. DirectX or WinFooBarMethod()).
Once the drawing surface is created, it's made accessible to the internal guts of the JavaScript interpreter, likely via a pointer or handle to the constructed drawing surface. Then, when the JS interpreter sees an invocation of one of the canvas methods, it turns this into a call to the appropriate OS native command.
So, using the Windows 3.1 style metaphor:
"new canvas(width, height)" = "WinCreatePixmap(width, height)"
"canvas.setPixel(x,y,color)" = "WinSetPixel(x,y,color)"
And using a manually managed pixmap:
"new canvas(width, height)" = "malloc(width * height * sizeof(Pixel))"
"canvas.setPixel(x,y,color)" = "canvas[x][y] = color;"
Again, it shouldn't matter to the JavaScript developer how these methods are implemented. The only people who need to care are the ones who are writing HTML5 compliant web browsers with canvas support.
If you know C++, you can go to the source.
For example, in Firefox, the "graphics context" object is implemented by the class nsCanvasRenderingContext2D. But that class doesn't actually modify the pixels directly. Instead, it asks a separate object, called Thebes, to do that. Thebes in turn delegates this work to a graphics library called Cairo, which typically asks a library provided by your operating system to do the actual pixel work. I imagine it's a similar story everywhere.
At the very bottom, the canvas has a two-dimensional array of pixels. Each pixel is a 32-bit integer. A pixel is set by assigning a value to an element of the array. Somewhere there's a bit of code that determines which pixels to paint and assigns the appropriate values to the appropriate array elements.
In theory, the pixels might be drawn by your video card, but I have heard that graphics cards generally can't be trusted to do 2D graphics, because the hardware is aggressively tuned for 3D gaming and trades away too much accuracy for speed.
If you're interested in how line drawing works, check out Bresenham's Line Drawing Algorithm.
Surely that's implementation-specific to the JavaScript engine browser in question?
You're thinking too much, it's simple:
A canvas is like an image that can be drawn on to the browser.
I think implementation is important. Why does it matter? Look at flash. When you use the drawing API to create complex fractal artwork it is actually creating vector artwork and making every line and curve a child of the object being drawn on, thus it rerenders the vector artwork every frame.. CRASH! or chug... chug........ chug..............
So for complex fractals or art that records equations, I have to use a Bitmap or the render engine CACKS. It DOES make a difference, since now I am trying to transfer some of my flash multimedia to Javascript and encountering differences among browsers.