---
title: 动画
source: https://vjmap.com/guide/animation.html
---

# 动画
::: tip 提示
以下函数的命名空间为`vjmap`，执行前记得加上`vjmap`，如 vjmap.`createAnimation`
:::
## 动画

`animate` 执行关键帧或弹簧动画。

```js
createAnimation({
  from: 0,
  to: 100,
  onUpdate: latest => console.log(latest)
})
```

它可以为数字设置动画：

```js
createAnimation({ from: 0, to: 100 })
```

或相同类型的字符串：

```js
createAnimation({ from: "0px", to: "100px" })
createAnimation({ from: "#fff", to: "#000" })
```

字符串可能非常复杂，例如框阴影或 SVG 路径定义。唯一的限制是其中包含的数字和颜色必须按相同顺序排列：

```js
createAnimation({
  from: "0px 0px 0px rgba(0, 0, 0, 0)",
  to: "10px 10px 0px rgba(0, 0, 0, 0.2)"
})
```

执行的动画类型将从提供的选项中自动检测，或者可以通过定义`type`为`"keyframes"`、`"spring"`或手动选择`"decay"`。

### 选项

可以为**所有动画**设置这些选项：

#### from
开始动画的初始值。

默认为 `0`

```js
createAnimation({
  from: "linear-gradient(#e66465, #9198e5)",
  to: "linear-gradient(#9198e5, #e66465)"
})
```

#### elapsed

设置初始经过时间，以毫秒为单位。为延迟设置为负值。

```js
createAnimation({
  to: 100,
  elapsed: -300
})
```
#### repeat

重复动画的次数。设置为`Infinity`永远重复。

```js
createAnimation({
  to: 100,
  repeat: 2
})
```

#### repeatDelay


在重复动画之前等待的持续时间（以毫秒为单位）。

```js
createAnimation({
  to: 100,
  repeat: 2,
  repeatDelay: 200
})
```

#### repeatType

要么`"loop"`，`"mirror"`要么`"reverse"`。默认为`"loop"`.

- `"loop"`：从 重复动画`0`。
- `"mirror":`交替交换`from`/`to`值。
- `"reverse":` 交替反转动画。

```js
createAnimation({
  to: 100,
  repeat: 2,
  repeatType: "reverse"
})
```

#### type
animate将根据提供的选项自动检测要使用的动画类型。但是可以通过定义type为"keyframes","spring"或手动选择特定类型"decay"。

```js
createAnimation({
  to: 100,
  type: "spring"
})
```

### 生命周期事件

以下生命周期事件可用于所有动画：

#### onUpdate

这被称为动画以最新计算值触发的每一帧。

```js
createAnimation({
  to: 100,
  onUpdate: latest => console.log(latest)
})
```
#### onPlay

这在动画开始时调用。当前，这会在animate被调用时自动执行。

```js
createAnimation({
  to: 100,
  onPlay: () => {}
})
```

#### onComplete

当动画成功完成时调用它。

```js
createAnimation({
  to: 100,
  onComplete:() => {}
})
```

#### onRepeat

这在动画重复时调用。

```js
createAnimation({
  to: 100,
  repeat: 2,
  onRepeat: () => {}
})
```

#### onStop

当stop控件停止动画时调用此方法。

```js
const animation = createAnimation({
  to: 100,
  onStop: () => {}
})

animation.stop()
```

关键帧选项

关键帧动画是默认的动画类型，可以使用from和to选项定义：

```js
createAnimation({ from: 0, to: 100 })
```

或者作为提供给to选项的一系列关键帧：

```js
createAnimation({ to: [0, 100, 200] })
```

#### to

要设置动画的单个值，或要设置动画的值数组。

```js
createAnimation({
  to: ["#0ff", "#f00", "#0f0"]
})
```
如果to是一个数组，任何定义的from都将被忽略。

#### duration

这定义了动画的持续时间，以毫秒为单位。

```js
createAnimation({
  to: 100,
  duration: 300
})
```


#### ease
这是一个缓动函数或函数数组，用于在每个关键帧之间进行缓动。


