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

Canvas是一种非保留性的绘图界面,即不会记录过去执行的绘图操作,而是保持最终结果(构成图像的彩色像素)。
如果想让Canvas变得具有交互性,比如用户可以选择、拖动画布上的图形。那么我们必须记录绘制的每一个对象,才能在将来灵活的修改并重绘它们,实现交互。

1,鼠标点击选择图形对象
(1)下面样例中点击“添加圆圈”按钮可以在画布上增加位置、大小、颜色都是随机的圆圈。
(2)点击“清空画布”按钮可以清除画布上所有圆圈。
(3)鼠标点击任意圆圈,该圆圈会出现黑色边框,表示选中。
添加圆圈 清空画布

代码说明:
(1)为了能够将圆圈对象保存起来,我们定义了一个叫 Circle() 的函数类创建自定义对象。同时要让这个对象能够保持数据,要使用关键字 this 来创建属性。
(2)drawCircles() 函数用来根据当前圆圈的集合来填充画布。每次程序刷新画布时,会先使用 clearRect() 方法清除画布上的所有内容。但不用当心这样会造成画布闪烁,即画布上的圆圈一下子全部消失,然后一下子又重新出现。
因为Canvas针对这个问题进行了优化,会在所有绘图逻辑执行完毕后才清除或绘制所有内容,保证最终结果的流畅。
(3)要实现鼠标选中某个图像,就要用到碰撞检测。即计算鼠标点击的那个点是否落在某个形状里。对于圆圈而言,只要计算单击点与圆心的直线距离即可。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>hangge.com</title>
 
 <style>
     canvas {
       cursor: pointer;
       border: 1px solid black;
     }
 </style>
 <script>
    // 这个方法用来储存每个圆圈对象
    function Circle(x, y, radius, color) {
      this.x = x;
      this.y = y;
      this.radius = radius;
      this.color = color;
      this.isSelected = false;
    }
 
    // 保存画布上所有的圆圈
    var circles = [];
 
    var canvas;
    var context;
 
    window.onload = function() {
      canvas = document.getElementById("canvas");
      context = canvas.getContext("2d");
 
      canvas.onmousedown = canvasClick;
    };
 
    function addRandomCircle() {
      // 为圆圈计算一个随机大小和位置
      var radius = randomFromTo(10, 60);
      var x = randomFromTo(0, canvas.width);
      var y = randomFromTo(0, canvas.height);
 
      // 为圆圈计算一个随机颜色
      var colors = ["green", "blue", "red", "yellow", "magenta", "orange", "brown", "purple", "pink"];
      var color = colors[randomFromTo(0, 8)];
 
      // 创建一个新圆圈
      var 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(var i=0; i<circles.length; i++) {
        var 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();
      }
    }
 
    var previousSelectedCircle;
 
    function canvasClick(e) {
      // 取得画布上被单击的点
      var clickX = e.pageX - canvas.offsetLeft;
      var clickY = e.pageY - canvas.offsetTop;
 
      // 查找被单击的圆圈
      for(var i=circles.length-1; i>=0; i--) {
        var circle = circles[i];
        //使用勾股定理计算这个点与圆心之间的距离
        var 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;
 
          //更新显示
          drawCircles();
 
          //停止搜索
          return;
        }
      }
    }
 
    //在某个范围内生成随机数
    function randomFromTo(from, to) {
      return Math.floor(Math.random() * (to - from + 1) + from);
    }
 </script>
</head> 
 
<body>
 
  <canvas id="canvas" width="400" height="300">
  </canvas>
 
  <div>
    <button onclick="addRandomCircle()">添加圆圈</button>
    <button onclick="clearCanvas()">清空画布</button>
  </div>
 
</body>
</html>

2,鼠标拖动图形对象

