首页 > 其他分享 >Vue3实现加入购物车抛物线效果组件

Vue3实现加入购物车抛物线效果组件

时间:2024-02-18 12:33:21浏览次数:34  
标签:动画 style const point dom 购物车 抛物线 Vue3 ele

前言

在前几天的一次迭代中,我遇到了这么一个需求,模仿支付宝首页应用中心的编辑功能,支持编辑首页展示的应用,在支付宝应用首页编辑功能中,我注意到一种独特而细致的设计。无论是增加还是移除某个应用,都会引发一个精美的移动动画效果。这种贴心的设计在用户体验中起到了微妙而关键的作用,使得操作更加流畅,为整个过程增添了趣味性。不由地想起我们在使用各种购物外卖软件时,添加商品到购物车也有这么一个抛物线的动画效果。因此,决定手动造轮子,封装一个通用的抛物线组件。该组件已开源上传npm,可以直接安装使用,源码已上传Git,地址在文尾。

贝赛尔曲线

贝塞尔曲线(Bezier curve)是应用于二维图形应用程序的数学曲线,在矢量图形软件中,贝塞尔曲线被广泛用于精确画出曲线,它也是计算机图形学中相当重要的参数曲线。

CSS中的贝塞尔曲线主要应用在动画和过渡中,可以使用cubic-bezier函数来创建自定义动画的速度曲线。使用transition-timing-function和animation-timing-function属性来定义贝塞尔曲线,这个函数接收四个参数,cubic-bezier(n,n,n,n),这四个点定义了一条贝塞尔曲线,其中n是一个0到1之间的数值。CSS提供了几个预定义的函数:ease, linear, ease-in, ease-out, ease-in-out。

实现思路

了解了Css中的贝赛尔曲线使用方法后,我们实现一个抛物线也就简单了,只用控制一个dom节点,在x轴和y轴上分别用不同的过度动画效果,改变dom节点left和top的位置,这样就能得到一个抛物线运动轨迹的动画效果了。在运动结束后我们将operaty设为0以达到动画结束隐藏节点。

优化 但是在实际使用时,如果我们不断地创造节点增加动画效果,那么就会有无数个dom节点冗余,大大降低了浏览器性能,因此,在动画结束还需要考虑回收dom,将不需要的dom节点移除,这样就大功告成,具体实现请看代码。

主要实现代码

1、定义一个基础dom结构,用slot以支持自定义不同的动画节点

<template>
    <div class="cubic-bezier-ball" v-for="item in ballList" :ref="(el) => setRefAction(el, item)" :key="item">
        <slot></slot>
    </div>
</template>

  

2、执行动画效果处理,将dom移动到起点,执行动画到末点,并在动画结束后销毁节点

//开始执行动画
const start = (point: any, time = 1, xcubic = 'linear', ycubic = 'ease-in') => {
    const nowTime = new Date().getTime();
    //新增一个动画节点
    ballList.value.push(nowTime);
    //dom渲染后增加动画效果
    nextTick(() => {
        const ele = ballRef.value[nowTime];
        ele.style.left = `${point.x1}px`;
        ele.style.top = `${point.y1}px`;
        ele.style.opacity = 1;
        setTimeout(() => {
            ele.style.left = `${point.x2}px`;
            ele.style.top = `${point.y2}px`;
            ele.style.transition = `left ${time}s ${xcubic}, top ${time}s ${ycubic}`;
        })
        setTimeout(() => {
            ele.style.opacity = 0;
            ele.style.left = `${point.x1}px`;
            ele.style.top = `${point.y1}px`;
            //动画结束回收dom
            removeDom(nowTime);
        }, time * 1000)
    })
}
 

3、保留每个Dom引用,移除dom

//将循环ref放入到数组中
const setRefAction = (el: any, item: number) => {
    ballRef.value[item] = el;
}

//动画结束回收dom
const removeDom = (nowTime: number) => {
    ballList.value = ballList.value.filter((item: number) => {
        return item != nowTime;
    })
}

  

使用示例

npm install @fcli/vue-cubic-bezier --save-dev 来安装

在项目中使用
import VueCubicBezier from '@fcli/vue-cubic-bezier';
const app=createApp(App)
app.use(VueCubicBezier);

示例:

<template>
  <div class="content">
    <cubic-bezier ref="myCubic">
      测试
    </cubic-bezier>
    <button class="btn" @click="getData">开始</button>
  </div>
</template>

<script setup lang="ts">
import CubicBezier from './plugin/index.vue';
import { ref } from 'vue';
component: {
  CubicBezier
}
const myCubic = ref<any>();
const params = {
  point: { x1: 250, y1: 50, x2: 100, y2: 400 },
  time: 0.5,
  xcubic: 'linear',
  ycubic: 'cubic-bezier(0.49, -0.29, 0.75, 0.41)',
}