```js
nimate({
  to: 100,
  ease: linear
})

createAnimation({
  to: ["#fff", "#000", "#f00"],
  ease: [linear, easeInOut]
})
```

如果设置为任何数组，则此数组的长度必须比在其间设置动画的值的数量短一。

#### offset

这是一个介于0和之间的值数组，1它定义了在整个动画中应该到达每个关键帧的哪个点。

该数组的长度应与定义的关键帧数相同。

```js
createAnimation({
  to: ["#fff", "#000", "#f00"],
  offset: [0, 0.2, 1]
})
```

### 弹簧选项

Springs 非常适合创建自然感觉的界面和动态的可中断动画。

如果检测到stiffness,damping或mass选项中的任何一个，则将使用弹簧动画。

注意：弹簧模拟本质上是数值型的，因此如果给它一个颜色、数组或对象，它会从0to运行动画100并将其插入到给定的值。

#### to
要动画化的单个值。

```js
createAnimation({
  to: 100,
  type: "spring"
})
```

如果to是一个数组，任何定义的from都将被忽略。

#### stiffness
这定义了弹簧的刚度。更高的刚度将产生更快速的动画。

默认为 100

```js
createAnimation({
  to: 100,
  stiffness: 1000
})
```

#### damping
这是 的反作用力stiffness。当您相对于 减小此值时，stiffness弹簧将变得更有弹性并且动画将持续更长时间。同样，较高的相对值将具有较小的弹性并导致动画较短。

默认为 10

```js
createAnimation({
  to: 100,
  damping: 50
})
```

#### mass
这是动画对象的质量。较重的物体需要更长的时间来加速和减速。

默认为1.

```js
createAnimation({
  to: 100,
  mass: 2
})
```
####  velocity
动画的初始速度，以每秒为单位。

```js
createAnimation({
  to: 100,
  velocity: 1000
})
```

#### duration
弹簧的持续时间，以毫秒为单位。

将被stiffness,mass或覆盖damping。

```js
createAnimation({
  to: 100,
  duration: 1000
})
```

#### bounce
弹簧的弹力，作为0和之间的值1，其中0没有弹跳。

将被stiffness,mass或damping覆盖。

```js
createAnimation({
  to: 100,
  bounce: 0.2
})
```

#### restDelta
距动画目标的距离，在该距离处动画可以被视为完成。当restDelta和restSpeed都满足时，动画完成。

```js
createAnimation({
  to: 100,
  restDelta: 0.5
})
```

#### restSpeed
绝对速度，以每秒单位数为单位，低于该速度可以认为动画完成。当restDelta和restSpeed都满足时，动画完成。默认为10.

``js
createAnimation({
  to: 100,
  restSpeed: 5
})
``

### 播放控制
`createAnimation` 返回 `PlaybackControls`，可用于控制动画的播放。

目前这只包括一个stop方法，但可能会扩展更多。

#### stop
停止动画。

```js
const playback = createAnimation({ from: 0, to: 100 })
playback.stop()
```

### inertia
该inertia动画用于逐渐减速一个数字。

####  选项
除了`from`,`onUpdate`和`onComplete`之外，`inertia`还支持以下内容：

#### velocity
动画的初始速度，以每秒为单位。

```js
inertia({
  from: 0,
  velocity: 100
})
```

#### power
用于计算目标值的常数。更高的功率 = 进一步的目标。

默认为0.8.

```js
inertia({
  from: 0,
  power: 0.3
})
```

#### timeConstant

调整时间常数会改变减速的持续时间。

默认为350.

```js
inertia({
  from: 0,
  velocity: 100,
  timeConstant: 400
})
```

#### modifyTarget
一个接收计算目标并返回一个新目标的函数。用于将目标捕捉到网格。

```js
const roundToNearest = target => v => Math.ceil(v / target) * target

inertia({
  from: 0,
  velocity: 100,
  modifyTarget: roundToNearest(100)
})
```

#### min
动画将从逐渐减速切换并使用弹簧动画捕捉到该点的最小值。

```js
inertia({
  from: 50,
  velocity: -100,
  min: 0
})
```

