储存、释放与损耗——运动系统的动画规律:弹簧动画

ios_spring_animation_gif.gif (800×600) (dribbble.com)

弹簧动画原理

弹簧动画指的是符合弹簧物理特性的动画,这种动画形式连贯流畅,能让动画元素显得更鲜活。例如,苹果等前端设计中常运用弹簧动画,为用户提供更丝滑的体验。

弹簧系统的物理基础

根据胡克定律,在弹簧系统中,弹力 𝐹 和位移 𝑥 的关系为:
F=kx
根据这条定理,我们可以进一步推导出,在没有阻尼的情况下弹簧应该做简谐运动

在弹簧释放弹力的过程中,会由内部摩擦,外部摩擦等关系损耗掉这些弹力,因此,弹簧不会做往返的简谐运动,在此过程中,消耗掉弹力的因子我们称之为阻尼

阻尼的类型

根据阻尼的大小,弹簧的运动可以分为四种状态:无阻尼、欠阻尼、临界阻尼和过阻尼。下列代码展示了不同阻尼下弹簧的运动性质:

import numpy as np

import matplotlib.pyplot as plt

from scipy.integrate import solve_ivp

  

# 设置字体的属性

# plt.rcParams["font.sans-serif"] = "Arial Unicode MS"

plt.rcParams["font.sans-serif"] = "SimHei"

plt.rcParams["axes.unicode_minus"] = False

  

# 定义系统的参数

m = 1.0  # 质量

k = 1.0  # 弹簧常数

  

# 定义初始条件

x0 = -1.0  # 初始位移

v0 = 0.0  # 初始速度

  

# 定义时间范围

t = np.linspace(0, 20, 400)

  

# 系统的微分方程

def damped_oscillator(t, y, m, c, k):

    x, v = y

    dxdt = v

    dvdt = -(c/m) * v - (k/m) * x

    return [dxdt, dvdt]

  

# 不同阻尼情况的系数

damping_cases = {

    '无阻尼': 0,

    '欠阻尼': 0.5,

    '临界阻尼': 2 * np.sqrt(m * k),

    '过阻尼': 5,

}

  

# 创建绘图

plt.figure(figsize=(10, 8))

  

for label, c in damping_cases.items():

    sol = solve_ivp(damped_oscillator, [0, t[-1]], [x0, v0], args=(m, c, k), t_eval=t)

    plt.plot(sol.t, sol.y[0], label=label)

  

# 添加图例和标签

plt.title('弹簧系统的运动曲线')

plt.xlabel('时间 (s)')

plt.ylabel('位移 (m)')

plt.legend()

plt.grid(True)

  

# 显示图形

plt.show()

运行结果如下图所示:
Figure_1.png

而这就是弹簧动画所使用的曲线

相关资料:
WWDC23: 用弹簧制作动画 | Apple (youtube.com)