@@ -102,59 +102,72 @@ class Scene extends React.Component<SceneProps, {}> {
102102 }
103103 }
104104
105+ /* istanbul ignore next */
105106 scrollCharacterIntoView ( ) {
106- // Required to avoid the lack of scrollIntoView on SVG elements in Safari.
107- /* istanbul ignore next */
108- if ( this . sceneRef . current != null && this . sceneSvgRef . current != null ) {
107+ this . scrollSquareIntoView (
108+ this . props . characterState . xPos ,
109+ this . props . characterState . yPos
110+ ) ;
111+ }
112+
113+ /* istanbul ignore next */
114+ scrollDesignModeCursorIntoView ( ) {
115+ this . scrollSquareIntoView (
116+ this . props . designModeCursorState . x ,
117+ this . props . designModeCursorState . y
118+ ) ;
119+ }
109120
121+ /* istanbul ignore next */
122+ scrollSquareIntoView ( x : number , y : number ) {
123+ // Check to see if the specified square is visible. If not, scroll to
124+ // bring it into view. We do this ourselves for two reasons:
125+ //
126+ // 1. On Safari, scrollIntoView doesn't work on SVG elements (C2LC-347)
127+ // 2. On Firefox, scrollIntoView seems to scroll to the centre of
128+ // an element rather than bringing it completely into view (C2LC-343)
129+
130+ if ( this . sceneRef . current != null && this . sceneSvgRef . current != null ) {
110131 const sceneElem = this . sceneRef . current ;
111132 const sceneSvgElem = this . sceneSvgRef . current ;
112133
113134 const sceneBounds = sceneElem . getBoundingClientRect ( ) ;
114135 const sceneSvgBounds = sceneSvgElem . getBoundingClientRect ( ) ;
115136
116- // Calculate the grid cell width in pixels by dividing the width
137+ // Calculate the grid square width in pixels by dividing the width
117138 // of the scene in pixels by the number of columns in the scene
118- const cellWidth = sceneSvgBounds . width / this . props . dimensions . getWidth ( ) ;
119- // Calculate the grid cell height in pixels by dividing the height
120- // of the scene in pixels by the number of rows in the scene
121- const cellHeight = sceneSvgBounds . height / this . props . dimensions . getHeight ( ) ;
139+ const squareW = sceneSvgBounds . width / this . props . dimensions . getWidth ( ) ;
122140
123- // Check to see if the character is visible. If not, scroll to
124- // bring it into view. We do this ourselves for two reasons:
125- //
126- // 1. On Safari, scrollIntoView doesn't work on SVG elements
127- // (C2LC-347)
128- // 2. On Firefox, scrollIntoView seems to scroll to the center of
129- // the character rather than bringing it completely into view
130- // (C2LC-343)
141+ // Calculate the grid square height in pixels by dividing the height
142+ // of the scene in pixels by the number of rows in the scene
143+ const squareH = sceneSvgBounds . height / this . props . dimensions . getHeight ( ) ;
131144
132145 // We add some padding to the position checking to ensure that we
133- // always leave some room between the character and the edge of the
134- // scene (unless we are in the first or last row/col)
135- const paddingH = 0.75 * cellWidth ;
136- const paddingV = 0.75 * cellHeight ;
146+ // always leave some room between the target square and the edge of
147+ // the scene (unless we are in the first or last row/col)
148+ const paddingH = 0.75 * squareW ;
149+ const paddingV = 0.75 * squareH ;
137150
138- // Calculate the location of the grid cell that the character is on
139- const cellLeft = ( this . props . characterState . xPos - this . props . dimensions . getMinX ( ) ) * cellWidth ;
140- const cellRight = cellLeft + cellWidth ;
141- const cellTop = ( this . props . characterState . yPos - this . props . dimensions . getMinY ( ) ) * cellHeight ;
142- const cellBottom = cellTop + cellHeight ;
151+ // Calculate the bounds of the target square to scroll into view
152+ const targetSquareLeft = ( x - this . props . dimensions . getMinX ( ) ) * squareW ;
153+ const targetSquareRight = targetSquareLeft + squareW ;
154+ const targetSquareTop = ( y - this . props . dimensions . getMinY ( ) ) * squareH ;
155+ const targetSquareBottom = targetSquareTop + squareH ;
143156
144- if ( cellLeft - paddingH < sceneElem . scrollLeft ) {
157+ if ( targetSquareLeft - paddingH < sceneElem . scrollLeft ) {
145158 // Off screen to the left
146- sceneElem . scrollLeft = cellLeft - paddingH ;
147- } else if ( cellRight + paddingH > sceneElem . scrollLeft + sceneBounds . width ) {
159+ sceneElem . scrollLeft = targetSquareLeft - paddingH ;
160+ } else if ( targetSquareRight + paddingH > sceneElem . scrollLeft + sceneBounds . width ) {
148161 // Off screen to the right
149- sceneElem . scrollLeft = cellRight + paddingH - sceneBounds . width ;
162+ sceneElem . scrollLeft = targetSquareRight + paddingH - sceneBounds . width ;
150163 }
151164
152- if ( cellTop - paddingV < sceneElem . scrollTop ) {
165+ if ( targetSquareTop - paddingV < sceneElem . scrollTop ) {
153166 // Off screen above
154- sceneElem . scrollTop = cellTop - paddingV ;
155- } else if ( cellBottom + paddingV > sceneElem . scrollTop + sceneBounds . height ) {
167+ sceneElem . scrollTop = targetSquareTop - paddingV ;
168+ } else if ( targetSquareBottom + paddingV > sceneElem . scrollTop + sceneBounds . height ) {
156169 // Off screen below
157- sceneElem . scrollTop = cellBottom + paddingV - sceneBounds . height ;
170+ sceneElem . scrollTop = targetSquareBottom + paddingV - sceneBounds . height ;
158171 }
159172 }
160173 }
@@ -308,14 +321,21 @@ class Scene extends React.Component<SceneProps, {}> {
308321 ) ;
309322 }
310323
324+ /* istanbul ignore next */
311325 componentDidUpdate ( prevProps ) {
312326 if ( prevProps . characterState . xPos !== this . props . characterState . xPos
313327 || prevProps . characterState . yPos !== this . props . characterState . yPos ) {
314328 this . scrollCharacterIntoView ( ) ;
315- }
316- if ( prevProps . runningState !== this . props . runningState
329+ } else if ( prevProps . runningState !== this . props . runningState
317330 && this . props . runningState === 'running' ) {
318331 this . scrollCharacterIntoView ( ) ;
332+ } else if ( prevProps . customBackgroundDesignMode !== this . props . customBackgroundDesignMode
333+ && this . props . customBackgroundDesignMode === false ) {
334+ this . scrollCharacterIntoView ( ) ;
335+ } else if ( this . props . customBackgroundDesignMode === true
336+ && ( prevProps . designModeCursorState . x !== this . props . designModeCursorState . x
337+ || prevProps . designModeCursorState . y !== this . props . designModeCursorState . y ) ) {
338+ this . scrollDesignModeCursorIntoView ( ) ;
319339 }
320340 }
321341}
0 commit comments