@@ -29,7 +29,7 @@ export const scrollIntoView = function (this: MindElixirInstance, el: HTMLElemen
2929 const containerCenterY = containerRect . top + containerRect . height / 2
3030 const offsetX = elCenterX - containerCenterX
3131 const offsetY = elCenterY - containerCenterY
32- this . move ( - offsetX , - offsetY )
32+ this . move ( - offsetX , - offsetY , true )
3333 }
3434}
3535
@@ -154,14 +154,21 @@ export const scaleFit = function (this: MindElixirInstance) {
154154/**
155155 * Move the map by `dx` and `dy`.
156156 */
157- export const move = function ( this : MindElixirInstance , dx : number , dy : number ) {
157+ export const move = function ( this : MindElixirInstance , dx : number , dy : number , smooth = false ) {
158158 const { map, scaleVal, bus } = this
159159 const transform = map . style . transform
160160 let { x, y } = getTranslate ( transform )
161161 x += dx
162162 y += dy
163163
164+ if ( smooth ) {
165+ map . style . transition = 'transform 0.3s'
166+ setTimeout ( ( ) => {
167+ map . style . transition = 'none'
168+ } , 300 )
169+ }
164170 map . style . transform = `translate(${ x } px, ${ y } px) scale(${ scaleVal } )`
171+
165172 bus . fire ( 'move' , { dx, dy } )
166173}
167174
@@ -310,6 +317,14 @@ export const expandNode = function (this: MindElixirInstance, el: Topic, isExpan
310317 } else {
311318 node . expanded = true
312319 }
320+
321+ // Calculate position before expansion
322+ const expanderRect = el . getBoundingClientRect ( )
323+ const beforePosition = {
324+ x : expanderRect . left ,
325+ y : expanderRect . top ,
326+ }
327+
313328 const parent = el . parentNode
314329 const expander = parent . children [ 1 ] !
315330 expander . expanded = node . expanded
@@ -331,22 +346,40 @@ export const expandNode = function (this: MindElixirInstance, el: Topic, isExpan
331346
332347 this . linkDiv ( el . closest ( 'me-main > me-wrapper' ) as Wrapper )
333348
334- // scroll into view if the node is out of view
335- const elRect = el . getBoundingClientRect ( )
336- const containerRect = this . container . getBoundingClientRect ( )
337- const isOutOfView =
338- elRect . bottom > containerRect . bottom || elRect . top < containerRect . top || elRect . right > containerRect . right || elRect . left < containerRect . left
339- if ( isOutOfView ) {
340- this . scrollIntoView ( el )
349+ // Calculate position after expansion and compensate for drift
350+ const afterRect = el . getBoundingClientRect ( )
351+ const afterPosition = {
352+ x : afterRect . left ,
353+ y : afterRect . top ,
341354 }
342355
356+ // Calculate the drift and move to compensate
357+ const driftX = beforePosition . x - afterPosition . x
358+ const driftY = beforePosition . y - afterPosition . y
359+
360+ this . move ( driftX , driftY )
361+
343362 this . bus . fire ( 'expandNode' , node )
344363}
345364
346365export const expandNodeAll = function ( this : MindElixirInstance , el : Topic , isExpand ?: boolean ) {
347366 const node = el . nodeObj
367+ const beforeRect = el . getBoundingClientRect ( )
368+ const beforePosition = {
369+ x : beforeRect . left ,
370+ y : beforeRect . top ,
371+ }
348372 setExpand ( node , isExpand ?? ! node . expanded )
349373 this . refresh ( )
374+ const afterRect = this . findEle ( node . id ) . getBoundingClientRect ( )
375+ const afterPosition = {
376+ x : afterRect . left ,
377+ y : afterRect . top ,
378+ }
379+ const driftX = beforePosition . x - afterPosition . x
380+ const driftY = beforePosition . y - afterPosition . y
381+
382+ this . move ( driftX , driftY )
350383}
351384
352385/**
0 commit comments