Любая дискуссия приветствуется. Спасибо за чтение!
Что я пытаюсь сделать
Я пытаюсь реализовать простую бумагу (доску), используя Konva. js.
Итак До сих пор я реализовал Drag, Zoom и Free рисование на бумаге.
Я ссылался на
- https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html для Zoom
- https://konvajs.org/docs/sandbox/Free_Drawing.html для свободного рисования
Я хочу рисовать только на области с бежевым цветным фоном , а Я хочу рисовать точно под указатель, даже если он увеличен или перетащен.
Но функции «Свободное рисование» и «Перетаскивание» и «Масштаб» не работают вместе.
Ошибка
Не может рисовать правильно после перетаскивания или масштабирования.
Там, где я думаю, что происходит что-то не так, но не могу исправить
Я думаю, что что-то не так в 2 частях ниже.
- Реализация увеличения
- Как я использую stage.getPointerPosition () в реализации чертежа
- Или реализации этих двух не совмещается
Код
Минимальный код здесь.
/* ---- 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>