@@ -673,6 +673,9 @@ class Activity {
673673 * This method is part of the internal mechanism to ensure that blocks are displayed correctly and efficiently.
674674 * @constructor
675675 */
676+ // Flag to track number of clicks and for alternate mode switching while clicking
677+ this . _isFirstHomeClick = true ;
678+
676679 this . _findBlocks = ( ) => {
677680 // Ensure visibility of blocks
678681 if ( ! this . blocks . visible ) {
@@ -688,85 +691,158 @@ class Activity {
688691 this . blocksContainer . x = 0 ;
689692 this . blocksContainer . y = 0 ;
690693
691- // Calculate initial positions for block placement
692- let toppos ;
693- if ( this . auxToolbar . style . display === "block" ) {
694- toppos = 90 + this . toolbarHeight ;
695- } else {
696- toppos = 90 ;
697- }
698-
699- const screenWidth = window . innerWidth ;
694+ if ( this . _isFirstHomeClick ) {
695+ // First clicked logic (arrange blocks in rows may have overlapping of blocks)
696+ let toppos ;
697+ if ( this . auxToolbar . style . display === "block" ) {
698+ toppos = 90 + this . toolbarHeight ;
699+ } else {
700+ toppos = 90 ;
701+ }
702+ const leftpos = Math . floor ( this . canvas . width / 4 ) ;
700703
701- /**
702- * Number of columns are dynamic accrding to the screen size
703- * Minimum column width is set to 400px to ensure readability and usability.
704- */
704+ this . palettes . updatePalettes ( ) ;
705+ let x = Math . floor ( leftpos * this . turtleBlocksScale ) ;
706+ let y = Math . floor ( toppos * this . turtleBlocksScale ) ;
707+ let even = true ;
705708
706- const minColumnWidth = 400 ;
707- let numColumns ;
709+ // Position "start" blocks first
710+ for ( const blk in this . blocks . blockList ) {
711+ if ( ! this . blocks . blockList [ blk ] . trash ) {
712+ const myBlock = this . blocks . blockList [ blk ] ;
713+ if ( myBlock . name !== "start" ) {
714+ continue ;
715+ }
708716
709- // Determine device type and adjust number of columns
710- if ( screenWidth <= 320 ) {
711- // For small screen phones
712- numColumns = 1 ;
713- } else {
714- // anything other than small screen phones
715- numColumns = Math . floor ( screenWidth / minColumnWidth ) ;
716- }
717+ if ( myBlock . connections [ 0 ] === null ) {
718+ const dx = x - myBlock . container . x ;
719+ const dy = y - myBlock . container . y ;
720+ this . blocks . moveBlockRelative ( blk , dx , dy ) ;
721+ this . blocks . findDragGroup ( blk ) ;
717722
718- const columnSpacing = screenWidth / numColumns ;
719- const initialY = Math . floor ( toppos * this . turtleBlocksScale ) ;
720- const verticalSpacing = Math . floor ( 20 * this . turtleBlocksScale ) ;
723+ if ( this . blocks . dragGroup . length > 0 ) {
724+ for ( let b = 0 ; b < this . blocks . dragGroup . length ; b ++ ) {
725+ const bblk = this . blocks . dragGroup [ b ] ;
726+ if ( b !== 0 ) {
727+ this . blocks . moveBlockRelative ( bblk , dx , dy ) ;
728+ }
729+ }
730+ }
731+
732+ x += Math . floor ( 150 * this . turtleBlocksScale ) ;
733+ if ( x > ( this . canvas . width * 7 ) / 8 / this . turtleBlocksScale ) {
734+ even = ! even ;
735+ if ( even ) {
736+ x = Math . floor ( leftpos ) ;
737+ } else {
738+ x = Math . floor ( leftpos + STANDARDBLOCKHEIGHT ) ;
739+ }
740+ y += STANDARDBLOCKHEIGHT ;
741+ }
742+ }
743+ }
744+ }
721745
722- const columnXPositions = Array . from ( { length : numColumns } , ( _ , i ) =>
723- Math . floor ( i * columnSpacing + columnSpacing / 2 )
724- ) ;
725- const columnYPositions = Array ( numColumns ) . fill ( initialY ) ;
746+ // Position other blocks
747+ for ( const blk in this . blocks . blockList ) {
748+ if ( ! this . blocks . blockList [ blk ] . trash ) {
749+ const myBlock = this . blocks . blockList [ blk ] ;
750+ if ( myBlock . name === "start" ) {
751+ continue ;
752+ }
726753
727- // Helper function to move a block and its connected group
728- const moveBlockAndGroup = ( blk , x , y ) => {
729- const myBlock = this . blocks . blockList [ blk ] ;
730- const dx = x - myBlock . container . x ;
731- const dy = y - myBlock . container . y ;
754+ if ( myBlock . connections [ 0 ] === null ) {
755+ const dx = x - myBlock . container . x ;
756+ const dy = y - myBlock . container . y ;
757+ this . blocks . moveBlockRelative ( blk , dx , dy ) ;
758+ this . blocks . findDragGroup ( blk ) ;
732759
733- this . blocks . moveBlockRelative ( blk , dx , dy ) ;
734- this . blocks . findDragGroup ( blk ) ;
760+ if ( this . blocks . dragGroup . length > 0 ) {
761+ for ( let b = 0 ; b < this . blocks . dragGroup . length ; b ++ ) {
762+ const bblk = this . blocks . dragGroup [ b ] ;
763+ if ( b !== 0 ) {
764+ this . blocks . moveBlockRelative ( bblk , dx , dy ) ;
765+ }
766+ }
767+ }
735768
736- if ( this . blocks . dragGroup . length > 0 ) {
737- for ( let b = 0 ; b < this . blocks . dragGroup . length ; b ++ ) {
738- const bblk = this . blocks . dragGroup [ b ] ;
739- if ( b !== 0 ) {
740- this . blocks . moveBlockRelative ( bblk , dx , dy ) ;
769+ x += Math . floor ( 150 * this . turtleBlocksScale ) ;
770+ if ( x > ( this . canvas . width * 7 ) / 8 / this . turtleBlocksScale ) {
771+ even = ! even ;
772+ if ( even ) {
773+ x = Math . floor ( leftpos ) ;
774+ } else {
775+ x = Math . floor ( leftpos + STANDARDBLOCKHEIGHT ) ;
776+ }
777+ y += STANDARDBLOCKHEIGHT ;
778+ }
741779 }
742780 }
743781 }
744- } ;
782+ } else {
783+ // Second click logic (arrange blocks in columns this avoid overlapping of blocks)
784+ let toppos ;
785+ if ( this . auxToolbar . style . display === "block" ) {
786+ toppos = 90 + this . toolbarHeight ;
787+ } else {
788+ toppos = 90 ;
789+ }
790+
791+ /**
792+ * Device type resolution ranges and typical orientation:
793+ * Desktop: 1024x768 to 5120x2880 (Landscape primary, Portrait supported)
794+ * Tablet: 768x1024 to 2560x1600 (Portrait common, Landscape supported)
795+ * Mobile: 320x480 to 1440x3200 (Portrait primary, Landscape supported)
796+ * Minimum column width is set to 400px to ensure readability and usability.
797+ */
745798
746- // Position blocks in columns
747- for ( const blk in this . blocks . blockList ) {
748- if ( ! this . blocks . blockList [ blk ] . trash ) {
749- const myBlock = this . blocks . blockList [ blk ] ;
799+ const screenWidth = window . innerWidth ;
800+ const minColumnWidth = 400 ;
801+ let numColumns = screenWidth <= 320 ? 1 : Math . floor ( screenWidth / minColumnWidth ) ;
750802
751- // Skip blocks already connected
752- if ( myBlock . connections [ 0 ] !== null ) {
753- continue ;
754- }
803+ const baseColumnSpacing = screenWidth / numColumns ;
804+ const columnSpacing = baseColumnSpacing * 1.2 ;
755805
756- // Determine column and position
757- let minYIndex = 0 ;
758- for ( let i = 1 ; i < numColumns ; i ++ ) {
759- if ( columnYPositions [ i ] < columnYPositions [ minYIndex ] ) {
760- minYIndex = i ;
806+ const initialY = Math . floor ( toppos * this . turtleBlocksScale ) ;
807+ const baseVerticalSpacing = Math . floor ( 20 * this . turtleBlocksScale ) ;
808+ const verticalSpacing = baseVerticalSpacing * 1.2 ;
809+
810+ const columnXPositions = Array . from ( { length : numColumns } , ( _ , i ) =>
811+ Math . floor ( i * columnSpacing + columnSpacing / 2 )
812+ ) ;
813+ const columnYPositions = Array ( numColumns ) . fill ( initialY ) ;
814+
815+ for ( const blk in this . blocks . blockList ) {
816+ if ( ! this . blocks . blockList [ blk ] . trash ) {
817+ const myBlock = this . blocks . blockList [ blk ] ;
818+ if ( myBlock . connections [ 0 ] === null ) {
819+ let minYIndex = 0 ;
820+ for ( let i = 1 ; i < numColumns ; i ++ ) {
821+ if ( columnYPositions [ i ] < columnYPositions [ minYIndex ] ) {
822+ minYIndex = i ;
823+ }
824+ }
825+
826+ const dx = columnXPositions [ minYIndex ] - myBlock . container . x ;
827+ const dy = columnYPositions [ minYIndex ] - myBlock . container . y ;
828+ this . blocks . moveBlockRelative ( blk , dx , dy ) ;
829+ this . blocks . findDragGroup ( blk ) ;
830+
831+ if ( this . blocks . dragGroup . length > 0 ) {
832+ for ( let b = 0 ; b < this . blocks . dragGroup . length ; b ++ ) {
833+ const bblk = this . blocks . dragGroup [ b ] ;
834+ if ( b !== 0 ) {
835+ this . blocks . moveBlockRelative ( bblk , dx , dy ) ;
836+ }
837+ }
838+ }
839+ columnYPositions [ minYIndex ] += myBlock . height + verticalSpacing ;
761840 }
762841 }
763-
764- moveBlockAndGroup ( blk , columnXPositions [ minYIndex ] , columnYPositions [ minYIndex ] ) ;
765- columnYPositions [ minYIndex ] += myBlock . height + verticalSpacing ;
766842 }
767843 }
768844
769- // Blocks are all home, so reset go-home- button.
845+ // Reset go-home button
770846 this . setHomeContainers ( false ) ;
771847 this . boundary . hide ( ) ;
772848
@@ -779,7 +855,9 @@ class Activity {
779855 this . turtles . turtleList [ turtle ] . painter . doSetHeading ( 0 ) ;
780856 this . turtles . turtleList [ turtle ] . painter . penState = savedPenState ;
781857 }
782- } ;
858+ // Alternate mode switching on clicking Home button
859+ this . _isFirstHomeClick = ! this . _isFirstHomeClick ;
860+ } ;
783861
784862 /**
785863 * Toggles the visibility of the home button container.
0 commit comments