I noticed a weird outline on my canvas lines. Below is an example:
http://jsfiddle.net/0Lzd562x/6/
The blue stroked rectangle is drawn after the red one but it looks like they mix together or there is a glow on the lines. I've tried setting the lineWidth to a larger value and it fixes the issue, but I want slim lines. Also tried using ctx.lineTo() to draw the rectangles but with same results. I want the latter (blue) rectangle to be on top overriding the right side of the red one.
What's happening is that you're drawing lines along the splits between pixels, not in the middle of the pixels themselves. This causes the line to be rendered at half opacity on each of the pixels. Because of the opacity, the colors from both squares are being added to 2 pixels, resulting in a thick 2px purple line.
The reason for the splitting of the line is antialiasing. You can find a fantastic talk about it by Steve Wittens
You can't turn antialiasing off, but you can draw the lines in the middle of the pixels by adding .5 to the starting x/ys of the rectangles, as long as the sizes are integers
Here's the resulting fiddle: http://jsfiddle.net/0Lzd562x/11/
This image is what I am trying to achieve. Circles on the edges are clickable. Its structure is made such that each rotation will be multiple of 45 deg.
I am using css transform rotate property for rotation.
How is it supposed to work?
When we click on any circle on the edge it should come to its active position and it should always rotate in clockwise direction.
Here is what I did
I achieved rotation by assigning numbers to the circles.
i.e., if clicked on 7 number then it will rotate by angle (9-7)*45=90 degrees.
(This time I did not change the numbers dynamically. i.e., as the circle is rotating the numbers given to the circles are the same.)
This works fine here. But, lets see this scenario: when we click on 2nd position circle it will rotate by 315 deg and then if you click again on the same (second) position then it will make the angle of 270 and it rotates the div in anti-clockwise direction. I think this is its behavior. But, I don't want this to happen. It should rotate again in clockwise direction and should take the active position.
Now to achieve above I did this:
Adding angle with prev angle.
var prev_degree = prev_degree + current_degree;
(current degree is being calculated using the same formula from above.)
This time I changed numbers dynamically i.e., on each click numbers are given to the desired positions. Starting 1 as from Active position till 8 as shown in Image
But this time, when I rotate circle 1, 2 times it rotates perfect then it starts working strange. If you are constantly clicking on the same number then it will add the same angle and will keep rotating perfect no matter what your angle is. If you click on random circles then it wont work which is totally wrong.
Why clockwise?
Because the circles on edges, they contain icon of which I have to maintain position when whole circle rotates.(I can achieve that rotating circles on the edges by assigning negative angles. But, now this is not a problem.)
There is no case when I am getting negative angle.
Let me know if you are not clear with my question.
Please let me know your suggestions to make this work :-)
I am trying to smoothen the transition from a diagonal line to a horizontal line by using arcs of circles that I calculate with a little calculus. The problem I am running into is that it seems as though I can't get the arcs to be positioned correctly.
For example: jsfiddle.net/5Wa9e/2
It might just be a problem with my calculations but from "inspection" it seems as though I have the right circles. I want the red points on the right to always be at the bottom of the circle at the point where the tangent is horizontal.
I am using: A#{radius},#{radius} 0 0 0 #{curveEndX},#{curveEndY}" to define the arc. Am I missing something?
--edit--
It was just my math. Turns out the arcs I see are just fallback mechanisms for when the SVG renderer can't find a circle matching my constraints.
--edit--
end result: jsfiddle.net/5Wa9e/2
I have a large circle with smaller ones inside made using two.js.
My problem is that these two do not rotate in their own place but in the top left axis.
I want the group of circles (circlesGroup) rotate only inside the large one in a static position. The circlesGroup and the large circle are grouped together as rotatoGroup.
two.bind('update', function(frameCount, timeDelta) {
circlesGroup.rotation = frameCount / 120;
});
two.bind('update', function(frameCount, timeDelta) {
rotatoGroup.rotation = frameCount / 60;
});
The whole code is in CodePen.
All visible shapes when invoked with two.make... ( circles, rectangles, polygons, and lines ) are oriented in the center like this Adobe Illustrator example:
When this shape's translation, rotation, or scale change those changes will be reflected as transformations about the center of the shape.
Two.Groups however do not behave this way. Think of them as display-less rectangles. They're origin, i.e group.translation vector, always begins at (0, 0). In your case you can deal with this by normalizing the translation your defining on all your circles.
Example 1: Predefined in normalized space
In this codepen example we're defining the position of all the circles around -100, 100, effectively half the radius in both positive-and-negative x-and-y directions. Once we've defined the circles within these constraints we can move the whole group with group.translation.set to place it in the center of the screen. Now when the circles rotate they are perceived as rotating around themselves.
Example 2: Normalizing after the fact
In this codepen example we're working with what we already have. A Two.Group that contains all of our shapes ( the bigger circle as well as the array of the smaller circles ). By using the method group.center(); ( line 31 ) we can normalize the children of the group to be around (0, 0). We can then change the translation of the group in order to be in the desired position.
N.B: This example is a bit complicated because it invokes underscore's defer method which forces the centering of the group after all the changes have been registered. I'm in the process of fixing this.
I'm using canvas of HTML5 to create a "preview" image which mainly consists of some rectangles and simple lines. Works fine so far, but there's one problem I cannot fix somehow. Presume the following situation:
context.fillStyle = "rgba(0,0,0,0.75)";
context.fillRect(100.64646,100,50.94967,20);
context.fillRect(100.64646+50.94967,100,100,20);
So I'm drawing 2 rectangles with some opacity. The x-starting coordinate plus the x-length of the first rect is equal to the x-starting coordinate of the second rect, so in theory they should collide without any margin between. Sadly, the result is different:
(see http://files.clemensfreitag.de/thin_spacing.jpg)
There's a very tiny spacing between the boxes, and the background color is visible. But:
This problem doesn't occur if the coordinates and lengths are integer values.
Is there any way to get it done by using float values? Converting them to integers before drawing might be acceptable in my application, but I'm just wondering why this should not work with floats.
Best,
Clemens
What you're seeing is the result of overlaying two opaque colors. When the first rectangle ends at 151.59613, the rectangle is automatically antialiased, filling in the rightmost column with rgba(0,0,0,0.4470975). When the second rectangle starts at the same x coordinate, it is also antialiased, filling in the leftmost column (the same as the first rectangle's rightmost) with rgba(0,0,0,0.3029025). The two values do add up to rgba(0,0,0,0.75), but that's not how they are blended. Instead, the second color (rgba(0,0,0,.3029025)) is drawn on top of the first, resulting in rgba(0,0,0,0.4470975+(1-0.4470975)*0.3029025) = rgba(0,0,0,0.61457305). So there isn't actually a gap between the two rectangles, but rather a 1px column that is a slightly lighter shade of grey.
Similarly, if you were using solid colors then the second rectangle's antialiased column would overwrite the first's, resulting in an even lighter shade of grey in the "gap".
The issue does not show up with integer values because no antialiasing is required - each rectangle ends at the edge of a pixel.
It looks like none of the globalCompositeOperation settings fix this, and turning off antialiasing would sometimes result in a 1px gap, so I think your simplest solution is to force integer values (alternatively, you could clear that column then fill it in with the desired color).
This problem is related to the way objects are drawn on a float based grid (especially vertical and horizontal lines and thus rects).
See there for an explanation and a schema : http://canop.org/blog/?p=220
Depending on the size of your objects, you need to use integer or mid-integer coordinates and sizes for your shapes, the goal being to fill complete pixels in both dimensions.
For example :
use a mid-integer for a thin line (one pixel width)
use an integer coordinate for a 2 pixels wide line
(and extend the logic for rects)