|
30 | 30 | $: isHorizontal = direction === "Horizontal"; |
31 | 31 | $: trackedAxis = isHorizontal ? axes.horiz : axes.vert; |
32 | 32 | $: otherAxis = isHorizontal ? axes.vert : axes.horiz; |
33 | | - $: otherVec = flipVec(otherAxis.vec, flip); |
| 33 | + $: crossAxisDirection = flipVector(otherAxis.vec, flip); |
34 | 34 | $: stretchFactor = 1 / Math.max(Math.abs(isHorizontal ? trackedAxis.vec[0] : trackedAxis.vec[1]), 1e-10); |
35 | 35 | $: stretchedSpacing = majorMarkSpacing * stretchFactor; |
36 | | - $: effectiveOrigin = projectOntoRuler(direction, originX, originY, otherVec); |
37 | | - $: svgPath = computeSvgPath(direction, effectiveOrigin, stretchedSpacing, stretchFactor, minorDivisions, microDivisions, rulerLength, otherVec); |
38 | | - $: svgTexts = computeSvgTexts(direction, effectiveOrigin, stretchedSpacing, numberInterval, rulerLength, trackedAxis, otherAxis.vec, tilt); |
39 | | - $: cursorIndicatorPath = computeCursorIndicator(direction, cursorPosition, otherVec); |
| 36 | + $: effectiveOrigin = projectOntoRuler(direction, originX, originY, crossAxisDirection); |
| 37 | + $: svgPath = computeSvgPath(direction, effectiveOrigin, stretchedSpacing, stretchFactor, minorDivisions, microDivisions, rulerLength, crossAxisDirection); |
| 38 | + $: svgTexts = computeSvgTexts(direction, effectiveOrigin, stretchedSpacing, numberInterval, rulerLength, trackedAxis, crossAxisDirection); |
| 39 | + $: cursorIndicatorPath = computeCursorIndicator(direction, cursorPosition, crossAxisDirection); |
40 | 40 |
|
41 | 41 | function computeAxes(tilt: number): { horiz: Axis; vert: Axis } { |
42 | 42 | const normTilt = ((tilt % TAU) + TAU) % TAU; |
|
54 | 54 | return { horiz: posY, vert: negX }; |
55 | 55 | } |
56 | 56 |
|
57 | | - function flipVec(vec: [number, number], flipped: boolean): [number, number] { |
| 57 | + function flipVector(vec: [number, number], flipped: boolean): [number, number] { |
58 | 58 | return flipped ? [-vec[0], vec[1]] : vec; |
59 | 59 | } |
60 | 60 |
|
|
82 | 82 | minorDivisions: number, |
83 | 83 | microDivisions: number, |
84 | 84 | rulerLength: number, |
85 | | - otherVec: [number, number], |
| 85 | + crossAxisDirection: [number, number], |
86 | 86 | ): string { |
87 | 87 | const adaptive = stretchFactor > 1.3 ? { minor: minorDivisions, micro: 1 } : { minor: minorDivisions, micro: microDivisions }; |
88 | 88 | const divisions = stretchedSpacing / adaptive.minor / adaptive.micro; |
89 | 89 | const majorMarksFrequency = adaptive.minor * adaptive.micro; |
90 | 90 | const shiftedOffsetStart = mod(effectiveOrigin, stretchedSpacing) - stretchedSpacing; |
91 | 91 |
|
92 | | - const { dx, dy, sxBase, syBase } = tickMarkGeometry(direction, otherVec[0], otherVec[1]); |
| 92 | + const { dx, dy, sxBase, syBase } = tickMarkGeometry(direction, crossAxisDirection[0], crossAxisDirection[1]); |
93 | 93 |
|
94 | 94 | let path = ""; |
95 | 95 | let i = 0; |
|
115 | 115 | numberInterval: number, |
116 | 116 | rulerLength: number, |
117 | 117 | trackedAxis: Axis, |
118 | | - unflippedOtherVec: [number, number], |
119 | | - tilt: number, |
| 118 | + crossAxisDirection: [number, number], |
120 | 119 | ): { transform: string; text: string }[] { |
121 | 120 | const isVertical = direction === "Vertical"; |
122 | 121 |
|
123 | | - // Tip offset uses the un-flipped axis so text stays on the correct side of tick marks |
124 | | - const { dx: tipDx, dy: tipDy } = tickMarkGeometry(direction, unflippedOtherVec[0], unflippedOtherVec[1]); |
125 | | - const tiltScale = tilt >= 0 ? 1 : 0.5; |
| 122 | + const { dx: tipDx, dy: tipDy } = tickMarkGeometry(direction, crossAxisDirection[0], crossAxisDirection[1]); |
| 123 | + const forwardTip = isVertical ? -tipDy : tipDx; |
| 124 | + const tiltScale = forwardTip >= 0 ? 1 : 0.5; |
126 | 125 | const tipOffsetX = tipDx * MAJOR_MARK_THICKNESS * tiltScale; |
127 | 126 | const tipOffsetY = tipDy * MAJOR_MARK_THICKNESS * tiltScale; |
128 | 127 |
|
|
151 | 150 | return results; |
152 | 151 | } |
153 | 152 |
|
154 | | - function computeCursorIndicator(direction: RulerDirection, cursor: { x: number; y: number } | undefined, otherVec: [number, number]): string { |
| 153 | + function computeCursorIndicator(direction: RulerDirection, cursor: { x: number; y: number } | undefined, crossAxisDirection: [number, number]): string { |
155 | 154 | if (cursor === undefined) return ""; |
156 | 155 |
|
157 | | - const projected = projectOntoRuler(direction, cursor.x, cursor.y, otherVec); |
158 | | - const { dx, dy, sxBase, syBase } = tickMarkGeometry(direction, otherVec[0], otherVec[1]); |
| 156 | + const projected = projectOntoRuler(direction, cursor.x, cursor.y, crossAxisDirection); |
| 157 | + const { dx, dy, sxBase, syBase } = tickMarkGeometry(direction, crossAxisDirection[0], crossAxisDirection[1]); |
159 | 158 |
|
160 | 159 | // Scale the line so it spans the full ruler bar thickness |
161 | 160 | const thicknessComponent = Math.abs(direction === "Horizontal" ? dy : dx); |
|
0 commit comments