diff --git a/examples/index.html b/examples/index.html
index 0e0e12e..7287d78 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -128,11 +128,12 @@
@@ -260,7 +261,8 @@
const skinLayers = ["innerLayer", "outerLayer"];
const availableAnimations = {
walk: skinview3d.WalkingAnimation,
- run: skinview3d.RunningAnimation
+ run: skinview3d.RunningAnimation,
+ fly: skinview3d.FlyingAnimation
};
let skinViewer;
diff --git a/src/animation.ts b/src/animation.ts
index 872a25d..8971dd8 100644
--- a/src/animation.ts
+++ b/src/animation.ts
@@ -195,3 +195,30 @@ export const RunningAnimation: Animation = (player, time) => {
export const RotatingAnimation: Animation = (player, time) => {
player.rotation.y = time;
};
+
+function clamp(num: number, min: number, max: number): number {
+ return num <= min ? min : num >= max ? max : num;
+}
+
+export const FlyingAnimation: Animation = (player, time) => {
+ // body rotation finishes in 0.5s
+ // elytra expansion finishes in 3.3s
+
+ if (time < 0) time = 0;
+ time *= 20;
+ const startProgress = clamp((time * time) / 100, 0, 1);
+
+ player.rotation.x = startProgress * Math.PI / 2;
+ player.skin.head.rotation.x = startProgress > .5 ? Math.PI / 4 - player.rotation.x : 0;
+
+ const basicArmRotationZ = Math.PI * .25 * startProgress;
+ player.skin.leftArm.rotation.z = basicArmRotationZ;
+ player.skin.rightArm.rotation.z = -basicArmRotationZ;
+
+ const elytraRotationX = .34906584;
+ const elytraRotationZ = Math.PI / 2;
+ const interpolation = Math.pow(.9, time);
+ player.elytra.leftWing.rotation.x = elytraRotationX + interpolation * (.2617994 - elytraRotationX);
+ player.elytra.leftWing.rotation.z = elytraRotationZ + interpolation * (.2617994 - elytraRotationZ);
+ player.elytra.updateRightWing();
+};