欢迎任何讨论。感谢您的阅读!
我想做的是
我正在尝试使用Konva.js实现简单的纸张(白板)。
到目前为止,我已经在纸上实现了拖动、缩放和自由绘图。
我指的是
我只想在带米色背景的区域上绘图,而则希望精确地在指针下面绘制,即使它是缩放或拖动的。
但是自由绘图和拖动和缩放功能并不能很好地结合在一起。
错误
拖动或缩放后无法正确绘制。
我认为错误的事情正在发生,但却无法修复
我认为下面两个部分有问题。
代码
最低限度代码在这里。
/* ---- Mode management ---- */
let modeSelector = document.getElementById('mode-selector');
let mode = modeSelector.value;
modeSelector.addEventListener('change', () => {
// Discaed event handlers used by old mode
switch (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 = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
// A layer that is only used for background color
let backgroundLayer = new Konva.Layer();
let backgroundColor = new Konva.Image({
width: window.innerWidth,
height: window.innerHeight,
fill: 'rgb(242,233,226)'
})
backgroundLayer.add(backgroundColor);
stage.add(backgroundLayer);
backgroundLayer.draw();
// A layer for free drawing
let drawLayer = new Konva.Layer();
stage.add(drawLayer);
/* ---- Functions for mode change ----*/
function useHand () {
// 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.html
let 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();
});
}
function endHand () {
stage.draggable(false);
stage.off('wheel');
}
function usePen () {
let isDrawing = false;
let currentLine;
stage.on('mousedown', (evt) => {
// Start drawing
isDrawing = true;
// Create new line object
let pos = stage.getPointerPosition();
currentLine = new Konva.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 object
let pos = stage.getPointerPosition();
let newPoints = currentLine.points().concat([pos.x, pos.y]);
currentLine.points(newPoints);
drawLayer.batchDraw();
});
stage.on('mouseup', (evt) => {
// End drawing
isDrawing = false;
});
}
function endPen () {
stage.off('mousedown');
stage.off('mousemove');
stage.off('mouseup');
}
/* ---- Init ---- */
useHand();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paper</title>
</head>
<body>
<select id="mode-selector">
<option value="Hand">Hand</option>
<option value="Pen">Pen</option>
</select>
<div id="container"></div>
<script src="https://unpkg.com/konva@4.0.0/konva.min.js"></script>
<!-- <script src="konvaTest.js"></script> -->
<script src="buggyPaper.js"></script>
</body>
</html>
发布于 2020-03-14 05:00:40
stage.getPointerPosition()
返回指针的绝对位置(相关的画布容器左上角)。
当您正在转换(移动和缩放一个舞台)时,您需要找到一个相对位置,这样您就可以将其用于线路。
相对鼠标位置演示演示了如何做到这一点:
function getRelativePointerPosition(node) {
// the function will return pointer position relative to the passed node
var transform = node.getAbsoluteTransform().copy();
// to detect relative position we need to invert transform
transform.invert();
// get pointer (say mouse or touch) position
var pos = node.getStage().getPointerPosition();
// now we find a relative point
return transform.point(pos);
}
/* ---- Mode management ---- */
let modeSelector = document.getElementById('mode-selector');
let mode = modeSelector.value;
modeSelector.addEventListener('change', () => {
// Discaed event handlers used by old mode
switch (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 = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
});
// A layer that is only used for background color
let backgroundLayer = new Konva.Layer();
let backgroundColor = new Konva.Image({
width: window.innerWidth,
height: window.innerHeight,
fill: 'rgb(242,233,226)'
})
backgroundLayer.add(backgroundColor);
stage.add(backgroundLayer);
backgroundLayer.draw();
// A layer for free drawing
let drawLayer = new Konva.Layer();
stage.add(drawLayer);
/* ---- Functions for mode change ----*/
function useHand () {
// 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.html
let 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();
});
}
function endHand () {
stage.draggable(false);
stage.off('wheel');
}
function getRelativePointerPosition(node) {
// the function will return pointer position relative to the passed node
var transform = node.getAbsoluteTransform().copy();
// to detect relative position we need to invert transform
transform.invert();
// get pointer (say mouse or touch) position
var pos = node.getStage().getPointerPosition();
// now we find relative point
return transform.point(pos);
}
function usePen () {
let isDrawing = false;
let currentLine;
stage.on('mousedown', (evt) => {
// Start drawing
isDrawing = true;
// Create new line object
let pos = getRelativePointerPosition(stage);
currentLine = new Konva.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 object
let 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;
});
}
function endPen () {
stage.off('mousedown');
stage.off('mousemove');
stage.off('mouseup');
}
/* ---- Init ---- */
useHand();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paper</title>
</head>
<body>
<select id="mode-selector">
<option value="Hand">Hand</option>
<option value="Pen">Pen</option>
</select>
<div id="container"></div>
<script src="https://unpkg.com/konva@4.0.0/konva.min.js"></script>
<!-- <script src="konvaTest.js"></script> -->
<script src="buggyPaper.js"></script>
</body>
</html>
https://stackoverflow.com/questions/60680088
复制