js实现盒子拖拽动画效果

实现盒子拖拽动画效果需要以下步骤:

1. 为拖拽目标元素绑定事件监听器

首先需要为需要拖拽的目标元素添加事件监听器,通常是mousedown事件或者touchstart事件。

let target = document.getElementById('drag-target');
target.addEventListener('mousedown', dragStart);
target.addEventListener('touchstart', dragStart);

其中dragStart函数是拖拽开始的处理函数,我们接下来会讲到。

2. 实现拖拽功能

当用户开始拖拽目标元素时,我们需要对鼠标或手指的移动进行监听,并实时更新目标元素的位置,以实现拖拽效果。我们需要给目标元素的父元素绑定事件监听器,监听mousemove事件或者touchmove事件,并在事件处理函数中更新目标元素的位置。

let container = document.getElementById('drag-container');
container.addEventListener('mousemove', dragging);
container.addEventListener('touchmove', dragging);

其中dragging函数是拖拽中的处理函数,我们接下来会讲到。

在处理函数中,我们通过事件对象获取鼠标或手指的位置,然后计算出目标元素相对于父元素的位置,再设置目标元素的样式即可。

function dragging(e) {
  e.preventDefault(); // 防止默认行为(比如滚动)
  let offsetX, offsetY;
  if (e.type === 'mousemove') {
    offsetX = e.clientX - container.offsetLeft;
    offsetY = e.clientY - container.offsetTop;
  } else if (e.type === 'touchmove') {
    offsetX = e.touches[0].clientX - container.offsetLeft;
    offsetY = e.touches[0].clientY - container.offsetTop;
  }
  target.style.left = offsetX + 'px';
  target.style.top = offsetY + 'px';
}

需要注意的是,在触摸设备上,我们需要获取touches数组中第一个触摸点的位置。

3. 实现拖拽动画效果

在上一步拖动中,我们已经可以实现目标元素的拖动。接下来我们需要添加缓动效果,使目标元素在松开鼠标或手指时能够平稳地移动到目标位置。我们可以使用requestAnimationFrame函数来实现动画效果。

首先,我们需要在mousedowntouchstart事件中记录目标元素的初始位置和事件发生的时间。

function dragStart(e) {
  let offsetX, offsetY;
  if (e.type === 'mousedown') {
    offsetX = e.clientX - target.offsetLeft;
    offsetY = e.clientY - target.offsetTop;
  } else if (e.type === 'touchstart') {
    offsetX = e.touches[0].clientX - target.offsetLeft;
    offsetY = e.touches[0].clientY - target.offsetTop;
  }
  let startTime = Date.now();
  let startPos = {x: target.offsetLeft, y: target.offsetTop};
  // 在这里保存初始位置和时间
}

然后,我们可以在mousemovetouchmove事件中更新目标元素的位置,并计算出目标位置和当前位置之间的距离和时间间隔,以便计算缓动效果。

function dragging(e) {
  // 在这里更新目标元素的位置
  let offsetX, offsetY;
  if (e.type === 'mousemove') {
    offsetX = e.clientX - container.offsetLeft;
    offsetY = e.clientY - container.offsetTop;
  } else if (e.type === 'touchmove') {
    offsetX = e.touches[0].clientX - container.offsetLeft;
    offsetY = e.touches[0].clientY - container.offsetTop;
  }
  target.style.left = offsetX + 'px';
  target.style.top = offsetY + 'px';

  // 在这里计算移动距离和时间间隔
  let distance = Math.sqrt(Math.pow(offsetX-startPos.x,2) + Math.pow(offsetY-startPos.y,2));
  let duration = Date.now() - startTime;
}

最后,在mouseuptouchend事件中,我们可以根据移动距离和时间间隔计算出缓动效果的参数(速度和加速度),然后使用requestAnimationFrame函数实现动画效果。

function dragEnd(e) {
  // 在这里计算速度和加速度
  let velocity = distance / duration;
  let direction = Math.atan2(offsetY-startPos.y, offsetX-startPos.x);
  let acceleration = velocity * 10;
  let startX = target.offsetLeft, startY = target.offsetTop;

  // 定义动画函数
  function animate() {
    let elapsed = Date.now() - startTime;
    let dx = startX + velocity * elapsed * Math.cos(direction);
    let dy = startY + velocity * elapsed * Math.sin(direction) + acceleration * Math.pow(elapsed, 2) / 2;
    // 判断动画是否结束,如果未结束继续更新位置,否则停止动画
    if (elapsed < duration) {
      target.style.left = dx + 'px';
      target.style.top = dy + 'px';
      requestAnimationFrame(animate);
    } else {
      target.style.left = startX + distance * Math.cos(direction) + 'px';
      target.style.top = startY + distance * Math.sin(direction) + 'px';
    }
  }
  animate();
}

