@@ -6,11 +6,18 @@ import {
6
6
MAX_ZOOM_X ,
7
7
MIN_ZOOM_MS_PER_PX ,
8
8
MIN_ZOOM_X ,
9
+ MAX_ZOOM_Y ,
10
+ MIN_ZOOM_Y ,
11
+ MAX_ZOOM_MANCHETTE_HEIGHT_MILLIMETER ,
9
12
} from './consts' ;
10
13
import { calcTotalDistance , getHeightWithoutLastWaypoint } from './utils' ;
11
14
import type { InteractiveWaypoint , Waypoint } from '../Manchette' ;
12
15
13
- type WaypointsOptions = { isProportional : boolean ; yZoom : number ; height : number } ;
16
+ type WaypointsOptions = {
17
+ isProportional : boolean ;
18
+ yZoom : number ;
19
+ height : number ;
20
+ } ;
14
21
15
22
export const filterVisibleElements = (
16
23
elements : Waypoint [ ] ,
@@ -43,20 +50,23 @@ export const filterVisibleElements = (
43
50
44
51
export const computeWaypointsToDisplay = (
45
52
waypoints : Waypoint [ ] ,
46
- { height, isProportional, yZoom } : WaypointsOptions
53
+ { height, isProportional, yZoom } : WaypointsOptions ,
54
+ minZoomMillimetrePerPx : number ,
55
+ maxZoomMillimetrePerPx : number
47
56
) : InteractiveWaypoint [ ] => {
48
57
if ( waypoints . length < 2 ) return [ ] ;
49
58
50
59
const totalDistance = calcTotalDistance ( waypoints ) ;
51
- const heightWithoutFinalWaypoint = getHeightWithoutLastWaypoint ( height ) ;
60
+ const manchetteHeight = getHeightWithoutLastWaypoint ( height ) ;
52
61
53
62
// display all waypoints in linear mode
54
63
if ( ! isProportional ) {
55
64
return waypoints . map ( ( waypoint , index ) => {
56
65
const nextWaypoint = waypoints . at ( index + 1 ) ;
66
+ const waypointHeight = BASE_WAYPOINT_HEIGHT * ( nextWaypoint ? yZoom : 1 ) ;
57
67
return {
58
68
...waypoint ,
59
- styles : { height : `${ BASE_WAYPOINT_HEIGHT * ( nextWaypoint ? yZoom : 1 ) } px` } ,
69
+ styles : { height : `${ waypointHeight } px` } ,
60
70
} ;
61
71
} ) ;
62
72
}
@@ -67,30 +77,36 @@ export const computeWaypointsToDisplay = (
67
77
const filteredWaypoints = filterVisibleElements (
68
78
waypoints ,
69
79
totalDistance ,
70
- heightWithoutFinalWaypoint ,
80
+ manchetteHeight ,
71
81
minSpace
72
82
) ;
73
83
84
+ const spaceScale = zoomValueToSpaceScale ( minZoomMillimetrePerPx , maxZoomMillimetrePerPx , yZoom ) ;
85
+
74
86
return filteredWaypoints . map ( ( waypoint , index ) => {
75
87
const nextWaypoint = filteredWaypoints . at ( index + 1 ) ;
88
+ const waypointHeight = ! nextWaypoint
89
+ ? BASE_WAYPOINT_HEIGHT
90
+ : ( nextWaypoint . position - waypoint . position ) / spaceScale
76
91
return {
77
92
...waypoint ,
78
93
styles : {
79
- height : ! nextWaypoint
80
- ? `${ BASE_WAYPOINT_HEIGHT } px`
81
- : `${
82
- ( ( nextWaypoint . position - waypoint . position ) / totalDistance ) *
83
- heightWithoutFinalWaypoint *
84
- yZoom
85
- } px`,
94
+ height : `${ waypointHeight } px` ,
86
95
} ,
87
96
} ;
88
97
} ) ;
89
98
} ;
90
99
100
+ /**
101
+ * 2 modes for space scales
102
+ * km: { coefficient: gives a scale in metre/pixel } (isProportional true)
103
+ * linear: { size: height in pixel } (each point distributed evenly along the height of manchette.)
104
+ */
91
105
export const getScales = (
92
106
waypoints : Waypoint [ ] ,
93
- { height, isProportional, yZoom } : WaypointsOptions
107
+ { isProportional, yZoom } : WaypointsOptions ,
108
+ minZoomMillimetrePerPx : number ,
109
+ maxZoomMillimetrePerPx : number
94
110
) => {
95
111
if ( waypoints . length < 2 ) return [ ] ;
96
112
@@ -109,11 +125,8 @@ export const getScales = (
109
125
const from = waypoints . at ( 0 ) ! . position ;
110
126
const to = waypoints . at ( - 1 ) ! . position ;
111
127
112
- const totalDistance = calcTotalDistance ( waypoints ) ;
113
- const heightWithoutFinalWaypoint = getHeightWithoutLastWaypoint ( height ) ;
114
-
115
128
const scaleCoeff = isProportional
116
- ? { coefficient : totalDistance / heightWithoutFinalWaypoint / yZoom }
129
+ ? { coefficient : zoomValueToSpaceScale ( minZoomMillimetrePerPx , maxZoomMillimetrePerPx , yZoom ) }
117
130
: { size : BASE_WAYPOINT_HEIGHT * ( waypoints . length - 1 ) * yZoom } ;
118
131
119
132
return [
@@ -132,6 +145,49 @@ export const timeScaleToZoomValue = (timeScale: number) =>
132
145
( 100 * Math . log ( timeScale / MIN_ZOOM_MS_PER_PX ) ) /
133
146
Math . log ( MAX_ZOOM_MS_PER_PX / MIN_ZOOM_MS_PER_PX ) ;
134
147
148
+ /**
149
+ * min zoom is computed with manchette px height between first and last waypoint.
150
+ * max zoom just the canvas drawing height (without the x-axis scale section)
151
+ */
152
+ export const getExtremaScales = (
153
+ drawingHeightWithoutTopPadding : number ,
154
+ drawingHeightWithoutBothPadding : number ,
155
+ pathLengthMillimeter : number
156
+ ) => {
157
+ return {
158
+ minZoomMillimetrePerPx : pathLengthMillimeter / drawingHeightWithoutBothPadding ,
159
+ maxZoomMillimetrePerPx : MAX_ZOOM_MANCHETTE_HEIGHT_MILLIMETER / drawingHeightWithoutTopPadding ,
160
+ } ;
161
+ } ;
162
+
163
+ // export const getScaleFromRectangle = ()
164
+
165
+ export const zoomValueToSpaceScale = (
166
+ minZoomMillimetrePerPx : number ,
167
+ maxZoomMillimetrePerPx : number ,
168
+ slider : number
169
+ ) => {
170
+ return (
171
+ minZoomMillimetrePerPx *
172
+ Math . pow (
173
+ maxZoomMillimetrePerPx / minZoomMillimetrePerPx ,
174
+ ( slider - MIN_ZOOM_Y ) / ( MAX_ZOOM_Y - MIN_ZOOM_Y )
175
+ )
176
+ ) ;
177
+ } ;
178
+
179
+ export const spaceScaleToZoomValue = (
180
+ minZoomMillimetrePerPx : number ,
181
+ maxZoomMillimetrePerPx : number ,
182
+ spaceScale : number
183
+ ) => {
184
+ return (
185
+ ( ( MAX_ZOOM_Y - MIN_ZOOM_Y ) * Math . log ( spaceScale / minZoomMillimetrePerPx ) ) /
186
+ Math . log ( maxZoomMillimetrePerPx / minZoomMillimetrePerPx ) +
187
+ MIN_ZOOM_Y
188
+ ) ;
189
+ } ;
190
+
135
191
/** Zoom on X axis and center on the mouse position */
136
192
export const zoomX = (
137
193
currentZoom : number ,
0 commit comments