为啥我无法在画布上正确绘制 [重复]

Posted

技术标签:

【中文标题】为啥我无法在画布上正确绘制 [重复]【英文标题】:Why am I not able to draw properly on canvas [duplicate]为什么我无法在画布上正确绘制 [重复] 【发布时间】:2020-02-19 17:19:49 【问题描述】:

我正在开发一个绘画应用程序。当我将画板放置在屏幕的左侧时,我能够正确绘制。但是当我将它放在屏幕的右侧时,鼠标不会在它所在的位置绘制,而是在它右侧 100 px 之外。我开发了一个拖动功能,它可以让我将绘图应用程序的窗口拖动到屏幕中的不同位置。我正在使用香草 javascript 和自定义元素。

const template = document.createElement('template')
template.innerhtml = `
<head>
<link rel="stylesheet" href="../css/paint-board.css">
</head>
<div id="board">
<div class="navbar">
<img id="pic" src="../image/tools.png"  />
<img id="close" src="../image/error.png"  />
</div>
<div id="bucketDiv" class="colour">
<img id="bucket" src="../image/paint-bucket.png"  />
</div>
</div>
<div id="paint">
<canvas id="canvasDrawing">
</canvas>
</div>
</div>
`
export class PaintBoard extends window.HTMLElement 
  constructor () 
    super()
    this.attachShadow( mode: 'open' )
    this.shadowRoot.appendChild(template.content.cloneNode(true))
    this.x = 0
    this.y = 0
    window.colour = 'black'
    const canvas = this.shadowRoot.querySelector('#canvasDrawing')
    window.ctx = canvas.getContext('2d')
  

  connectedCallback () 
    this.initialize()
    this.closeWindow()
    this.changeColour()
    this.changeLineWidth()
    this.changeBackground()
  

  closeWindow () 
    const close = this.shadowRoot.querySelector('#board')
    close.addEventListener('click', event => 
      if (event.target === this.shadowRoot.querySelector('#close')) 
        close.classList.add('removed')
      
    )
  

  // intialize drawing on the board
  initialize () 
    const paintingBoard = this.shadowRoot.querySelector('#paint')
    this.size()
    paintingBoard.addEventListener('mousemove', event => 
      event.stopImmediatePropagation()
      this.draw(event)
    )
    paintingBoard.addEventListener('mousedown', event => 
      event.stopImmediatePropagation()
      this.setPosition(event)
    )
    paintingBoard.addEventListener('mouseenter', event => 
      this.setPosition(event)
    )
    dragElement(this.shadowRoot.querySelector('#board'))
  

  draw (e) 
    if (e.buttons !== 1) return // if mouse is pressed.....
    window.ctx.beginPath() // begin the drawing path
    window.ctx.lineCap = 'round' // rounded end cap
    window.ctx.strokeStyle = window.colour // hex color of line
    window.ctx.moveTo(this.x, this.y) // from position
    this.x = e.clientX
    this.y = e.clientY
    window.ctx.lineTo(this.x, this.y) // to position
    window.ctx.stroke() // draw it!
  

  // size canvas
  size () 
    window.ctx.canvas.width = 750
    window.ctx.canvas.height = 510
  

  // new position from mouse events
  setPosition (e) 
    this.x = e.clientX
    this.y = e.clientY
  

【问题讨论】:

看起来您正在根据视口捕获鼠标坐标位置。为了获得相对于画布的绘图上下文的鼠标位置,您需要从鼠标的 x 和 y 位置(相对于视口)中减去画布的 x 和 y 位置(相对于视口)。 @sean 我应该在 setPosition() 函数中这样做吗? 有人可以帮忙吗? 【参考方案1】:
// where canvas is your canvas element
const rect = canvas.getBoundingClientRect();
this.x = e.pageX - window.pageXOffset - rect.left;
this.y = e.pageY - window.pageYOffset - rect.top;

为我工作,希望它对你有用。

e.pageX/e.pageY 将为您获取鼠标在整个页面上的坐标。

window.pageXOffset/window.pageYOffset 将为您提供用户到目前为止滚动的数量。

rect.left/rect.top 将为您提供canvas 元素左上角的坐标

e.pageY - window.pageYOffset = 鼠标在窗口中的位置

e.pageY - window.pageYOffset - rect.top = 鼠标在画布中的位置

【讨论】:

以上是关于为啥我无法在画布上正确绘制 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

我无法获得连续的画布矩形在js中具有重复的线性渐变。谁知道怎么样?

在 HTML5 画布上绘制一个点 [重复]

无法在画布上绘制垂直虚线

将图像添加到画布 [重复]

Java jFrame画布绘制点而不是线条

在javascript画布上的椭圆内剪切线[重复]