这样,我们就实现了盒子拖拽动画效果。下面给出两个示例,分别实现了鼠标和触摸设备的拖拽效果。

示例 1:鼠标拖拽

<div id="drag-container" style="position: relative;width: 300px;height: 300px;background-color: #eee;">
  <div id="drag-target" style="position: absolute;width: 50px;height: 50px;background-color: red;"></div>
</div>

<script>
let target = document.getElementById('drag-target');
let container = document.getElementById('drag-container');
let startPos, startTime, distance, duration;

target.addEventListener('mousedown', dragStart);
container.addEventListener('mousemove', dragging);
container.addEventListener('mouseup', dragEnd);

function dragStart(e) {
  let offsetX = e.clientX - target.offsetLeft;
  let offsetY = e.clientY - target.offsetTop;
  startTime = Date.now();
  startPos = {x: target.offsetLeft, y: target.offsetTop};
}

function dragging(e) {
  e.preventDefault();
  let offsetX = e.clientX - container.offsetLeft;
  let offsetY = e.clientY - container.offsetTop;
  target.style.left = offsetX + 'px';
  target.style.top = offsetY + 'px';
  distance = Math.sqrt(Math.pow(offsetX-startPos.x,2) + Math.pow(offsetY-startPos.y,2));
  duration = Date.now() - startTime;
}

function dragEnd(e) {
  let velocity = distance / duration;
  let direction = Math.atan2(offsetY-startPos.y, offsetX-startPos.x);
  let acceleration = velocity * 10;
  let startX = target.offsetLeft, startY = target.offsetTop;

  function animate() {
    let elapsed = Date.now() - startTime;
    let dx = startX + velocity * elapsed * Math.cos(direction);
    let dy = startY + velocity * elapsed * Math.sin(direction) + acceleration * Math.pow(elapsed, 2) / 2;
    if (elapsed < duration) {
      target.style.left = dx + 'px';
      target.style.top = dy + 'px';
      requestAnimationFrame(animate);
    } else {
      target.style.left = startX + distance * Math.cos(direction) + 'px';
      target.style.top = startY + distance * Math.sin(direction) + 'px';
    }
  }
  animate();
}
</script>

示例 2:触摸设备拖拽

<div id="drag-container" style="position: relative;width: 300px;height: 300px;background-color: #eee;">
  <div id="drag-target" style="position: absolute;width: 50px;height: 50px;background-color: red;"></div>
</div>

<script>
let target = document.getElementById('drag-target');
let container = document.getElementById('drag-container');
let startPos, startTime, distance, duration;

target.addEventListener('touchstart', dragStart);
container.addEventListener('touchmove', dragging);
container.addEventListener('touchend', dragEnd);

function dragStart(e) {
  e.preventDefault();
  let offsetX = e.touches[0].clientX - target.offsetLeft;
  let offsetY = e.touches[0].clientY - target.offsetTop;
  startTime = Date.now();
  startPos = {x: target.offsetLeft, y: target.offsetTop};
}

function dragging(e) {
  e.preventDefault();
  let offsetX = e.touches[0].clientX - container.offsetLeft;
  let offsetY = e.touches[0].clientY - container.offsetTop;
  target.style.left = offsetX + 'px';
  target.style.top = offsetY + 'px';
  distance = Math.sqrt(Math.pow(offsetX-startPos.x,2) + Math.pow(offsetY-startPos.y,2));
  duration = Date.now() - startTime;
}

