Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

canvas画板 #372

Open
klren0312 opened this issue Jan 25, 2021 · 5 comments
Open

canvas画板 #372

klren0312 opened this issue Jan 25, 2021 · 5 comments
Labels
JS js相关问题

Comments

@klren0312
Copy link
Owner

klren0312 commented Jan 25, 2021

@klren0312 klren0312 added the JS js相关问题 label Jan 25, 2021
@klren0312
Copy link
Owner Author

klren0312 commented Jan 25, 2021

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      padding: 0;
      margin: 0;
      height: 100vh;
      overflow: hidden;
    }
    .canvas-block {
      position: relative;
      width: 100%;
      height: 200px;
    }
    #canvas,
    #canvas2 {
      position: absolute;
      top: 0;
      left: 0;
    }
    #canvas {
      z-index: 1;
    }
  </style>
</head>
<body>
  <div class="canvas-block">
    under
    <canvas id="canvas" width="400" height="200"></canvas>
    <canvas id="canvas2" width="400" height="200"></canvas>
  </div>
  <button onclick="undoHandle()">undo</button>
  <script>
    let historyList = []

    const canvas = document.getElementById('canvas')
    const ctx = canvas.getContext('2d')
    let width = canvas.width
    let height = canvas.height
    if (window.devicePixelRatio) {
      canvas.style.width = width + 'px'
      canvas.style.height = height + 'px'
      canvas.height = height * window.devicePixelRatio
      canvas.width = width * window.devicePixelRatio
      ctx.scale(window.devicePixelRatio, window.devicePixelRatio)
    }
    canvas.getContext('2d').imageSmoothingEnabled = true
    let lineWidth = 3
    let lineColor = '#fff'
    let painting = false

    canvas.onmousedown = e => {
      painting = true
      const event = e || window.event
      ctx.lineCap = 'round'
      ctx.lineJoin = 'round'
      const x = event.offsetX
      const y = event.offsetY
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineWidth = lineWidth
      ctx.strokeStyle = lineColor
    }

    canvas.onmousemove = e => {
      if (!painting) {
        return
      }
      const event = e || window.event
      const x = event.offsetX
      const y = event.offsetY
      ctx.lineTo(x, y)
      ctx.stroke()
    }

    canvas.onmouseup = () => {
      if (!painting) {
        return false
      }
      painting = false
      historyList.push(ctx.getImageData(0, 0, canvas.width, canvas.height))
      ctx.closePath()
    }

    canvas.onmouseleave = () => {
      if (!painting) {
        return false
      }
      painting = false
      historyList.push(ctx.getImageData(0, 0, canvas.width, canvas.height))
      ctx.closePath()
    }

    canvas.ontouchstart = e => {
      console.log(e.touches)
      painting = true
      const event = e.touches[0]
      ctx.lineCap = 'round'
      ctx.lineJoin = 'round'
      const x = event.pageX
      const y = event.pageY
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineWidth = lineWidth
      ctx.strokeStyle = lineColor
    }

    canvas.ontouchmove = e => {
      if (!painting) {
        return
      }
      const event = e.touches[0]
      const x = event.pageX
      const y = event.pageY
      ctx.lineTo(x, y)
      ctx.stroke()
    }

    canvas.ontouchend = () => {
      if (!painting) {
        return false
      }
      painting = false
      historyList.push(ctx.getImageData(0, 0, canvas.width, canvas.height))
      ctx.closePath()
    }

    ontouchcancel = () => {
      if (!painting) {
        return false
      }
      painting = false
      historyList.push(ctx.getImageData(0, 0, canvas.width, canvas.height))
      ctx.closePath()
    }
    const canvas2 = document.getElementById('canvas2')
    const ctx2 = canvas2.getContext('2d')
    ctx2.globalAlpha = 0.3
    ctx2.fillStyle = '#000000'
    ctx2.fillRect(0, 0, 400, 400);
  </script>
  <script>
    function undoHandle() {
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      try {
        historyList.pop()
        const history = historyList[historyList.length - 1]
        if (history) {
          ctx.putImageData(history, 0, 0)
        } else {
          ctx.clearRect(0, 0, canvas.width, canvas.height)   
        }
      } catch (error) {
        ctx.clearRect(0, 0, canvas.width, canvas.height)  
      }
    }
  </script>
