HTML5 Canvas - неожиданный эффект с квадратичными кривыми
Недавно я работал над приложением для рисования просто ради удовольствия. Попробовав множество методов для рисования гладких кривых с помощью точек выборки, заданных мышью, я остановился на чем-то, используя Quadratic Curve.
Я должен признать, что мое понимание этих кривых не является оптимальным, но я думаю, что понял, как они работают. Чего я не могу понять, так это того, что когда я рисую кривую, которая поднимается, а затем внезапно падает, пик кривой больше не округляется (он выглядит сплюснутым).
Демо гораздо лучше понять, о чем я говорю: ссылка на песочницу JCanvas
Если вы удалите последнюю часть кривой (от cx11 до y15): ссылка на другую песочницу JCanvas. Это выглядит хорошо, но когда вы добавляете следующую контрольную точку и конечную точку, вы получаете этот странный эффект.
Примечание: я не использую JCanvas, но у него та же ошибка, и песочница удобна. Я предполагаю, что это происходит от координат, которые я получаю, но я не могу объяснить и не могу найти обходной путь / хак, чтобы он выглядел округлым...
Для тех, кто не может быть обеспокоен с песочницей, вот краткая версия координат, которые вызывают проблему:
x1: 216, y1: 98, cx1: 216, cy1: 97, x2: 216, y2: 98, cx2: 216, cy2: 99, x3: 215, y2: 103,
Есть идеи, почему? Математические вещи приветствуются. Я немного искал и читал о проблеме, но ничего подобного не нашел.
-
Обновить
Как отметил Саймон, я использую Chrome 16, и я протестировал пример с Firefox 4 и последним Safari, и ошибка есть. Я пробовал с Opera, и это выглядит нормально.
Я довольно разочарован этим, поскольку ошибка также есть на iPad, и я пытался создать мобильное веб-приложение, поэтому я застрял.
Есть идеи для обхода / взлома?
1 ответ
Нашел обходной путь. Это одна из тех глупых ошибок типа "бла-подход-ноль", я не знаю, как их правильно назвать. Сложно закруглить угол, если связь между двумя точками представляет собой очень крошечную вертикальную линию и Safari запутывается.
В месте вашей проблемы есть кривая вертикальной линии высотой 1 пиксель, которую необходимо округлить.
Если пункт назначения X идентичен между одной квадратичной кривой и следующей, Safari доставит вам проблемы. Так что это плохо
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();
Смотрите это здесь: http://jsfiddle.net/Ws6UY/
Так что, если мы просто изменим это значение на крошечную сумму:
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();
Смотрите это здесь: http://jsfiddle.net/Ws6UY/1/
Как глупо! Все, что вам нужно сделать, чтобы браузеры Safari/iOS работали, это убедиться, что значения x (и, вероятно, y) не совпадают с последней точкой.