Skip to content

Commit ed85b71

Browse files
committed
Add overflow auto to focused lines
1 parent 0983368 commit ed85b71

File tree

2 files changed

+92
-17
lines changed

2 files changed

+92
-17
lines changed

packages/smooth-lines/src/index.tsx

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,51 @@ function SmoothLines({
3535
prevFocus,
3636
nextFocus,
3737
center,
38-
minZoom = 0, // TODO use minZoom
38+
minZoom = 0,
3939
maxZoom = 1.2,
4040
}: Props) {
4141
const lines = useLineTransitions(prevLines, nextLines)
4242

43-
const focusWidth = Array.isArray(lineWidth)
44-
? tweenProp(lineWidth[0], lineWidth[1], progress)
45-
: lineWidth
46-
4743
const prevFocusKeys = prevFocus.map(
4844
index => prevLines[index]?.key
4945
)
5046
const nextFocusKeys = nextFocus.map(
5147
index => nextLines[index]?.key
5248
)
5349

54-
const [prevZoom, prevDX, prevDY] = getContentProps({
50+
const [
51+
prevZoom,
52+
prevDX,
53+
prevDY,
54+
prevContentHeight,
55+
prevContentWidth,
56+
] = getContentProps({
5557
containerWidth,
5658
containerHeight,
5759
lineWidth: Array.isArray(lineWidth)
5860
? lineWidth[0]
5961
: lineWidth,
6062
lineHeight,
63+
minZoom,
6164
maxZoom,
6265
horizontalCenter: !!center,
6366
focusLineIndexList: prevFocus,
6467
originalContentHeight: prevLines.length * lineHeight,
6568
})
66-
const [nextZoom, nextDX, nextDY] = getContentProps({
69+
const [
70+
nextZoom,
71+
nextDX,
72+
nextDY,
73+
nextContentHeight,
74+
nextContentWidth,
75+
] = getContentProps({
6776
containerWidth,
6877
containerHeight,
6978
lineWidth: Array.isArray(lineWidth)
7079
? lineWidth[1]
7180
: lineWidth,
7281
lineHeight,
82+
minZoom,
7383
maxZoom,
7484
horizontalCenter: !!center,
7585
focusLineIndexList: nextFocus,
@@ -79,13 +89,29 @@ function SmoothLines({
7989
const zoom = tweenProp(prevZoom, nextZoom, progress)
8090
const dx = tweenProp(prevDX, nextDX, progress)
8191
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+
)
82102

83103
return (
84104
<Container
85105
width={containerWidth}
86106
height={containerHeight}
87107
>
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+
>
89115
<Lines
90116
lines={lines}
91117
prevFocusKeys={prevFocusKeys}
@@ -104,6 +130,7 @@ function getContentProps({
104130
containerHeight,
105131
lineWidth,
106132
lineHeight,
133+
minZoom,
107134
maxZoom,
108135
focusLineIndexList,
109136
originalContentHeight,
@@ -113,6 +140,7 @@ function getContentProps({
113140
containerHeight: number
114141
lineWidth: number
115142
lineHeight: number
143+
minZoom: number
116144
maxZoom: number
117145
focusLineIndexList: number[]
118146
originalContentHeight: number
@@ -124,32 +152,45 @@ function getContentProps({
124152
]
125153
const originalFocusHeight =
126154
(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
131162
)
132163

133164
const contentHeight = originalContentHeight * zoom
134165

135166
const focusStart = (extremes[0] - 1) * lineHeight * zoom
136167
const focusEnd = (extremes[1] + 2) * lineHeight * zoom
137168
const focusCenter = (focusEnd + focusStart) / 2
169+
const focusHeight = focusEnd - focusStart
138170

139171
const dy =
140172
containerHeight > contentHeight
141173
? (containerHeight - contentHeight) / 2
142174
: clamp(
143175
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+
),
145180
0
146181
)
147182

148183
const dx = horizontalCenter
149184
? containerWidth / 2 - (lineWidth * zoom) / 2
150185
: 0
151186

152-
return [zoom, dx, dy] as const
187+
return [
188+
zoom,
189+
dx,
190+
dy,
191+
focusHeight,
192+
lineWidth * zoom,
193+
] as const
153194
}
154195

155196
function Container({
@@ -167,6 +208,7 @@ function Container({
167208
width,
168209
height,
169210
position: "relative",
211+
overflow: "auto",
170212
}}
171213
>
172214
{children}
@@ -178,11 +220,15 @@ function Content({
178220
dx,
179221
dy,
180222
scale,
223+
height,
224+
width,
181225
children,
182226
}: {
183227
dx: number
184228
dy: number
185229
scale: number
230+
height: number
231+
width: number
186232
children: React.ReactNode
187233
}) {
188234
return (
@@ -191,10 +237,23 @@ function Content({
191237
position: "absolute",
192238
top: 0,
193239
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",
195244
}}
196245
>
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>
198257
</div>
199258
)
200259
}

packages/storybook/src/smooth-lines.story.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,23 @@ export default {
1515
},
1616
defaultValue: 150,
1717
},
18+
minZoom: {
19+
control: {
20+
type: "range",
21+
min: 0,
22+
max: 1,
23+
step: 0.1,
24+
},
25+
defaultValue: 0.2,
26+
},
1827
},
1928
}
2029

21-
export const basic = ({ center, containerWidth }) => (
30+
export const basic = ({
31+
center,
32+
containerWidth,
33+
minZoom,
34+
}) => (
2235
<WithProgress>
2336
{progress => (
2437
<div
@@ -38,6 +51,7 @@ export const basic = ({ center, containerWidth }) => (
3851
lineWidth={lineWidth}
3952
prevFocus={[1, 1]}
4053
nextFocus={[3, 11]}
54+
minZoom={minZoom}
4155
/>
4256
</div>
4357
)}
@@ -86,6 +100,7 @@ export const verticalCenter = ({
86100
export const dynamicLineWidth = ({
87101
center,
88102
containerWidth,
103+
minZoom,
89104
}) => {
90105
const prevLines = [
91106
{ element: <Line>One</Line>, key: 1 },
@@ -126,6 +141,7 @@ export const dynamicLineWidth = ({
126141
lineWidth={[lineWidth, lineWidth * 2]}
127142
prevFocus={[1, 1]}
128143
nextFocus={[2, 2]}
144+
minZoom={minZoom}
129145
/>
130146
</div>
131147
)}

0 commit comments

Comments
 (0)