js 实现点击按钮小球加入购物车动画

本文旨在实现类似点击按钮实现小球加入购物车效果。

使用技术:

  • Vue2
  • 使用 Pubsub 监听按钮点击事件(如果不想用也可以自己改造下)
  • 监听 onmousemove 来获取按钮点击时的鼠标位置

在这里插入图片描述

小球组件:

html + css:

小球父元素:定义了一些基本样式。采用 fixed 布局,让小球相对浏览器窗口进行定位;通过 opacity 控制显隐。

小球:采用任意图片。

<template>
  <div class="ball-wrap"
    ref="ball"
    :style="{
      opacity: ball.show,
      width: size + 'px',
      height: size + 'px',
    }"
  >
    <i class="el-icon-document" ></i>
  </div>
</template>

<style scoped>
.ball-wrap {
  border-radius: 50%;
  z-index: 9999;
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #165BD3;
}
.el-icon-document {
  color: #fff !important;
  margin: 0 !important;
}
</style>

js:

props:控制小球大小、动画持续时间(不传也有默认值)

data:通过 ball.show 来控制小球的 opacity

mounted:

小球当前位置通过变量 currentMousePos 来记录,通过使用监听函数 onmousemove 修改当前鼠标位置。

小球挂载时增加监听 onmousemove,使用 debounce 防抖函数,保证 50ms 内只更新一次鼠标位置

核心方法 drop:开启小球动画

exportRecordsListNav:小球结束处的 dom 元素,直接通过 id 获取了,用 ref 还需要跨组件获取,觉得有些麻烦

主要流程:获取结束元素的位置 -> 设置小球到初始位置 -> 设置结束位置 -> 动画结束后小球隐藏、清除 transition 属性

<script>
  import debounce from 'lodash/debounce'
  // 记录小球当前位置、通过监听 onmousemove 来更新小球位置
  const currentMousePos = {
    x: 0,
    y: 0
  }
  export default {
    props: {
      // 球的大小
      size: {
        type: Number,
        default: 30
      },
      //持续时间
      duration: {
        type: Number,
        default: 1000
      },
    },
    data() {
      return {
        ball: {
          show: 0,
        },
      };
    },
    mounted() {
      // 初始化小球,控制小球显隐
      this.initBall()
      // 小球挂载时监听 onmousemove,使用 debounce 保证 50ms 内只更新一次小球位置
      window.addEventListener('mousemove', debounce((e) => {
        currentMousePos.x = e.clientX
        currentMousePos.y = e.clientY
      }, 50))
    },
    methods: {
      initBall(){
        this.ball.show = 0
      },
      // 外部调用方法,开始执行动画
      drop(){
        // 获取结束位置的元素及坐标
        const exportRecordsListNav = document.getElementById('export-records-list')
        const endPos = {}
        endPos.x = exportRecordsListNav.getBoundingClientRect().left
        endPos.y = exportRecordsListNav.getBoundingClientRect().top
      
        // 小球显示
        this.ball.show = 1
        // 设置小球初始位置
        this.$refs.ball.style.transform = `translate(${currentMousePos.x}px, ${currentMousePos.y}px)`
      
        // 延时是为了防止合并移动
        setTimeout(() => {
           // 增加动画效果
          this.$refs.ball.style.transition = `transform ${this.duration}ms ease-in-out`
          // 设置小球结束位置
          this.$refs.ball.style.transform = `translate(${endPos.x}px, ${endPos.y}px)`
          
          // 动画结束后,小球隐藏,清除动画效果
          // 清除动画效果是为了下次小球从 (0,0) 移动到初始位置时不需要有动画
          setTimeout(()=>{
            this.ball.show = 0
            this.$refs.ball.style.transition = 'unset'
          }, this.duration)
        }, 100)
      },
    }
  }
 </script>

使用方式:

我将结束元素和小球封装成了一个组件,原因是认为工作项目中小球动画只和该导航栏相关。

由于加入购物车的按钮会在很多不同的单页面 page 里,因此使用 Pubsub 技术告诉结束元素此刻点击了按钮,再由结束元素组件调用 drop 方法,这样在其他页面只需进行发布订阅,不需要关注其他操作。