</body>
</html>

@klren0312
Copy link
Owner Author

klren0312 commented Feb 4, 2021

使用pointerevent

可以捕捉鼠标, 手指, 笔等

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" 
	content="
		width=device-width,
		initial-scale=1.0,
		minimum-scale=1.0,
		maximum-scale=1.0,
		user-scalable=no">
  <title>Document</title>
  <style>
    body {
      padding: 0;
      margin: 0;
      overflow: hidden;
      height: 100vh;
    }
    .canvas-block {
      position: relative;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    #canvas {
      position: absolute;
      top: 0;
      left: 0;
      touch-action: none;
      cursor: crosshair;
    }
  </style>
</head>
<body>
  <div class="canvas-block">
    <canvas id="canvas"></canvas>
  </div>
  <button onclick="undoHandle()">undo</button>
  <script>
    let historyList = []

    const canvas = document.getElementById('canvas')
    const ctx = canvas.getContext('2d')
    let width = window.innerWidth
    let height = window.innerHeight
    if (window.devicePixelRatio) {
      canvas.style.width = width + 'px'
      canvas.style.height = height + 'px'
      canvas.height = height * window.devicePixelRatio
      canvas.width = width * window.devicePixelRatio
      ctx.scale(window.devicePixelRatio, window.devicePixelRatio)
    }
    ctx.imageSmoothingEnabled = true
    let lineWidth = 3
    let lineColor = '#000'
    let painting = false

    canvas.onpointerdown = e => {
      console.log('start', e.pointerType, e.pressure, e.shiftKey)
      painting = true
      const event = e || window.event
      ctx.lineCap = 'round'
      ctx.lineJoin = 'round'
      const x = event.offsetX
      const y = event.offsetY
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineWidth = getLineWidth(e)
      ctx.strokeStyle = lineColor
    }

    canvas.onpointermove = e => {
      if (!painting) {
        return
      } else {
        console.log('move', e.pointerType, e.pressure, e.shiftKey)
        const event = e || window.event
        const x = event.offsetX
        const y = event.offsetY
        ctx.lineWidth = getLineWidth(e)
        ctx.lineTo(x, y)
        ctx.stroke()
      }
    }

    canvas.onpointerup = e => {
      pointerCancel()
    }

    canvas.onpointerleave = e => {
      pointerCancel()
    }

    function pointerCancel () {
      if (!painting) {
        return false
      }
      painting = false
      historyList.push(ctx.getImageData(0, 0, canvas.width, canvas.height))
      ctx.closePath()
    }

    var getLineWidth = e => {
      switch (e.pointerType) {
        case 'touch': {
          if (e.width < 10 && e.height < 10) {
            return (e.width + e.height) * 2 + 10;
          } else {
            return (e.width + e.height - 40) / 2;
          }
        }
        case 'pen': return e.pressure * 8;
        default: return (e.pressure) ? e.pressure * 8 : 4;
      }
    }
  </script>
  <script>
    function undoHandle() {
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      try {
        historyList.pop()
        const history = historyList[historyList.length - 1]
        if (history) {
          ctx.putImageData(history, 0, 0)
        } else {
          ctx.clearRect(0, 0, canvas.width, canvas.height)   
        }
      } catch (error) {
        ctx.clearRect(0, 0, canvas.width, canvas.height)  
      }
    }
  </script>
</body>
</html>

参考资料

#377

@klren0312
Copy link
Owner Author

@klren0312
Copy link
Owner Author

#377

@klren0312
Copy link
Owner Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JS js相关问题
Projects
None yet
Development

No branches or pull requests

1 participant