Konva.js: [free Drawing & Drag & Zoom] Can't Draw Correctly With Pointer After Drag Or Zoom
Any discussion is welcomed. Thanks for reading! What I am trying to do I'm trying to implement simple paper(whiteboard) using Konva.js. So far I've implemented Drag, Zoom and Free
Solution 1:
stage.getPointerPosition()
returns absolute position of pointer (related top-left corner of canvas container).
As you are transforming (moving and scaling a stage) you need to find a relative position, so you can use it for the line.
Relative mouse position demo demonstrates how to do that:
functiongetRelativePointerPosition(node) {
// the function will return pointer position relative to the passed nodevar transform = node.getAbsoluteTransform().copy();
// to detect relative position we need to invert transform
transform.invert();
// get pointer (say mouse or touch) positionvar pos = node.getStage().getPointerPosition();
// now we find a relative pointreturn transform.point(pos);
}
/* ---- Mode management ---- */let modeSelector = document.getElementById('mode-selector');
let mode = modeSelector.value;
modeSelector.addEventListener('change', () => {
// Discaed event handlers used by old modeswitch (mode) {
case'Hand': {
endHand();
break;
}
case'Pen': {
endPen();
break;
}
}
// Set event handlers for new mode
mode = modeSelector.value;
switch (mode) {
case'Hand': {
useHand();
break;
}
case'Pen': {
usePen();
break;
}
}
});
/* ---- Konva Objects ---- */let stage = newKonva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
// A layer that is only used for background colorlet backgroundLayer = newKonva.Layer();
let backgroundColor = newKonva.Image({
width: window.innerWidth,
height: window.innerHeight,
fill: 'rgb(242,233,226)'
})
backgroundLayer.add(backgroundColor);
stage.add(backgroundLayer);
backgroundLayer.draw();
// A layer for free drawinglet drawLayer = newKonva.Layer();
stage.add(drawLayer);
/* ---- Functions for mode change ----*/functionuseHand () {
// Make stage draggable
stage.draggable(true);
// Make stage zoomable// *** Code is copy and pasted from// *** https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.htmlhttps://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.htmllet scaleBy = 1.3;
stage.on('wheel', (evt) => {
evt.evt.preventDefault();
let oldScale = stage.scaleX();
let mousePointTo = {
x: stage.getPointerPosition().x / oldScale - stage.x() / oldScale,
y: stage.getPointerPosition().y / oldScale - stage.y() / oldScale
};
let newScale = evt.evt.deltaY > 0 ? oldScale * scaleBy : oldScale / scaleBy;
stage.scale({ x: newScale, y: newScale });
let newPos = {
x: -(mousePointTo.x - stage.getPointerPosition().x / newScale) * newScale,
y: -(mousePointTo.y - stage.getPointerPosition().y / newScale) * newScale
};
stage.position(newPos);
stage.batchDraw();
});
}
functionendHand () {
stage.draggable(false);
stage.off('wheel');
}
functiongetRelativePointerPosition(node) {
// the function will return pointer position relative to the passed nodevar transform = node.getAbsoluteTransform().copy();
// to detect relative position we need to invert transform
transform.invert();
// get pointer (say mouse or touch) positionvar pos = node.getStage().getPointerPosition();
// now we find relative pointreturn transform.point(pos);
}
functionusePen () {
let isDrawing = false;
let currentLine;
stage.on('mousedown', (evt) => {
// Start drawing
isDrawing = true;
// Create new line objectlet pos = getRelativePointerPosition(stage);
currentLine = newKonva.Line({
stroke: 'black',
strokeWidth: 3,
points: [pos.x, pos.y]
});
drawLayer.add(currentLine);
});
stage.on('mousemove', (evt) => {
if (!isDrawing) {
return;
}
// If drawing, add new point to the current line objectlet pos = getRelativePointerPosition(stage);
let newPoints = currentLine.points().concat([pos.x, pos.y]);
currentLine.points(newPoints);
drawLayer.batchDraw();
});
stage.on('mouseup', (evt) => {
// End drawing
isDrawing = false;
});
}
functionendPen () {
stage.off('mousedown');
stage.off('mousemove');
stage.off('mouseup');
}
/* ---- Init ---- */useHand();
<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Paper</title></head><body><selectid="mode-selector"><optionvalue="Hand">Hand</option><optionvalue="Pen">Pen</option></select><divid="container"></div><scriptsrc="https://unpkg.com/konva@4.0.0/konva.min.js"></script><!-- <script src="konvaTest.js"></script> --><scriptsrc="buggyPaper.js"></script></body></html>
Post a Comment for "Konva.js: [free Drawing & Drag & Zoom] Can't Draw Correctly With Pointer After Drag Or Zoom"