Black Trigram (흑괘) - Korean Martial Arts Combat Simulator API - v0.7.0
    Preparing search index...

    Class MartialArtsAnimationBuilder

    Martial Arts Animation Builder

    Fluent API for creating Korean martial arts animations with semantic methods. Designed to be readable by martial arts practitioners.

    // Create a front kick (앞차기)
    const frontKick = MartialArtsAnimationBuilder
    .create("front_kick", "앞차기")
    .asAttack(0.55)
    .chamber() // 준비 - Knee lifts
    .withHighGuard() // 상단방어 - Protect face
    .extend() // 차기 - Leg extends
    .retract() // 회수 - Return to chamber
    .recover() // 복귀 - Return to stance
    .build();

    무술애니메이션빌더

    Index

    Constructors

    Methods

    _addKeyframe addKeyframe applyFootPositionsDuring applyHandPose applyHandPoseDuring applyHandPoseToKeyframe applyHookTorsoRotation applyKickTorsoLean applyKoreanGuard applyPunchTorsoRotation armBarDrop armBarEntry asAttack asDefense asIdle asMovement asStance at axeKick axeKickChop axeKickRise backKickSpin backKickThrust backwardStep blockHigh blockKnifeHand blockLow blockMiddle bob brachialElbow build chamber chokeGrip clinchGrab counterParry counterStrike crescentKickArc crescentKickChamber crossPunch duck elbowChamber elbowLockApply elbowStrike elbowUppercut extend eyeGouge femoralKnee fingerLockTwist flyingKnee forwardStep groinStrike groundMount hipThrow hookKickExtend hookKickHook hookPunch hookWindup jawStrike jointLock jugularStrike jump kidneyKnee kidneyStrike kneeStrike lean liverShot lowKickChamber lowKickSweep nerveStrike occipitalStrike overhandPunch palmStrike parry punchChamber punchExtend punchPeak punchWindup pushKickChamber pushKickThrust recover resetTorsoRotation retract rotate roundhouse roundhouseChamber roundhouseExtend setDown shift shoulderLockTwist sideKickChamber sideKickExtend sideKneeStrike sideStepLeft sideStepRight slamDown slamLift slashingElbow solarPlexusStrike spin spinalElbow spineStrike spinKick spinningHeelKick spinRecover stance step sweep takedownDump takedownShoot templeElbow throatStrike throwEntry throwExecute tornadoJump uppercutCrouch uppercutPunch weave withBackfist withClinch withFootWidth withGrab withGuard withHighGuard withKoreanHighGuard withKoreanLowGuard withKoreanMiddleGuard withOpenPalm withSpearHand withTrigramGuard wristGrab wristTwist create getTrigramArmGuard

    Properties

    Constructors

    Methods

    • Apply foot positions to current keyframe during addKeyframe Inline version for use within keyframe callback

      Parameters

      • kf: KeyframeConfig

        KeyframeConfig to modify

      • stanceWidthMultiplier: number

        Multiplier from KOREAN_STANCE_BIOMECHANICS

      • shoulderWidth: number

        Fighter's shoulder width in centimeters

      Returns void

      발너비설정

    • Helper to apply finger rotations from a hand pose to a keyframe

      Parameters

      • kf: KeyframeConfig
      • pose:
            | {
                index_dist: readonly [0.8, 0, 0];
                index_inter: readonly [1.57, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.57, 0, 0];
                middle_dist: readonly [0.8, 0, 0];
                middle_inter: readonly [1.57, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.57, 0, 0];
                pinky_dist: readonly [0.8, 0, 0];
                pinky_inter: readonly [1.57, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.57, 0, 0];
                ring_dist: readonly [0.8, 0, 0];
                ring_inter: readonly [1.57, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.57, 0, 0];
                thumb_dist: readonly [0.3, 0, 0];
                thumb_meta: readonly [0.3, 0.5, 0.2];
                thumb_prox: readonly [0.4, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0, 0, 0];
                index_meta: readonly [0, 0, -0.1];
                index_prox: readonly [0, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0, 0, 0];
                pinky_dist: readonly [0, 0, 0];
                pinky_inter: readonly [0, 0, 0];
                pinky_meta: readonly [0, 0, 0.2];
                pinky_prox: readonly [0, 0, 0];
                ring_dist: readonly [0, 0, 0];
                ring_inter: readonly [0, 0, 0];
                ring_meta: readonly [0, 0, 0.1];
                ring_prox: readonly [0, 0, 0];
                thumb_dist: readonly [0, 0, 0];
                thumb_meta: readonly [0, 0.4, -0.3];
                thumb_prox: readonly [0.1, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [0, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0, 0, 0];
                pinky_dist: readonly [0, 0, 0];
                pinky_inter: readonly [0, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [0, 0, 0];
                ring_dist: readonly [0, 0, 0];
                ring_inter: readonly [0, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [0, 0, 0];
                thumb_dist: readonly [0.1, 0, 0];
                thumb_meta: readonly [0.4, 0.6, 0.3];
                thumb_prox: readonly [0.2, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0.05, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [0.1, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0.05, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0.1, 0, 0];
                pinky_dist: readonly [0, 0, 0];
                pinky_inter: readonly [0.05, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [0.1, 0, 0];
                ring_dist: readonly [0, 0, 0];
                ring_inter: readonly [0.05, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [0.1, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.5, 0.8, 0.4];
                thumb_prox: readonly [0.4, 0, 0];
            }
            | {
                index_dist: readonly [1, 0, 0];
                index_inter: readonly [1.7, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.7, 0, 0];
                middle_dist: readonly [1, 0, 0];
                middle_inter: readonly [1.7, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.7, 0, 0];
                pinky_dist: readonly [1, 0, 0];
                pinky_inter: readonly [1.7, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.7, 0, 0];
                ring_dist: readonly [1, 0, 0];
                ring_inter: readonly [1.7, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.7, 0, 0];
                thumb_dist: readonly [0.4, 0, 0];
                thumb_meta: readonly [0.4, 0.6, 0.3];
                thumb_prox: readonly [0.5, 0, 0];
            }
            | {
                index_dist: readonly [0.7, 0, 0];
                index_inter: readonly [1.4, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.4, 0, 0];
                middle_dist: readonly [0.7, 0, 0];
                middle_inter: readonly [1.4, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.4, 0, 0];
                pinky_dist: readonly [0.7, 0, 0];
                pinky_inter: readonly [1.4, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.4, 0, 0];
                ring_dist: readonly [0.7, 0, 0];
                ring_inter: readonly [1.4, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.4, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.3, 0.5, 0.2];
                thumb_prox: readonly [0.3, 0, 0];
            }
            | {
                index_dist: readonly [0.6, 0, 0];
                index_inter: readonly [1, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.2, 0, 0];
                middle_dist: readonly [0.7, 0, 0];
                middle_inter: readonly [1.1, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.3, 0, 0];
                pinky_dist: readonly [0.6, 0, 0];
                pinky_inter: readonly [1, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.2, 0, 0];
                ring_dist: readonly [0.7, 0, 0];
                ring_inter: readonly [1.1, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.3, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.2, 0.3, 0.1];
                thumb_prox: readonly [0.3, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0, 0, 0];
                index_meta: readonly [0, 0, -0.1];
                index_prox: readonly [0, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0, 0, 0];
                middle_meta: readonly [0, 0, 0.1];
                middle_prox: readonly [0, 0, 0];
                pinky_dist: readonly [0.8, 0, 0];
                pinky_inter: readonly [1.57, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.57, 0, 0];
                ring_dist: readonly [0.8, 0, 0];
                ring_inter: readonly [1.57, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.57, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.4, 0.6, 0.3];
                thumb_prox: readonly [0.3, 0, 0];
            }
            | {
                index_dist: readonly [0.1, 0, 0];
                index_inter: readonly [0.2, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [0.3, 0, 0];
                middle_dist: readonly [0.15, 0, 0];
                middle_inter: readonly [0.25, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0.35, 0, 0];
                pinky_dist: readonly [0.1, 0, 0];
                pinky_inter: readonly [0.2, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [0.3, 0, 0];
                ring_dist: readonly [0.15, 0, 0];
                ring_inter: readonly [0.25, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [0.35, 0, 0];
                thumb_dist: readonly [0.05, 0, 0];
                thumb_meta: readonly [0.1, 0.2, 0.1];
                thumb_prox: readonly [0.1, 0, 0];
            }
      • hand: "left" | "right" | "both"

      Returns void

    • Apply hand pose during a keyframe (inline version for addKeyframe)

      Parameters

      • kf: KeyframeConfig
      • pose:
            | "FIST"
            | "OPEN_PALM"
            | "SPEAR_HAND"
            | "KNIFE_HAND"
            | "HAMMER_FIST"
            | "BACKFIST"
            | "GRAB"
            | "TWO_FINGER"
            | "RELAXED"

        The hand pose to apply

      • hand: "left" | "right" | "both" = "both"

        Which hand(s) to apply the pose to

      Returns void

      손모양적용

    • Helper to apply finger rotations from a hand pose to an existing keyframe

      Parameters

      • kf: AnimationKeyframe
      • pose:
            | {
                index_dist: readonly [0.8, 0, 0];
                index_inter: readonly [1.57, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.57, 0, 0];
                middle_dist: readonly [0.8, 0, 0];
                middle_inter: readonly [1.57, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.57, 0, 0];
                pinky_dist: readonly [0.8, 0, 0];
                pinky_inter: readonly [1.57, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.57, 0, 0];
                ring_dist: readonly [0.8, 0, 0];
                ring_inter: readonly [1.57, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.57, 0, 0];
                thumb_dist: readonly [0.3, 0, 0];
                thumb_meta: readonly [0.3, 0.5, 0.2];
                thumb_prox: readonly [0.4, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0, 0, 0];
                index_meta: readonly [0, 0, -0.1];
                index_prox: readonly [0, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0, 0, 0];
                pinky_dist: readonly [0, 0, 0];
                pinky_inter: readonly [0, 0, 0];
                pinky_meta: readonly [0, 0, 0.2];
                pinky_prox: readonly [0, 0, 0];
                ring_dist: readonly [0, 0, 0];
                ring_inter: readonly [0, 0, 0];
                ring_meta: readonly [0, 0, 0.1];
                ring_prox: readonly [0, 0, 0];
                thumb_dist: readonly [0, 0, 0];
                thumb_meta: readonly [0, 0.4, -0.3];
                thumb_prox: readonly [0.1, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [0, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0, 0, 0];
                pinky_dist: readonly [0, 0, 0];
                pinky_inter: readonly [0, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [0, 0, 0];
                ring_dist: readonly [0, 0, 0];
                ring_inter: readonly [0, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [0, 0, 0];
                thumb_dist: readonly [0.1, 0, 0];
                thumb_meta: readonly [0.4, 0.6, 0.3];
                thumb_prox: readonly [0.2, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0.05, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [0.1, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0.05, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0.1, 0, 0];
                pinky_dist: readonly [0, 0, 0];
                pinky_inter: readonly [0.05, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [0.1, 0, 0];
                ring_dist: readonly [0, 0, 0];
                ring_inter: readonly [0.05, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [0.1, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.5, 0.8, 0.4];
                thumb_prox: readonly [0.4, 0, 0];
            }
            | {
                index_dist: readonly [1, 0, 0];
                index_inter: readonly [1.7, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.7, 0, 0];
                middle_dist: readonly [1, 0, 0];
                middle_inter: readonly [1.7, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.7, 0, 0];
                pinky_dist: readonly [1, 0, 0];
                pinky_inter: readonly [1.7, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.7, 0, 0];
                ring_dist: readonly [1, 0, 0];
                ring_inter: readonly [1.7, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.7, 0, 0];
                thumb_dist: readonly [0.4, 0, 0];
                thumb_meta: readonly [0.4, 0.6, 0.3];
                thumb_prox: readonly [0.5, 0, 0];
            }
            | {
                index_dist: readonly [0.7, 0, 0];
                index_inter: readonly [1.4, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.4, 0, 0];
                middle_dist: readonly [0.7, 0, 0];
                middle_inter: readonly [1.4, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.4, 0, 0];
                pinky_dist: readonly [0.7, 0, 0];
                pinky_inter: readonly [1.4, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.4, 0, 0];
                ring_dist: readonly [0.7, 0, 0];
                ring_inter: readonly [1.4, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.4, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.3, 0.5, 0.2];
                thumb_prox: readonly [0.3, 0, 0];
            }
            | {
                index_dist: readonly [0.6, 0, 0];
                index_inter: readonly [1, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [1.2, 0, 0];
                middle_dist: readonly [0.7, 0, 0];
                middle_inter: readonly [1.1, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [1.3, 0, 0];
                pinky_dist: readonly [0.6, 0, 0];
                pinky_inter: readonly [1, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.2, 0, 0];
                ring_dist: readonly [0.7, 0, 0];
                ring_inter: readonly [1.1, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.3, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.2, 0.3, 0.1];
                thumb_prox: readonly [0.3, 0, 0];
            }
            | {
                index_dist: readonly [0, 0, 0];
                index_inter: readonly [0, 0, 0];
                index_meta: readonly [0, 0, -0.1];
                index_prox: readonly [0, 0, 0];
                middle_dist: readonly [0, 0, 0];
                middle_inter: readonly [0, 0, 0];
                middle_meta: readonly [0, 0, 0.1];
                middle_prox: readonly [0, 0, 0];
                pinky_dist: readonly [0.8, 0, 0];
                pinky_inter: readonly [1.57, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [1.57, 0, 0];
                ring_dist: readonly [0.8, 0, 0];
                ring_inter: readonly [1.57, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [1.57, 0, 0];
                thumb_dist: readonly [0.2, 0, 0];
                thumb_meta: readonly [0.4, 0.6, 0.3];
                thumb_prox: readonly [0.3, 0, 0];
            }
            | {
                index_dist: readonly [0.1, 0, 0];
                index_inter: readonly [0.2, 0, 0];
                index_meta: readonly [0, 0, 0];
                index_prox: readonly [0.3, 0, 0];
                middle_dist: readonly [0.15, 0, 0];
                middle_inter: readonly [0.25, 0, 0];
                middle_meta: readonly [0, 0, 0];
                middle_prox: readonly [0.35, 0, 0];
                pinky_dist: readonly [0.1, 0, 0];
                pinky_inter: readonly [0.2, 0, 0];
                pinky_meta: readonly [0, 0, 0];
                pinky_prox: readonly [0.3, 0, 0];
                ring_dist: readonly [0.15, 0, 0];
                ring_inter: readonly [0.25, 0, 0];
                ring_meta: readonly [0, 0, 0];
                ring_prox: readonly [0.35, 0, 0];
                thumb_dist: readonly [0.05, 0, 0];
                thumb_meta: readonly [0.1, 0.2, 0.1];
                thumb_prox: readonly [0.1, 0, 0];
            }
      • hand: "left" | "right" | "both"

      Returns void

    • Apply torso rotation for hook punch circular power (훅허리비틀기)

      Korean martial arts principle: 몸통회전 (Momtong Hoejeon) - Full torso rotation Hook punches generate power from hip and shoulder rotation in a circular motion. Larger rotation angle (45-60°) creates the circular arc needed for hooks.

      Biomechanics:

      • SPINE_LOWER rotates 50% (hip engagement)
      • SPINE_MIDDLE rotates 70% (core power transfer)
      • SPINE_UPPER rotates 100% (shoulder whip into target)

      Parameters

      • kf: KeyframeConfig

        KeyframeConfig to apply rotation to

      • side: "left" | "right"

        Which hand is hooking ("left" | "right")

      • rotationDegrees: number

        Target rotation in degrees (45-60° recommended)

      Returns void

      // Right hook with 50° rotation
      this.addKeyframe(0.30, "ease-out", (kf) => {
      this.applyHookTorsoRotation(kf, "right", 50);
      // ... other hook mechanics
      });

      훅허리비틀기

    • Apply torso lean for kick balance (차기허리기울이기)

      Korean martial arts principle: 중심축회전 (Jungsim Chuk Hoejeon) - Central axis rotation When executing kicks, the torso leans AWAY from the kicking leg to:

      1. Maintain balance on the support leg
      2. Increase reach by extending the kick further
      3. Prevent falling backward during high kicks

      Biomechanics:

      • SPINE_LOWER leans away from kick (foundation)
      • SPINE_MIDDLE leans with lower spine (stability)
      • SPINE_UPPER leans slightly less (control)

      Parameters

      • kf: KeyframeConfig

        KeyframeConfig to apply lean to

      • side: "left" | "right"

        Which leg is kicking ("left" | "right")

      • leanDegrees: number

        Amount of lean in degrees (10-20° recommended)

      Returns void

      // Right roundhouse kick with compensatory lean
      this.addKeyframe(0.35, "ease-out", (kf) => {
      this.applyKickTorsoLean(kf, "right", 15);
      // ... other kick mechanics
      });

      차기허리기울이기

    • Private

      Apply Korean guard position helper

      Private helper method to reduce code duplication across guard methods. Applies guard positions to the last keyframe in the animation.

      Parameters

      • guardType: "HIGH_GUARD" | "MIDDLE_GUARD" | "LOW_GUARD"

        Type of guard to apply

      • side: "left" | "right" | "both" = "both"

        Which side to apply ("left" | "right" | "both")

      Returns this

      this for chaining

      한국방어자세적용헬퍼

    • Apply torso rotation for straight punch power generation (주먹허리비틀기)

      Korean martial arts principle: 허리비틀기 (Heori Biteulgi) - Waist twist for power The torso rotates OPPOSITE to the punch direction, creating torque through the spine that transfers power into the strike.

      Biomechanics:

      • SPINE_LOWER rotates 50% of target angle (foundation rotation)
      • SPINE_MIDDLE rotates 70% of target angle (power transfer zone)
      • SPINE_UPPER rotates 100% of target angle (maximum rotation at shoulders)

      Parameters

      • kf: KeyframeConfig

        KeyframeConfig to apply rotation to

      • side: "left" | "right"

        Which hand is punching ("left" | "right")

      • rotationDegrees: number

        Target rotation in degrees (15-25° recommended)

      Returns void

      // Right cross with 20° counter-rotation
      this.addKeyframe(0.35, "ease-out", (kf) => {
      this.applyPunchTorsoRotation(kf, "right", 20);
      // ... other punch mechanics
      });

      주먹허리비틀기

    • Axe kick chop - Downward heel strike for 내려차기

      Enhanced with hip rotation and guard hands

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-in"

      Returns this

      내려차기

    • Axe kick rise - Leg rises high for 내려차기

      Enhanced with hip rotation and support leg positioning

      Parameters

      • timeOffset: number = 0.15
      • easing: string = "ease-out"

      Returns this

      내려차기올리기

    • Back kick spin - 180° turn for 뒤차기

      Authentic Taekwondo back kick spin (뒤차기 회전):

      • Body rotates 180° (pelvis -1.5 rad initially)
      • Spine rotates with body (lower: -1.3 rad, upper: -1.0 rad)
      • Head looks over shoulder (0.5 rad) to maintain target visual
      • Hip chambers (0.3 rad flex)
      • Knee bends (-0.8 rad) preparing for backward thrust
      • Support leg maintains balance

      Looking over the shoulder is CRITICAL - you must see the target to execute an accurate back kick. This is emphasized in all traditional Korean martial arts.

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      뒤차기회전

    • Back kick thrust - Heel drives backward for 뒤차기

      Authentic Taekwondo back kick thrust (뒤차기 밀기):

      • Body completes 180° rotation (pelvis -3.14 rad = π)
      • Hip extends backward (0.5 rad flex maintained)
      • Knee extends fully (-0.2 rad) driving heel back
      • Foot dorsiflexes (-0.4 rad) presenting heel
      • Foot position extends backward (0 forward, 0 up, -0.8 back)
      • Head maintains target visual (1.0 rad look-back)
      • Spine fully rotated with body
      • Support leg powers the thrust

      The back kick delivers tremendous power because the entire body mass drives through the strongest leg muscles (glutes, hamstrings) in a straight line backward.

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      뒤차기

    • Brachial elbow - Horizontal elbow to brachial nerve (상박치기) Targets the lateral neck/brachial plexus area

      Parameters

      • timeOffset: number = 0.08
      • easing: string = "ease-out"

      Returns this

      상박치기

    • Chamber - Knee lifts to waist height (준비자세) Starting position for all kicks

      Authentic Korean martial arts chamber mechanics:

      • Hip flexed to 90° (1.57 rad) bringing knee to torso height
      • Knee bent tight (120° angle = -2.0 rad) for power generation
      • Support leg slightly bent for stability
      • Pelvis tilts back slightly for balance
      • Toe neutral, ready for extension

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      준비자세

    • Elbow lock application - Arm bar pressure (팔꿈치꺾기) Specific elbow hyperextension lock

      Parameters

      • timeOffset: number = 0.18
      • easing: string = "ease-in"

      Returns this

      팔꿈치꺾기

    • Extend - Leg snaps forward (차기 - 확장)

      Authentic Korean martial arts extension mechanics:

      • Hip maintains elevation (1.7 rad ~97°) for target height
      • Knee extends fully (0.1 rad ~6°) for maximum reach
      • Ankle dorsiflexes (0.5 rad ~29°) pointing toe/ball of foot
      • Pelvis tilts forward (0.15 rad ~9°) for hip thrust
      • Support leg bends deeper (-0.35 rad) for power transfer
      • Spine remains upright for balance

      This is the impact frame where the strike connects.

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      차기확장

    • Femoral knee - Knee to femoral nerve (대퇴부무릎) Low knee targeting thigh/femoral nerve

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      대퇴부무릎

    • Finger manipulation - Small joint lock (손가락비틀기) Precise finger control technique

      Parameters

      • timeOffset: number = 0.12
      • easing: string = "ease-in"

      Returns this

      손가락비틀기

    • Hip throw - Classic hip projection (배대되치기) Rotating hip throw with arm control

      Parameters

      • timeOffset: number = 0.18
      • easing: string = "ease-out"

      Returns this

      배대되치기

    • Hook kick extension - Leg extends past target (후려차기 연장)

      Authentic Korean hook kick (후려차기) first phase:

      • Body rotates past perpendicular (~100°)
      • Leg extends past target like a missed side kick
      • Foot positioned to hook back toward target
      • Head maintains target visual

      The hook kick is distinct from crescent kick:

      • Crescent: sweeps ACROSS body
      • Hook: extends PAST, then hooks BACK

      Parameters

      • timeOffset: number = 0.15
      • easing: string = "ease-out"

      Returns this

      후려차기연장

    • Hook kick hook-back - Heel hooks back toward target (후려차기 후림)

      Authentic Korean hook kick (후려차기) second phase:

      • Leg retracts/hooks back toward target
      • Heel is the striking surface (발뒤꿈치)
      • Body rotates back toward target during hook
      • Snapping motion at knee for power

      The hook motion is what makes this kick unique:

      • Extends past, then HOOKS back
      • Catches opponent from unexpected angle
      • Heel strikes back of head or temple

      Parameters

      • timeOffset: number = 0.12
      • easing: string = "ease-in"

      Returns this

      후려차기후림

    • Hook punch - Circular punch targeting temple (후크) Enhanced with Korean martial arts shoulder rotation and hikite (당기기)

      Enhanced with realistic circular torso rotation (몸통회전):

      • Hook punches: 50° rotation for circular power
      • Torso rotates INTO the punch for arc generation
      • Sequential spine rotation creates whipping motion

      Parameters

      • timeOffset: number = 0.1

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand is hooking ("left" | "right")

      • easing: string = "ease-out"

        Easing function

      Returns this

      후크

    • Hook wind-up - Arm pulls to side (후크준비) Enhanced with hikite (당기기) preparation

      Parameters

      • timeOffset: number = 0.08

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand is hooking ("left" | "right")

      • easing: string = "linear"

        Easing function

      Returns this

      후크준비

    • Kidney knee - Knee to kidney from side (신장무릎) Targets kidney area from side clinch

      Parameters

      • timeOffset: number = 0.11
      • easing: string = "ease-out"

      Returns this

      신장무릎

    • Knee strike from clinch (무릎차기)

      Enhanced with hip rotation and proper clinch mechanics

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      무릎차기

    • Nerve strike - Precision brachial plexus attack (신경격) Short sharp strike to nerve cluster

      Parameters

      • timeOffset: number = 0.06
      • easing: string = "ease-out"

      Returns this

      신경격

    • Occipital strike - Palm heel to base of skull (후두부격) Upward palm strike to brain stem area

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      후두부격

    • Punch chamber - Fist at hip with vertical palm (주먹준비자세) Korean martial arts chamber position with fist vertical (세로주먹)

      Parameters

      • timeOffset: number = 0.1

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand to chamber ("left" | "right")

      • easing: string = "ease-out"

        Easing function

      Returns this

      주먹준비자세

    • Punch extension - Arm extends with torso rotation (지르기) Includes fist rotation from vertical to pronated and hikite

      Enhanced with realistic torso rotation (허리비틀기):

      • Straight punches: 20° counter-rotation for power
      • Torso rotates OPPOSITE to punch direction
      • Sequential spine rotation (lower → mid → upper)

      Parameters

      • timeOffset: number = 0.07

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand to extend ("left" | "right")

      • easing: string = "ease-out"

        Easing function

      Returns this

      지르기

    • Punch peak - Maximum extension with full rotation (정점) Hold at full extension for impact frame

      Enhanced with sustained torso rotation at impact:

      • Maintains 20° counter-rotation at peak
      • Maximizes power transfer through spine

      Parameters

      • timeOffset: number = 0.05

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand is extended ("left" | "right")

      • easing: string = "linear"

        Easing function

      Returns this

      정점

    • Punch wind-up - Arm coils back (주먹준비)

      Parameters

      • timeOffset: number = 0.08

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand to wind up ("left" | "right")

      • easing: string = "linear"

        Easing function

      Returns this

      주먹준비

    • Push kick chamber - Ball of foot position (밀어차기준비)

      Enhanced with hip rotation and guard hand protection

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      밀어차기준비

    • Push kick thrust - Foot pushes opponent back (밀어차기)

      Enhanced with hip rotation for power and guard hand protection

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      밀어차기

    • Retract - Return to chamber (회수)

      Authentic Korean martial arts retraction mechanics:

      • Leg returns THROUGH chamber position (proper 낙법)
      • Knee bends back to tight position (-2.0 rad)
      • Hip maintains height initially, then lowers
      • Foot resets to neutral from pointed position
      • Pelvis returns to neutral
      • Support leg maintains stability

      This is critical for proper technique - the leg must return through chamber to protect against counters and maintain balance.

      Parameters

      • timeOffset: number = 0.15
      • easing: string = "ease-in"

      Returns this

      회수자세

    • Roundhouse chamber - Hip rotates for 돌려차기

      Authentic Taekwondo roundhouse chamber (돌려차기 준비):

      • Hip flexed and rotated out (~1.2 rad flex, ~0.8 rad external rotation)
      • Knee bent tight (-1.5 rad) preparing for snap
      • Pelvis begins rotation (-0.5 rad on Y-axis)
      • Spine counter-rotates for power (0.3 rad on Y-axis)
      • Support leg stable
      • Arms in high guard

      The hip rotation is KEY - it opens the hip for the circular strike path that defines a roundhouse kick vs. a front kick.

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      돌려차기준비

    • Roundhouse extension - Full hip rotation for 돌려차기

      Authentic Taekwondo roundhouse extension (돌려차기 실행):

      • Hip fully extended with maximal rotation (1.2 rad flex, 1.6 rad rotation)
      • Knee snaps out to nearly straight (-0.1 rad)
      • Foot pointed and rotated (0.4 rad dorsiflexion, 0.3 rad rotation)
      • Pelvis fully rotated (-1.5 rad) providing hip whip power
      • Spine counter-rotates (0.8 rad) for torque generation
      • Foot position extends laterally (0.8m forward)
      • Support leg pivots on ball of foot

      Enhanced with compensatory torso lean (중심축회전):

      • Torso leans AWAY from kicking leg for balance
      • Increases reach and prevents backward fall
      • 12° lateral lean on Z-axis for high kicks

      The "snap" comes from the sudden knee extension combined with the hip rotation - this is the signature of Taekwondo roundhouse.

      Parameters

      • timeOffset: number = 0.15
      • easing: string = "ease-out"

      Returns this

      돌려차기

    • Shoulder lock twist - Shoulder manipulation (어깨꺾기) Rotational shoulder joint attack

      Parameters

      • timeOffset: number = 0.2
      • easing: string = "ease-in"

      Returns this

      어깨꺾기

    • Side kick chamber - Turn sideways for 옆차기

      Authentic Taekwondo side kick chamber (옆차기 준비):

      • Body turns 90° sideways (pelvis -1.57 rad on Y-axis)
      • Hip flexed and chambered (1.3 rad flex, 0.3 rad rotation)
      • Knee bent tight (-1.6 rad) preparing for lateral thrust
      • Spine rotates with body (-1.2 rad on Y-axis)
      • Lean away from kick for balance (0.2 rad lean)
      • Support leg stable and aligned
      • Arms protect vital areas

      The perpendicular chamber is essential - the hips must turn sideways to allow the heel to drive through the target laterally.

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      옆차기준비

    • Side kick extension - Lateral heel thrust for 옆차기

      Authentic Taekwondo side kick extension (옆차기 실행):

      • Hip extends laterally (1.3 rad flex, 0.7 rad rotation)
      • Knee extends fully (-0.1 rad) driving heel through target
      • Foot turned heel-first (0.4 rad on Y-axis)
      • Pelvis maintains 90° turn (-1.57 rad)
      • Spine leans away (0.4 rad) for counterbalance
      • Foot extends laterally (0.7m to side)
      • Support leg drives power

      The side kick is one of the most powerful kicks because the entire body mass drives through the heel in a straight line.

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "linear"

      Returns this

      옆차기

    • Slashing elbow - Diagonal cutting elbow (베기팔꿈치) Diagonal slash across opponent's face/temple

      Parameters

      • timeOffset: number = 0.09
      • easing: string = "linear"

      Returns this

      베기팔꿈치

    • Spinal elbow - Downward elbow to spine (척추팔꿈치) Strikes spine from behind or above

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-in"

      Returns this

      척추팔꿈치

    • Spinning heel kick - 360° with heel strike (뒤돌려차기)

      Full 360° spin requires complete support foot pivot

      Parameters

      • timeOffset: number = 0.15
      • easing: string = "ease-out"

      Returns this

      뒤돌려차기

    • Add initial fighting stance keyframe (기본 자세)

      Adds a neutral fighting stance at time 0 as the starting position for attack animations. This is the ready position before techniques.

      Returns this

      기본자세추가

    • Temple strike - Precision temple elbow (관자놀이격) Horizontal elbow targeting temple

      Parameters

      • timeOffset: number = 0.1
      • easing: string = "ease-out"

      Returns this

      관자놀이격

    • Tornado kick jump with 360° rotation (회전차기 도약)

      Authentic Korean tornado kick (회전차기) jump phase:

      • Jump with full 360° body rotation
      • Arms swing to generate rotational momentum
      • Body elevates during spin
      • Prepares for roundhouse at apex

      Parameters

      • timeOffset: number = 0.3

      Returns this

      회전차기도약

    • Uppercut crouch - Dip before rising punch (어퍼컷준비) Enhanced with hikite (당기기) preparation

      Parameters

      • timeOffset: number = 0.08

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand is uppercutting ("left" | "right")

      • easing: string = "linear"

        Easing function

      Returns this

      어퍼컷준비

    • Uppercut punch - Rising punch to chin (어퍼컷) Enhanced with Korean martial arts leg drive and hikite (당기기)

      Parameters

      • timeOffset: number = 0.1

        Time offset in seconds

      • hand: "left" | "right" = "right"

        Which hand is uppercutting ("left" | "right")

      • easing: string = "ease-out"

        Easing function

      Returns this

      어퍼컷

    • Apply foot positions based on stance width (발너비) Sets left and right foot X positions symmetrically around center

      Parameters

      • stanceWidthMultiplier: number

        Multiplier from KOREAN_STANCE_BIOMECHANICS

      • shoulderWidth: number

        Fighter's shoulder width in centimeters

      Returns this

      발너비적용

      // Jin Thunder stance (2.0x shoulder width)
      .withFootWidth(2.0, 46) // 0.92m total width

      // Son Wind stance (0.0x - crane stance)
      .withFootWidth(0.0, 46) // 0m - single leg
    • Apply Korean high guard position (상단막기)

      Traditional Korean martial arts high guard with hands at temple level protecting head and face. Uses authentic 막기자세 positioning.

      Parameters

      • side: "left" | "right" | "both" = "both"

        Which side to apply ("left" | "right" | "both")

      Returns this

      this for chaining

      상단막기자세

    • Apply Korean low guard position (하단막기)

      Low guard position protecting lower body and groin. Used in grappling and ground-fighting scenarios.

      Parameters

      • side: "left" | "right" | "both" = "both"

        Which side to apply ("left" | "right" | "both")

      Returns this

      this for chaining

      하단막기자세

    • Apply Korean middle guard position (중단막기)

      Standard Korean martial arts guard at chest/solar plexus level. Most versatile guard position, used in most fighting stances.

      Parameters

      • side: "left" | "right" | "both" = "both"

        Which side to apply ("left" | "right" | "both")

      Returns this

      this for chaining

      중단막기자세

    • Apply trigram-specific guard pose (팔괘자세)

      Sets the complete body position for the specified trigram stance, including arms, legs, torso, and pelvis. Unlike generic guards, this applies the authentic Korean martial arts posture for each of the eight trigram stances.

      Use this for:

      • Idle stance animations
      • Returning to guard after techniques
      • Walk/run animations (arms only mode)

      Parameters

      • stance: TrigramStance

        Trigram stance (e.g., TrigramStance.GEON)

      • Optionaloptions: TrigramGuardOptions

        Application options (what body parts to apply)

      Returns this

      this for chaining

      // Full guard pose in idle stance
      builder.at(0).withTrigramGuard(TrigramStance.GEON);

      // Arms only for walk animation (legs handled separately)
      builder.at(0).withTrigramGuard(TrigramStance.TAE, {
      includeLegs: false,
      includePelvis: false
      });

      팔괘방어자세

    • Get trigram guard arm positions for locomotion animations

      Returns the base arm positions for the specified trigram's guard pose. Use this when building walk/run animations that need to maintain the trigram's arm guard while adding swing motion.

      Parameters

      Returns {
          left: {
              elbow: [number, number, number];
              shoulder: [number, number, number];
          };
          right: {
              elbow: [number, number, number];
              shoulder: [number, number, number];
          };
      }

      Left and right arm base rotations (shoulder, elbow)

      const arms = builder.getTrigramArmGuard(TrigramStance.GEON);
      // Add swing to left shoulder while keeping guard shape
      kf.rotate(BoneName.SHOULDER_L,
      arms.left.shoulder[0] + swingOffset,
      arms.left.shoulder[1],
      arms.left.shoulder[2]
      );

      팔괘팔자세가져오기

    Properties

    currentTime: number = 0
    duration: number = 0.5
    keyframes: AnimationKeyframe[] = []
    koreanName: string
    loop: boolean = false
    name: string
    type: "idle" | "attack" | "defense" | "stance" | "walk" | "movement" = "attack"