引言
在電商網站中,“加入購物車”動畫 是提升用戶體驗的經典交互之一。一個小小的商品圖標從頁面飄向購物車,不僅直觀地反饋了操作結果,還能增加趣味性與沉浸感。
實現這一效果的方式有很多,比如 JavaScript 計算路徑 + 動畫,或者 CSS3 動畫 + 貝塞爾曲線。本文將帶你從 CSS 動畫的基礎 出發,逐步講解如何利用 @keyframes、animation-timing-function 以及 多層容器組合 來實現一個優雅的 拋物線加入購物車效果,并提供完整代碼案例。
基礎代碼示例
我們先來看一個利用 嵌套元素 來實現 X 軸勻速、Y
軸曲線運動的拋物線動畫。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Parabola Animation</title></head><body><div class="container"><div class="box-x"><div class="box-y"><div class="box"></div></div></div></div></body><style>:root {--containerWidth: 400px;--containerHeight: 400px;}.container {width: var(--containerWidth);height: var(--containerHeight);position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);border: 1px solid black;}/* X 軸:勻速運動 */.box-x {animation: jumpX 0.8s infinite linear;}/* Y 軸:使用曲線模擬加速下落、減速上升 */.box-y {animation: jumpY 0.8s infinite cubic-bezier(0.75, 0.06, 0.94, 0.88);}.box {width: 30px;height: 30px;background-color: blueviolet;border-radius: 50%;}@keyframes jumpX {from {transform: translateX(0);}to {transform: translateX(calc(var(--containerWidth) - 30px));}}@keyframes jumpY {from {transform: translateY(0);}to {transform: translateY(calc(var(--containerHeight) - 30px));}}</style>
</html>
效果示例
為什么要用嵌套元素?
- 問題:
transform: translate(x, y)
會同時作用于 X 和
Y,如果我們在一個元素上設置animation-timing-function
,那么 X 和 Y
會同時受到影響。\ - 解決方案:通過嵌套結構,把 X 和 Y 的運動分開:
- 外層
.box-x
只管 X 軸,并設置linear
勻速運動; - 內層
.box-y
只管 Y 軸,并用cubic-bezier
調整速度曲線。
- 外層
這樣就能實現一個接近 物理拋物線 的運動效果。
animation-timing-function 詳解
animation-timing-function
控制動畫在
時間進度與實際位置之間的映射關系。常見值如下:
-
linear
- 勻速運動,沒有加速度。\
- 在本例中用于 X 軸運動。
animation-timing-function: linear;
-
ease
- 默認值,開始和結束慢,中間快。
animation-timing-function: ease;
-
ease-in
- 由慢到快,模擬加速進入。\
- 常用于模擬"加速下落"。
animation-timing-function: ease-in;
-
ease-out
- 由快到慢,模擬減速停止。\
- 常用于"物體上升或停止"。
animation-timing-function: ease-out;
-
ease-in-out
- 先加速,后減速。\
- 常用于"自然的往返運動"。
animation-timing-function: ease-in-out;
-
cubic-bezier(n, n, n, n)
- 自定義貝塞爾曲線,范圍為
0 ~ 1
。\ - 我們示例中的參數
cubic-bezier(0.75, 0.06, 0.94, 0.88)
,表現為
快速下落、緩慢上升,模擬重力加速度。
animation-timing-function: cubic-bezier(0.75, 0.06, 0.94, 0.88);
- 自定義貝塞爾曲線,范圍為
總結
- X 軸:使用
linear
勻速,保證水平運動自然。\ - Y 軸:使用
cubic-bezier
或
ease-in/ease-out
,制造出"加速下落、減速上升"的效果。\ - 嵌套結構:分離 X 和 Y 的動畫邏輯,是實現更復雜動畫的常用技巧。
通過 animation-timing-function
的不同曲線組合,我們可以在純 CSS
中模擬出接近物理效果的運動,增強動畫的自然感。
? 建議:在實際項目中,如果需要更精確的物理效果(比如拋物線軌跡公式
y = ax2 + bx + c
),可以考慮使用 JavaScript +
requestAnimationFrame 來實現。