const getData = () => {
  myCubic.value.start(params.point, params.time, params.xcubic, params.ycubic)
}

</script>

  

参数说明

使用时需要调用该组件的start方法,并传对应参数即可实现一个自定义抛物线,具体使用可以参考代码示例。

属性属性名称类型可选值
point 起点和结束点距离左上角的距离,(x1,y1)起点坐标,(x2,y2)结束点坐标 object { x1: 250, y1: 50, x2: 100, y2: 400 }
time 动画效果过渡时间 number 1
xcubic 横向过渡贝赛尔动画参数 number linear
ycubic 竖向过渡贝赛尔动画参数 number ease-in

slot 可自定义动画的图标或者内容

 

标签:动画,style,const,point,dom,购物车,抛物线,Vue3,ele
From: https://www.cnblogs.com/ranyihang/p/18019084

相关文章

  • Vue3杂碎知识记录
    vue引入bootstrap当卸载App.vue里不行的时候就还可以写在main.js里导入bootstrap的时候写在main.js里,(还要添加依赖@popperjs/core)import'bootstrap/dist/css/bootstrap.css';import'bootstrap/dist/js/bootstrap';//注意js文件也要引入进来写在vue的script里面不行,要......
  • Vue3学习(16) - 左侧显示分类菜单
    写在前面和大家不太一样,我觉得今年的自己更加relax,没有亲戚要走,没有朋友相聚,也没有很好的哥们要去叙旧,更没有无知的相亲,甚至可以这么说没有那些闲得慌的邻居。也可以说是从今天开始,算是可以进入自己的小世界,做自己想做的事,看看书,学习一下。生活的精髓在于善待自己,用心感受每一......
  • python3.9 + django4.1 + vue3 ,报错,无法访问配置的路由地址,Using the URLconf defined
    python3.9+django4.1+vue3,报错,无法访问配置的路由地址,UsingtheURLconfdefinedinStudentMgrBE.urls,DjangotriedtheseURLpatterns,inthisorder:-------------------------------------------------------------------------------无法访问 地址,报错如下: Us......
  • Vite+Vue3项目如何获取环境配置,并解决前端跨域问题
    步骤根目录新建.env.development和.env.production文件package.json配置启动参数vite命令启动项目时,指定mode参数,加载vite.config.ts文件。"dev":"vite--host0.0.0.0--port8093--modedevelopment","prod":"vite--port8093--host0.0.0.0--modepr......
  • vue3 let,var,const区别
    在Vue3中,let、var和const都是用于声明变量的关键字区别:   var:在JavaScript中,var是声明变量的最常用的关键字。var声明的变量的作用域是函数级的,如果在函数内部声明的变量,其作用域将限制在函数体内部。如果在函数外部声明的变量,则其作用域将是全局的。   let:let也用于声明......
  • vue3整合echarts
    Vue3是一个流行的前端框架,而ECharts是一个功能强大的图表库。将ECharts整合到Vue3项目中可以方便地展示各种图表。以下是将ECharts整合到Vue3项目中的基本步骤:安装ECharts:使用npm或yarn安装ECharts:bash复制代码npminstallecharts--save或......
  • 为什么vue3内不使用this
    在Vue3中,this 的使用受到了限制,主要是因为在Vue3中引入了CompositionAPI,它提供了一种更灵活、更可组合的方式来组织和管理组件的逻辑。在CompositionAPI中,不再使用传统的选项(如 data、methods、computed 等)来定义组件的逻辑,而是使用 setup 函数来组织逻辑。在 s......
  • python3.9+django4.1+vue3 ,后端项目运行时,报错了,WSGI application 'XXX.wsgi.applicat
    python3.9+django4.1+vue3,后端项目运行时,报错了; 报错信息,如下:django.core.exceptions.ImproperlyConfigured:WSGIapplication'StudentMgrBE.wsgi.application'couldnotbeloaded;Errorimportingmodule.     ------------------------------百度......
  • Vue3 - 移动端配置Rem布局
    1、项目搭建2、安装插件npminstallamfe-flexible--savenpminstallpostcss-pxtorem--save-dev3、引入插件import'amfe-flexible'//main.ts4、vite.config.ts配置import{defineConfig}from'vite'importpostCssPxToRemfrom'postcss-pxtore......
  • Java微服务SpringCloud+Uniapp+Vue3+Element Plus开源BizSpring商城
    产品介绍BizSpring电商平台概述BizSpring电商平台,是基于最新SpringCloud微服务架构开发的多语言电商平台,使用领先的Vue3.0+ElementPlus+uniapp技术开发的移动全端业务、实现了多平台同步构建及建设的解决方案。应用发布基于Uni-app,实现跨多个平台(H5、公众号、头条、抖音......