contra-renderer/www/js/moves/starPromenade.ts

63 lines
2.6 KiB
TypeScript

import { DancerDistance, handToDancerToSideInCircleFacingAcross } from "../interpreterCommon.js";
import { SemanticAnimationKind } from "../lowLevelMove.js";
import { Hand } from "../rendererConstants.js";
import { ISingleVariantMoveInterpreter, LowLevelMovesForAllDancers, MoveInterpreter, MoveInterpreterCtorArgs, SemanticPositionsForAllDancers, SingleVariantMoveInterpreter, moveInterpreters } from "./_moveInterpreter.js";
const moveName = "star promenade";
class StarPromenadeSingleVariant extends SingleVariantMoveInterpreter<StarPromenade, typeof moveName> {
moveAsLowLevelMoves(): LowLevelMovesForAllDancers {
// TODO start promenade hands/show dancers close
return this.handleCircleMove(({ id, startPos }) => {
const inCenter = this.findPairOpposite(this.move.parameters.who, id) !== null;
// TODO Actually, does star promenade end facing out and butterfly whirl swaps?
const endWhich = this.moveInterpreter.swap ? startPos.which.swapDiagonal() : startPos.which;
const endFacing = endWhich.facingAcross();
return this.combine([{
beats: this.move.beats,
endPosition: {
...startPos,
which: endWhich,
facing: endFacing,
dancerDistance: DancerDistance.Compact,
// TODO Perhaps different hands indication for "scooped"?
hands: handToDancerToSideInCircleFacingAcross(endWhich),
longLines: undefined,
balance: undefined,
},
movementPattern: {
kind: SemanticAnimationKind.RotateAround,
around: "Center",
byHand: inCenter ? this.moveInterpreter.hand : undefined,
close: inCenter,
minAmount: this.move.parameters.hand ? this.move.parameters.circling : -this.move.parameters.circling,
}
}], startPos);
});
}
}
class StarPromenade extends MoveInterpreter<typeof moveName> {
public readonly hand: Hand;
public readonly swap: boolean;
constructor(args: MoveInterpreterCtorArgs<typeof moveName>) {
super(args);
this.hand = this.move.parameters.hand ? Hand.Right : Hand.Left;
this.swap = (this.move.parameters.circling % 360) === 180;
if (!this.swap && (this.move.parameters.circling % 360 !== 0)) {
throw new Error(this.move.move + " circling by not a multiple of 180 degrees is unsupported.");
}
}
override allowStartingLongLines(): boolean {
return true;
}
buildSingleVariantMoveInterpreter(startingPos: SemanticPositionsForAllDancers): ISingleVariantMoveInterpreter {
return new StarPromenadeSingleVariant(this, startingPos);
}
}
moveInterpreters.set(moveName, StarPromenade);