# JSON 导出文件格式

本页描述了Spine的skeleton和动画数据的JSON导出文件格式. [Spine 运行时](/spine-runtimes)将加载这些数据以显示动画. 同时, Spine可以导入这种格式的数据从而实现与其他工具的操作互通. JSON导出文件可在 Spine Runtimes 的[各示例项目](/git/spine-runtimes/tree/examples)中找到.

Spine 运行时能处理和加载JSON和二进制数据. 你无需自己编写加载代码吗, 除非你准备从零开始打造你自己的运行时(这工作量浩瀚无涯).

JSON格式是人类可读可改的, 设置了 "规整格式化(pretty print)" 后更是如此. 这使得该格式在需要人工检查或以其他手段处理数据时成为一个不错的选择. 它还能在运行时发生细微改动后依旧保持健壮, 这可在运行时发生变化后亦无需重新导出数据. 其缺点是JSON格式的文件大小比[二进制格式](/spine-binary-format)要大, 在运行时中的加载速度稍慢.

标记为 "非必要(nonessential)" 的数据只有在导出设置中勾选了 `Nonessential data` 时才会被输出. 在渲染时不需要这些数据, 但它对于其他工具或将数据导入Spine时可能有用.

JSON格式是序列化后的"skeleton data" 实例, 它有一个包含了骨骼、槽位、皮肤和动画的列表. 它是无状态的数据, 与屏幕上某个具体的skeleton实例没有联系.

<a href="/files/runtime-diagram.png" target="blank"><img src="/files/runtime-diagram.png"/></a>


!!
# Skeleton #
导出文件的skeleton部分存储了关于skeleton的元数据.

skeleton JSON示例:
```
"skeleton": {
	"hash": "5WtEfO08B0TzTg2mDqj4IHYpUZ4",
	"spine": "3.8.24",
	"x": -17.2,
	"y": -13.3,
	"width": 470.86,
	"height": 731.44,
	"images": "./images/",
	"audio": "./audio/"
},
```

**Skeleton 属性:**
* **hash:** 所有skeleton数据的哈希值. 工具软件用它来检测Skeleton数据自上次加载后是否有变化.
* **version:** 导出数据的Spine版本. 工具软件用它将Skeleton数据限制于某个特定的Spine版本.
* **x:** skeleton附件AABB(axis-aligned bounding box)包围盒左下角点的X坐标, 与Spine中的setup pose相同.
* **y:** skeleton附件AABB包围盒左下角点的Y坐标, 与Spine中的setup pose相同.
* **width:** skeleton附件AABB包围盒宽度, 与Spine中的setup pose相同. 虽然skeleton的AABB盒取决于其pose, 但也可作为skeleton的大体尺寸.
* **height:** skeleton附件AABB包围盒高度, 与Spine中的setup pose相同.
* **fps:** Dopesheet(摄影表)的帧率, 单位为帧数/秒, 与Spine中相同. 若省略则默认为30. 非必要数据.
* **images:** 图像文件路径, 与Spine中相同. 非必要数据.
* **audio:** 音频文件路径, 与Spine中相同. 非必要数据.

# 骨骼(Bones) #
导出文件的bones部分存储了setup pose状态的骨骼数据.

bones skeleton JSON示例:
```
"bones": [
	{ "name": "root" },
	{ "name": "torso", "parent": "root", "length": 85.82, "x": -6.42, "y": 1.97, "rotation": 94.95 },
	...
],
```
骨骼是有序的, 父骨骼总是排在子骨骼之前.

