# 动画

提示

以下函数的命名空间为vjmap,执行前记得加上vjmap,如 vjmap.createAnimation

# 动画

animate 执行关键帧或弹簧动画。

createAnimation({
  from: 0,
  to: 100,
  onUpdate: latest => console.log(latest)
})
1
2
3
4
5

它可以为数字设置动画:

createAnimation({ from: 0, to: 100 })
1

或相同类型的字符串:

createAnimation({ from: "0px", to: "100px" })
createAnimation({ from: "#fff", to: "#000" })
1
2

字符串可能非常复杂,例如框阴影或 SVG 路径定义。唯一的限制是其中包含的数字和颜色必须按相同顺序排列:

createAnimation({
  from: "0px 0px 0px rgba(0, 0, 0, 0)",
  to: "10px 10px 0px rgba(0, 0, 0, 0.2)"
})
1
2
3
4

执行的动画类型将从提供的选项中自动检测,或者可以通过定义type"keyframes""spring"或手动选择"decay"

# 选项

可以为所有动画设置这些选项:

# from

开始动画的初始值。

默认为 0

createAnimation({
  from: "linear-gradient(#e66465, #9198e5)",
  to: "linear-gradient(#9198e5, #e66465)"
})
1
2
3
4

# elapsed

设置初始经过时间,以毫秒为单位。为延迟设置为负值。

createAnimation({
  to: 100,
  elapsed: -300
})
1
2
3
4

# repeat

重复动画的次数。设置为Infinity永远重复。

createAnimation({
  to: 100,
  repeat: 2
})
1
2
3
4

# repeatDelay

在重复动画之前等待的持续时间(以毫秒为单位)。

createAnimation({
  to: 100,
  repeat: 2,
  repeatDelay: 200
})
1
2
3
4
5

# repeatType

要么"loop""mirror"要么"reverse"。默认为"loop".

  • "loop":从 重复动画0
  • "mirror":交替交换from/to值。
  • "reverse": 交替反转动画。
createAnimation({
  to: 100,
  repeat: 2,
  repeatType: "reverse"
})
1
2
3
4
5

# type

animate将根据提供的选项自动检测要使用的动画类型。但是可以通过定义type为"keyframes","spring"或手动选择特定类型"decay"。

createAnimation({
  to: 100,
  type: "spring"
})
1
2
3
4

# 生命周期事件

以下生命周期事件可用于所有动画:

# onUpdate

这被称为动画以最新计算值触发的每一帧。

createAnimation({
  to: 100,
  onUpdate: latest => console.log(latest)
})
1
2
3
4

# onPlay

这在动画开始时调用。当前,这会在animate被调用时自动执行。

createAnimation({
  to: 100,
  onPlay: () => {}
})
1
2
3
4

# onComplete

当动画成功完成时调用它。

createAnimation({
  to: 100,
  onComplete:() => {}
})
1
2
3
4

# onRepeat

这在动画重复时调用。

createAnimation({
  to: 100,
  repeat: 2,
  onRepeat: () => {}
})
1
2
3
4
5

# onStop

当stop控件停止动画时调用此方法。

const animation = createAnimation({
  to: 100,
  onStop: () => {}
})

animation.stop()
1
2
3
4
5
6

关键帧选项

关键帧动画是默认的动画类型,可以使用from和to选项定义:

createAnimation({ from: 0, to: 100 })
1

或者作为提供给to选项的一系列关键帧:

createAnimation({ to: [0, 100, 200] })
1

# to

要设置动画的单个值,或要设置动画的值数组。

createAnimation({
  to: ["#0ff", "#f00", "#0f0"]
})
1
2
3

如果to是一个数组,任何定义的from都将被忽略。

# duration

这定义了动画的持续时间,以毫秒为单位。

createAnimation({
  to: 100,
  duration: 300
})
1
2
3
4

# ease

这是一个缓动函数或函数数组,用于在每个关键帧之间进行缓动。

nimate({
  to: 100,
  ease: linear
})

createAnimation({
  to: ["#fff", "#000", "#f00"],
  ease: [linear, easeInOut]
})
1
2
3
4
5
6
7
8
9

如果设置为任何数组,则此数组的长度必须比在其间设置动画的值的数量短一。

# offset

这是一个介于0和之间的值数组,1它定义了在整个动画中应该到达每个关键帧的哪个点。

该数组的长度应与定义的关键帧数相同。

createAnimation({
  to: ["#fff", "#000", "#f00"],
  offset: [0, 0.2, 1]
})
1
2
3
4

# 弹簧选项

Springs 非常适合创建自然感觉的界面和动态的可中断动画。

如果检测到stiffness,damping或mass选项中的任何一个,则将使用弹簧动画。

注意:弹簧模拟本质上是数值型的,因此如果给它一个颜色、数组或对象,它会从0to运行动画100并将其插入到给定的值。

# to

要动画化的单个值。

createAnimation({
  to: 100,
  type: "spring"
})
1
2
3
4

如果to是一个数组,任何定义的from都将被忽略。

