Skip to content

Commit 57a1301

Browse files
authored
Adding Responsiveness In Blocks (#4350)
* Adding Responsiveness In Blocks * minor changes * mobileResponsive * some unscrambling * No Scrambling * duplicated blocks issue resolve
1 parent 1f2a54f commit 57a1301

File tree

1 file changed

+184
-1
lines changed

1 file changed

+184
-1
lines changed

js/activity.js

Lines changed: 184 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,189 @@ class Activity {
673673
}
674674
};
675675

676+
/**
677+
* Ensures blocks stay within canvas boundaries when resized.
678+
* Ensures that music blocks are responsive to horizontal resizing.
679+
* Ensures that overall integrity of blocks isn't hampered with.
680+
*/
681+
function repositionBlocks(activity) {
682+
683+
const canvasWidth = window.innerWidth;
684+
const processedBlocks = new Set();
685+
686+
//Array for storing individual dragGroups (the chunks of code linked together which are not connected)
687+
const dragGroups = [];
688+
689+
// Identifying individual dragGroups
690+
Object.values(activity.blocks.blockList).forEach(block => {
691+
if (!processedBlocks.has(block.id)) {
692+
693+
activity.blocks.findDragGroup(block.id);
694+
695+
if (activity.blocks.dragGroup.length > 0) {
696+
dragGroups.push([...activity.blocks.dragGroup]); // Store the group into dragGroups
697+
activity.blocks.dragGroup.forEach(id => processedBlocks.add(id)); // Process individual groups
698+
}
699+
}
700+
});
701+
702+
// Repositioning of dragGroups according to horizontal resizing
703+
dragGroups.forEach(group => {
704+
let referenceBlock = activity.blocks.blockList[group[0]];
705+
706+
// Store initial positions
707+
if (!referenceBlock.initialPosition) {
708+
referenceBlock.initialPosition = { x: referenceBlock.container.x, y: referenceBlock.container.y };
709+
}
710+
711+
if (canvasWidth < 768 && !referenceBlock.beforeMobilePosition) {
712+
referenceBlock.beforeMobilePosition = { x: referenceBlock.container.x, y: referenceBlock.container.y };
713+
}
714+
715+
if (canvasWidth >= 768 && referenceBlock.beforeMobilePosition) {
716+
let dx = referenceBlock.beforeMobilePosition.x - referenceBlock.container.x;
717+
let dy = referenceBlock.beforeMobilePosition.y - referenceBlock.container.y;
718+
group.forEach(blockId => {
719+
let block = activity.blocks.blockList[blockId];
720+
block.container.x += dx;
721+
block.container.y += dy;
722+
});
723+
referenceBlock.beforeMobilePosition = null; // Clear stored position
724+
//this prevents old groups from affecting new calculations.
725+
}
726+
727+
if (canvasWidth < 600 && !referenceBlock.before600pxPosition) {
728+
referenceBlock.before600pxPosition = { x: referenceBlock.container.x, y: referenceBlock.container.y };
729+
}
730+
731+
if (canvasWidth >= 600 && referenceBlock.before600pxPosition) {
732+
let dx = referenceBlock.before600pxPosition.x - referenceBlock.container.x;
733+
let dy = referenceBlock.before600pxPosition.y - referenceBlock.container.y;
734+
735+
group.forEach(blockId => {
736+
let block = activity.blocks.blockList[blockId];
737+
block.container.x += dx;
738+
block.container.y += dy;
739+
});
740+
referenceBlock.before600pxPosition = null;
741+
}
742+
743+
// Ensure blocks stay within horizontal boundary
744+
let rightmostX = Math.max(...group.map(id => activity.blocks.blockList[id].container.x + activity.blocks.blockList[id].width));
745+
746+
if (rightmostX > canvasWidth) {
747+
let shiftX = Math.max(10, canvasWidth - rightmostX - 10);
748+
749+
group.forEach(blockId => {
750+
activity.blocks.blockList[blockId].container.x += shiftX;
751+
});
752+
}
753+
754+
// Ensures that blocks do not go hide behind the search for blocks div
755+
let leftmostX = Math.min(...group.map(id => activity.blocks.blockList[id].container.x));
756+
if (leftmostX < 0) {
757+
let shiftX = 100 - leftmostX;
758+
759+
group.forEach(blockId => {
760+
activity.blocks.blockList[blockId].container.x += shiftX;
761+
});
762+
}
763+
764+
});
765+
766+
activity._findBlocks();
767+
}
768+
769+
//if any window resize event occurs:
770+
window.addEventListener("resize", () => repositionBlocks(this));
771+
772+
/**
773+
* Finds and organizes blocks within the workspace.
774+
* Arranges blocks in grid format on wide screens and vertically on narrow screens.
775+
*/
776+
this._findBlocks = () => {
777+
if (!this.blocks.visible) {
778+
this._changeBlockVisibility();
779+
}
780+
781+
this.blocks.activeBlock = null;
782+
hideDOMLabel();
783+
this.blocks.showBlocks();
784+
this.blocksContainer.x = 0;
785+
this.blocksContainer.y = 0;
786+
787+
const screenWidth = window.innerWidth;
788+
const isNarrowScreen = screenWidth < 600;
789+
const minColumnWidth = 400;
790+
let numColumns = isNarrowScreen ? 1 : Math.floor(screenWidth / minColumnWidth);
791+
792+
let toppos = this.auxToolbar.style.display === "block" ? 90 + this.toolbarHeight : 90;
793+
let x = isNarrowScreen ? Math.floor(screenWidth / 2) : Math.floor(this.canvas.width / 4);
794+
let y = Math.floor(toppos * this.turtleBlocksScale);
795+
let verticalSpacing = Math.floor(40 * this.turtleBlocksScale);
796+
797+
const columnSpacing = (screenWidth / numColumns) * 1.2;
798+
const columnXPositions = Array.from({ length: numColumns }, (_, i) =>
799+
Math.floor(i * columnSpacing + columnSpacing / 2)
800+
);
801+
const columnYPositions = Array(numColumns).fill(y);
802+
803+
for (const blk in this.blocks.blockList) {
804+
if (!this.blocks.blockList[blk].trash) {
805+
const myBlock = this.blocks.blockList[blk];
806+
807+
// Store original position only once
808+
if (!myBlock.originalPosition) {
809+
myBlock.originalPosition = { x: myBlock.container.x, y: myBlock.container.y };
810+
}
811+
812+
if (myBlock.connections[0] === null) {
813+
if (isNarrowScreen) {
814+
const dx = x - myBlock.container.x;
815+
const dy = y - myBlock.container.y;
816+
this.blocks.moveBlockRelative(blk, dx, dy);
817+
y += myBlock.height + verticalSpacing;
818+
} else {
819+
let minYIndex = columnYPositions.indexOf(Math.min(...columnYPositions));
820+
const dx = columnXPositions[minYIndex] - myBlock.container.x;
821+
const dy = columnYPositions[minYIndex] - myBlock.container.y;
822+
this.blocks.moveBlockRelative(blk, dx, dy);
823+
columnYPositions[minYIndex] += myBlock.height + verticalSpacing;
824+
}
825+
}
826+
827+
// Making code to make sure that
828+
if (myBlock.connections.length>0) {
829+
myBlock.connections.forEach(conn => {
830+
if (conn !== null) {
831+
let innerBlock = this.blocks.blockList[conn] ;
832+
if (innerBlock) {
833+
834+
innerBlock.container.x = myBlock.container.x + innerBlock.relativeX;
835+
innerBlock.container.y = myBlock.container.y + innerBlock.relativeY;
836+
}
837+
838+
}
839+
840+
});
841+
}
842+
}
843+
}
844+
845+
repositionBlocks(this);
846+
this.setHomeContainers(false);
847+
this.boundary.hide();
848+
849+
for (let turtle = 0; turtle < this.turtles.turtleList.length; turtle++) {
850+
const savedPenState = this.turtles.turtleList[turtle].painter.penState;
851+
this.turtles.turtleList[turtle].painter.penState = false;
852+
this.turtles.turtleList[turtle].painter.doSetXY(0, 0);
853+
this.turtles.turtleList[turtle].painter.doSetHeading(0);
854+
this.turtles.turtleList[turtle].painter.penState = savedPenState;
855+
}
856+
};
857+
858+
676859
/**
677860
* Finds and organizes blocks within the workspace.
678861
* Blocks are positioned based on their connections and availability within the canvas area.
@@ -801,7 +984,7 @@ class Activity {
801984
*/
802985

803986
const screenWidth = window.innerWidth;
804-
const minColumnWidth = 400;
987+
const minColumnWidth = 320;
805988
let numColumns = screenWidth <= 320 ? 1 : Math.floor(screenWidth / minColumnWidth);
806989

807990
const baseColumnSpacing = screenWidth / numColumns;

0 commit comments

Comments
 (0)