Вот простое решение, которое должно вас начать. Он не обрабатывает поворот, потому что я не уверен, как вы представляете, как работает пользовательский интерфейс, но, изменив ограничивающий прямоугольник, чтобы изменить размер прямоугольника, вы можете его без проблем поворачивать.
paperjs sketch
я решил сделать свой собственный пользовательский интерфейс и идти вперед и сделать пример более сложной для решения как много вы спрашиваете, как я могу без дополнительной информации. Вот новый эскиз:
new sketch
Пользовательский интерфейс
- нажмите на прямоугольник, чтобы переместить его с помощью перетаскивания
- нажмите на углу и перетащите, чтобы изменить его размер
- управления щелкните угол поворота
Немного сложно щелкнуть по углам, но это упражнение, оставленное читателю. Они представляют собой цветные круги, чтобы подчеркнуть, где расположена каждая точка сегмента Path
.
Ключевые моменты кода:
Используйте границы прямоугольника масштабирования. Path.Rectangle
не является прямоугольником в отношении бумаги. Это четыре кривые (которые кажутся прямыми), соединяющие четыре точки сегмента. Когда вам нужно работать с прямоугольником, чтобы получить его центр, верхний левый и т. Д., Вам нужен Rectangle
. Масштабируйте видимый прямоугольник, используя границы прямоугольника (Path.Rectangle.bounds
). Код иллюстрирует границы с дополнительным прямоугольником aqua, чтобы он был виден (его легче всего видеть при вращении).
onMouseDown()
устанавливает состояние для onMouseDrag()
и устанавливает данные, необходимые для каждого состояния, например, сохраняет базу шкалы для изменения размера.
onMouseDrag()
осуществляет перемещение, изменение размера и поворот.
tool.onMouseDrag = function(e) { if (rect.data.state === 'moving') { rect.position = rect.position + e.point - e.lastPoint; adjustRect(rect); } else if (rect.data.state === 'resizing') { // scale by distance from down point var bounds = rect.data.bounds; var scale = e.point.subtract(bounds.center).length/ rect.data.scaleBase.length; var tlVec = bounds.topLeft.subtract(bounds.center).multiply(scale); var brVec = bounds.bottomRight.subtract(bounds.center).multiply(scale); var newBounds = new Rectangle(tlVec + bounds.center, brVec + bounds.center);
rect.bounds = newBounds;
adjustRect(rect); } else if (rect.data.state === 'rotating') { // rotate by difference of angles, relative to center, of // the last two points. var center = rect.bounds.center; var baseVec = center - e.lastPoint; var nowVec = center - e.point; var angle = nowVec.angle - baseVec.angle; rect.rotate(angle); adjustRect(rect); } }
Moving довольно легко - просто вычислить разницу между текущими и последними точками из события и изменить положение прямоугольника, что много.
Изменение размера не так очевидно.Стратегия - настроить границы x и y на основе исходного расстояния (scaleBase.length
) между точкой мыши и центром прямоугольника. Обратите внимание, что в то время как paper-full.js позволяет использовать операторы («+», «-», «*», «/») с точками, я несколько раз использовал необработанные методы и multiply()
- я нахожу естественным цепочку расчеты таким образом.
Вращение использует очень приятную концепцию бумаги, что точка также определяет вектор, а вектор имеет угол. Он просто отмечает разницу в углах между событием lastPoint
и point
относительно центра прямоугольника и поворачивает прямоугольник по этой разности.
moveCircles()
и adjustRect()
- это просто функции бухгалтерского учета для обновления угловых кругов и прямоугольника aqua.