**骨骼属性:**
* **name:** 骨骼名称, 该名称在skeleton上唯一.
* **length:** 骨骼长度. 运行时通常不使用骨骼长度属性, 除非需要为骨骼绘制调试线. 若省略则默认为0.
* **transform:** 该属性决定子骨骼以何种方式继承父骨骼的变换: normal, onlyTranslation, noRotationOrReflection, noScale或noScaleOrReflection. 若省略则默认为normal.
* **skin:** 若为true, 则只有当活动皮肤包含该骨骼时该骨骼才算活动. 若省略则默认为false.
* **x:** setup pose时骨骼相对于父对象位置的X值. 若省略则默认为0.
* **y:** setup pose时骨骼相对于父对象位置的Y值. 若省略则默认为0.
* **rotation:** setup pose时骨骼相对于父对象的旋转角度. 若省略则默认为0.
* **scaleX:** setup pose时骨骼X方向的缩放比例. 若省略则默认为1.
* **scaleY:** setup pose时骨骼Y方向的缩放比例. 若省略则默认为1.
* **shearX:** setup pose时骨骼X方向的斜切角度. 若省略则默认为0.
* **shearY:** setup pose时骨骼Y方向的斜切角度. 若省略则默认为0.
* **color:** 骨骼的颜色, 与Spine中相同. 若省略则默认为0x989898FF RGBA. 非必要数据.

# 槽位(Slots) 
槽位部分描述了绘制顺序和可分配附件的可用槽位.

slots skeleton JSON示例:
```
"slots": [
	{ "name": "left shoulder", "bone": "left shoulder", "attachment": "left-shoulder" },
	{ "name": "left arm", "bone": "left arm", "attachment": "left-arm" },
	...
],
```
如果没有槽位, "slots"部分可被省略. 槽位是按照setup pose的绘制顺序排序的. 索引较高的槽位中的图像被绘制在索引较低的槽位的图像之上.

**槽位属性:**
* **name:** 槽位名称. 该名称在skeleton上唯一.
* **bone:** 该槽位所在骨骼的名称.
* **color:**  setup pose时槽位的颜色. 它是一个长度为8的字符串, 包含4个按RGBA顺序排列的两位十六进制数字. 若省略alpha, 则alpha默认为 "FF". 若省略该属性则默认为 "FFFFFFF".
* **dark:** 设置setup pose时槽位用于双色tinting的dark color. 这是一个6个字符的字符串, 包含3个按RGB顺序排列的两位十六进制数字. 当不使用双色tinting时则省略.
* **attachment:** setup pose时槽位中附件的名称. 若省略则默认setup pose没有附件.
* **blend:** 在绘制槽位中可见附件时要使用的blend类别: normal, additive, multiply, 或screen.

# 约束(Constraints)

## IK约束
该节描述了[IK约束](/spine-ik-constraints).

```
"ik": [
	{
		"name": "left leg",
		"order": 2,
		"bones": [ "left thigh", "left shin" ],
		"target": "left ankle",
		"mix": 0.5,
		"bendPositive": false,
		"compress": true,
	},
	...
],
```

如果没有IK约束, "ik"部分可被省略.

**IK约束属性:**
* **name:** 约束名称. 该名称在skeleton上唯一.
* **order:** 约束生效(applied)的顺序序数.
* **skin:** 若为true, 则只有当活动皮肤包含该约束时该约束才生效. 若省略则默认为false.
* **bones:** 一个包含1到2个骨骼名称的列表, 这些骨骼的旋转将被IK约束限制.
* **target:** 目标(target)骨骼的名称.
* **mix:** 一个介于0到1区间的值, 表示约束对骨骼的影响, 其中0表示只有FK, 1表示只有IK, 而中间值表示混合了FK和IK. 若省略则默认为1.
* **softness:** 对于双骨骼IK, 表示目标骨骼到旋转减缓前骨骼的最大活动范围的距离. 若省略则默认为0.
* **bendPositive:** 若为true, 则骨骼的弯曲方向为正的旋转方向. 若省略则默认为false.
* **compress:** 若为true且只有一个骨骼被约束, 则当目标太近时会缩放骨骼以保持连接. 若省略则默认为false.
* **stretch:** 若为true且如果目标超出了范围, 将缩放父骨骼以保持连接. 若约束了多个骨骼且父骨骼的局部缩放比例非均匀(nonuniform), 则不应用拉伸(stretch). 若省略则默认为false.
* **uniform:** 若为true且只约束了一个骨骼, 而且使用了压缩或拉伸, 则该骨骼将在X和Y方向上缩放. 若省略则默认为false.

