How to check if canvas objects overlap each other - html

I'm trying to check if two objects (e.g. a rectangle and a triangle) on a HTML5 canvas are overlapping each other.
Currently I can only check that by looking at the screen (having set globalCompositeOperation='lighter').
My first idea would have been to scan all over the canvas if the "lighter" (compare code snippet above) color exists in the canvas. But therefor I would have to look at every single pixel which was rather costly for what I need.
Is there a (better) alternative to automatically check if they are overlapping?
Best regards.

The site below explains how to use the Separating Axis Theorem to determine if two convex shapes overlap.
http://www.codezealot.org/archives/55
To use this you will need to know the coordinate data used in contstructing the shapes.

Related

After Effect Bezier surface Wrap to AS3 DisplacementMapFilter

After Effect has the possibility to apply the a Bezier Surface over an image.
However we want to achieve that affect with AS3.
We can use DisplacementMapFilter, using a mapBitmap for each frame for the bezier effect..
How can we generate each of those bitmaps?
The only information that after effect gives are the 12 control points for 12 key frames each one.
How can we with that information generate those mapBitmap that the DisplacementMapFilter operation requests?
Maybe after effect has another information that we are missing?
Thanks in advance.
I'm asuming you're trying to come up with something like this: http://fatlinesofcode.philipandrews.org/2011/02/20/warping-bitmaps-with-a-bezier-surface/
Displacement map filter has limitations that would make this difficult.
The trick is to break up the image into triangles and warp these triangles along the bezier lines/surface you like. The more triangles you use the smoother the resulting image.
this is a good place to start : http://www.flashandmath.com/advanced/p10triangles/index.html
here is a more advanced example (without code) http://www.miaumiau.cat/2010/03/simple-surface-editor/ that is using bezier curves
more code here also: http://wonderfl.net/c/rFOlY
you can try looking up more resources with drawTriangles and distort keywords

html5 basic paint tool

I'm new to html5. And I'm trying to create a basic painting tool.
What I want to do in this tool is to have one or more shapes(maybe overlapping) and to paint the shapes without getting the colors overlapped. If a circle is drawn inside a rectangle and if I start coloring the circle, the rectangle should not be painted even if the mouse is dragged over it unless the dragging starts inside it.
To achieve this should I use multiple canvases or shapes?
Thanks in advance.
Well, first you need to program in the idea of keeping track of separate shapes. If you haven't already done that see here for a tutorial.
I imagine your shapes will all be kept as images or in-memory canvases themselves. I'm not sure how else you can do it.
There are a million ways you could do this, here's one:
When you start your drawing operation you need to detect which shape you're on. Then you draw that shape to an in-memory canvas and switch that temporary canvas' globalcompositeoperation to source-atop. This will make sure the paint can only paint in the already opaque regions of that shape (if that's your intent here, which it seems to be).
All while you are painting you will want to update the temporary canvas and redraw the main canvas constantly. While you are redrawing the main canvas, instead of painting that shape's image file you'll want to paint the temporary canvas (if you use canvases to keep the shapes you can just update those in real time).
If you are not using temporary canvases for each shape, when you stop the drawing operation you are gonna have to update the image associated with the shape to complete the operation.
Using an in-memory canvas (not added to the DOM) for every shape (that is the size of the shape and no larger) will make coding things slightly easier and might not be that bad on performance. I'd give it a try with 100 and 1000 (or more) in-memory canvases on your targeted platforms to see though.
The alternative is to use one in-memory canvas and have an HTMLImageElement (png) that represents every shape, but using the canvas.toImageURL function can be a bit of a performance hit in itself. I'd try both methods to see which works best in your case. If the shape count is small enough, it probably doesn't matter which.

Fill HTML canvas excluding arbitrary (possibly overlapping) circles

Given an HTML canvas that has already been drawn to, what's the best way to shade the whole canvas except given circular regions? (in context: shadows except where are there light sources)
I was hoping it would be as simple as a rect() followed by subsequent arc()s, but AFAIK there's no way to "remove" those circular sections after the fact. I can get close ( http://jsfiddle.net/mW8D3/2/), but the overlapping regions of circles end up shaded (in XOR fashion, whereas I want OR). Using clip() has the same problem.
I've also tried using globalCompositeOperation but can't quite seem to achieve what I want.
Any ideas?
You could first create the shadow image on a second canvas and knock out holes from it with globalCompositeOperation 'copy' and a transparent fillStyle.
Like this: http://jsfiddle.net/mW8D3/4/

Draw shapes/text on canvas using layers or z-index

I draw several text elements using a for loop.
But I want the first element to be drawn on top of all the other elments.
Other than reversing the loop, is there a way to define a layer number for a drawn element like text or shapes?
No, the HTML5 Canvas—like SVG—uses a "painters model" when rendering: the ink you lay down immediately dries on the canvas; successive draw calls go on top of the result.
Further, HTML5 Canvas—unlike SVG or HTML—uses a non-retained (or immediate) graphics mode: no objects are preserved corresponding to the original drawing commands after you have issued them.
Your options are:
Change your loop, or otherwise implement your own layering system that queues up draw calls and then issues them in order from bottom to top.
As #Stoive suggests, create separate (non-displayed) canvas elements programmatically, draw to them and then blit the results back to your main canvas in the order you like.
Create multiple (displayed) canvases on the page and layer them using CSS, drawing to each as its own layer.
The last option allows you the most freedom, including the ability to dirty/clear just one of the layers at any time, or re-order the layers without having to recomposite them yourself.
There is no concept of layers in canvas in the 2D context - think of it as a programmable paintbrush-like application.
You can, however, draw one canvas onto another using context.drawImage - so if you maintain each 'layer' in it's own canvas, and then compose them into the one for display, you could emulate the concept of layers.

HTML5 canvas hittesting

I have some images drawn on a HTML5 Canvas and I want to check if they are hit on mouse click. Seems easy, I have the bounds of the images, however the images are transformed (translated and scaled). Unfortunately, the context does not have a method to get the current transform matrix, and also, there is no API for matrices multiplication.
Seems the only solution is to keep track of the transforms myself and implement matrix multiplication.
Suggestions are welcomed.
This is a common problem in the 3D (OpenGL) graphics world as well.
The solution is to create an auxiliary canvas object (which is not displayed), and to redraw your image into it. The draw is exactly the same as with your main canvas draw, except that each element gets drawn with a unique color. You then look up the pixel corresponding to your mouse pick, and read off its color, which will give you the corresponding element (if any).
This is a commonly used method in the OpenGL world. You can find descriptions of it by Googling terms like "opengl object picking". Here is one of the many search results.
Update: The HTML5 canvas spec now includes hit regions. I'm not sure to what degree these are supported by browsers yet.