2013-10-09 1 views
12

Я собираю информацию о проекте, который должен начаться через несколько недель. Этот проект содержит инструмент рисования на основе браузера, в котором пользователи могут добавлять предопределенные формы или сами формировать фигуры. Формы должны выбираться, свободно масштабироваться и поворачиваться с помощью Illustrator-подобного transformtool (ручки). Предопределенные формы, которые мы имеем в виду: прямоугольники, эллипсы, полуэллипсы и (равнобедренные) треугольники.Применение закругленных углов к дорожкам/полигонам

До сих пор так хорошо, для этого я думал о RaphaelJS или FabricJS, но ... Каждая фигура (полигон/путь) должна быть нарисована с помощью определенного угла. И cornerradius должен поддерживаться при масштабировании, поэтому никаких искажений не возникает. Пользователь может указать округление по входам.

Там в несколько препятствий/вопросы:

  • есть какой-то равномерная mathemetical формула применить cornerradius к формам, которые я упоминал? Или каждая форма должна рассматриваться как сам мини-проект? Я хочу вернуть его как путь или поли, поэтому его можно нарисовать с помощью SVG или холста.
  • Каждая операция масштабирования или поворота, перетаскивая манипуляторы преобразования, приведет к (массивным) вычислениям для получения обновленной формы, я думаю. Прямоугольники являются самыми легкими для достижения и, кроме эллипсов, все остальные формы будут намного сложнее вычислять. Есть ли способ ускорить процесс?

Я нашел сайт, на котором пользователи могут рисовать блок-схемы и применять краеугольный камень практически на всех фигурах. Он работает так гладко, я не могу прибить, как они это сделали. Ссылка: https://www.lucidchart.com/ (кнопка try)

На данный момент, я немного невежественный, я думаю, что это посредственно в математике. Может быть, кто-то может подтолкнуть меня в правильном направлении и поделиться опытом?

Заранее спасибо.

BTW. Производительность является ключевым в этом проекте. Вывод чертежа должен быть SVG-форматом.

ответ

1

Отправной точкой может быть using-svg-curves-to-imitate-rounded-corners. Принцип состоит в том, чтобы преобразовать каждый угол с сокращенной относительной кубической (ыми). Этот пример очень прост и работает только с двумя возможными угловыми случаями.

Я думаю, что расширение этого, как и замена угла, сокращением относительной кубики можно расширить, чтобы покрыть и другие сегменты пути. Каждый сегмент имеет координатную точку на кривой, которая должна быть заменена сегментом s. Математика может быть интересной частью этого решения.

27

У меня возникла аналогичная проблема, и я не смог найти простое решение. В итоге я написал довольно общую функцию округления углов, основанную на работе Adobe Illustrator. Он использует кривые Безье вместо дуг, но я думаю, что результат довольно приличный.

Он поддерживает округление с радиусом, заданным в координатном пространстве изображения SVG, или как часть расстояния между углом и его соседями.

Чтобы использовать это, включите округление.JS в вашем проекте и вызовите функцию:

roundPathCorners(pathString, radius, useFractionalRadius) 

код и некоторые тестовые пути здесь: http://embed.plnkr.co/kGnGGyoOCKil02k04snu/preview

Это как примеры из Plnkr визуализации:

SVG Path Rounding Examples

1

Несмотря на этот вопрос находится в течение некоторого времени, некоторые могут остановиться и попробовать это решение:

var BORDER_RADIUS = 20; 

function roundedPath(/* x1, y1, x2, y2, ..., xN, yN */){ 
    context.beginPath(); 
    if (!arguments.length) return; 

    //compute the middle of the first line as start-stop-point: 
    var deltaY = (arguments[3] - arguments[1]); 
    var deltaX = (arguments[2] - arguments[0]); 
    var xPerY = deltaY/deltaX; 
    var startX = arguments[0] + deltaX/2; 
    var startY = arguments[1] + xPerY * deltaX/2; 

    //walk around using arcTo: 
    context.moveTo(startX, startY); 
    var x1, y1, x2, y2; 
    x2 = arguments[2]; 
    y2 = arguments[3]; 
    for (var i = 4; i < arguments.length; i += 2) { 
     x1 = x2; 
     y1 = y2; 
     x2 = arguments[i]; 
     y2 = arguments[i + 1]; 
     context.arcTo(x1, y1, x2, y2, BORDER_RADIUS); 
    } 

    //finally, close the path: 
    context.arcTo(x2, y2, arguments[0], arguments[1], BORDER_RADIUS); 
    context.arcTo(arguments[0], arguments[1], startX, startY, BORDER_RADIUS); 
    context.closePath(); 
} 

Уловка заключается в том, чтобы начать (и остановить) в середине первой строки, а затем использовать функцию arcTo, которая описана очень хорошо here.

Теперь вы «просто» должны найти способ выразить все ваши фигуры как полигоны.

+0

Что такое контекст? –

+0

'context' обозначает [CanvasRenderingContext2D] (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D) –