下面做个功能改进,允许用户在画布上拖动圆圈。只要监听Canvas的 onMouseMove 事件,相应地修改圆圈的坐标,然后再调用 drawCircle() 函数重绘画布即可。
添加圆圈  清空画布
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>hangge.com</title>
 
 <style>
     canvas {
       cursor: pointer;
       border: 1px solid black;
     }
 </style>
 <script>
    // 这个方法用来储存每个圆圈对象
    function Circle(x, y, radius, color) {
      this.x = x;
      this.y = y;
      this.radius = radius;
      this.color = color;
      this.isSelected = false;
    }
 
    // 保存画布上所有的圆圈
    var circles = [];
 
    var canvas;
    var context;
 
    window.onload = function() {
      canvas = document.getElementById("canvas");
      context = canvas.getContext("2d");
 
      canvas.onmousedown = canvasClick;
      canvas.onmouseup = stopDragging;
      canvas.onmouseout = stopDragging;
      canvas.onmousemove = dragCircle;
    };
 
    function addRandomCircle() {
      // 为圆圈计算一个随机大小和位置
      var radius = randomFromTo(10, 60);
      var x = randomFromTo(0, canvas.width);
      var y = randomFromTo(0, canvas.height);
 
      // 为圆圈计算一个随机颜色
      var colors = ["green", "blue", "red", "yellow", "magenta", "orange", "brown", "purple", "pink"];
      var color = colors[randomFromTo(0, 8)];
 
      // 创建一个新圆圈
      var 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(var i=0; i<circles.length; i++) {
        var 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();
      }
    }
 
    var previousSelectedCircle;
 
    function canvasClick(e) {
      // 取得画布上被单击的点
      var clickX = e.pageX - canvas.offsetLeft;
      var clickY = e.pageY - canvas.offsetTop;
 
      // 查找被单击的圆圈
      for(var i=circles.length-1; i>=0; i--) {
        var circle = circles[i];
        //使用勾股定理计算这个点与圆心之间的距离
        var 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;
 
          // 使圆圈允许拖拽
          isDragging = true;
 
          //更新显示
          drawCircles();
 
          //停止搜索
          return;
        }
      }
    }
 
    //在某个范围内生成随机数
    function randomFromTo(from, to) {
      return Math.floor(Math.random() * (to - from + 1) + from);
    }
 
    var isDragging = false;
 
    function stopDragging() {
      isDragging = false;
    }
 
    function dragCircle(e) {
      // 判断圆圈是否开始拖拽
      if (isDragging == true) {
        // 判断拖拽对象是否存在
        if (previousSelectedCircle != null) {
          // 取得鼠标位置
          var x = e.pageX - canvas.offsetLeft;
          var y = e.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>

 

时间: 2025-01-05 06:53:39

HTML5中Canvas的使用样例(图形增加鼠标点击、拖动交互)的相关文章

关于HTML5中Canvas的宽、高设置有关问题

关于HTML5中Canvas的宽.高设置问题 Canvas元素默认宽 300px, 高 150px, 设置其宽高可以使用如下方法:方法一:1 <canvas width="500" height="500"></canvas>方法二:使用HTML5 Canvas API操作 OK1 var canvas = document.getElementById('欲操作canvas的id');2 canvas.width = 500;3 canva

html5中canvas的一个简单的例子

买了两本关于HTML5的书,一本<HTML5揭秘>,一本<HTML5高级程序设计>,现在在看<html5揭秘>网上说这本书是非常入门的一本,<HTML5权威指南>就相对深一点.所以买了揭秘,没买指南.都说HTML5的canvas很重要,所以这里把书上关于canvas的一些简单例子,给试着自己写了一遍,放上来把  代码如下 复制代码 window.onload = function(){     var canvas = document.getElement

代码-qt中鼠标点击view获取点并将坐标转换为scene坐标之后在坐标处绘制item,位置发生偏移

问题描述 qt中鼠标点击view获取点并将坐标转换为scene坐标之后在坐标处绘制item,位置发生偏移 如题,我的组件是用QGraphicsItem绘制的,重载了QMouseEvent,但是点击时在view上显示的地方不对,主要代码如下: QPoint viewPos = event->pos();//获取视口坐标 QPointF scenePos = view_1->mapToScene(viewPos);//将视口坐标转换为场景坐标 select->setRect(scenePos

HTML5中使用Canvas的使用样例1 (画布定义、绘制直线)

1,Canvas的定义 <canvas id="myCanvas" width="400" height="200"> 默认<canvas>画布在页面上会显示一块空白.无边框的矩形.为了让其显示轮廓,通过定义样式规则给其添加一个虚线边框: canvas {     border: 1px dashed black; } 2,获取Canvas的上下文对象 要完成绘图任务,首先我们要拿到<canvas>对象,接着取

HTML5中Canvas的使用路径绘制自定义形状,并填充使用样例

下面通过样例演示使用路径绘制一个三角形并进行填充. 1,绘制时要注意如下两个地方: (1)路径绘制完毕后,要调用 closePath() 来明确地关闭路径. (2)看下面代码其实我只画了两条边,因为 closePath() 会自动在最后一个绘制点与绘制起点间绘制一条线. (3)最好先填充颜色,再绘制轮廓,否则轮廓线会有一部分被填充色覆盖掉. var canvas = document.getElementById("myCanvas"); var context = canvas.ge

HTML5中Canvas(绘制)使用例子

Canvas中不仅可以画线(路径),还能画很多其他的图像,这一章就介绍Canvas的其他两种绘图API. 一.简单图形,整套的属性和方法专门用于绘制矩形: 1.fillStyle可以设置为CSS颜色.一个图案或一种颜色渐变.fillStyle默认是纯黑色,你可以设置成你喜欢的任意颜色.只要页面打开着,每个绘图上下文都会记录自己的属性,除非你重置过它. 2.fillRect(x,y,width,height)绘制一个矩形,并以当前的fillStyle来填充. 3.srtokeStyle和fillS

html5中canvas的使用 获取鼠标点击页面上某点的RGB

1.html5中的canvas在IE9中可以跑起来.在IE8则跑不起来,这时候就需要一些东西了. 我推荐这种方法,这样显得代码不乱. <!--[if lt IE9]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> 需要谷歌的一个html5.js的文件即可. 注意:必须插入在<head></he

HTML5中Canvas绘制曲线:圆、圆弧、贝塞尔曲线使用样例

绘制曲线有如下四个方法:arc().artTo().bezierCurveTo()和quadraticCurveTo(). 第一个比较简单,就是绘制一段圆弧.后面三个方法复杂一些,都需要定义控制点. 1,arc()绘制圆弧 圆弧就是圆上的一部分.要绘制圆弧必须确定:圆形的坐标.圆的半径.圆弧的起点角度和终点角度. 其中起点角度和终点角度都要用弧度表示,即常量pi的倍数(1pi是半圆,2pi是整个圆形). (1)下面使用arc()方法绘制一段圆弧: var canvas = document.ge

HTML5中Canvas变换的使用使用样例

1,变换介绍 变换,就是一种通过变化<canvas>坐标系达到绘图目的的技术,具体有如下几种变换 : (1)translate:平移变换 (2)scale:缩放变换 (3)rotate:旋转变换 (4)matrix:矩阵变换 2,平移变换(translate) 比如我们想要在三个地方绘制同样大小的正方形: 可以调用三次rect(),每次都传入不同的起点位置: var canvas = document.getElementById("myCanvas"); var cont