我正在使用纸张JS在画布上创建一个矩形。以下是在vue.js中绘制矩形的代码。
created () {
const toolDrag = event => {
let trackingRect = new paper.Path.Rectangle(event.downPoint, event.point)
trackingRect.strokeColor = new paper.Color('#2661D8')
trackingRect.strokeColor.alpha = 0.7
trackingRect.strokeWidth = this.strokeWidth
trackingRect.removeOn({
drag: true,
up: true
})
}
// Finalise rectangle properties and draw.
let $this = this;
const toolUp = event => {
let newRect = new paper.Path.Rectangle(event.downPoint, event.point)
newRect.strokeColor = new paper.Color(this.getColor().stroke)
newRect.fillColor = new paper.Color(this.getColor().fill)
newRect.strokeWidth = this.strokeWidth
newRect.selected = true;
// Custom data attribute:
newRect.data.type = 'rectangle'
newRect.data.class = ''
// Flag the annotation has been edited and the changes are not saved
this.flagAnnotationEdits()
}
this.toolRect = new paper.Tool();
this.toolRect.onMouseDrag = toolDrag;
this.toolRect.onMouseUp = toolUp;
},
现在,我想允许用户通过拖动矩形的任何角来调整绘制的矩形的大小,但是我有点卡住了,无法理解该怎么做。
我已经看到了通过更改边界来调整矩形大小的解决方案,但是找不到我的用例的解决方案。任何帮助表示赞赏。
答案 0 :(得分:1)
有很多方法可以实现您想要的。
我发现的最简单的方法之一是,每次拖动矩形的一个角时都重新创建矩形。
这样,您只需要知道拖动的角位置和对角位置,就可以轻松创建合适的矩形。
这是sketch,演示了可能的实现。
我认为您应该可以轻松地将其转换为您的特定案例。
// This settings controls the handles size.
const HANDLES_RADIUS = 5;
// This flag allow us to know when we are dragging an handle.
let dragging = false;
// This will store the offset from the handle position to the
// mouse down point. This allow a better drag UX.
let offset;
// This will store the point representing the opposite rectangle corner from
// the one being dragged.
let oppositePoint;
// We start by creating a rectangle in the middle of the canvas.
// This rectangle will be replaced each time a corner is dragged.
let rectangle = createRectangle(view.center - 50, view.center + 50);
// Then, we create an handle for each of the corners.
// These will be used to modify the rectangle shape.
const handles = rectangle.segments.map((segment, index) => new Path.Rectangle({
from: segment.point - HANDLES_RADIUS,
to: segment.point + HANDLES_RADIUS,
fillColor: 'orange',
// We store the segment index bound to this specific handle in the custom
// data object. This will allow us to know, when an handle is clicked,
// which segment is concerned by the event.
data: { segmentIndex: index },
// On mouse down on an handle...
onMouseDown: function(event) {
// ...get and store the opposite segment point.
// We will use it later to redraw the rectangle.
const oppositeSegmentIndex = (this.data.segmentIndex + 2) % 4;
oppositePoint = rectangle.segments[oppositeSegmentIndex].point;
// Store the offset.
offset = event.point - rectangle.segments[this.data.segmentIndex].point;
// Activate dragging state.
dragging = true;
}
}));
// On mouse move...
function onMouseMove(event) {
// ...don't do nothing if we are not dragging an handle.
if (!dragging) {
return;
}
// Get the new corner position by applying the offset to the event point.
const activePoint = event.point + offset;
// Recreate the rectangle with the new corner.
rectangle.remove();
rectangle = createRectangle(oppositePoint, activePoint);
// For each corner...
rectangle.segments.forEach((segment, index) => {
// ...place an handle...
handles[index].position = segment.point;
// ...store the potentially new segment <=> corner bound.
handles[index].data.segmentIndex = index;
});
}
// On mouse up...
function onMouseUp() {
// Disable dragging state
dragging = false;
}
//
// HELPERS
//
// This method is used to avoid duplicating the rectangle instantiation code.
function createRectangle(from, to) {
return new Path.Rectangle({
from,
to,
strokeColor: 'orange'
});
}