All files / src/elements/line LineAnimations.ts

97.01% Statements 65/67
100% Branches 5/5
71.42% Functions 5/7
97.01% Lines 65/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 681x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 1x 1x 1x  
// Animations targeting LineElement. See ../Animations.ts for the
// abstract base + registry mechanics.
 
import {Animation, AllAnimations, IAnimationStep, registerAnimation} from "../Animations";
import {GeomElement} from "../GeomElement";
import {Slate} from "../../Slate";
import {LineElement} from "./LineElement";
 
// Default trace rate in px/ms. Calibrated for unhurried teaching: a
// typical 100-px construction line draws over ~400 ms; 200-px lines
// take ~800 ms. Authors who want snappier transitions raise the rate
// via slate.animationConfig.rates["Line.straightEdgeConnect"].
const DEFAULT_LINE_RATE_PX_PER_MS = 0.25;
 
// Common helper: trace the target line from A toward B by driving
// drawProgress. Used by both StraightEdgeConnect (the canonical
// straightedge stroke between two existing points) and
// StraightEdgeExtend (same shape, just visually framed as extending
// past an endpoint instead of joining two existing ones).
function traceLine(target: LineElement, rate: number): IAnimationStep {
    // duration = length / rate, clamped low so an extremely short
    // line still gets a perceptible draw.
    const dx = target.B.x - target.A.x;
    const dy = target.B.y - target.A.y;
    const length = Math.sqrt(dx * dx + dy * dy);
    const durationMs = Math.max(120, length / rate);
    return {
        durationMs,
        tick: (progress) => { target.drawProgress = progress; },
        finalise: () => {
            target.drawProgress = 1;
            target.visible = true;
        },
    };
}
 
// A.Line.straightEdgeConnect — pencil stroke from A toward B.
// Args: none. Duration = length × default rate (0.5 px/ms).
export class LineStraightEdgeConnectAnimation extends Animation {
    public animationMethod = AllAnimations.LINE_STRAIGHT_EDGE_CONNECT;
    public name = "Line.straightEdgeConnect";
    public elementType = LineElement;
    public defaultRate = DEFAULT_LINE_RATE_PX_PER_MS;
 
    public build(target: GeomElement, slate: Slate, args: any): IAnimationStep[] {
        return [traceLine(target as LineElement, this.defaultRate)];
    }
}
 
// A.Line.straightEdgeExtend — for Line.extend constructions where one
// endpoint sits on an existing line and the other is the projected
// new endpoint. v1 renders the same trace as StraightEdgeConnect;
// future richer variants might pivot a straightedge guide against the
// existing line first.
export class LineStraightEdgeExtendAnimation extends Animation {
    public animationMethod = AllAnimations.LINE_STRAIGHT_EDGE_EXTEND;
    public name = "Line.straightEdgeExtend";
    public elementType = LineElement;
    public defaultRate = DEFAULT_LINE_RATE_PX_PER_MS;
 
    public build(target: GeomElement, slate: Slate, args: any): IAnimationStep[] {
        return [traceLine(target as LineElement, this.defaultRate)];
    }
}
 
registerAnimation(new LineStraightEdgeConnectAnimation());
registerAnimation(new LineStraightEdgeExtendAnimation());