## Transform约束 
该节描述了变换约束(transform constraints).

```
"transform": [
	{ "name": "weapon to hip", "order": 1, "bone": "weapon", "target": "hip" },
	...
],
```

如果没有变换约束, "transform"部分可被省略.

**Transform约束属性:**
* **name:** 约束名称. 该名称在skeleton上唯一.
* **order:** 约束生效(applied)的顺序序数.
* **skin:** 若为true, 则只有当活动皮肤包含该约束时该约束才生效. 若省略则默认为false.
* **bones:** 将被约束控制transform的骨骼.
* **target:** 目标(target)骨骼的名称.
* **rotation:** 相对于目标骨骼的旋转角度偏移量. 若省略则默认为0.
* **x:** 相对于目标骨骼的X方向距离偏移量. 若省略则默认为0.
* **y:** 相对于目标骨骼的Y方向距离偏移量. 若省略则默认为0.
* **scaleX:** 相对于目标骨骼的X方向缩放偏移量. 若省略则默认为0.
* **scaleY:** 相对于目标骨骼的Y方向缩放偏移量. 若省略则默认为0.
* **shearY:** 相对于目标骨骼的Y方向斜切角度偏移量. 若省略则默认为0.
* **rotateMix:** 一个介于0到1区间的值, 表示约束对骨骼的影响, 其中0表示无影响, 1表示只有约束, 而中间值表示正常pose和约束的混合. 若省略则默认为1.
* **translateMix:** 参见 **rotateMix**.
* **scaleMix:** 参见 **rotateMix**.
* **shearMix:** 参见 **rotateMix**.
* **local:** 如果需要影响目标的局部transform则设置为True, 反之则影响全局transform. 若省略则默认为false.
* **relative:**  如果目标的transform为相对的则设置为True, 反之则其transform为绝对的. 若省略则默认为false.

## Path约束 
该节描述了路径约束(Path constraints).

```
"path": [
	{
		"name": "constraintName",
		"order": 0,
		"bones": [ "boneName1", "boneName2" ],
		"target": "slotName",
		"positionMode": "fixed",
		"spacingMode": "length",
		"rotateMode": "tangent",
		"rotation": "45",
		"position": "204",
		"spacing": "10",
		"rotateMix": "0",
		"translateMix": "1"
	},
	...
],
```

如果没有路径约束, "path"部分可被省略.

**Path约束属性:**
* **name:** 约束名称. 该名称在skeleton上唯一.
* **order:** 约束生效(applied)的顺序序数.
* **skin:** 若为true, 则只有当活动皮肤包含该约束时该约束才生效. 若省略则默认为false.
* **bones:** 将被约束控制旋转或平移的骨骼.
* **target:** 目标(target)骨骼的名称.
* **positionMode:** 指定计算路径位置的方式: 定值(fixed)或百分比(percent). 若省略则默认为percent.
* **spacingMode:** 指定骨骼间间距的计算方式: 长度(length), 定值(fixed)或百分比(percent). 若省略则默认为length.
* **rotateMode:** 决定骨骼旋转的计算方式: 切线(tangent)、链式或链式缩放. 若省略则默认为tangent.
* **rotation:** 相对于路径的旋转偏移量. 若省略则默认为0.
* **position:** 路径位置. 若省略则默认为0.
* **spacing:** 骨骼间间距. 若省略则默认为0.
* **rotateMix:** 一个介于0到1区间的值, 表示约束对骨骼的影响, 其中0表示无影响, 1表示只有约束, 而中间值表示正常pose和约束的混合. 若省略则默认为1.
* **translateMix:** 参见 **rotateMix**.

# Skins(皮肤)
在皮肤(skins)部分描述的每个皮肤都描述了可分配给每个槽位的附件.

