javascript利用canvas实现鼠标拖拽功能

yizhihongxing

下面是关于“javascript利用canvas实现鼠标拖拽功能”的完整攻略:

什么是canvas?

Canvas是HTML5中的一个新特性,是一个可以用脚本(通常为JavaScript)在其中绘制图形的HTML元素。Canvas有两种绘制路径:一种是通过命令式的JavaScript进行绘图;另外一次是通过使用矢量图形编辑器生成并导入路径。

实现鼠标拖拽的步骤

第一步:创建画布和要绘制的图形

为了在画布上实现鼠标拖拽的功能,我们需要先创建一个画布,然后在其上绘制需要被拖拽的图形。这里以绘制一个矩形为例,代码如下:

<canvas id="myCanvas" width="500" height="500"></canvas>
let canvas = document.querySelector('#myCanvas');
let ctx = canvas.getContext('2d');

ctx.fillStyle = '#ff0000';
ctx.fillRect(100, 100, 50, 50);

第二步:监听鼠标事件

在画布上监听鼠标事件,当鼠标按下时记录下鼠标的坐标,当鼠标移动时根据移动距离改变图形的位置,当鼠标松开时停止拖拽。示例代码如下:

let isDragging = false;
let offset = {x: 0, y: 0};
let rect = {x: 100, y: 100, w: 50, h: 50};

canvas.addEventListener('mousedown', function(e) {
  let rectLeft = canvas.offsetLeft;
  let rectTop = canvas.offsetTop;
  let mouseX = e.pageX - rectLeft;
  let mouseY = e.pageY - rectTop;

  if(mouseX >= rect.x && mouseX <= rect.x + rect.w && mouseY >= rect.y && mouseY <= rect.y + rect.h) {
    isDragging = true;
    offset.x = mouseX - rect.x;
    offset.y = mouseY - rect.y;
  }
});

canvas.addEventListener('mousemove', function(e) {
  if(isDragging) {
    let rectLeft = canvas.offsetLeft;
    let rectTop = canvas.offsetTop;
    let mouseX = e.pageX - rectLeft;
    let mouseY = e.pageY - rectTop;
    rect.x = mouseX - offset.x;
    rect.y = mouseY - offset.y;

    draw();
  }
});

canvas.addEventListener('mouseup', function(e) {
  isDragging = false;
});

第三步:重绘图形

当图形的位置发生改变时,需要立即重新绘制图形。示例代码如下:

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = '#ff0000';
  ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
}

示例

以下是两个示例,一个是鼠标拖拽矩形,另一个是鼠标拖拽图片:

示例1:鼠标拖拽矩形

<canvas id="myCanvas1" width="500" height="500"></canvas>
<script>
let canvas = document.querySelector('#myCanvas1');
let ctx = canvas.getContext('2d');

let isDragging = false;
let offset = {x: 0, y: 0};
let rect = {x: 100, y: 100, w: 50, h: 50};

canvas.addEventListener('mousedown', function(e) {
  let rectLeft = canvas.offsetLeft;
  let rectTop = canvas.offsetTop;
  let mouseX = e.pageX - rectLeft;
  let mouseY = e.pageY - rectTop;

  if(mouseX >= rect.x && mouseX <= rect.x + rect.w && mouseY >= rect.y && mouseY <= rect.y + rect.h) {
    isDragging = true;
    offset.x = mouseX - rect.x;
    offset.y = mouseY - rect.y;
  }
});

canvas.addEventListener('mousemove', function(e) {
  if(isDragging) {
    let rectLeft = canvas.offsetLeft;
    let rectTop = canvas.offsetTop;
    let mouseX = e.pageX - rectLeft;
    let mouseY = e.pageY - rectTop;
    rect.x = mouseX - offset.x;
    rect.y = mouseY - offset.y;

    draw();
  }
});

canvas.addEventListener('mouseup', function(e) {
  isDragging = false;
});

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = '#ff0000';
  ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
}
</script>

示例2:鼠标拖拽图片

<canvas id="myCanvas2" width="500" height="500"></canvas>
<script>
let canvas = document.querySelector('#myCanvas2');
let ctx = canvas.getContext('2d');

let isDragging = false;
let offset = {x: 0, y: 0};
let img;

img = new Image();
img.src = 'https://picsum.photos/200/300';

img.onload = function() {
  ctx.drawImage(img, 100, 100);
};

canvas.addEventListener('mousedown', function(e) {
  let rectLeft = canvas.offsetLeft;
  let rectTop = canvas.offsetTop;
  let mouseX = e.pageX - rectLeft;
  let mouseY = e.pageY - rectTop;

  if(mouseX >= 100 && mouseX <= 100 + img.width && mouseY >= 100 && mouseY <= 100 + img.height) {
    isDragging = true;
    offset.x = mouseX - 100;
    offset.y = mouseY - 100;
  }
});

