2

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?

Mathieu
  • 622
  • 1
  • 6
  • 12
  • what browser are you using? Can you post a screenshot? The examples look normal to me on Chrome 17 and FF – Simon Sarris Dec 28 '11 at 18:33
  • I'm using Chrome 16 on Mac OS 10.6. Here's a screenshot: [link](http://i.imgur.com/NlAne.png). May I add, It's the same on my iPad and Safari. – Mathieu Dec 28 '11 at 18:42
  • Well the semi-good news is that this is a browser/platform and not a code problem, it seems fine on Chrome 17 (developer Chrome), Firefox 8, IE9, and Opera on Windows and Android 4.0. It does NOT look good (looks like your screenshot) on Safari on Windows. Screenshot of what it looks like in everything except Safari: http://i.imgur.com/QTaJf.png – Simon Sarris Dec 28 '11 at 18:58
  • Cheers Simon. It should look like this. Thank you very much for the extensive testing. I'm now looking for a (dirty) hack to have the complete round effect... If you have any ideas, I'll be glad to hear them :) – Mathieu Dec 28 '11 at 19:01

1 Answers1

1

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.

Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
  • Thank you so much! It's indeed a silly bug and a clever fix. I'll be doing some testing very soon but I think I can confirm for the y value already. Cheers! – Mathieu Dec 28 '11 at 20:23
  • After a few tests the answer is not that simple. The "trick" still works though but you sometimes have to apply it to the control point and sometimes to the end point. You also seem to have to change the amount you add depending on the gap between the related points. And finally the condition to add seems to depend on the movement (x1 > x2 and x3 < x2 for instance). I have to investigate more. But if you have a new lead again, you would be even more awesome (if that's possible :D)! – Mathieu Dec 28 '11 at 22:44
  • I will see if I can figure out the formal conditions for the weirdness, at least so we can have a detailed bug to submit – Simon Sarris Dec 28 '11 at 22:47