结束元素组件:
<template>
  <div>
    <span id="export-records-list">购物车</span>
    <MovableBall ref="movableBallRef"/>
  </div>
</template>

<script>
import MovableBall from '@/components/movable-ball/index.vue' 
import Pubsub from 'pubsub-js'
export default {
  data () {},
  components: {
    MovableBall,
  },
  mounted () {
    // 订阅消息、接受到消息后执行 moveBall 方法
    Pubsub.subscribe('add-to-card', this.moveBall)
  },
  methods: {
    moveBall() {
      if(this.$refs.movableBallRef) {
        // 开启小球动画
        this.$refs.movableBallRef.drop()
      }
    },
  },
}
</script>
点击「加入购物车按钮」的单页面:
<script>
import Pubsub from 'pubsub-js'
export default {
    methods: {
        // 点击按钮加入购物车
        addToCard() {
            // 发布消息
            Pubsub.publish('add-to-card')                        
        }
    }
}
</script>

参考文档:
仿加入购物车飞入动画效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/436629.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小心!Springer旗下34年老刊大量撤稿中国论文,16天见刊,中国人该如何应对?

毕业推荐 SCIE&#xff1a; • 计算机类&#xff0c;6.5-7.0&#xff0c;JCR1区&#xff0c;中科院2区 • 2个月19天录用&#xff0c;6天见刊&#xff0c;36天检索 SCI&EI&#xff08;CCF-C类&#xff09; • 算法类&#xff0c;2.0-3.0&#xff0c;JCR3区&#xff0c;…

ChatGPT提问技巧——标准提示

ChatGPT提问技巧——标准提示 标准提示是一种通过向模型提供一个具体要完成的任务&#xff0c;指导ChatGPT输出的简单方式。例如&#xff0c;如果你想生成一个新闻的总结&#xff0c;你要提供一个任务像这样的“总结一下这篇新闻文章“。 提示格式&#xff1a;”生成【任务】…

IoT数据采集网关在企业应用中扮演着关键角色-天拓四方

随着物联网&#xff08;IoT&#xff09;技术的不断发展&#xff0c;越来越多的企业开始利用IoT技术实现智能化、自动化的生产和管理。在这个过程中&#xff0c;IoT数据采集网关作为连接物理世界与数字世界的桥梁&#xff0c;发挥着至关重要的作用。 IoT数据采集网关是一种硬件…

LeetCode 2917.找出数组中的 K-or 值:基础位运算

【LetMeFly】2917.找出数组中的 K-or 值&#xff1a;基础位运算 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-the-k-or-of-an-array/ 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数&#xff1a; 只有…

横琴正式封关运行,惟客数据都做了什么?

​作为中国实施高水平制度型开放的重大探索&#xff0c;位于珠海横琴岛的横琴粤澳深度合作区于2024年3月1日零时正式实施分线管理封关运行&#xff0c;共设1个“一线”口岸、7个“二线”海关作业现场&#xff0c;覆盖旅检、货运、通关、稽&#xff08;核&#xff09;查等多线条…

第26章 模块

本章内容  理解模块模式  凑合的模块系统  使用前 ES6 模块加载器  使用 ES6 模块 现代 JavaScript 开发毋庸置疑会遇到代码量大和广泛使用第三方库的问题。解决这个问题的方案通常需要把代码拆分成很多部分&#xff0c;然后再通过某种方式将它们连接起来。 文章目录 …

MySQL基础-----函数

目录 前言 一、字符串函数 演示 案例 二、数值函数 演示 案例 三、日期函数 演示 案例 四、流程函数 演示 案例 前言 本期我们就开始MySQL中函数的学习。函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着&#xff0c;这一段程序或代码在MySQL中 已经…

Linux之线程概念

目录 一、细粒度划分 1、堆区细粒度划分 2、物理内存和可执行程序细粒度划分 3、虚拟地址到物理地址的转化 二、线程的概念 1、基本概念 2、线程的优点 3、线程的缺点 4、线程异常 5、线程用途 三、Linux下的进程和线程 一、细粒度划分 1、堆区细粒度划分 在语言…

php安装kafka

