@@ -335,6 +335,13 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
335335 private obsidianMenu : ObsidianMenu ;
336336 private embeddableMenu : EmbeddableMenu ;
337337 private destroyers : Function [ ] = [ ] ;
338+ private contentSizeMap = new WeakMap < Element , number > ( ) ;
339+ private lastContentResizeDeltaHeight : number ;
340+ private resizeBatchTimer : number = null ;
341+ private resizeBatchStartHeight = 0 ;
342+ private lastAggregatedDh = 0 ;
343+ private lastClientElHeight = 0 ;
344+ private oldKeyboardScroll :number = null ;
338345
339346 //https://stackoverflow.com/questions/27132796/is-there-any-javascript-event-fired-when-the-on-screen-keyboard-on-mobile-safari
340347 private isEditingTextResetTimer : number = null ;
@@ -1655,7 +1662,18 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
16551662 this . handleLinkClick ( ev ) ,
16561663 ) ;
16571664
1658- this . registerDomEvent ( this . ownerWindow , "resize" , this . onExcalidrawResize . bind ( this ) ) ;
1665+ const ro = new ResizeObserver ( ( entries ) => {
1666+ for ( const entry of entries ) {
1667+ const { height } = entry . contentRect ;
1668+ const prevHeight = this . contentSizeMap . get ( entry . target ) ;
1669+ const dh = prevHeight ? height - prevHeight : 0 ;
1670+ this . contentSizeMap . set ( entry . target , height ) ;
1671+ this . lastContentResizeDeltaHeight = dh ;
1672+ this . scheduleBatchedResize ( entry ) ;
1673+ }
1674+ } ) ;
1675+ ro . observe ( this . contentEl ) ;
1676+ this . destroyers . push ( ( ) => ro . disconnect ( ) ) ;
16591677
16601678 this . app . workspace . onLayoutReady ( async ( ) => {
16611679 ( process . env . NODE_ENV === 'development' ) && DEBUGGING && debug ( this . onload , `ExcalidrawView.onload > app.workspace.onLayoutReady, file:${ this . file ?. name } , isActiveLeaf:${ this ?. app ?. workspace ?. activeLeaf === this . leaf } , is activeExcalidrawView set:${ Boolean ( this ?. plugin ?. activeExcalidrawView ) } ` ) ;
@@ -5463,7 +5481,30 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
54635481 return this . obsidianMenu ?. renderButton ( isMobile , appState ) ;
54645482 }
54655483
5466- private onExcalidrawResize ( ) {
5484+ private scheduleBatchedResize ( entry : ResizeObserverEntry ) {
5485+ if ( ! this . lastClientElHeight ) this . lastClientElHeight = this . contentEl . clientHeight ;
5486+
5487+ if ( ! this . resizeBatchTimer ) {
5488+ const prev = this . contentSizeMap . get ( entry . target ) ;
5489+ this . resizeBatchStartHeight = prev ?? entry . contentRect . height ;
5490+ }
5491+ const curH = entry . contentRect . height ;
5492+ this . lastAggregatedDh = curH - this . resizeBatchStartHeight ;
5493+
5494+ if ( this . resizeBatchTimer ) window . clearTimeout ( this . resizeBatchTimer ) ;
5495+ this . resizeBatchTimer = window . setTimeout ( ( ) => {
5496+ const dh = this . lastAggregatedDh ;
5497+ const heightNow = this . contentEl . clientHeight ?? 0 ;
5498+ this . lastClientElHeight = heightNow ;
5499+ this . resizeBatchTimer = null ;
5500+ this . onExcalidrawResize ( dh ) ;
5501+ } , 700 ) ;
5502+ }
5503+
5504+ private onExcalidrawResize ( dhArg ?: number ) {
5505+ const dh = typeof dhArg === "number" ? dhArg : this . lastContentResizeDeltaHeight ;
5506+ console . log ( dh , "(batched)" ) ;
5507+
54675508 try {
54685509 const api = this . excalidrawAPI as ExcalidrawImperativeAPI ;
54695510 if ( ! api ) return ;
@@ -5489,29 +5530,19 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
54895530 const isKeyboardBackEvent :Boolean = ( this . semaphores . isEditingText || isEventOnSameElement ) && ! isKeyboardOutEvent ;
54905531 this . editingTextElementId = isKeyboardOutEvent ? st . editingTextElement . id : null ;
54915532 if ( isKeyboardOutEvent ) {
5492- const appToolHeight = ( this . contentEl . querySelector ( ".Island.App-toolbar" ) as HTMLElement ) ?. clientHeight ?? 0 ;
5493- const editingElViewY = sceneCoordsToViewportCoords ( { sceneX :0 , sceneY :st . editingTextElement . y } , st ) . y ;
5494- const scrollViewY = sceneCoordsToViewportCoords ( { sceneX :0 , sceneY :- st . scrollY } , st ) . y ;
5495- const delta = editingElViewY - scrollViewY ;
5496- const isElementAboveKeyboard = height > ( delta + appToolHeight * 2 )
5497- const excalidrawWrapper = this . excalidrawWrapperRef . current ;
5498- //console.log({isElementAboveKeyboard});
5499- if ( excalidrawWrapper && ! isElementAboveKeyboard ) {
5500- excalidrawWrapper . style . top = `${ - ( st . height - height ) } px` ;
5501- excalidrawWrapper . style . height = `${ st . height } px` ;
5502- this . excalidrawContainer ?. querySelector ( ".App-bottom-bar" ) ?. scrollIntoView ( ) ;
5503- this . headerEl ?. scrollIntoView ( ) ;
5504- }
5533+ console . log ( "Keyboard open" , Date . now ( ) ) ;
5534+ const elCenterY = st . editingTextElement . y + st . editingTextElement . height / 2 ;
5535+ const newScroll = ( st . height / st . zoom . value ) / 2 - elCenterY ;
5536+ this . oldKeyboardScroll = st . scrollY ;
5537+ this . updateScene ( { appState : { scrollY : newScroll } , captureUpdate : CaptureUpdateAction . NEVER } ) ;
5538+ this . containerEl . scrollIntoView ( ) ;
55055539 }
5506- if ( isKeyboardBackEvent ) {
5507- const excalidrawWrapper = this . excalidrawWrapperRef . current ;
5508- const appButtonBar = this . excalidrawContainer ?. querySelector ( ".App-bottom-bar" ) ;
5509- const headerEl = this . headerEl ;
5510- if ( excalidrawWrapper ) {
5511- excalidrawWrapper . style . top = "" ;
5512- excalidrawWrapper . style . height = "" ;
5513- appButtonBar ?. scrollIntoView ( ) ;
5514- headerEl ?. scrollIntoView ( ) ;
5540+ if ( isKeyboardBackEvent ) {
5541+ console . log ( "Keyboard close" , Date . now ( ) ) ;
5542+ if ( this . oldKeyboardScroll != null ) {
5543+ this . updateScene ( { appState : { scrollY : this . oldKeyboardScroll } , captureUpdate : CaptureUpdateAction . NEVER } ) ;
5544+ this . oldKeyboardScroll = null ;
5545+ this . containerEl . scrollIntoView ( ) ;
55155546 }
55165547 }
55175548 //end of aweful hack
0 commit comments