@@ -35,41 +35,51 @@ function SmoothLines({
35
35
prevFocus,
36
36
nextFocus,
37
37
center,
38
- minZoom = 0 , // TODO use minZoom
38
+ minZoom = 0 ,
39
39
maxZoom = 1.2 ,
40
40
} : Props ) {
41
41
const lines = useLineTransitions ( prevLines , nextLines )
42
42
43
- const focusWidth = Array . isArray ( lineWidth )
44
- ? tweenProp ( lineWidth [ 0 ] , lineWidth [ 1 ] , progress )
45
- : lineWidth
46
-
47
43
const prevFocusKeys = prevFocus . map (
48
44
index => prevLines [ index ] ?. key
49
45
)
50
46
const nextFocusKeys = nextFocus . map (
51
47
index => nextLines [ index ] ?. key
52
48
)
53
49
54
- const [ prevZoom , prevDX , prevDY ] = getContentProps ( {
50
+ const [
51
+ prevZoom ,
52
+ prevDX ,
53
+ prevDY ,
54
+ prevContentHeight ,
55
+ prevContentWidth ,
56
+ ] = getContentProps ( {
55
57
containerWidth,
56
58
containerHeight,
57
59
lineWidth : Array . isArray ( lineWidth )
58
60
? lineWidth [ 0 ]
59
61
: lineWidth ,
60
62
lineHeight,
63
+ minZoom,
61
64
maxZoom,
62
65
horizontalCenter : ! ! center ,
63
66
focusLineIndexList : prevFocus ,
64
67
originalContentHeight : prevLines . length * lineHeight ,
65
68
} )
66
- const [ nextZoom , nextDX , nextDY ] = getContentProps ( {
69
+ const [
70
+ nextZoom ,
71
+ nextDX ,
72
+ nextDY ,
73
+ nextContentHeight ,
74
+ nextContentWidth ,
75
+ ] = getContentProps ( {
67
76
containerWidth,
68
77
containerHeight,
69
78
lineWidth : Array . isArray ( lineWidth )
70
79
? lineWidth [ 1 ]
71
80
: lineWidth ,
72
81
lineHeight,
82
+ minZoom,
73
83
maxZoom,
74
84
horizontalCenter : ! ! center ,
75
85
focusLineIndexList : nextFocus ,
@@ -79,13 +89,29 @@ function SmoothLines({
79
89
const zoom = tweenProp ( prevZoom , nextZoom , progress )
80
90
const dx = tweenProp ( prevDX , nextDX , progress )
81
91
const dy = tweenProp ( prevDY , nextDY , progress )
92
+ const focusHeight = tweenProp (
93
+ prevContentHeight ,
94
+ nextContentHeight ,
95
+ progress
96
+ )
97
+ const focusWidth = tweenProp (
98
+ prevContentWidth ,
99
+ nextContentWidth ,
100
+ progress
101
+ )
82
102
83
103
return (
84
104
< Container
85
105
width = { containerWidth }
86
106
height = { containerHeight }
87
107
>
88
- < Content dx = { dx } dy = { dy } scale = { zoom } >
108
+ < Content
109
+ dx = { dx }
110
+ dy = { dy }
111
+ scale = { zoom }
112
+ height = { Math . max ( focusHeight , containerHeight ) }
113
+ width = { Math . max ( focusWidth , containerWidth ) }
114
+ >
89
115
< Lines
90
116
lines = { lines }
91
117
prevFocusKeys = { prevFocusKeys }
@@ -104,6 +130,7 @@ function getContentProps({
104
130
containerHeight,
105
131
lineWidth,
106
132
lineHeight,
133
+ minZoom,
107
134
maxZoom,
108
135
focusLineIndexList,
109
136
originalContentHeight,
@@ -113,6 +140,7 @@ function getContentProps({
113
140
containerHeight : number
114
141
lineWidth : number
115
142
lineHeight : number
143
+ minZoom : number
116
144
maxZoom : number
117
145
focusLineIndexList : number [ ]
118
146
originalContentHeight : number
@@ -124,32 +152,45 @@ function getContentProps({
124
152
]
125
153
const originalFocusHeight =
126
154
( extremes [ 1 ] - extremes [ 0 ] + 3 ) * lineHeight
127
- const zoom = Math . min (
128
- containerWidth / lineWidth ,
129
- containerHeight / originalFocusHeight ,
130
- maxZoom
155
+ const zoom = Math . max (
156
+ Math . min (
157
+ containerWidth / lineWidth ,
158
+ containerHeight / originalFocusHeight ,
159
+ maxZoom
160
+ ) ,
161
+ minZoom
131
162
)
132
163
133
164
const contentHeight = originalContentHeight * zoom
134
165
135
166
const focusStart = ( extremes [ 0 ] - 1 ) * lineHeight * zoom
136
167
const focusEnd = ( extremes [ 1 ] + 2 ) * lineHeight * zoom
137
168
const focusCenter = ( focusEnd + focusStart ) / 2
169
+ const focusHeight = focusEnd - focusStart
138
170
139
171
const dy =
140
172
containerHeight > contentHeight
141
173
? ( containerHeight - contentHeight ) / 2
142
174
: clamp (
143
175
containerHeight / 2 - focusCenter ,
144
- containerHeight - contentHeight ,
176
+ Math . max (
177
+ containerHeight - contentHeight ,
178
+ - focusStart // to ensure first focus line is shown when focus is bigger than container
179
+ ) ,
145
180
0
146
181
)
147
182
148
183
const dx = horizontalCenter
149
184
? containerWidth / 2 - ( lineWidth * zoom ) / 2
150
185
: 0
151
186
152
- return [ zoom , dx , dy ] as const
187
+ return [
188
+ zoom ,
189
+ dx ,
190
+ dy ,
191
+ focusHeight ,
192
+ lineWidth * zoom ,
193
+ ] as const
153
194
}
154
195
155
196
function Container ( {
@@ -167,6 +208,7 @@ function Container({
167
208
width,
168
209
height,
169
210
position : "relative" ,
211
+ // overflow: "auto",
170
212
} }
171
213
>
172
214
{ children }
@@ -178,11 +220,15 @@ function Content({
178
220
dx,
179
221
dy,
180
222
scale,
223
+ height,
224
+ width,
181
225
children,
182
226
} : {
183
227
dx : number
184
228
dy : number
185
229
scale : number
230
+ height : number
231
+ width : number
186
232
children : React . ReactNode
187
233
} ) {
188
234
return (
@@ -191,10 +237,23 @@ function Content({
191
237
position : "absolute" ,
192
238
top : 0 ,
193
239
left : 0 ,
194
- transform : `translateX(${ dx } px) translateY(${ dy } px) scale(${ scale } )` ,
240
+ transformOrigin : "top left" ,
241
+ width : width ,
242
+ height : height ,
243
+ overflow : "hidden" ,
195
244
} }
196
245
>
197
- { children }
246
+ < div
247
+ style = { {
248
+ position : "absolute" ,
249
+ top : 0 ,
250
+ left : 0 ,
251
+ transform : `translateX(${ dx } px) translateY(${ dy } px) scale(${ scale } )` ,
252
+ transformOrigin : "top left" ,
253
+ } }
254
+ >
255
+ { children }
256
+ </ div >
198
257
</ div >
199
258
)
200
259
}
0 commit comments