KineticJS strokeWidth centering - javascript

When you use strokeWidth in Kinetic, it adds width on each side of the actual point. So, in other words the stroke is centered on the normally 1px line and the width of that line grows outward from the center.
So for example in the below image "A", you see that the point is at (0,0) but the line is growing outward from that point. What I need is something like image "B".
I know I can accomplish this by just enlarging the polygon by the difference of the strokeWidth, but that will throw off many measurements and I'm hoping there's something easier to say "grow outward."

Center-aligned is the only native html canvas stroke alignment.
It is occasionally proposed that strokes be given "in" | "out" | "center" alignments, but so far nothing from whatWG: http://old.nabble.com/Canvas-stroke-alignment-tc29205720.html
You could put your polygon in a custom Kinetic Shape. That way you could draw a second "stroking" polygon that is outside the original polygon. It's a bit more setup work, but you could achieve your desired result.

Related

Convert polygon to inverted polygon, i.e. carve out the negative polygon from viewport rectangle

I'm using this Line of sight library which works similar to the demo. When you move the player character around it constructs a polygon for the visible area, see the yellow polygon in the screenshot below.
However, I would like to get the inverted polygon or the "negative" polygon, so the blue area in the example screenshot. The inverted polygon can be used to block any sprites and elements by filling it with solid black color.
The yellow visibility polygon is an array of x,y positions, for example like this:
// viewport 640 x 640 px
// example of visibility polygon
var visibilityPolygon = [ [640, 334], [502, 248], [402, 248], [406, 246], [406, 202], [246, 170], [353, 170], [353, 100], [278, 0], [548, 0], [480, 128], [480, 200], [549, 200], [640, 195], [640, 334] ];
In the example screenshot the blue area is one continuous shape, and the problem is that sometimes the visibility polygon will break up the game area into 2 or more invisible parts. I think it is theoretically possible to always draw the blue polygon as one single polygon by using the edges of the viewport to connect any seperate parts. So this can result in infinitely thin lines along the viewport edges but that's not a problem. Another consideration is that it has to redraw every frame, so it needs to be efficient enough to run at 60fps.
I don't know how to create such an algorithm to get the inverted polygon. Btw the starting point can vary, sometimes it's on the edge of the area but sometimes somewhere in the middle. In the example screenshot it starts on te bottom-left corner of white rectangle.
So my question is, what would such an algorithm look like? Are there any known example of this using just JavaScript?
What you call the negative polygon is essentially the original polygon from which you remove the edges on the square outline, which results in one or more open polylines, and to which you add closing segments drawn on the square outline, in the reversed traversal order.
In your second case, drop the edges 6-7-8-9, then close 9-10-11-12-13 with 13-X-9, close 14-15-16-4 with 1-14 and close 2-3-4-5-6 with 6-Y-2 (X and Y are corners).
This is a matter of rearranging the chains of vertices.

How to Calculate Collision of rotated Rectangle

I try to calculate the collision of the edges of an rotated Rectangle.
Here is an example on jsFiddle : http://jsfiddle.net/XgHxx/
Something like this:
if( mask.x < img.x * rotate_Factor ) mask.x = img.x * rotate_Factor ;
As you see my Collision is only for the not rotated Image.
And i want the Rectangle to be inside of the image even when its rotated.
Thanks, Mottenmann.
ps.: I made an example of how i think it could be calculated :
It looks like it already has been answered: see this question How to check intersection between 2 rotated rectangles?, there's also an answer that provides a JS implementation.
Thinking from my weak mathematical mind, you can check that by finding out if any of the corner points of the mask is contained by the boundary lines of your image.
You can do that by calculating the line equations of your image (based on its position), then check to see if any of the corner points of the mask lie on any of the boundaries and then stop the movement of the box in that direction in which the corner point is hitting the boundary.
Just a couple of mathematical formulas.
There is probably a better way to do this in jquery but you don't need any library for the above solution :)

How do the createRadialGradient() and addColorStop() methods work?