skins skeleton JSON示例:
```
"skins": [
	{
		"name": "skinName",
		"attachments": {
			"slotName": {
				"attachmentName": { "x": -4.83, "y": 10.62, "width": 63, "height": 47 },
				...
			},
			...
		}
	},
	{
		"name": "skinName",
		"attachments": {
			"slotName": {
				"attachmentName": { "name": "actualAttachmentName", "x": 53.94, "y": -5.75, "rotation": -86.9, "width": 121, "height": 132 },
				...
			},
			...
		}
	},
	...
],
```
如果没有皮肤或附件, "skins"部分可被省略. 

每个皮肤本质上是一个映射(map), 键名是槽位和附件名称的复合键名, 其键值为一个附件. 虽然键中使用的附件名称对每个皮肤都相同, 但附件的实际附件名可能会有所不同.

例如, 有槽位"pelvis"中的图像"pelvis", 对于皮肤"red", 其实际附件名可能为"red/pelvis", 而对于皮肤"blue", 其附件名称则可能为"blue/pelvis". 如果skeleton的皮肤"blue"处于激活状态, 并被告知需要显示槽位"pelvis"中的图像"pelvis", 那么它检索到的附件的实际附件名应为"blue/pelvis".

当一个skeleton需要找到一个槽位中的一个附件时, 它首先会检查其皮肤. 如果没有找到, skeleton就会检查其默认皮肤. 默认皮肤包含没有被其他皮肤包含的附件, Spine可以混合使用皮肤和非皮肤附件. 默认皮肤总是带有"default"这个字样.

除默认皮肤外, 其他皮肤可能包含骨骼和/或约束:
```
"skins": [
	{
		"name": "skinName",
		"bones": [ "bone1", "bone2" ],
		"ik": [ "ik1", "ik2" ],
		"transform": [ "transform1", "transform2" ],
		"path": [ "path1", "path2" ],
		"attachments": {
			...
		}
	},
	...
}
```

## 附件(Attachments)

每个附件的属性根据附件类型的不同而不同.

**一般的附件属性:**
 * **type:** 附件类型. 若省略则默认为"region".
 * **name:** 附件名称. 该名称在skeleton上唯一. 图像附件其实是一个用于查找texture区域的键, 可以在磁盘上或texture atlas中查找. 若省略则将使用周边区域的JSON映射中的键当作实际附件名.

**附件类型:**
 * **region:** 一个textured矩形.
 * **mesh:** 一个textured网格, 其顶点受到多个有权重骨骼的影响.
 * **linkedmesh:** 与另一个网格共享的UVs、顶点和权重的网格.
 * **boundingbox:** 一个用于撞击检测, 物理运动等功能的多边形.
 * **path:** 一个通常用于沿着路径来移动骨骼的三次样条曲线.
 * **point:** 一个带有旋转的单点, 通常用于产生弹丸或粒子.
 * **clipping:** 一个多边形, 用于在绘制中裁剪其他附件.

**region附件属性:**
* **path:** 指定后, 将使用该值查找texture区域而非附件名称.
* **x:** 图像相对于槽位骨骼的X轴位置. 若省略则默认为0.
* **y:** 图像相对于槽位骨骼的Y轴位置. 若省略则默认为0.
* **scaleX:** 图像X轴方向的缩放比例. 若省略则默认为1.
* **scaleY:** 图像Y轴方向的缩放比例. 若省略则默认为1.
* **rotation:** 图像相对于槽位骨骼的旋转角度. 若省略则默认为0.
* **width:** 图像宽度.
* **height:** 图像高度.
* **color:** 用于附件tint(染色)的颜色. 若省略则默认为FFFFFFF RGBA.