#### max
动画将从逐渐减速切换并使用弹簧动画捕捉到该点的最大值。

```js
inertia({
  from: 50,
  velocity: 100,
  max: 100
})
```

#### bounceStiffness
这定义了动画命中min或时弹簧的刚度max。更高的刚度将产生更快速的动画。

默认为 500

```js
inertia({
  from: 0,
  velocity: 100,
  max: 50,
  bounceStiffness: 1000
})
```

#### bounceDamping
这是 的反作用力bounceStiffness。当您相对于 减小此值时，bounceStiffness弹簧将变得更有弹性并且动画将持续更长时间。同样，较高的相对值将具有较小的弹性并导致动画较短。

默认为 10

```js
inertia({
  from: 0,
  velocity: 100,
  max: 50,
  bounceDamping: 300
})
```

#### restDelta
距动画目标的距离，在该距离处动画可以被视为完成。

```js
inertia({
  from: 0,
  velocity: 100,
  restDelta: 0.5
})
```

### 迭代器

迭代器使您能够以高度控制的方式运行动画。

每个都可以使用上面的匹配选项进行初始化（decay使用inertia's 选项的子集，不包括bounce-选项）：

```js
const animation = spring({
  from: 0,
  to: 100,
  stiffness: 200
})
```

使用返回的迭代器，您可以使用其next方法在特定时间戳处解析动画。

```js
// 在 200 毫秒时解析动画
const { value, done } = animation.next(200)
```

## Easing
内置的缓动功能

### 函数
每个缓动函数都可以像这样导入：

每个函数都接受0和之间的进度值1，并返回一个新值：

```js
const progress = 0.5
const easedProgress = easeInOut(progress)
```

- linear
- easeIn
- easeInOut
- easeOut
- circIn
- circInOut
- circOut
- backIn
- backInOut
- backOut
- anticipate
- bounceIn
- bounceInOut
- bounceOut


#### cubicBezier

```js
const easing = cubicBezier(0, .42, 0, 1)
```

#### steps
steps 返回一个缓动函数，它将动画转换为一系列离散的步骤。

```js
const easing = steps(5)
```
它可以选择接受第二个参数，"start"或者"end"（默认）决定步骤是与动画的开始还是结束对齐。

```js
steps(5, "start")
```

#### mirrorEasing
镜像现有的缓动函数。

#### reverseEasing
反转现有的缓动函数。例如，提供它easeIn会返回一个easeOut.

```js
const reversed = reverseEasing(linear)
reversed(1) // 0
reversed(0.5) // 0.5
reversed(0) // 1
```

#### createExpoIn
根据所提供的指数创建缓动函数power。越高power，宽松力度越大。

```js
const expoIn = createExpoIn(4)
```

返回的缓动函数是缓动函数，这意味着它开始缓慢，结束迅速。mirrorEasing并且reverseEasing可用于创建缓入和缓出变体：

```js
const expoIn = createExpoIn(4)
const expoOut = mirrorEasing(easeIn)
const expoInOut = reverseEasing(easeIn)
```

#### createBackIn
创建一个带有过冲的缓动函数。它接受一个power值，越高power越强过冲。

 ```js
 const backIn = createBackIn(4)
 ```

返回的缓动函数是缓入，这意味着过冲发生在动画开始时。mirrorEasing并且reverseEasing可用于创建缓入和缓出变体：

```js
const backIn = createBackIn(4)
const backOut = mirrorEasing(easeIn)
const backInOut = reverseEasing(easeIn)
```

#### createAnticipate
创建一个缓动，在以过冲进行动画处理之前稍微向后拉。越强power，过冲越大。

```js
const anticipate = createAnticipate(4)
```

### 通用

#### angle
返回两点之间的角度，以度为单位。

```js
angle(
  { x: 0, y: 0 },
  { x: 45, y: 100 }
)
```

#### attract

```js
attract(5, 10, 12)
```

#### attractExpo

```js
attractExpo(5, 10, 12)
```

#### clamp
将值限制在给定范围内。

```js
const min = 50
const max = 100
clamp(min, max, 150) // 100
```