Can anybody explain me, preferably with illustrative pictures, how do these methods work? I've looked at different examples and tutorials but can't seem to grasp the idea. I understand, that the createRadialGradient() creates two circles, but how do those two circles relate to each other and the addColorStop() method ?
Yes, I know this is necro'd... but it seems a valid question that was never snawered, so I leave this here in case someone else needs it.
================================================================================
Well, a gradient is a smooth shift from one color to another.
In any gradient, you pick a point where the colors begin, a point where the color ends, and the colors you want, and the color smoothly transitions between them.
The color stops are there to determine what colors will be a part of the gradient, and where in the gradient those colors will appear.
In a linear gradient, the color transitions from one color to the next in a straight line so that bands of color form along the line, perpendicular to the axis.
In a radial gradient, the color wraps itself around a central circle (or point, which is simply a very small circle) and transitions from that center to the edge of the gradient.
This means that the color bands that make up the gradient form into larger and larger circles as they transition from center to edge.
HEREis an example of a simple radial gradient transitioning from white in the center to black at the outside edge.
This is the origin of the syntax for createRadialGradient.
This first circle will be where the color begins, we will arbitrarily state that it starts in the center... lets say that is x:100,y:100
The second circle will be where the color ends, since we picked the center to start it, the color finishes at the outside edge of the circle (although these could just as easily be reversed).
For simplicity's sake, the center point (in this case) will remain the same: x:100,y:100
The real difference between these circles will be the radius. Since the center should be small, we will give it a radius of 1, while the larger outside radius of the circle, we will make 100.
This gives us the required parameters:
x = 100;
y = 100;
radiusStart = 1;
radiusEnd = 100;
var grad = ctx.createRadialGradient(x,y,radiusStart,x,y,radiusEnd);
However, if we try to display this code as is, we won't see anything... this is because we need the color stops.
Color stops are declared with two parameters... the position and the color of the stop.
The position is a number between 0 and 1, and represents the percentage of the distance from start to end.
If we want the color to start at white, then we would use:
grad.addColorStop(0,'#FFFFFF');
This means that we the color stop starts at 0% of the way down the line (meaning right where the gradient begins), and gives the color to paint there as white.
Similarly, the second gradient should be black, and should be placed at the very end of the gradient:
grad.addColorStop(1,'#000000');
Notice that these do not reference context directly... we referenced context to create the gradient, but we are adding stops directly to the gradient that we created.
When we are finished creating the gradient, then we can use this gradient as a fillStyle (or even a strokeStyle) for as long as the gradient that we created remains in scope.
Full code:
x = 100;
y = 100;
radiusStart = 1;
radiusEnd = 100;
var grad = ctx.createRadialGradient(x,y,radiusStart,x,y,radiusEnd);
grad.addColorStop(0,'#FFFFFF');
grad.addColorStop(1,'#000000');
ctx.beginPath();
ctx.arc(x,y,radiusEnd,0,Math.PI*2,false);
ctx.fillStyle = grad;
ctx.fill();
While you are playing with this, don't forget to experiment a bit.
Try adding more than two color stops... this means that instead of transitioning from black to white (boring), you can transition from blue to green to yellow to orange to red to purple.
Just remember to set the positions appropriately... if you have 6 colors, for example (as above), and you want them evenly spaced, then you would set the positions at .2 intervals:
grad.addColorStop(0,'#0000FF');
grad.addColorStop(.2,'#00FF00');
grad.addColorStop(.4,'#FFFF00');
grad.addColorStop(.6,'#FF8800');
grad.addColorStop(.8,'#FF0000');
grad.addColorStop(1,'#AA00AA');
Any color stops you try to place in the same position will overwrite one another.
Another cool effect is to set two different centers for the circles when creating the gradient... this lends a different effect to the gradient, and can be a worthy addition to your arsenal.
HERE are two images from the W3C specification (which itself is HERE). Both of these are radial gradient with different center points for the first and second circles.
A better example is HERE, although the code itself is written in svg for html backgrounds, the examples still show some great ways to use radial gradients with differing centers. He covers the theory of radial gradients as well as shows some very nice examples.
Finally, a tip... while it is quite possible to write gradients by hand, its kind of a pain in the butt. It is usually far easier to grab Photoshop, Illustrator, GIMP, or Inkscape, and build the gradient in one of those... then you can adjust the gradient directly until you like it. Then simply copy the color stop information over to your canvas code.
Hope some of that helps someone.

How to create a gradient fill on the inner edge of an object with Raphael?

I have a dynamically generated graph that illustrates the range of items that will fit within a container, relative to the item's width and thickness. I'm trying to show that the items near the edge of the "fit range" might not be as good of a fit as those closer to the middle of the graph. To do this I'd like to fill my shape with green, which has a gradient that turns to yellow around the edges. This yellow area should be of uniform thickness around the entire inside edge, as illustrated in the image below. How might I accomplish this with Raphael? I know how to do a solid fill; the gradient is where I'm having difficulty. Thanks in advance for your help!
In theory it should be possible to do this by slicing the graph into four triangles.
Each triangle can then be filled with a gradient that is mostly your solid color but at one end it turns into your edge color. By setting the right angle on the gradient you can make it look like only the edges on the graph have a different color.
I've created the rectangle above using the following code.
var slice1 = paper.path("M200 200L100 100L300 100").attr({
"fill": "90-#0f0:70-#ff0:95",
});
var slice2 = paper.path("M200 200L300 100L300 300").attr({
"fill": "0-#0f0:70-#ff0:95",
});
var slice3 = paper.path("M200 200L300 300L100 300").attr({
"fill": "270-#0f0:70-#ff0:95",
});
var slice4 = paper.path("M200 200L100 300L100 100").attr({
"fill": "180-#0f0:70-#ff0:95",
});
Your case will be a bit more complex though. You will have to first find the middle of the graph to be able to slice it into triangles. Then you need to find the angle for each of the gradients.
Evening,
It's not as easy as it looks like it should be. Probably due to an issue with how to implement it in VML.
The best I was able to do is to use a slightly larger clone of your target object behind the original, and then use a gradient fill on it.
I've made an example in this fiddle
Hope that helps.
You could use a radial gradient on an overllying ellipse but that will leave a rather large corner of yellow
To find the centre of your object use good old getBBox()

Grid drawn using a <canvas> element looking stretched

I'm trying to draw a grid on a <canvas> element with the ultimate goal of making a Go board.
For some reason the grid is looking stretched, with the lines being thicker than 1 pixel and the spacing being completely wrong. It doesn't even start in the (10,10) position..
It would be great if someone could take a look at tell me what I'm doing wrong.
http://jsfiddle.net/h2yJn/
I've found the problem. I was setting the dimensions of the <canvas> using CSS, when you actually have to set the width and height attributes. This was causing it to be stretched/skewed.
var canvas = $('<canvas/>').attr({width: cw, height: ch}).appendTo('body');
http://jsfiddle.net/h2yJn/66/
Please try it outside jsfiddle, maybe jsfiddle is applying some linear transformation.
Also please make sure that you add 0.5 everywhere to both x and y coordinates. Alternatively, you can apply translate(0.5, 0.5) to shift all coordinates by half a pixel.

Categories

Resources