# stiffness

这定义了弹簧的刚度。更高的刚度将产生更快速的动画。

默认为 100

createAnimation({
  to: 100,
  stiffness: 1000
})
1
2
3
4

# damping

这是 的反作用力stiffness。当您相对于 减小此值时,stiffness弹簧将变得更有弹性并且动画将持续更长时间。同样,较高的相对值将具有较小的弹性并导致动画较短。

默认为 10

createAnimation({
  to: 100,
  damping: 50
})
1
2
3
4

# mass

这是动画对象的质量。较重的物体需要更长的时间来加速和减速。

默认为1.

createAnimation({
  to: 100,
  mass: 2
})
1
2
3
4

# velocity

动画的初始速度,以每秒为单位。

createAnimation({
  to: 100,
  velocity: 1000
})
1
2
3
4

# duration

弹簧的持续时间,以毫秒为单位。

将被stiffness,mass或覆盖damping。

createAnimation({
  to: 100,
  duration: 1000
})
1
2
3
4

# bounce

弹簧的弹力,作为0和之间的值1,其中0没有弹跳。

将被stiffness,mass或damping覆盖。

createAnimation({
  to: 100,
  bounce: 0.2
})
1
2
3
4

# restDelta

距动画目标的距离,在该距离处动画可以被视为完成。当restDelta和restSpeed都满足时,动画完成。

createAnimation({
  to: 100,
  restDelta: 0.5
})
1
2
3
4

# restSpeed

绝对速度,以每秒单位数为单位,低于该速度可以认为动画完成。当restDelta和restSpeed都满足时,动画完成。默认为10.

js createAnimation({ to: 100, restSpeed: 5 })

# 播放控制

createAnimation 返回 PlaybackControls,可用于控制动画的播放。

目前这只包括一个stop方法,但可能会扩展更多。

# stop

停止动画。

const playback = createAnimation({ from: 0, to: 100 })
playback.stop()
1
2

# inertia

该inertia动画用于逐渐减速一个数字。

# 选项

除了from,onUpdateonComplete之外,inertia还支持以下内容:

# velocity

动画的初始速度,以每秒为单位。

inertia({
  from: 0,
  velocity: 100
})
1
2
3
4

# power

用于计算目标值的常数。更高的功率 = 进一步的目标。

默认为0.8.

inertia({
  from: 0,
  power: 0.3
})
1
2
3
4

# timeConstant

调整时间常数会改变减速的持续时间。

默认为350.

inertia({
  from: 0,
  velocity: 100,
  timeConstant: 400
})
1
2
3
4
5

# modifyTarget

一个接收计算目标并返回一个新目标的函数。用于将目标捕捉到网格。

const roundToNearest = target => v => Math.ceil(v / target) * target

inertia({
  from: 0,
  velocity: 100,
  modifyTarget: roundToNearest(100)
})
1
2
3
4
5
6
7

# min

动画将从逐渐减速切换并使用弹簧动画捕捉到该点的最小值。

inertia({
  from: 50,
  velocity: -100,
  min: 0
})
1
2
3
4
5

# max

动画将从逐渐减速切换并使用弹簧动画捕捉到该点的最大值。

inertia({
  from: 50,
  velocity: 100,
  max: 100
})
1
2
3
4
5

# bounceStiffness

这定义了动画命中min或时弹簧的刚度max。更高的刚度将产生更快速的动画。

默认为 500

inertia({
  from: 0,
  velocity: 100,
  max: 50,
  bounceStiffness: 1000
})
1
2
3
4
5
6

# bounceDamping

这是 的反作用力bounceStiffness。当您相对于 减小此值时,bounceStiffness弹簧将变得更有弹性并且动画将持续更长时间。同样,较高的相对值将具有较小的弹性并导致动画较短。

默认为 10

inertia({
  from: 0,
  velocity: 100,
  max: 50,
  bounceDamping: 300
})
1
2
3
4
5
6

# restDelta

距动画目标的距离,在该距离处动画可以被视为完成。

inertia({
  from: 0,
  velocity: 100,
  restDelta: 0.5
})
1
2
3
4
5

# 迭代器

迭代器使您能够以高度控制的方式运行动画。