#### degreesToRadians
将度数转换为弧度。

```js
degreesToRadians(45) // 0.785...
```

#### distance
返回两个数字、两个 2D 点或两个 3D 点之间的距离。

```js
distance(10, 50)
distance({ x: 0, y: 0 }, { x: 45, y: 100 })
distance({ x: 0, y: 0, z: 100 }, { x: 45, y: 100, z: 0 })
```

#### interpolate
创建一个函数，该函数将从线性数字序列插入到非线性数字序列、相同数字格式的字符串、颜色或它们的数组/对象。


```js
const mapXToOpacity = interpolate(
  [-100, 0, 100],
  [0, 1, 0]
)
mapXToOpacity(-50) // 0.5

const mapProgressToValues = interpolate(
  [0, 1],
  [
    { x: 0, color: "#fff" },
    { x: 100, color: "#000" }
  ]
)
mapProgressToValues(0.5) // { x: 50, color: "#888" }

const rescale = interpolate(
  [0, 1],
  [100, 200],
  { clamp: false }
)
rescale(2) // 300
```

##### 选项
interpolate 接受可选的第三个参数，一个选项对象。

- clamp：将值限制在给定范围内。默认为true.
- ease：一个Easing函数或缓动函数数组，用于缓和每个段的插值。
- mixer：一个函数，当提供 afrom和to值时，将返回一个新函数，该函数接受这两个值之间的进度值0并1在这两个值之间进行混合。

#### isPoint
如果提供的参数是 2D 点，则返回true。

```js
isPoint({ x: 0 }) // false
isPoint({ x: 0, y: 0 }) // true
```

####  isPoint3D
如果提供的参数是 3D 点，则返回true。

```js
isPoint3D({ x: 0 }) // false
isPoint3D({ x: 0, y: 0 }) // false
isPoint3D({ x: 0, y: 0, z: 0 }) // true
```

#### mix
将在两个值之间混合，progress作为第三个参数给出。

```js
mix(0, 100, 0.5) // 50
mix(0, 100, 2) // 200
```

#### mixColor
返回一个函数，当提供一个progress值时，它将在两种颜色之间混合。接受十六进制、rgba 和 hsla 颜色。

 ```js
 mixColor("#000", "#fff")(0.5) // "rgba(125, 125, 125, 1)"
 ```

#### mixComplex
返回一个函数，当提供一个progress值时，它将在具有相同数字和颜色顺序的两个字符串之间混合。

```js
mixComplex("100px #fff", "0px #000")(0.5) // "50px rgba(125, 125, 125, 1)"
```

#### pointFromVector
给定一个点，以度为单位的角度和距离，将返回一个新点。

```js
const point = { x: 0, y: 0 }
const angle = 45
const distance = 100

pointFromVector(point, angle, distance)
```

#### progress
给定一个最小和最大范围以及一个值，将返回progress范围内的值归一化为0-1范围。

 ```js
const min = 100
const max = 200
progress(min, max, 150) // 0.5
```

#### radiansToDegrees
将弧度转换为度数。

```js
radiansToDegrees(0.785) // 45
```

#### snap
创建一个函数，它将数字捕捉到提供的数组中最近的位置或固定间隔。

 ```js
 // Snap to regular intervals
 const snapTo = snap(45);

 snapTo(1); // 0
 snapTo(40); // 45
 snapTo(50); // 45
 snapTo(80); // 90

 // Snap to values in an array
 const snapTo = snap([-100, -50, 100, 200]);

 snapTo(-200); // -100
 snapTo(-76); // -100
 snapTo(-74); // -50
 ```

#### toDecimal
将数字四舍五入到特定的小数位。

```js
toDecimal(3.3333); // 3.33
toDecimal(6.6666, 1); // 6.67
```

#### velocityPerFrame

```js
velocityPerFrame(50, 16.7); // 0.835
```

#### velocityPerSecond
```js
velocityPerSecond(1, 16.7); // 59.880...
```

#### wrap

```js
wrap(0, 1, 0.5); // 0.5
wrap(0, 1, 1.5); // 0.5
```