I am using Konva.js for the annotation of data visualizations in the browser. A common use case is to draw lines between a shape (rectangle, ellipse) and its description (a text node). Lines need to be dragged, rotated and resized by users. Resizing is limited to line width.
Lines and their transformers are currently being added as follows:
var line = new Konva.Line({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
points: [0, 0, 100, 0],
stroke: '#000',
strokeWidth: 3,
lineCap: 'round',
lineJoin: 'round',
draggable: true,
id: id,
strokeScaleEnabled: false,
hitStrokeWidth: 15
});
layer.add(line);
var tr = new Konva.Transformer({
node: line,
enabledAnchors: ['middle-left', 'middle-right']
});
layer.add(tr);
Correctly positioning a line is not very intuitive at the moment since it requires a user to separately rotate and resize the line using the rotate, middle-left and middle-right anchors.
Instead, I'm looking for a way to use the middle-left and middle-right anchors to rotate and resize a line at the same time. My inspiration for this is PowerPoint - lines only have anchors on both ends which can be used to resize and rotate at the same time:
I've tried combining the rotater and middle-left/middle-right functionality in Konva's Transformer _handleMouseMove function, but this does not work as expected.
Has anyone perhaps found a way to use the left and right anchors to do both things at the same time?
At the current moment, I don't recommend to use Konva.Transformer
for a simple line. It is simple to build a custom solution with a couple of circles:
const line = new Konva.Line({
points: [50, 50, 250, 50],
stroke: 'green'
});
layer.add(line);
const anchor1 = new Konva.Circle({
x: line.points()[0],
y: line.points()[1],
radius: 10,
fill: 'red',
draggable: true
})
layer.add(anchor1);
const anchor2 = new Konva.Circle({
x: line.points()[2],
y: line.points()[3],
radius: 10,
fill: 'red',
draggable: true
})
layer.add(anchor2);
function updateLine() {
const points = [
anchor1.x(),
anchor1.y(),
anchor2.x(),
anchor2.y(),
]
line.points(points);
layer.batchDraw();
}
anchor1.on('dragmove', updateLine);
anchor2.on('dragmove', updateLine);