每个都可以使用上面的匹配选项进行初始化(decay使用inertia's 选项的子集,不包括bounce-选项):

const animation = spring({
  from: 0,
  to: 100,
  stiffness: 200
})
1
2
3
4
5

使用返回的迭代器,您可以使用其next方法在特定时间戳处解析动画。

// 在 200 毫秒时解析动画
const { value, done } = animation.next(200)
1
2

# Easing

内置的缓动功能

# 函数

每个缓动函数都可以像这样导入:

每个函数都接受0和之间的进度值1,并返回一个新值:

const progress = 0.5
const easedProgress = easeInOut(progress)
1
2
  • linear
  • easeIn
  • easeInOut
  • easeOut
  • circIn
  • circInOut
  • circOut
  • backIn
  • backInOut
  • backOut
  • anticipate
  • bounceIn
  • bounceInOut
  • bounceOut

# cubicBezier

const easing = cubicBezier(0, .42, 0, 1)
1

# steps

steps 返回一个缓动函数,它将动画转换为一系列离散的步骤。

const easing = steps(5)
1

它可以选择接受第二个参数,"start"或者"end"(默认)决定步骤是与动画的开始还是结束对齐。

steps(5, "start")
1

# mirrorEasing

镜像现有的缓动函数。

# reverseEasing

反转现有的缓动函数。例如,提供它easeIn会返回一个easeOut.

const reversed = reverseEasing(linear)
reversed(1) // 0
reversed(0.5) // 0.5
reversed(0) // 1
1
2
3
4

# createExpoIn

根据所提供的指数创建缓动函数power。越高power,宽松力度越大。

const expoIn = createExpoIn(4)
1

返回的缓动函数是缓动函数,这意味着它开始缓慢,结束迅速。mirrorEasing并且reverseEasing可用于创建缓入和缓出变体:

const expoIn = createExpoIn(4)
const expoOut = mirrorEasing(easeIn)
const expoInOut = reverseEasing(easeIn)
1
2
3

# createBackIn

创建一个带有过冲的缓动函数。它接受一个power值,越高power越强过冲。

const backIn = createBackIn(4)
1

返回的缓动函数是缓入,这意味着过冲发生在动画开始时。mirrorEasing并且reverseEasing可用于创建缓入和缓出变体:

const backIn = createBackIn(4)
const backOut = mirrorEasing(easeIn)
const backInOut = reverseEasing(easeIn)
1
2
3

# createAnticipate

创建一个缓动,在以过冲进行动画处理之前稍微向后拉。越强power,过冲越大。

const anticipate = createAnticipate(4)
1

# 通用

# angle

返回两点之间的角度,以度为单位。

angle(
  { x: 0, y: 0 },
  { x: 45, y: 100 }
)
1
2
3
4

# attract

attract(5, 10, 12)
1

# attractExpo

attractExpo(5, 10, 12)
1

# clamp

将值限制在给定范围内。

const min = 50
const max = 100
clamp(min, max, 150) // 100
1
2
3

# degreesToRadians

将度数转换为弧度。

degreesToRadians(45) // 0.785...
1

# distance

返回两个数字、两个 2D 点或两个 3D 点之间的距离。

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 })
1
2
3

# interpolate

创建一个函数,该函数将从线性数字序列插入到非线性数字序列、相同数字格式的字符串、颜色或它们的数组/对象。

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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 选项

interpolate 接受可选的第三个参数,一个选项对象。

  • clamp:将值限制在给定范围内。默认为true.
  • ease:一个Easing函数或缓动函数数组,用于缓和每个段的插值。
  • mixer:一个函数,当提供 afrom和to值时,将返回一个新函数,该函数接受这两个值之间的进度值0并1在这两个值之间进行混合。

# isPoint

如果提供的参数是 2D 点,则返回true。

isPoint({ x: 0 }) // false
isPoint({ x: 0, y: 0 }) // true
1
2

# isPoint3D

如果提供的参数是 3D 点,则返回true。

isPoint3D({ x: 0 }) // false
isPoint3D({ x: 0, y: 0 }) // false
isPoint3D({ x: 0, y: 0, z: 0 }) // true
1
2
3

# mix

将在两个值之间混合,progress作为第三个参数给出。

mix(0, 100, 0.5) // 50
mix(0, 100, 2) // 200
1
2

# mixColor

返回一个函数,当提供一个progress值时,它将在两种颜色之间混合。接受十六进制、rgba 和 hsla 颜色。

mixColor("#000", "#fff")(0.5) // "rgba(125, 125, 125, 1)"
1

# mixComplex

返回一个函数,当提供一个progress值时,它将在具有相同数字和颜色顺序的两个字符串之间混合。

mixComplex("100px #fff", "0px #000")(0.5) // "50px rgba(125, 125, 125, 1)"
1

# pointFromVector

给定一个点,以度为单位的角度和距离,将返回一个新点。

const point = { x: 0, y: 0 }
const angle = 45
const distance = 100

pointFromVector(point, angle, distance)
1
2
3
4
5

# progress

给定一个最小和最大范围以及一个值,将返回progress范围内的值归一化为0-1范围。

const min = 100
const max = 200
progress(min, max, 150) // 0.5
1
2
3

# radiansToDegrees

将弧度转换为度数。

radiansToDegrees(0.785) // 45
1

# snap

创建一个函数,它将数字捕捉到提供的数组中最近的位置或固定间隔。

// 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# toDecimal

将数字四舍五入到特定的小数位。

toDecimal(3.3333); // 3.33
toDecimal(6.6666, 1); // 6.67
1
2

# velocityPerFrame

velocityPerFrame(50, 16.7); // 0.835
1

# velocityPerSecond

velocityPerSecond(1, 16.7); // 59.880...
1

# wrap

wrap(0, 1, 0.5); // 0.5
wrap(0, 1, 1.5); // 0.5
1
2