david2tdw / blog

学习记录
1 stars 1 forks source link

[canvas] Canvas拖动交互 #182

Open david2tdw opened 4 years ago

david2tdw commented 4 years ago
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>canvas drag</title>
    <style>
      canvas {
        cursor: pointer;
        border: 1px solid #008080;
      }
    </style>
    <script>
      // 这个方法用来储存每个圆圈对象
      function Circle(x, y, radius, color) {
        this.x = x
        this.y = y
        this.radius = radius
        this.color = color
      }

      // 保存画布上所有的圆圈
      var circles = []
      var canvas
      var context

      var isDraging = false
      let previousSelectedCircle

      window.onload = function () {
        canvas = document.getElementById('canvas')
        context = canvas.getContext('2d')

        canvas.onmousedown = canvasClick
        canvas.onmouseup = stopDragging
        canvas.onmouseout = stopDragging
        canvas.onmousemove = dragCircle
      }

      // 在某个范围内生成随机数
      function randomFromTo(from, to) {
        return Math.floor(Math.random() * (to - from + 1) + from)
      }

      function addRandomCircle() {
        // 为圆圈计算一个随机大小和位置
        let radius = randomFromTo(10, 60)
        let x = randomFromTo(0, canvas.width)
        let y = randomFromTo(0, canvas.height)

        // 为圆圈计算一个随机颜色
        const colors = ['green', 'blue', 'red', 'yellow', 'magenta', 'orange', 'brown', 'purple', 'pink']
        let color = colors[randomFromTo(0, 8)]
        console.log(color)
        // 创建一个新圆圈
        let circle = new Circle(x, y, radius, color)

        // 把它保存在数组中
        circles.push(circle)

        // 重新绘制画布
        drawCircles()
      }

      function clearCanvas() {
        // 去除所有圆圈
        circles = []
        // 重新绘制画布
        drawCircles()
      }

      function drawCircles() {
        // 清除画布,准备绘制
        context.clearRect(0, 0, canvas.width, canvas.height)

        for (let i = 0; i < circles.length; i++) {
          let circle = circles[i]
          //绘制圆圈

          context.globalAlpha = 0.85
          context.beginPath()
          context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2)
          context.fillStyle = circle.color
          context.strokeStyle = 'black'
          if (circle.isSelected) {
            context.lineWidth = 5
          } else {
            context.lineWidth = 1
          }
          context.fill()
          context.stroke()
        }
      }

      function canvasClick(event) {
        //取得画布上被单击的点
        let clickX = event.pageX - canvas.offsetLeft
        let clickY = event.pageY - canvas.offsetTop

        // 查找被单击的圆圈
        // 后添加的圆层级高,所以要倒过来循环查找, 否则在覆盖的时候会出现层级错误问题!!!
        for (let i = circles.length - 1; i >= 0; i--) {
          let circle = circles[i]
          // 使用勾股定理计算这个点与圆心之间的距离
          let distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2))

          // 判断这个点是否在圆圈中
          if (distanceFromCenter <= circle.radius) {
            // 清除之前选择的圆圈
            if (previousSelectedCircle != null) {
              previousSelectedCircle.isSelected = false
            }
            // 选择新圆圈
            previousSelectedCircle = circle
            circle.isSelected = true

            // 使圆圈允许拖拽
            isDraging = true

            // 更新显示
            drawCircles()
            // return 停止搜索
            return
          }
          console.log(i)
        }
      }

      function stopDragging() {
        isDraging = false
      }

      function dragCircle(event) {
        // 判断圆圈是否开始拖拽
        if (isDraging === true) {
          // 判断拖拽对象是否存在
          if (previousSelectedCircle != null) {
            // 取得鼠标位置
            let x = event.pageX - canvas.offsetLeft
            let y = event.pageY - canvas.offsetTop

            // 将圆圈移动到鼠标位置
            previousSelectedCircle.x = x
            previousSelectedCircle.y = y

            // 更新画布
            drawCircles()
          }
        }
      }
    </script>
  </head>
  <body>
    <canvas id="canvas" width="400" height="300"></canvas>

    <div>
      <button onclick="addRandomCircle()">添加圆圈</button>
      <button onclick="clearCanvas()">清空画布</button>
    </div>
  </body>
</html>

HTML5 - Canvas的使用样例14(图形增加鼠标点击、拖动交互)