这篇post主要为了了解动画的原理,始末,已经一些常用的技术路线,为之后可能遇到的工作做准备。

动画是什么

计算机动画即利用计算机绘制技术,绘制图画,为了制造连续的假象,将画面显示在计算机上,然后很块的用另一个相似但有一些移动的画面替代,制造平滑移动的假象。

由于人脑和眼存在视觉停留的现象,眼和脑会将看到的画面存储几分之一秒,然后将场景切换的跳跃平滑掉。因此制作动画的一个基本最低切换帧率为12帧,在这个帧率是人们比较能够接受的帧率。通常电影为24帧,当帧率提升到60帧以上时,为人眼处理图像的极限,画面真实感将不再提升。

SVG

SVG是一种基于XML的标记语言,是由万维网联盟开发的开放标准,用于描述二维的矢量图形。是一个基于文本的开放web标准,可以与CSS,DOM,HTML在统一标准下使用。SVG是可伸缩的矢量图像,本质上是一段文本,可以被编辑,检索,压缩,编辑和创建的。

通过上面的介绍,容易发现SVG和万维网联盟的其他标准类似,是一种专门为了互联网而生的一种产物。

SVG文件大小比较小,可用代码进行绘图,支持web协议,可在网页中打开。

pose-animator

由模型得到的点位信息的结构如下:

image-20200514223027223

image-20200514223058374

修改代码,将pose的keypoint信息通过json传入,得到相同的结果:

image-20200518161834873

Paper.js

Paper.js在处理path的时候,将整个curve分成多个segment,每个segment由handleOut,handleIn,以及一个点组成,由三个点绘制出一条curve。

贝塞尔曲线下链接:https://www.jianshu.com/p/8f82db9556d2

绘制动画的基本思路

pose-animator的总体思路是首先利用PoseNet和faceMesh得到人体和面部的关键点信息。动画部分,使用Paper.js控制SVG图像,首先给出了一个通用的骨骼结构(skeleton.svg),通过skeleton.js获取关节点的位置以及关节点之间可能存在的骨骼信息:

image-20200522163733751

然后利用已有的svg动画图像如下:

image-20200522164204453

最后遍历skeleton.svg中path中的segment第三个point与图二中所有的bone计算距离,去寻找最接近的bone,计算距离如下:

1
2
3
4
5
6
7
8
9
10
11
static getClosestPointOnSegment(p0, p1, p) {
let d = p1.subtract(p0);
let c = p.subtract(p0).dot(d) / (d.dot(d));
if (c >= 1) {
return p1.clone();
} else if (c <= 0) {
return p0.clone();
} else {
return p0.add(d.multiply(c));
}
}

上诉函数将返回一个最接近point的点坐标,然后计算distance,作为判断图二最近的segment的标准,随后计算一个weight,以及根据handleIn,handleOut去计算动画的一些形变

形变代码:

1
2
3
4
5
6
7
8
if (s.handleIn) {
let pHandleIn = s.handleIn.add(s.point);
segment.handleIn = this.getSkinning(pHandleIn, collinear ? weightsP : this.getWeights(pHandleIn, bones)); //skinning指的是肉
}
if (s.handleOut) {
let pHandleOut = s.handleOut.add(s.point);
segment.handleOut = this.getSkinning(pHandleOut, collinear ? weightsP : this.getWeights(pHandleOut, bones));
}

添加自己的动画结果

首先需要绘制一张svg图像,节点的名称与已有的一致,然后传入图片,检测出关键点,然后就可以显示了。