@@ -20,10 +20,49 @@ export type PreviewMoonGeometry = {
2020 moonTravelHalfSpan : number ;
2121} ;
2222
23+ export type PreviewDirectionBearings = {
24+ c1BearingDeg ?: number ;
25+ c2BearingDeg ?: number ;
26+ c3BearingDeg ?: number ;
27+ c4BearingDeg ?: number ;
28+ } ;
29+
2330function clamp01 ( v : number ) {
2431 return Math . max ( 0 , Math . min ( 1 , v ) ) ;
2532}
2633
34+ function normalizeSignedDeltaDeg ( fromDeg : number , toDeg : number ) {
35+ const delta = ( ( toDeg - fromDeg + 540 ) % 360 ) - 180 ;
36+ return delta === - 180 ? 180 : delta ;
37+ }
38+
39+ function resolveDirectionalBearingPair ( bearings : PreviewDirectionBearings ) {
40+ const pairs : Array < [ number | undefined , number | undefined ] > = [
41+ [ bearings . c1BearingDeg , bearings . c4BearingDeg ] ,
42+ [ bearings . c2BearingDeg , bearings . c3BearingDeg ] ,
43+ [ bearings . c1BearingDeg , bearings . c3BearingDeg ] ,
44+ [ bearings . c2BearingDeg , bearings . c4BearingDeg ] ,
45+ ] ;
46+
47+ for ( const [ start , end ] of pairs ) {
48+ if ( typeof start !== "number" || ! Number . isFinite ( start ) ) continue ;
49+ if ( typeof end !== "number" || ! Number . isFinite ( end ) ) continue ;
50+ return { start, end } ;
51+ }
52+
53+ return null ;
54+ }
55+
56+ export function determinePreviewTravelDirection (
57+ bearings : PreviewDirectionBearings | undefined ,
58+ ) : 1 | - 1 {
59+ if ( ! bearings ) return 1 ;
60+ const pair = resolveDirectionalBearingPair ( bearings ) ;
61+ if ( ! pair ) return 1 ;
62+ const delta = normalizeSignedDeltaDeg ( pair . start , pair . end ) ;
63+ return delta >= 0 ? 1 : - 1 ;
64+ }
65+
2766export function determineMoonRadius ( kindAtLocation : EclipseKindAtLocation ) {
2867 if ( kindAtLocation === "annular" ) return 58 ;
2968 if ( kindAtLocation === "total" ) return 76 ;
@@ -109,6 +148,7 @@ export function calculatePreviewMoonGeometry(params: {
109148 contacts ?: PreviewMotionContacts ;
110149 stageSize ?: number ;
111150 sunRadius ?: number ;
151+ travelDirection ?: 1 | - 1 ;
112152} ) : PreviewMoonGeometry {
113153 const stageSize = params . stageSize ?? PREVIEW_STAGE_SIZE ;
114154 const sunRadius = params . sunRadius ?? PREVIEW_SUN_RADIUS ;
@@ -121,7 +161,8 @@ export function calculatePreviewMoonGeometry(params: {
121161 ) ;
122162
123163 const anchors = buildMotionAnchors ( params . contacts ?? { } , sunRadius , moonRadius ) ;
124- const moonOffsetX = interpolateOffsetX ( params . progress , anchors ) ;
164+ const travelDirection = params . travelDirection ?? 1 ;
165+ const moonOffsetX = interpolateOffsetX ( params . progress , anchors ) * travelDirection ;
125166 const moonCenterX = stageSize / 2 + moonOffsetX ;
126167 const moonCenterY = stageSize / 2 + moonClosestOffset ;
127168
0 commit comments