Compare commits
2 Commits
61da3d55aa
...
a294baf6cf
Author | SHA1 | Date | |
---|---|---|---|
a294baf6cf | |||
98bdcef232 |
|
@ -25,10 +25,10 @@ export abstract class AnimationSegment {
|
||||||
this.endPosition = endPosition;
|
this.endPosition = endPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract interpolateOffset(progress: number);
|
abstract interpolateOffset(progress: number);
|
||||||
|
|
||||||
// TODO Not sure this interpolation is actually right for arms...
|
// TODO Not sure this interpolation is actually right for arms...
|
||||||
protected interpolateHandOffset(progress: number, hand: Hand) : Offset | undefined {
|
interpolateHandOffset(progress: number, hand: Hand) : Offset | undefined {
|
||||||
let prev = hand === Hand.Left ? this.startPosition.leftArmEnd : this.startPosition.rightArmEnd;
|
let prev = hand === Hand.Left ? this.startPosition.leftArmEnd : this.startPosition.rightArmEnd;
|
||||||
let next = hand === Hand.Left ? this.endPosition.leftArmEnd : this.endPosition.rightArmEnd;
|
let next = hand === Hand.Left ? this.endPosition.leftArmEnd : this.endPosition.rightArmEnd;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ export abstract class AnimationSegment {
|
||||||
return interpolateLinearOffset(progress, prev, next);
|
return interpolateLinearOffset(progress, prev, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected interpolateRotation(progress: number) {
|
interpolateRotation(progress: number) {
|
||||||
return interpolateLinear(progress, this.startPosition.rotation, this.endPosition.rotation);
|
return interpolateLinear(progress, this.startPosition.rotation, this.endPosition.rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,19 +65,120 @@ function interpolateLinearOffset(progress: number, prev: Offset, next: Offset):
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LinearAnimationSegment extends AnimationSegment {
|
export class LinearAnimationSegment extends AnimationSegment {
|
||||||
constructor(beats: number, startPosition: DancerSetPosition, endPosition: DancerSetPosition) {
|
constructor({ beats, startPosition, endPosition }: {
|
||||||
|
beats: number;
|
||||||
|
startPosition: DancerSetPosition;
|
||||||
|
endPosition: DancerSetPosition;
|
||||||
|
}) {
|
||||||
super(beats, startPosition, endPosition);
|
super(beats, startPosition, endPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static standStill(startAndEndPosition: DancerSetPosition, beats?: number) {
|
public static standStill(startAndEndPosition: DancerSetPosition, beats?: number) {
|
||||||
return new LinearAnimationSegment(beats ?? 0, startAndEndPosition, startAndEndPosition);
|
return new LinearAnimationSegment({
|
||||||
|
beats: beats ?? 0,
|
||||||
|
startPosition: startAndEndPosition,
|
||||||
|
endPosition: startAndEndPosition
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected interpolateOffset(progress: number) {
|
override interpolateOffset(progress: number) {
|
||||||
return interpolateLinearOffset(progress, this.startPosition.position, this.endPosition.position);
|
return interpolateLinearOffset(progress, this.startPosition.position, this.endPosition.position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AnimationTransitionFlags {
|
||||||
|
rotation?: boolean;
|
||||||
|
hands?: boolean;
|
||||||
|
}
|
||||||
|
export class TransitionAnimationSegment extends AnimationSegment {
|
||||||
|
private readonly actualAnimation: AnimationSegment;
|
||||||
|
private readonly flags: AnimationTransitionFlags;
|
||||||
|
private readonly startTransitionProgress: number;
|
||||||
|
private readonly endTransitionProgress: number;
|
||||||
|
private readonly startRotation: number;
|
||||||
|
private readonly endRotation: number;
|
||||||
|
|
||||||
|
constructor({ actualAnimation, flags, startTransitionBeats, endTransitionBeats }: {
|
||||||
|
actualAnimation: AnimationSegment;
|
||||||
|
flags: AnimationTransitionFlags;
|
||||||
|
startTransitionBeats: number;
|
||||||
|
endTransitionBeats?: number;
|
||||||
|
}) {
|
||||||
|
super(actualAnimation.beats, actualAnimation.startPosition, actualAnimation.endPosition);
|
||||||
|
|
||||||
|
this.actualAnimation = actualAnimation;
|
||||||
|
this.flags = flags;
|
||||||
|
this.startTransitionProgress = startTransitionBeats / actualAnimation.beats;
|
||||||
|
this.endTransitionProgress = endTransitionBeats === undefined ? this.startTransitionProgress : endTransitionBeats / actualAnimation.beats;
|
||||||
|
|
||||||
|
this.startRotation = this.startPosition.rotation;
|
||||||
|
this.endRotation = this.endPosition.rotation;
|
||||||
|
if (this.flags.rotation) {
|
||||||
|
const actualStart = this.actualAnimation.interpolateRotation(0);
|
||||||
|
const actualEnd = this.actualAnimation.interpolateRotation(1);
|
||||||
|
|
||||||
|
const rotationPositive = actualEnd > actualStart;
|
||||||
|
|
||||||
|
const transitionStart = this.actualAnimation.interpolateRotation(this.startTransitionProgress);
|
||||||
|
const transitionEnd = this.actualAnimation.interpolateRotation(1 - this.endTransitionProgress);
|
||||||
|
|
||||||
|
if (rotationPositive) {
|
||||||
|
while (transitionStart < this.startRotation) {
|
||||||
|
this.startRotation -= 360;
|
||||||
|
}
|
||||||
|
while (transitionEnd > this.endRotation) {
|
||||||
|
this.endRotation += 360;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (transitionStart > this.startRotation) {
|
||||||
|
this.startRotation += 360;
|
||||||
|
}
|
||||||
|
while (transitionEnd < this.endRotation) {
|
||||||
|
this.endRotation -= 360;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override interpolateOffset(progress: number) {
|
||||||
|
return this.actualAnimation.interpolateOffset(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
override interpolateRotation(progress: number): number {
|
||||||
|
const actualRotation = this.actualAnimation.interpolateRotation(progress);
|
||||||
|
|
||||||
|
if (this.flags.rotation) {
|
||||||
|
if (progress < this.startTransitionProgress) {
|
||||||
|
return interpolateLinear(progress / this.startTransitionProgress, this.startRotation, actualRotation);
|
||||||
|
} else if ((1 - progress) < this.endTransitionProgress) {
|
||||||
|
return interpolateLinear((1 - progress) / this.endTransitionProgress, this.endRotation, actualRotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
override interpolateHandOffset(progress: number, hand: Hand): Offset | undefined {
|
||||||
|
const actualHandOffset = this.actualAnimation.interpolateHandOffset(progress, hand);
|
||||||
|
|
||||||
|
if (this.flags.hands) {
|
||||||
|
if (progress < this.startTransitionProgress) {
|
||||||
|
const startHand = hand === Hand.Left
|
||||||
|
? this.startPosition.leftArmEnd ?? leftShoulder
|
||||||
|
: this.startPosition.rightArmEnd ?? rightShoulder;
|
||||||
|
return interpolateLinearOffset(progress / this.startTransitionProgress, startHand, actualHandOffset ?? hand.shoulderPosition());
|
||||||
|
} else if (1 - progress < this.endTransitionProgress) {
|
||||||
|
const endHand = hand === Hand.Left
|
||||||
|
? this.endPosition.leftArmEnd ?? leftShoulder
|
||||||
|
: this.endPosition.rightArmEnd ?? rightShoulder;
|
||||||
|
return interpolateLinearOffset((1 - progress) / this.endTransitionProgress, endHand, actualHandOffset ?? hand.shoulderPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualHandOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO Not sure this really belongs here instead of on some Semantic* type.
|
// TODO Not sure this really belongs here instead of on some Semantic* type.
|
||||||
export enum RotationAnimationFacing {
|
export enum RotationAnimationFacing {
|
||||||
Linear = "Linear", // Default, linearly interpolate.
|
Linear = "Linear", // Default, linearly interpolate.
|
||||||
|
@ -95,12 +196,7 @@ interface Closer {
|
||||||
transitionProgress: number,
|
transitionProgress: number,
|
||||||
}
|
}
|
||||||
export interface HandAnimation {
|
export interface HandAnimation {
|
||||||
kind: "Linear" | "Center" | "None",
|
kind: "Linear" | "Center" | "None" | "Start" | "End"
|
||||||
transitionBeats?: number,
|
|
||||||
}
|
|
||||||
interface HandAnimationInternal {
|
|
||||||
kind: "Linear" | "Center" | "None",
|
|
||||||
transitionProgress: number,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RotationAnimationSegment extends AnimationSegment {
|
export class RotationAnimationSegment extends AnimationSegment {
|
||||||
|
@ -114,27 +210,21 @@ export class RotationAnimationSegment extends AnimationSegment {
|
||||||
private readonly facing: RotationAnimationFacing;
|
private readonly facing: RotationAnimationFacing;
|
||||||
private readonly startFacing: Rotation;
|
private readonly startFacing: Rotation;
|
||||||
private readonly closer?: Closer;
|
private readonly closer?: Closer;
|
||||||
private readonly hands: Map<Hand, HandAnimationInternal>;
|
private readonly hands: Map<Hand, HandAnimation>;
|
||||||
private readonly rotationTransitionProgress: number;
|
|
||||||
|
|
||||||
constructor(beats: number, startPosition: DancerSetPosition, endPosition: DancerSetPosition,
|
constructor({ beats, startPosition, endPosition, rotation, around, facing, closer, hands }: {
|
||||||
rotation: number, around: RotationAround, facing: RotationAnimationFacing,
|
beats: number;
|
||||||
closer?: CloserDuringRotation, hands?: Map<Hand, HandAnimation>,
|
startPosition: DancerSetPosition;
|
||||||
rotationTransitionBeats?: number) {
|
endPosition: DancerSetPosition;
|
||||||
|
rotation: number; around: RotationAround;
|
||||||
|
facing: RotationAnimationFacing;
|
||||||
|
closer?: CloserDuringRotation;
|
||||||
|
hands?: Map<Hand, HandAnimation>;
|
||||||
|
}) {
|
||||||
super(beats, startPosition, endPosition);
|
super(beats, startPosition, endPosition);
|
||||||
|
|
||||||
function convertHandAnimation(anim: HandAnimation | undefined): HandAnimationInternal {
|
this.hands = new Map<Hand, HandAnimation>(
|
||||||
if (!anim) {
|
[Hand.Left, Hand.Right].map(h => [h, hands?.get(h) ?? { kind: "Linear" }]));
|
||||||
return { kind: "Linear", transitionProgress: 0 };
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
...anim,
|
|
||||||
transitionProgress: (anim.transitionBeats ?? 0) / beats
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.hands = new Map<Hand, HandAnimationInternal>(
|
|
||||||
[Hand.Left, Hand.Right].map(h => [h, convertHandAnimation(hands?.get(h))]));
|
|
||||||
|
|
||||||
this.facing = facing;
|
this.facing = facing;
|
||||||
this.xRadius = around.width / 2;
|
this.xRadius = around.width / 2;
|
||||||
|
@ -148,7 +238,6 @@ export class RotationAnimationSegment extends AnimationSegment {
|
||||||
// Canvas rotation is backwards of what we expect, so take the negative here.
|
// Canvas rotation is backwards of what we expect, so take the negative here.
|
||||||
return -radiansToDegrees(radians);
|
return -radiansToDegrees(radians);
|
||||||
}
|
}
|
||||||
this.rotationTransitionProgress = (rotationTransitionBeats ?? 0) / beats;
|
|
||||||
this.startRotation = positionToDegrees(startPosition.position);
|
this.startRotation = positionToDegrees(startPosition.position);
|
||||||
this.startFacing = startPosition.rotation;
|
this.startFacing = startPosition.rotation;
|
||||||
const actualRotation = normalizeRotation(positionToDegrees(endPosition.position) - this.startRotation,
|
const actualRotation = normalizeRotation(positionToDegrees(endPosition.position) - this.startRotation,
|
||||||
|
@ -169,7 +258,7 @@ export class RotationAnimationSegment extends AnimationSegment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected interpolateOffset(progress: number) {
|
override interpolateOffset(progress: number) {
|
||||||
const radians = -degreesToRadians(interpolateLinear(progress, this.startRotation, this.endRotation));
|
const radians = -degreesToRadians(interpolateLinear(progress, this.startRotation, this.endRotation));
|
||||||
let distance: number;
|
let distance: number;
|
||||||
if (!this.closer) {
|
if (!this.closer) {
|
||||||
|
@ -189,7 +278,7 @@ export class RotationAnimationSegment extends AnimationSegment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected interpolateRotation(progress: number): number {
|
override interpolateRotation(progress: number): number {
|
||||||
if (this.facing === RotationAnimationFacing.Linear) {
|
if (this.facing === RotationAnimationFacing.Linear) {
|
||||||
return super.interpolateRotation(progress);
|
return super.interpolateRotation(progress);
|
||||||
} else {
|
} else {
|
||||||
|
@ -197,41 +286,27 @@ export class RotationAnimationSegment extends AnimationSegment {
|
||||||
let rotation : number;
|
let rotation : number;
|
||||||
switch (this.facing) {
|
switch (this.facing) {
|
||||||
case RotationAnimationFacing.Center:
|
case RotationAnimationFacing.Center:
|
||||||
rotation = degrees - 90;
|
return degrees - 90;
|
||||||
break;
|
|
||||||
case RotationAnimationFacing.CenterRelative:
|
case RotationAnimationFacing.CenterRelative:
|
||||||
rotation = degrees - this.startRotation + this.startFacing;
|
return degrees - this.startRotation + this.startFacing;
|
||||||
break;
|
|
||||||
case RotationAnimationFacing.Forward:
|
case RotationAnimationFacing.Forward:
|
||||||
rotation = degrees + 180;
|
return degrees + 180;
|
||||||
break;
|
|
||||||
case RotationAnimationFacing.Backward:
|
case RotationAnimationFacing.Backward:
|
||||||
rotation = degrees;
|
return degrees;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress < this.rotationTransitionProgress) {
|
|
||||||
return interpolateLinear(progress / this.rotationTransitionProgress, this.startRotation, rotation);
|
|
||||||
} else if ((1 - progress) < this.rotationTransitionProgress) {
|
|
||||||
return interpolateLinear((1 - progress) / this.rotationTransitionProgress, this.endRotation, rotation);
|
|
||||||
} else {
|
|
||||||
return rotation;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected interpolateHandOffset(progress: number, hand: Hand): Offset | undefined {
|
override interpolateHandOffset(progress: number, hand: Hand): Offset | undefined {
|
||||||
const handAnim : HandAnimationInternal = this.hands.get(hand)!;
|
const handAnim : HandAnimation = this.hands.get(hand)!;
|
||||||
let middlePos : Offset;
|
let middlePos : Offset;
|
||||||
switch (handAnim.kind) {
|
switch (handAnim.kind) {
|
||||||
|
case "Start":
|
||||||
|
return hand === Hand.Left ? this.startPosition.leftArmEnd : this.startPosition.rightArmEnd;
|
||||||
|
case "End":
|
||||||
|
return hand === Hand.Left ? this.endPosition.leftArmEnd : this.endPosition.rightArmEnd;
|
||||||
case "Linear":
|
case "Linear":
|
||||||
if (handAnim.transitionProgress === 0) {
|
return super.interpolateHandOffset(progress, hand);
|
||||||
return super.interpolateHandOffset(progress, hand);
|
|
||||||
} else if (progress < handAnim.transitionProgress) {
|
|
||||||
return super.interpolateHandOffset(progress / handAnim.transitionProgress, hand);
|
|
||||||
} else {
|
|
||||||
return super.interpolateHandOffset(1, hand);
|
|
||||||
}
|
|
||||||
case "Center":
|
case "Center":
|
||||||
const position = this.interpolateOffset(progress);
|
const position = this.interpolateOffset(progress);
|
||||||
const offset = {
|
const offset = {
|
||||||
|
@ -244,28 +319,10 @@ export class RotationAnimationSegment extends AnimationSegment {
|
||||||
x: -Math.cos(rotation) * offset.x + Math.sin(rotation) * offset.y,
|
x: -Math.cos(rotation) * offset.x + Math.sin(rotation) * offset.y,
|
||||||
y: -Math.sin(rotation) * offset.x - Math.cos(rotation) * offset.y,
|
y: -Math.sin(rotation) * offset.x - Math.cos(rotation) * offset.y,
|
||||||
}
|
}
|
||||||
middlePos = centerPos;
|
return centerPos;
|
||||||
break;
|
|
||||||
case "None":
|
case "None":
|
||||||
middlePos = hand === Hand.Left ? leftShoulder : rightShoulder;
|
return hand === Hand.Left ? leftShoulder : rightShoulder;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handAnim.transitionProgress) {
|
|
||||||
if (progress < handAnim.transitionProgress) {
|
|
||||||
const startHand = hand === Hand.Left
|
|
||||||
? this.startPosition.leftArmEnd ?? leftShoulder
|
|
||||||
: this.startPosition.rightArmEnd ?? rightShoulder;
|
|
||||||
return interpolateLinearOffset(progress / handAnim.transitionProgress, startHand, middlePos);
|
|
||||||
} else if (1 - progress < handAnim.transitionProgress) {
|
|
||||||
const endHand = hand === Hand.Left
|
|
||||||
? this.endPosition.leftArmEnd ?? leftShoulder
|
|
||||||
: this.endPosition.rightArmEnd ?? rightShoulder;
|
|
||||||
return interpolateLinearOffset((1 - progress) / handAnim.transitionProgress, endHand, middlePos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return middlePos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -287,12 +287,14 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
||||||
+ JSON.stringify(move.startPosition) + ", end=" + JSON.stringify(move.endPosition);
|
+ JSON.stringify(move.startPosition) + ", end=" + JSON.stringify(move.endPosition);
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
new animation.LinearAnimationSegment(move.beats,
|
new animation.LinearAnimationSegment({
|
||||||
startSetPosition,
|
beats: move.beats,
|
||||||
{
|
startPosition: startSetPosition,
|
||||||
|
endPosition: {
|
||||||
...endSetPosition,
|
...endSetPosition,
|
||||||
rotation: startSetPosition.rotation + rotation,
|
rotation: startSetPosition.rotation + rotation,
|
||||||
}),
|
}
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
case SemanticAnimationKind.Circle:
|
case SemanticAnimationKind.Circle:
|
||||||
if (move.startPosition.kind !== PositionKind.Circle || move.endPosition.kind !== PositionKind.Circle) {
|
if (move.startPosition.kind !== PositionKind.Circle || move.endPosition.kind !== PositionKind.Circle) {
|
||||||
|
@ -300,22 +302,27 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new animation.RotationAnimationSegment(move.beats,
|
new animation.TransitionAnimationSegment({
|
||||||
startSetPosition,
|
actualAnimation: new animation.RotationAnimationSegment({
|
||||||
endSetPosition,
|
beats: move.beats,
|
||||||
move.movementPattern.places * 90,
|
startPosition: startSetPosition,
|
||||||
{
|
endPosition: endSetPosition,
|
||||||
center: CenterOfSet(move.startPosition.setOffset, move.startPosition.lineOffset),
|
rotation: move.movementPattern.places * 90,
|
||||||
width: setWidth,
|
around: {
|
||||||
height: setHeight,
|
center: CenterOfSet(move.startPosition.setOffset, move.startPosition.lineOffset),
|
||||||
|
width: setWidth,
|
||||||
|
height: setHeight,
|
||||||
|
},
|
||||||
|
facing: animation.RotationAnimationFacing.Center, closer: undefined, hands: new Map<Hand, animation.HandAnimation>([
|
||||||
|
[Hand.Left, { kind: "End" }],
|
||||||
|
[Hand.Right, { kind: "End" }],
|
||||||
|
])
|
||||||
|
}),
|
||||||
|
flags: {
|
||||||
|
hands: true
|
||||||
},
|
},
|
||||||
animation.RotationAnimationFacing.Center,
|
startTransitionBeats: 1
|
||||||
undefined,
|
}),
|
||||||
new Map<Hand, animation.HandAnimation>([
|
|
||||||
[Hand.Left, { kind: "Linear", transitionBeats: 1 }],
|
|
||||||
[Hand.Right, { kind: "Linear", transitionBeats: 1 }],
|
|
||||||
])
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
case SemanticAnimationKind.DoSiDo:
|
case SemanticAnimationKind.DoSiDo:
|
||||||
// TODO Rotation
|
// TODO Rotation
|
||||||
|
@ -326,17 +333,18 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
||||||
}
|
}
|
||||||
const center = CenterOf(move.startPosition.which.leftRightSide(), move.startPosition.setOffset, move.startPosition.lineOffset);
|
const center = CenterOf(move.startPosition.which.leftRightSide(), move.startPosition.setOffset, move.startPosition.lineOffset);
|
||||||
return [
|
return [
|
||||||
new animation.RotationAnimationSegment(move.beats,
|
new animation.RotationAnimationSegment({
|
||||||
startSetPosition,
|
beats: move.beats,
|
||||||
endSetPosition,
|
startPosition: startSetPosition,
|
||||||
move.movementPattern.amount,
|
endPosition: endSetPosition,
|
||||||
{
|
rotation: move.movementPattern.amount,
|
||||||
|
around: {
|
||||||
center,
|
center,
|
||||||
width: setWidth / 3,
|
width: setWidth / 3,
|
||||||
height: setHeight,
|
height: setHeight,
|
||||||
},
|
},
|
||||||
animation.RotationAnimationFacing.Linear,
|
facing: animation.RotationAnimationFacing.Linear
|
||||||
),
|
}),
|
||||||
];
|
];
|
||||||
case SemanticAnimationKind.RotateAround:
|
case SemanticAnimationKind.RotateAround:
|
||||||
// TODO Rotation
|
// TODO Rotation
|
||||||
|
@ -349,31 +357,37 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
||||||
const rotateCenter = CenterOf(move.movementPattern.around, move.startPosition.setOffset, move.startPosition.lineOffset);
|
const rotateCenter = CenterOf(move.movementPattern.around, move.startPosition.setOffset, move.startPosition.lineOffset);
|
||||||
const hands = move.movementPattern.byHand
|
const hands = move.movementPattern.byHand
|
||||||
? new Map<Hand, animation.HandAnimation>([
|
? new Map<Hand, animation.HandAnimation>([
|
||||||
[move.movementPattern.byHand, { kind: "Center", transitionBeats: 1 }],
|
[move.movementPattern.byHand, { kind: "Center" }],
|
||||||
[move.movementPattern.byHand.opposite(), { kind: "None", transitionBeats: 1 }],
|
[move.movementPattern.byHand.opposite(), { kind: "None" }],
|
||||||
])
|
])
|
||||||
: new Map<Hand, animation.HandAnimation>([
|
: new Map<Hand, animation.HandAnimation>([
|
||||||
[Hand.Left, { kind: "None", transitionBeats: 1 }],
|
[Hand.Left, { kind: "None" }],
|
||||||
[Hand.Right, { kind: "None", transitionBeats: 1 }],
|
[Hand.Right, { kind: "None" }],
|
||||||
]);
|
]);
|
||||||
return [
|
return [
|
||||||
new animation.RotationAnimationSegment(move.beats,
|
new animation.TransitionAnimationSegment({
|
||||||
startSetPosition,
|
actualAnimation: new animation.RotationAnimationSegment({
|
||||||
endSetPosition,
|
beats: move.beats,
|
||||||
move.movementPattern.minAmount,
|
startPosition: startSetPosition,
|
||||||
{
|
endPosition: endSetPosition,
|
||||||
center: rotateCenter,
|
rotation: move.movementPattern.minAmount,
|
||||||
width: setWidth / 5,
|
around: {
|
||||||
height: setHeight / 5,
|
center: rotateCenter,
|
||||||
|
width: setWidth / 5,
|
||||||
|
height: setHeight / 5,
|
||||||
|
},
|
||||||
|
facing: animation.RotationAnimationFacing.Center, closer: {
|
||||||
|
transitionBeats: 1,
|
||||||
|
minDistance: setWidth,
|
||||||
|
},
|
||||||
|
hands
|
||||||
|
}),
|
||||||
|
flags: {
|
||||||
|
hands: true,
|
||||||
|
rotation: true
|
||||||
},
|
},
|
||||||
animation.RotationAnimationFacing.Center,
|
startTransitionBeats: 1
|
||||||
{
|
}),
|
||||||
transitionBeats: 1,
|
|
||||||
minDistance: setWidth,
|
|
||||||
},
|
|
||||||
hands,
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
case SemanticAnimationKind.Swing:
|
case SemanticAnimationKind.Swing:
|
||||||
if (move.startPosition.kind !== PositionKind.Circle || move.endPosition.kind !== PositionKind.Circle) {
|
if (move.startPosition.kind !== PositionKind.Circle || move.endPosition.kind !== PositionKind.Circle) {
|
||||||
|
@ -400,29 +414,33 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
||||||
});
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new animation.LinearAnimationSegment(1,
|
new animation.LinearAnimationSegment({
|
||||||
startSetPosition,
|
beats: 1,
|
||||||
swingStart,
|
startPosition: startSetPosition,
|
||||||
),
|
endPosition: swingStart,
|
||||||
new animation.RotationAnimationSegment(move.beats - 3,
|
}),
|
||||||
swingStart,
|
new animation.RotationAnimationSegment({
|
||||||
beforeUnfold,
|
beats: move.beats - 3,
|
||||||
move.movementPattern.minAmount, // TODO base minAmount on number of beats?
|
startPosition: swingStart,
|
||||||
{
|
endPosition: beforeUnfold,
|
||||||
|
rotation: move.movementPattern.minAmount,
|
||||||
|
around: {
|
||||||
center: rotateSwingCenter,
|
center: rotateSwingCenter,
|
||||||
width: setWidth / 5,
|
width: setWidth / 5,
|
||||||
height: setHeight / 5,
|
height: setHeight / 5,
|
||||||
},
|
},
|
||||||
animation.RotationAnimationFacing.CenterRelative,
|
facing: animation.RotationAnimationFacing.CenterRelative
|
||||||
),
|
}),
|
||||||
new animation.LinearAnimationSegment(1,
|
new animation.LinearAnimationSegment({
|
||||||
beforeUnfold,
|
beats: 1,
|
||||||
unfolded,
|
startPosition: beforeUnfold,
|
||||||
),
|
endPosition: unfolded,
|
||||||
new animation.LinearAnimationSegment(1,
|
}),
|
||||||
unfolded,
|
new animation.LinearAnimationSegment({
|
||||||
endSetPosition,
|
beats: 1,
|
||||||
),
|
startPosition: unfolded,
|
||||||
|
endPosition: endSetPosition,
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
case SemanticAnimationKind.TwirlSwap:
|
case SemanticAnimationKind.TwirlSwap:
|
||||||
const twirlCenter =
|
const twirlCenter =
|
||||||
|
@ -435,25 +453,26 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
||||||
rightArmEnd: startSetPosition.rightArmEnd === undefined ? undefined : endSetPosition.rightArmEnd,
|
rightArmEnd: startSetPosition.rightArmEnd === undefined ? undefined : endSetPosition.rightArmEnd,
|
||||||
};
|
};
|
||||||
return [
|
return [
|
||||||
new animation.RotationAnimationSegment(move.beats - 1,
|
new animation.RotationAnimationSegment({
|
||||||
startSetPosition,
|
beats: move.beats - 1,
|
||||||
{
|
startPosition: startSetPosition,
|
||||||
|
endPosition: {
|
||||||
...postTwirlPos,
|
...postTwirlPos,
|
||||||
rotation: endSetPosition.rotation - (move.startPosition.hands?.has(Hand.Left) ? 360 : 0)
|
rotation: endSetPosition.rotation - (move.startPosition.hands?.has(Hand.Left) ? 360 : 0)
|
||||||
},
|
},
|
||||||
180,
|
rotation: 180,
|
||||||
{
|
around: {
|
||||||
center: twirlCenter,
|
center: twirlCenter,
|
||||||
width: aroundTopOrBottom ? setWidth : setWidth / 4,
|
width: aroundTopOrBottom ? setWidth : setWidth / 4,
|
||||||
height: aroundTopOrBottom ? setHeight / 4 : setHeight,
|
height: aroundTopOrBottom ? setHeight / 4 : setHeight,
|
||||||
},
|
},
|
||||||
animation.RotationAnimationFacing.Linear,
|
facing: animation.RotationAnimationFacing.Linear, closer: undefined, hands: new Map<Hand, animation.HandAnimation>([[[...move.startPosition.hands!.keys()][0], { kind: "Center" }]])
|
||||||
undefined,
|
}),
|
||||||
new Map<Hand, animation.HandAnimation>([[[...move.startPosition.hands!.keys()][0], {kind: "Center"}]]),
|
new animation.LinearAnimationSegment({
|
||||||
),
|
beats: 1,
|
||||||
new animation.LinearAnimationSegment(1,
|
startPosition: postTwirlPos,
|
||||||
postTwirlPos,
|
endPosition: endSetPosition
|
||||||
endSetPosition)
|
})
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user