我的开发环境是php7.3 ,先来部署两个php扩展&#xff0c;php7.3目录下放librdkafka.dll,ext/php_rdkafka.dll&#xff0c;php.ini增加,[rdkafka] extension php_rdkafka.dll php7.3对应的扩展包链接&#xff1a;PECL :: Package :: rdkafka 看自己php版本对应在这里找PECL :: …

antd vue 选择控件的使用

Ant Design Vue-------Select 选择器 今天就讲讲Ant Design Vue下的控件----select 下拉框 结合项目中的需求&#xff0c;讲一下该控件如何配置&#xff0c;需求&#xff1a; &#xff08;1&#xff09;设置控件的宽度和高度 &#xff08;2&#xff09;绑定数据源 &#x…

IT人才职业发展路径

IT人才的职业发展路径通常是多样化的&#xff0c;因为IT领域涵盖了广泛的技术和职能角色。以下是一个典型的IT人才职业发展路径的梳理&#xff0c;但具体情况会根据个人兴趣、技能、经验和行业需求而有所不同&#xff1a; 入门级岗位&#xff1a; 技术支持工程师&#xff1a;提…

CVE-2024-25600 WordPress Bricks Builder RCE-漏洞分析研究

本次代码审计项目为PHP语言&#xff0c;我将继续以漏洞挖掘者的视角来分析漏洞的产生&#xff0c;调用与利用..... 前方高能&#xff0c;小伙伴们要真正仔细看咯..... 漏洞简介 CVE-2024-25600 是一个严重的&#xff08;CVSS 评分 9.8&#xff09;远程代码执行 (RCE) 漏洞&am…

SpringBoot初步学习

SpringBoot 今日目标&#xff1a; 掌握基于SpringBoot框架的程序开发步骤 熟练使用SpringBoot配置信息修改服务器配置 基于SpringBoot的完成SSM整合项目开发 1. SpringBoot简介 SpringBoot 其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。 1.1 SpringBoot快速…

ROS从入门到精通4-2:Docker安装ROS、可视化仿真与终端复用

目录 0 专栏介绍1 Docker安装ROS2 Docker可视化仿真2.1 显示配置2.2 启动容器 3 终端复用工具3.1 session操作3.2 window操作3.3 pane操作3.4 其他操作 0 专栏介绍 本专栏旨在通过对ROS的系统学习&#xff0c;掌握ROS底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS…

大数据开发-Hadoop之YARN介绍以及实战

文章目录 YARN基本介绍YARN的结构分析YARN中的调度器实际案例&#xff1a;YARN多资源队列的配置和使用 YARN基本介绍 实现Hadoop集群的资源共享不仅支持MapReduce&#xff0c;还支持Spark&#xff0c;Flink等计算 YARN的结构分析 主要复制集群资源的管理和调度&#xff0c;支…

【论文阅读】单词级文本攻击TAAD2.2

TAAD2.2论文概览 0.前言1-101.Bridge the Gap Between CV and NLP! A Gradient-based Textual Adversarial Attack Frameworka. 背景b. 方法c. 结果d. 论文及代码 2.TextHacker: Learning based Hybrid Local Search Algorithm for Text Hard-label Adversarial Attacka. 背景b…

javaWebssh水利综合信息管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh水利综合信息管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

BJFU|操作系统考试复习纲要(思维导图版)

纲要涵盖五个章节&#xff0c;每节一图。红色框部分为必考重点&#xff0c;建议认真复习。

数据结构与算法-归并排序

引言 在计算机科学的广阔领域中&#xff0c;数据结构与算法犹如两大基石&#xff0c;支撑着软件系统高效运行。本文将深度剖析一种基于分治策略的排序算法——归并排序&#xff0c;并探讨其原理、实现步骤以及优缺点&#xff0c;以期帮助读者深入理解这一高效的排序方法。 一、…

用开发CesiumJS模拟飞机飞行应用(一,基本功能)

本部分向您展示如何构建您的第一个 Cesium 应用程序&#xff0c;以可视化模拟从旧金山到哥本哈根的真实航班&#xff0c;并使用 FlightRadar24收集的雷达数据。您将学习如何&#xff1a; 在网络上设置并部署您的 Cesium 应用程序。 添加全球 3D 建筑物、地形和图像的基础图层。…