Question

I've been working on a doodling app recently just for kicks. After trying many methods to draw smooth curves with the sample points given by the mouse, I've settled for something using Quadratic Curve.

I must admit, my understanding of these curves is not optimal but I think I understood how they work. What I can't understand is that when I draw a curve which goes up and then suddenly down, the peak of the curve is not rounded anymore (it looks flattened).

A demo is much better to understand what I'm talking about: link to JCanvas sandbox

If you remove the last part of the curve (from cx11 to y15): link to another JCanvas sandbox. It looks fine, but when you add the next control point and end point, you get this weird effect.

Note: I'm not using JCanvas, but it has the same bug and the sandbox is handy. I guess it comes from the coordinates I get, but I can't explain and can't find a workaround/hack to make it look rounded...

For those who can't be bothered with the sandbox, here's a short version of the coordinates which are causing the problem:

x1: 216, y1: 98, cx1: 216, cy1: 97, x2: 216, y2: 98, cx2: 216, cy2: 99, x3: 215, y2: 103,

Any ideas on why? Mathematicals stuff are welcome. I've done a bit of searching and reading about the problem but didn't find anything about something similar.

--

Update

As Simon pointed out, I'm using Chrome 16 and I've tested the example with Firefox 4 and the latest Safari and the bug is there. I tried with Opera and it looks fine.

I'm rather frustrated about that as the bug is also on the iPad and I was trying to do a mobile web app so I'm sort of stuck.

Any ideas for a workaround/hack?

Was it helpful?

Solution

Found a workaround. It's one of those silly as-blah-approaches-zero bugs, I don't really know the proper name for them. It's hard to round a corner if the connection between two points is a very tiny vertical line and Safari gets confused.

At the location of your problem there is a 1 pixel high vertical line curve that needs to be rounded.

If the X destination is identical between one quadratic curve and the next, safari will give you problems. So this is bad:

ctx.beginPath();
ctx.moveTo(161,178);
ctx.quadraticCurveTo(215, 102, 216, 100);
ctx.quadraticCurveTo(216, 98, 216, 98);
ctx.quadraticCurveTo(216, 99, 215, 103); // I have the same X as the previous quadratic
ctx.quadraticCurveTo(213, 107, 211, 120);
ctx.quadraticCurveTo(209, 133, 209, 145);
ctx.stroke();

See it here: http://jsfiddle.net/Ws6UY/

So if we just change that value the tiniest amount:

ctx.beginPath();
ctx.moveTo(161,178);
ctx.quadraticCurveTo(215, 102, 216, 100);
ctx.quadraticCurveTo(216, 98, 216, 98);
ctx.quadraticCurveTo(216.01, 99, 215, 103); // 216.01 is not the same X as 216!
ctx.quadraticCurveTo(213, 107, 211, 120);
ctx.quadraticCurveTo(209, 133, 209, 145);
ctx.stroke();

See it here: http://jsfiddle.net/Ws6UY/1/

How silly! All you have to do to keep safari/iOS browsers working is make sure that the x (And probably y) values are not identical to the last point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top