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?
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.