function dragEnd(e) {
  let velocity = distance / duration;
  let direction = Math.atan2(offsetY-startPos.y, offsetX-startPos.x);
  let acceleration = velocity * 10;
  let startX = target.offsetLeft, startY = target.offsetTop;

  function animate() {
    let elapsed = Date.now() - startTime;
    let dx = startX + velocity * elapsed * Math.cos(direction);
    let dy = startY + velocity * elapsed * Math.sin(direction) + acceleration * Math.pow(elapsed, 2) / 2;
    if (elapsed < duration) {
      target.style.left = dx + 'px';
      target.style.top = dy + 'px';
      requestAnimationFrame(animate);
    } else {
      target.style.left = startX + distance * Math.cos(direction) + 'px';
      target.style.top = startY + distance * Math.sin(direction) + 'px';
    }
  }
  animate();
}
</script>

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:js实现盒子拖拽动画效果 - Python技术站

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

相关文章

  • 基于JavaScript实现仿京东图片轮播效果

    我会为你详细讲解如何基于JavaScript实现仿京东图片轮播效果的完整攻略。 1. 准备工作 在开始实现之前,需要先准备好以下内容:- 一份HTML文档,在其中包含轮播图片的标签- 用于存储图片的路径数组- 一个计时器用于定时切换图片- 两个按钮,分别用于切换到上一张或下一张图片 以下是一个简单的HTML文档示例,其中包含一张图片和两个按钮: <!D…

    JavaScript 2023年6月11日
    00
  • JavaScript小技巧 2.5 则

    完整攻略如下: JavaScript小技巧 2.5则 简介 这是第二篇JavaScript小技巧的第五则,本篇攻略将详细讲解如何利用JavaScript小技巧来提高开发效率和代码的可读性。 正文 小技巧1:使用数组解构赋值获取函数的多个返回值 在JavaScript中,函数可以有多个返回值,如果我们需要获取这些返回值并分别进行操作,那么可以使用数组解构赋值来…

    JavaScript 2023年5月27日
    00
  • ScrollDown的基本操作示例

    关于”ScrollDown的基本操作示例”的完整攻略,可以按照以下步骤进行: 1. 打开ScrollDown 在浏览器中输入ScrollDown的地址,即可进入。 2. 查看菜单栏 在网页的菜单栏中,有多个选项,包括: Home Features Examples Documentation Support 3. 查看示例及其操作 在菜单栏中选择”Examp…

    JavaScript 2023年6月10日
    00
  • javascript 表单日期选择效果

    我来为你详细讲解一下“JavaScript 表单日期选择效果”的完整攻略。 1. 学习目标 通过本文,你将学会如何使用 JavaScript 实现表单日期选择效果,具体实现包括以下几个部分: 在 HTML 页面中编写日期选择框 使用 JavaScript 实现日期选择框的弹出及隐藏 在 JavaScript 中编写判断闰年的函数 在 JavaScript 中…

    JavaScript 2023年5月27日
    00
  • JavaScript高级程序设计(第3版)学习笔记11 内建js对象

    下面是《JavaScript高级程序设计(第3版)学习笔记11 内建js对象》的学习攻略。 常用内建对象 JavaScript中内建对象众多,本章介绍的是一些常用的内建对象。 Boolean对象 Boolean对象只有两种可能的实例,即true和false,如果将其他数据类型转换为Boolean类型,规则是:除了””、0、NaN、null和undefined…

    JavaScript 2023年5月18日
    00
  • 关于ES6新特性最常用的知识点汇总

    关于ES6新特性最常用的知识点汇总 模板字符串 ES6 新增了一种字符串拼接的方式:模板字符串。使用反引号 “ 包裹字符串,并通过 ${} 插入表达式。 例如: const name = ‘John’; const message = `Hello, ${name}!`; console.log(message); // 输出 "Hello, J…

    JavaScript 2023年5月28日
    00
  • JavaScript使用encodeURI()和decodeURI()获取字符串值的方法

    JavaScript使用encodeURI()和decodeURI()获取字符串值的方法 在JavaScript中,有时候需要将字符串数据转换成URI格式,或者从URI格式中获取字符串数据。这时候可以使用encodeURI()和decodeURI()方法来完成转换。 encodeURI() encodeURI()方法将字符串数据作为URI进行编码,其中一些字…

    JavaScript 2023年5月19日
    00
  • JavaScript DOM基础

    JavaScript DOM基础攻略 前言 文档对象模型(DOM)是HTML和XML文档的编程接口,它将可用于操作文档内容的元素定义为对象。JavaScript可以使用DOM来实现对HTML页面中各个元素的动态访问和操作,从而实现页面交互和响应。 获取元素 DOM中最常用的操作之一就是获取页面的元素,这可以通过如下方法实现: getElementById()…

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