**mesh附件属性:**
* **path:** 指定后, 将使用该值查找texture区域而非附件名称.
* **uvs:** 一个坐标列表, 表示每个顶点的texture坐标.
* **triangles:** 一个顶点索引列表, 定义了网格中的每个三角形.
* **vertices:** 包含每个顶点的x,y对, 影响该顶点的骨骼数量(用于加权网格), 以及用于这些骨骼的: 骨骼索引, 绑定位置X坐标, 绑定位置Y坐标, 权重. 若顶点数量 > UV数量, 则该网格为加权网格.
* **hull:** 构成多边形壳的顶点数量. 壳顶点保持在**vertices**列表首位.
* **edges:** 一个顶点索引对的列表, 定义了连接顶点之间的边. 非必要数据.
* **color:** 用于附件tint(染色)的颜色. 若省略则默认为FFFFFFF RGBA.
* **width:** 网格所用图像的宽度, 非必要数据.
* **height:** 网格所用图像的高度, 非必要数据.

**linkedmesh附件属性:**
* **path:** 指定后, 将使用该值查找texture区域而非附件名称.
* **skin:** 包含源网格的皮肤. 若省略则默认源网格包含于默认皮肤.
* **parent:** 源网格的名称, 它总是同该网格处于同一个槽位中. 若源网格不存在于默认皮肤中, 则会用该名称来检索皮肤中实际存在附件.
* **deform:** 若为false, 则源网格的变形时间轴不会应用于该网格. 若省略则默认为true.
* **color:** 用于附件tint(染色)的颜色. 若省略则默认为FFFFFFF RGBA.
* **width:** 网格所用图像的宽度, 非必要数据.
* **height:** 网格所用图像的高度, 非必要数据.

**boundingbox附件属性:**
* **vertexCount**: 包围盒(bounding box)的顶点数量.
* **vertices:** 包含每个顶点的x,y对, 影响该顶点的骨骼数量(用于加权包围盒), 以及用于这些骨骼的: 骨骼索引, 绑定位置X坐标, 绑定位置Y坐标, 权重. 若顶点数量 > 顶点总数, 则该包围盒为加权包围盒.
* **color:** Spine中包围盒的颜色. 若省略则默认为60F000FF RGBA. 非必要数据.

**path附件属性:**
* **closed**: 若起始顶点相连(路径闭合), 则true. 若省略则默认为false.
* **constantSpeed**: 若以恒定速度沿路径的运动则为true. 若省略则默认为true.
* **lengths**: 以setup pose从路径起点到每段曲线终点的长度.
* **vertexCount**: 路径点的数量.
* **vertices:** 包含每个顶点的x,y对, 影响该顶点的骨骼数量(用于加权路径), 以及用于这些骨骼的: 骨骼索引, 绑定位置X坐标, 绑定位置Y坐标, 权重. 若顶点数量 > 顶点总数, 则该路径为加权路径.
* **color:** Spine中路径的颜色. 若省略则默认为FF7F00FF RGBA. 非必要数据.

**point附件属性:**
* **x:** 单点相对于槽位骨骼X方向的距离. 若省略则默认为0.
* **y:** 单点相对于槽位骨骼Y方向的距离. 若省略则默认为0.
* **rotation:** 单点相对于槽位骨骼的旋转角度. 若省略则默认为0.
* **color:** 该点在Spine中的颜色. 若省略则默认为F1F100FF RGBA. 非必要数据.

**clipping附件属性:**
* **end**: 裁剪停止时的槽位名称.
* **vertexCount**: 裁剪多边形的顶点数量.
* **vertices:** 包含每个顶点的x,y对, 影响该顶点的骨骼数量(用于加权裁剪多边形), 以及用于这些骨骼的: 骨骼索引, 绑定位置X坐标, 绑定位置Y坐标, 权重. 若顶点数量 > 顶点总数, 则该多边形为加权裁剪多边形.
* **color:** Spine中裁剪附件的颜色. 若省略则默认为CE3A3AFF RGBA. 非必要数据.

# 事件(Events) #
事件部分描述了在动画过程中可以触发的命名事件及其setup pose值.

