Konva.js:[自由绘制,拖动和缩放]在拖动或缩放后无法使用指针正确绘制

问题描述 投票:0回答:1

欢迎任何讨论。感谢您的阅读!

我想做什么

我正在尝试使用Konva.js实现简单的纸(白板)。>>

到目前为止,我已经实现了在纸上的拖动,缩放和自由绘制。

我指

  1. https://konvajs.org/docs/sandbox/Zooming_Relative_To_Pointer.html为变焦
  2. https://konvajs.org/docs/sandbox/Free_Drawing.html免费绘图
  3. 我只想在具有米色背景的区域上绘制

,并且即使要缩放或拖动,我也要在指针的正下方绘制。

但是自由绘图以及拖动和缩放功能不能很好地协同工作。

错误

拖动或缩放后无法正确绘制。

我认为发生错误的地方,但无法解决

我认为以下两部分有问题。

  1. 缩放的实现
  2. 我如何在图形实现中使用stage.getPointerPosition()
  3. 或这两个的实现不匹配
  4. 代码

    最小代码在这里。

/* ---- 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/[email protected]/konva.min.js"></script>
  <!-- <script src="konvaTest.js"></script> -->
  <script src="buggyPaper.js"></script>
</body>
</html>

欢迎任何讨论。谢谢阅读!我正在尝试使用Konva.js实现简单的纸张(白板)。到目前为止,我已经在纸上实现了“拖动”,“缩放”和“自由绘制”。 ...

javascript konvajs
1个回答
0
投票

[stage.getPointerPosition()返回指针的绝对位置(画布容器的相关左上角)。

在变换(移动和缩放舞台)时,您需要找到一个相对位置,以便可以将其用于线条。

© www.soinside.com 2019 - 2024. All rights reserved.