canvas.addEventListener('mousemove', function(e) {
  if(isDragging) {
    let rectLeft = canvas.offsetLeft;
    let rectTop = canvas.offsetTop;
    let mouseX = e.pageX - rectLeft;
    let mouseY = e.pageY - rectTop;
    ctx.clearRect(0, 0, 500, 500);
    ctx.drawImage(img, mouseX - offset.x, mouseY - offset.y);
  }
});

canvas.addEventListener('mouseup', function(e) {
  isDragging = false;
});

</script>

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:javascript利用canvas实现鼠标拖拽功能 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • JS 判断某变量是否为某数组中的一个值的3种方法(总结)

    下面是关于JS判断某变量是否为某数组中的一个值的3种方法的详细攻略。 标准方法:Array.prototype.indexOf() Array对象有一个原型方法indexOf(),可以用来查找数组中是否包含某个元素。使用该方法来判断某变量是否为某数组中的一个值,需要先调用indexOf()方法查找该元素在数组中的索引值。若索引值不为 -1(即查找到该元素),…

    JavaScript 2023年5月27日
    00
  • 简短几句 通俗解释javascript的闭包

    下面是详细讲解JavaScript闭包的完整攻略: 什么是闭包? 闭包(closure)是指函数能够访问并使用其自身定义范围之外的变量。 JavaScript 中的每个函数都是一种闭包,将函数作为参数或从函数中返回函数时常会用到闭包的知识。 闭包示例1 例如,下面的代码定义了一个 name 变量,并在函数中创建了一个内部函数,返回的函数能够访问并使用 nam…

    JavaScript 2023年6月10日
    00
  • JavaScript中Function与Object的关系

    JavaScript中Function与Object的关系 在JavaScript中,Function和Object的关系是非常密切的,因为Function就是一种特殊的Object。在JavaScript中,一切皆为对象,不仅包括原始类型(如数字、字符串),也包括函数。 Function是Object的一个子类 在JavaScript中,Function也…

    JavaScript 2023年5月27日
    00
  • js实现时间轴自动排列效果

    下面我将详细讲解如何使用JavaScript实现时间轴自动排列效果。 概述 时间轴是一种将时间点或事件与轴上的点或线连接起来的可视化工具,被广泛应用于各个网站的设计中。自动排列效果指的是时间轴上的点或线可以自动按照时间顺序排列显示。下面我们将分步骤详细介绍如何使用JavaScript实现这个效果。 步骤 1. 准备数据 首先需要准备一个包含时间信息的数据,通…

    JavaScript 2023年5月27日
    00
  • javascript 应用小技巧方法汇总

    JavaScript 应用小技巧方法汇总 简介 JavaScript 作为网页前端开发的重要语言,在实践中有许多小技巧和方法可供使用,既可以大幅提高代码的效率,还能让页面更加美观、友好。 本文将介绍一些 JavaScript 应用小技巧方法,旨在帮助读者更好地掌握 JavaScript 编程技能。 目录 样式操作 数组处理 对象操作 事件处理 字符串处理 1…

    JavaScript 2023年5月18日
    00
  • jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法

    问题描述:在使用jQuery Validate插件进行表单验证时,如果表单中有多个name相同的元素,插件默认只会验证第一个元素,其余同名元素不参与验证,这会影响到表单的正确性。 解决方法:我们可以使用addMethod方法来自定义验证函数,并结合groups属性来解决表单验证时多个name相同的元素只验证第一个元素的问题。 1.自定义验证函数首先,在jqu…

    JavaScript 2023年6月10日
    00
  • Javascript中数组去重与拍平的方法示例

    下面我会对 “Javascript中数组去重与拍平的方法示例” 进行详细讲解。 一、去重方法 Javascript中实现数组去重有多种方法,这里介绍两种常用方法。 1. Set去重法 Set是ES6中新增的数据结构,它可以实现快速的去重操作。我们可以用Set将数组转换为一个不包含重复值的集合,最后再将集合转回数组即可。 下面是具体的示例代码: 首先,定义一个…

    JavaScript 2023年5月27日
    00
  • 10个最受欢迎的 JavaScript框架(推荐)

    10个最受欢迎的 JavaScript框架(推荐)攻略 1. 什么是JavaScript框架? JavaScript框架是一种将一些较为复杂的任务给封装在一起,并提供一些便利性的工具的集合。JavaScript框架有很多,而每个框架都有自己独特的特性,可以根据项目需要进行选择。 2. 为什么需要用JavaScript框架? JavaScript框架有很多功能…

    JavaScript 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部