events JSON示例:
```
"events" [
	"name": { "int": 1, "float": 2, "string": "three" },
	"name": { "int": 1, "float": 2, "string": "three", "audio": "hit.wav", "volume": 0.9, "balance": -0.25 },
	...
],
```
**Event属性:**
* **name:** 事件名称. 该名称在skeleton上唯一.
* **int:** 事件的整型值. 若省略则默认为0.
* **float:** 事件的浮点值. 若省略则默认为0.
* **string:** 事件的字符串值. 若省略则默认为空(null).
* **audio:** 若该事件需要播放音频, 则该属性值为一个音频文件的路径. 若省略则默认为空(null).
* **volume:** 播放音频文件的音量. 若省略则默认为1.
* **balance:** 音频文件播放时的立体声均衡值. 若省略则默认为0.

# 动画(Animations) #
一个动画包含一个时间轴列表. 每条时间轴均存储了一个关键帧列表, 这些时间轴描述了骨骼或槽位的值如何随时间变化.

骨骼动画JSON示例:
```
"animations": {
	"name": {
		"bones": { ... },
		"slots": { ... },
		"ik": { ... },
		"deform": { ... },
		"events": { ... },
		"draworder": { ... },
	},
	...
}
```

## 骨骼时间轴
动画的"bones"部分描述了控制骨骼的时间轴.

骨骼时间轴JSON示例:
```
{
"bones": {
	"boneName": {
		"timelineType": [
			{ "time": 0, "angle": -26.55 },
			{ "time": 0.1333, "angle": -8.78 },
			...
		],
		...
	},
	...
},
```
每个关键帧的属性依时间轴的类型不同而变化.

**骨骼时间轴类型:**
* **rotate**: 骨骼的旋转关键帧.
* **translate**: 骨骼的X和Y位置关键帧.
* **scale**: 骨骼的X和Y缩放关键帧.
* **shear**: 骨骼的X和Y斜切(shear)关键帧.

**一般的骨骼关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒). 若省略则默认为0.
* **curve:** 定义该关键帧和下一关键帧间所使用的插值方法. 若该属性被省略, 则为线性插值; 若该值为字符串 "steppped", 则使用阶跃曲线; 若非以上两种属性值, 则使用一个4元数组来定义控制点, 它们是: `cx1`, `cy1`, `cx2`, 和`cy2`. X轴的单位是帧, Y轴的单位是值.

**rotate关键帧属性:**
* **angle:** 骨骼相对于setup pose的旋转角度. 若省略则默认为0.

**translate关键帧属性:**
* **x:** 骨骼相对于setup pose的X轴位置. 若省略则默认为0.
* **y:** 骨骼相对于setup pose的Y轴位置. 若省略则默认为0.

**scale关键帧属性:**
* **x:** 骨骼相对于setup pose的X轴缩放比例. 若省略则默认为0.
* **y:** 骨骼相对于setup pose的Y轴缩放比例. 若省略则默认为0.

**shear关键帧属性:**
* **x:** 骨骼相对于setup pose的X轴斜切量. 若省略则默认为0.
* **y:** 骨骼相对于setup pose的Y轴斜切量. 若省略则默认为0.

## 槽位时间轴
动画的"slots"部分描述了操作槽位时间轴.

slots animation JSON示例:
```
"slots": {
	"slotName": {
		"timelineType": [
			{ "time": 0.2333, "name": "eyes closed" },
			{ "time": 0.6333, "name": "eyes open" },
			...
		],
		...
	},
	...
}
```
每个关键帧的属性依时间轴的类型不同而变化.

**槽位时间轴类型:**
* **attachment**: 改变槽位内附件的关键帧.
* **color**: 改变槽位颜色的关键帧.

**一般的槽位关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).

**attachment关键帧属性:**
* **name:** 槽位内附件的名字.

