Uniapp、小程序中实现抛物线(贝塞尔曲线)加入购物车
一、cubic-bezier()函数
贝塞尔曲线(Bézier Curve)是一种在计算机图形学中广泛应用的数学曲线,它可以帮助我们绘制平滑的曲线图形。通过几个控制点来决定曲线形状。最基本的贝塞尔曲线需要两个端点(起始点和结束点)以及一个或多个中间控制点。曲线并不一定经过这些控制点之外的点,而是受到它们的“牵引”,形成平滑的路径。
实现贝塞尔曲线加入购物车,需要用到CSS中的cubic-bezier()
函数。
cubic-bezier()
函数是CSS中用于定义动画速度变化的一种时间函数,属于animation-timing-function属性的值之一。它通过四个参数定义了一个三次贝塞尔曲线,决定了动画在不同时间段的速度变化。这四个参数分别代表了贝塞尔曲线的两个控制点坐标,决定了动画的加速、减速模式。
贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义。P0 和 P3 是曲线的起点和终点。P0是(0,0)并且表示初始时间和初始状态,P3是(1,1)并且表示最终时间和最终状态。
从上图我们需要知道的是 cubic-bezier 的取值范围:
P0:默认值 (0, 0)
P1:动态取值 (x1, y1)
P2:动态取值 (x2, y2)
P3:默认值 (1, 1)
我们需要关注的是 P1 和 P2 两点的取值,而其中 X 轴的取值范围是 0 到 1,当取值超出范围时 cubic-bezier 将失效;Y 轴的取值没有规定,当然也毋须过大。
最直接的理解是,将以一条直线放在范围只有 1 的坐标轴中,并从中间拿出两个点来拉扯(X 轴的取值区间是 [0, 1],Y 轴任意),最后形成的曲线就是动画的速度曲线。
cubic-bezier(x1, y1, x2, y2)
x1, y1
: 第一个控制点坐标,决定动画开始时的加速度。x2, y2
: 第二个控制点坐标,决定动画结束前的减速模式。- 数字值,x1 和 x2 需要是 0 到 1 的数字。
二、实现方法
JS部分,可以直接复制改代码,哪里需要触发该函数请自行选择。
bezier() {
//实现贝塞尔
// 获取点击按钮和购物车图标元素
const btn = document.querySelector('#id_addShopCar'); // 点击的加入购物车按钮元素的ID,替换为你自己的元素的ID
const car = document.querySelector('#id_shopCar'); // 购物车图标元素的ID,替换为你自己的元素的ID
const PLUS_SIZE = 20; // 加号图标尺寸,可修改
// 创建一个动画元素(用于动画效果)
const div = document.createElement('div');
//将样式添加上去
div.className = 'plus-bezier';
//需要插入一个元素,最后移动的是该元素
div.innerHTML = `<div class="plus-bezier-icon">+</div>`;
// 获取购物车按钮的位置信息
const btnRect = btn.getBoundingClientRect();
// 计算动画元素的初始左偏移,因为要冲按钮的中间位置弹出
const left = btnRect.left + btnRect.width / 2 - PLUS_SIZE / 2;
// 计算动画元素的初始上偏移
const top = btnRect.top - PLUS_SIZE;
//将初始位置赋值给元素
div.style.setProperty('--left', `${left}px`);
div.style.setProperty('--top', `${top}px`);
// 获取购物车图标的位置信息
const carRect = car.getBoundingClientRect();
// 计算动画元素的终点水平偏移,要落到购物车的中间位置
const x = carRect.left + carRect.width / 2 - PLUS_SIZE / 2 - left;
// 计算动画元素的终点垂直偏移
const y = carRect.top - PLUS_SIZE - top;
// 设置动画元素的终点位置
div.style.setProperty('--x', `${x}px`);
div.style.setProperty('--y', `${y}px`);
// 监听动画结束事件,移除动画元素
div.addEventListener('animationend', () => {
div.remove();
});
// 将动画元素添加到页面中
document.body.appendChild(div);
},
CSS部分,该部分代码一定一定一定要放到app.vue中,作为全局样式,否则可能因为加载顺序原因,css未进行加载,将导致页面无法产生效果。
.plus-bezier {
position: fixed;
top: var(--top);
left: var(--left);
width: 20px;
height: 20px;
line-height: 20px;
border-radius: 50%;
z-index: 9999;
}
.plus-bezier-icon {
width: 100%;
height: 100%;
background-color: #16b29d;
border-radius: 50%;
text-align: center;
background-color: rgba(36, 147, 241, 1);
color: #fff;
}
//动画事件自行设定
.plus-bezier {
animation: moveY 0.8s cubic-bezier(0.5, -0.5, 1, 1);
}
.plus-bezier-icon {
animation: moveX 0.8s linear;
}
@keyframes moveX {
to {
transform: translateX(var(--x));
}
}
@keyframes moveY {
to {
transform: translateY(var(--y));
}
}
以上就是实现贝塞尔曲线加入购物车效果的方式,方法较为通用,如果需要多次使用,可以将函数全局暴露。