**color关键帧属性:**
* **color:** 槽位的颜色. 其为一个长度为8的字符串, 包含4个按RGBA顺序排列的两位16进制数字.
* **curve:** 定义该关键帧和下一关键帧间所使用的插值方法. 若该属性被省略, 则为线性插值; 若该值为字符串 "steppped", 则使用阶跃曲线; 若非以上两种属性值, 则使用贝塞尔曲线(Bézier curve)的`cx1`值.<br>贝塞尔曲线有4个元素分别定义控制点:`cx1`, `cy1`, `cx2`和`cy2`. X轴在取值[0, 1]内, 表示关键帧之间时长的百分比. Y轴也在取值[0, 1]内, 表示关键帧值(values)之间差额的百分比.
* **c2:** 贝塞尔曲线的`cy1`值. 若省略则默认为0.
* **c3:** 贝塞尔曲线的`cx2`值. 若省略则默认为1.
* **c4:** 贝塞尔曲线的`cy2`值. 若省略则默认为1.

**twoColor关键帧属性:**
* **light:** 槽位的浅色(light color). 其为一个长度为8的字符串, 包含4个按RGBA顺序排列的两位16进制数字.
* **dark:** 槽位的深色(dark color). 其为一个长度为8的字符串, 包含4个按RGBA顺序排列的两位16进制数字.
* **curve:** 定义该关键帧和下一关键帧间所使用的插值方法. 若该属性被省略, 则为线性插值; 若该值为字符串 "steppped", 则使用阶跃曲线; 若非以上两种属性值, 则使用贝塞尔曲线(Bézier curve)的`cx1`值.<br>贝塞尔曲线有4个元素分别定义控制点:`cx1`, `cy1`, `cx2`和`cy2`. X轴在取值[0, 1]内, 表示关键帧之间时长的百分比. Y轴也在取值[0, 1]内, 表示关键帧值(values)之间差额的百分比.
* **c2:** 贝塞尔曲线的`cy1`值. 若省略则默认为0.
* **c3:** 贝塞尔曲线的`cx2`值. 若省略则默认为1.
* **c4:** 贝塞尔曲线的`cy2`值. 若省略则默认为1.

## IK约束时间轴 
动画的"ik"部分描述了IK约束时间轴.

IK animation JSON示例:
```
"ik": {
	"constraintName": [
		{ "time": 0.5333, "mix": 0.616, "bendPositive": true },
		...
	],
	...
},
```

**IK约束关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).
* **mix:** 关键帧的IK约束混合. 若省略则默认为1.
* **softness:** 对于双骨骼IK, 表示目标骨骼到旋转减缓前骨骼的最大活动范围的距离. 若省略则默认为0.
* **bendPositive:** 关键帧的IK约束弯曲方向. 若省略则默认为false.
* **compress:** 若为true且只有一个骨骼被约束, 则当目标太近时会缩放骨骼以保持连接. 若省略则默认为false.
* **stretch:** 若为true且如果目标超出了范围, 将缩放父骨骼以保持连接. 若约束了多个骨骼且父骨骼的局部缩放比例非均匀(nonuniform), 则不应用拉伸(stretch). 若省略则默认为false.

## Transform约束时间轴 
动画的"transform"部分描述了transform约束时间轴.

transform constraint animation JSON示例:
```
"transform": {
	"constraintName": [
		{ "time": 1.81, "rotateMix": 0.66, "translateMix": 0, "scaleMix": 0.5, "shearMix": 0.5 },
		...
	],
	...
},
```

**Transform约束关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).
* **rotateMix:** 关键帧transform约束的旋转混合. 若省略则默认为1.
* **translateMix:** 关键帧transform约束的平移混合. 若省略则默认为1.
* **scaleMix:** 关键帧transform约束的缩放混合. 若省略则默认为1.
* **shearMix:** 关键帧transform约束的斜切混合度. 若省略则默认为1.

## Path约束时间轴 
动画的"path"部分描述了路径约束时间轴.

path constraint animation JSON示例:
```
"path": {
	"constraintName": 
		"position": [
			{ "time": 1.81, "position": 0.7 },
			...
		],
		"spacing": [
			{ "time": 2.92, "spacing": 0.05 },
			...
		],
		"mix": [
			{ "time": 3.03, "rotateMix": 0.5, "translateMix": 0.75 },
			...
		],
	...
},
```

**Path约束关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).
* **position:** 关键帧位置约束的位置. 若省略则默认为1.
* **spacing:** 关键帧位置约束的间距(spacing). 若省略则默认为1.
* **rotateMix:** 关键帧位置约束的旋转混合.若省略则默认为1.
* **translateMix:** 关键帧位置约束的平移混合. 若省略则默认为1.

## Deform时间轴  
动画的"deform"部分描述了用于操作每个网格附件的顶点(网格变形)的时间轴.

deform animation JSON示例:
```
"deform": {
	"skinName": {
		"slotName": {
			"meshName": [
				{
					"time": 0,
					"curve": [ 0.25, 0, 0.75, 1 ]
				},
				{
					"time": 1.5,
					"offset": 12,
					"vertices": [ -0.75588, -3.68987, -1.01898, -2.97404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
					-1.01898, -2.97404, -0.75588, -3.68987, 0, 0, -0.75588, -3.68987, -0.75588, -3.68987,
					-1.01898, -2.97404, -1.01898, -2.97404, -1.01898, -2.97404, -0.75588, -3.68987 ],
					"curve": [ 0.25, 0, 0.75, 1 ]
				},
				...
			],
			...
		},
		...
	},
	...
}
```

**Deform关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).
* **offset:** 在**vertices**生效之前要跳过的顶点数量. 默认为顶点数&lt;=偏移量为0.
* **vertices:** 一个数对(number pairs)的列表, 这些数对是要向关键帧添加的setup顶点位置的数量. 如果条目数少于顶点数, 则默认这些条目后的顶点数为0.
* **curve:** 定义该关键帧和下一关键帧间所使用的插值方法. 若该属性被省略, 则为线性插值; 若该值为字符串 "steppped", 则使用阶跃曲线; 若非以上两种属性值, 则使用贝塞尔曲线(Bézier curve)的`cx1`值.<br>贝塞尔曲线有4个元素分别定义控制点:`cx1`, `cy1`, `cx2`和`cy2`. X轴在取值[0, 1]内, 表示关键帧之间时长的百分比. Y轴也在取值[0, 1]内, 表示关键帧值(values)之间差额的百分比.
* **c2:** 贝塞尔曲线的`cy1`值. 若省略则默认为0.
* **c3:** 贝塞尔曲线的`cx2`值. 若省略则默认为1.
* **c4:** 贝塞尔曲线的`cy2`值. 若省略则默认为1.

## Event时间轴 
动画的"events"部分描述了一个用于触发事件的时间轴.

events animation JSON示例:
```
"events": [
	{ "time": 0.2, "name": "event1", "int": 1, "float": 2, "string": "three" },
	{ "time": 0.6, "name": "event2", "int": 4, "float": 5, "string": "six" },
	...
}
```
**Event关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).
* **name:** 事件名称.
* **int:** 事件的整型值. 若省略则默认为setup pose值.
* **float:** 事件的浮点值. 若省略则默认为setup pose值.
* **string:** 事件的字符串值. 若省略则默认为setup pose值.
* **volume:** 播放音频文件的音量. 若省略则默认为setup pose值.
* **balance:** 音频文件播放时的立体声均衡值. 若省略则默认为setup pose值.

## 绘制顺序(Draw order)时间轴 
动画的"draworder"部分描述了一个用于改变绘制顺序的时间轴, 它是一个skeleton上需绘制附件的槽位列表.

draworder animation JSON示例:
```
"draworder": [
	{
		"time": 0.2,
		"offsets": [
			{ "slot": "slotName", "offset": 1 },
			{ "slot": "slotName", "offset": -2 },
			...
		]
	},
	...
}
```
**绘制顺序关键帧属性:**
* **time:** 表示关键帧的时间(单位为秒).
* **offsets:** 槽位名称和偏移量数值的列表, 偏移量是指相对于setup pose绘制顺序索引, 具体槽位的绘制顺序条目与该索引的差值. 如若省略"offsets"则关键帧默认以setup pose绘制顺序来绘制.