Skip to content

Commit 76764f9

Browse files
fix: Remove duplicate methods in SensorsBlocks.js
- Eliminated duplicate getPixelDataFromMedia method by merging functionality into getPixelData - Updated arg method to use unified getPixelData method - Fixed color component indexing in GetBlueBlock and GetGreenBlock - Improved code organization and documentation - Added proper error handling - Maintained backward compatibility with existing tests This change makes the code more maintainable by following DRY principles while preserving all existing functionality.
1 parent c65d0d9 commit 76764f9

File tree

1 file changed

+93
-89
lines changed

1 file changed

+93
-89
lines changed

js/blocks/SensorsBlocks.js

Lines changed: 93 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,9 @@ function setupSensorsBlocks(activity) {
603603
*/
604604
arg(logo, turtle) {
605605
let colorString = activity.turtles.getTurtle(turtle).painter.canvasColor;
606-
if (colorString[2] === "#") colorString = hex2rgb(colorString.split("#")[1]);
606+
if (colorString[0] === "#") colorString = hex2rgb(colorString.split("#")[1]);
607607
const obj = colorString.split("(")[1].split(",");
608-
return parseInt(Number(obj[0]) / 2.55);
608+
return parseInt(Number(obj[2]) / 2.55); // Use index 2 for blue component
609609
}
610610
}
611611

@@ -655,9 +655,9 @@ function setupSensorsBlocks(activity) {
655655
*/
656656
arg(logo, turtle) {
657657
let colorString = activity.turtles.getTurtle(turtle).painter.canvasColor;
658-
if (colorString[1] === "#") colorString = hex2rgb(colorString.split("#")[1]);
658+
if (colorString[0] === "#") colorString = hex2rgb(colorString.split("#")[1]);
659659
const obj = colorString.split("(")[1].split(",");
660-
return parseInt(Number(obj[0]) / 2.55);
660+
return parseInt(Number(obj[1]) / 2.55); // Use index 1 for green component
661661
}
662662
}
663663

@@ -979,102 +979,106 @@ class GetColorMediaBlock extends ValueBlock {
979979
this.parameter = true;
980980
}
981981

982+
/**
983+
* Updates the parameter value of the block.
984+
* @param {Object} logo - The logo object.
985+
* @param {number} turtle - The turtle identifier.
986+
* @param {number} blk - The block identifier.
987+
* @returns {string} - Test value for parameter update.
988+
*/
982989
updateParameter(logo, turtle, blk) {
983990
return "test";
984991
}
985992

986-
987-
988-
989-
990-
arg(logo, turtle) {
991-
let requiredTurtle;
992-
993-
try {
994-
requiredTurtle = activity.turtles.getTurtle(turtle);
995-
} catch (error) {
996-
return this.getFallbackColor(); // Turtle not found, no visibility to restore
997-
}
998-
999-
if (!requiredTurtle.container) {
1000-
return this.getFallbackColor(); // Container not found, no visibility to restore
1001-
}
1002-
1003-
const { x, y } = requiredTurtle.container;
1004-
const originalVisibility = requiredTurtle.container.visible;
1005-
1006-
try {
1007-
requiredTurtle.container.visible = false;
1008-
activity.refreshCanvas();
1009-
1010-
const pixelData = this.getPixelData(x, y);
1011-
const color = this.detectColor(pixelData);
993+
/**
994+
* Retrieves the color value at the current position, either from the canvas or media.
995+
* @param {Object} logo - The logo object.
996+
* @param {number} turtle - The turtle identifier.
997+
* @param {Object} mediaBlock - Optional media block to read from.
998+
* @returns {number} - The color value at the specified position.
999+
*/
1000+
/**
1001+
* Gets pixel color data from either the canvas or a media block.
1002+
* @param {number} x - The x-coordinate of the pixel.
1003+
* @param {number} y - The y-coordinate of the pixel.
1004+
* @param {Object} [mediaBlock] - Optional media block to read from.
1005+
* @returns {Uint8ClampedArray} - The RGBA values of the pixel.
1006+
* @throws {Error} - If the canvas context is unavailable or media access fails.
1007+
*/
1008+
getPixelData(x, y, mediaBlock = null) {
1009+
if (mediaBlock) {
1010+
try {
1011+
const mediaBitmap = mediaBlock.container.getChildByName("media");
1012+
if (!mediaBitmap) {
1013+
throw new Error("No media found in this block");
1014+
}
10121015

1013-
requiredTurtle.container.visible = originalVisibility;
1014-
return color;
1015-
} catch (error) {
1016-
requiredTurtle.container.visible = originalVisibility;
1017-
return this.getFallbackColor();
1016+
const tempCanvas = document.createElement("canvas");
1017+
const tempCtx = tempCanvas.getContext("2d");
1018+
1019+
const image = mediaBitmap.image;
1020+
tempCanvas.width = image.width;
1021+
tempCanvas.height = image.height;
1022+
1023+
tempCtx.drawImage(image, 0, 0);
1024+
1025+
return tempCtx.getImageData(Math.floor(x), Math.floor(y), 1, 1).data;
1026+
} catch (error) {
1027+
console.error("Error getting pixel data from media:", error);
1028+
throw new Error("Cannot get pixel data from media block");
1029+
}
1030+
} else {
1031+
const canvas = docById("overlayCanvas");
1032+
const ctx = canvas?.getContext("2d");
1033+
if (!ctx) {
1034+
throw new Error("Canvas context unavailable");
1035+
}
1036+
return ctx.getImageData(Math.floor(x), Math.floor(y), 1, 1).data;
10181037
}
10191038
}
1020-
10211039

10221040
/**
1023-
* Extracts pixel data from the canvas at the specified coordinates.
1024-
* @param {number} x - The x-coordinate of the pixel.
1025-
* @param {number} y - The y-coordinate of the pixel.
1026-
* @returns {Uint8ClampedArray} - The RGBA values of the pixel.
1027-
* @throws {Error} - If the canvas context is unavailable.
1028-
*/
1029-
/**
1030-
* Gets pixel color data from the main drawing canvas at specified coordinates.
1031-
* Currently only works with turtle-drawn content on overlayCanvas.
1032-
*/
1033-
getPixelData(x, y) {
1034-
const canvas = docById("overlayCanvas");
1035-
const ctx = canvas?.getContext("2d");
1036-
if (!ctx) {
1037-
throw new Error("Canvas context unavailable");
1038-
}
1039-
return ctx.getImageData(Math.floor(x), Math.floor(y), 1, 1).data;
1040-
}
1041-
getPixelDataFromMedia(x, y, mediaBlock) {
1041+
* Retrieves the color value at the current position.
1042+
* @param {Object} logo - The logo object.
1043+
* @param {number} turtle - The turtle identifier.
1044+
* @param {Object} [mediaBlock] - Optional media block to read from.
1045+
* @returns {number} - The color value at the specified position.
1046+
*/
1047+
arg(logo, turtle, mediaBlock = null) {
10421048
try {
1043-
// Find the media bitmap in the block
1044-
const mediaBitmap = mediaBlock.container.getChildByName("media");
1045-
if (!mediaBitmap) {
1046-
throw new Error("No media found in this block");
1049+
if (mediaBlock) {
1050+
const { x, y } = mediaBlock.container;
1051+
const pixelData = this.getPixelData(x, y, mediaBlock);
1052+
return this.detectColor(pixelData);
10471053
}
10481054

1049-
// Create a temporary canvas
1050-
const tempCanvas = document.createElement("canvas");
1051-
const tempCtx = tempCanvas.getContext("2d");
1052-
1053-
// Set canvas size to match the image
1054-
const image = mediaBitmap.image;
1055-
tempCanvas.width = image.width;
1056-
tempCanvas.height = image.height;
1057-
1058-
// Draw the media image to the temporary canvas
1059-
tempCtx.drawImage(image, 0, 0);
1060-
1061-
// Get pixel data at the specified coordinates
1062-
const pixelData = tempCtx.getImageData(Math.floor(x), Math.floor(y), 1, 1).data;
1063-
1064-
return pixelData;
1065-
1055+
const requiredTurtle = activity.turtles.getTurtle(turtle);
1056+
if (!requiredTurtle?.container) {
1057+
return this.getFallbackColor();
1058+
}
1059+
1060+
const { x, y } = requiredTurtle.container;
1061+
const originalVisibility = requiredTurtle.container.visible;
1062+
1063+
try {
1064+
requiredTurtle.container.visible = false;
1065+
activity.refreshCanvas();
1066+
const pixelData = this.getPixelData(x, y);
1067+
return this.detectColor(pixelData);
1068+
} finally {
1069+
requiredTurtle.container.visible = originalVisibility;
1070+
}
10661071
} catch (error) {
1067-
console.error("Error getting pixel data from media:", error);
1068-
throw new Error("Cannot get pixel data from media block");
1072+
console.error("Error in GetColorMediaBlock.arg:", error);
1073+
return this.getFallbackColor();
10691074
}
10701075
}
10711076

1072-
10731077
/**
1074-
* Determines the color based on pixel data.
1075-
* @param {Uint8ClampedArray} pixelData - The RGBA values of the pixel.
1076-
* @returns {number} - The color index from searchColors.
1077-
*/
1078+
* Determines the color based on pixel data.
1079+
* @param {Uint8ClampedArray} pixelData - The RGBA values of the pixel.
1080+
* @returns {number} - The color index from searchColors.
1081+
*/
10781082
detectColor(pixelData) {
10791083
if (pixelData.length !== 4) {
10801084
throw new Error("Invalid pixel data");
@@ -1084,9 +1088,9 @@ class GetColorMediaBlock extends ValueBlock {
10841088
}
10851089

10861090
/**
1087-
* Retrieves the background color as a fallback.
1088-
* @returns {number} - The background color index.
1089-
*/
1091+
* Retrieves the background color as a fallback.
1092+
* @returns {number} - The background color index.
1093+
*/
10901094
getBackgroundColor() {
10911095
const [r, g, b] = platformColor.background
10921096
.match(/\(([^)]+)\)/)[1]
@@ -1096,9 +1100,9 @@ class GetColorMediaBlock extends ValueBlock {
10961100
}
10971101

10981102
/**
1099-
* Provides a default color value in case of failure.
1100-
* @returns {number} - A default color index (e.g., gray).
1101-
*/
1103+
* Provides a default color value in case of failure.
1104+
* @returns {number} - A default color index (e.g., gray).
1105+
*/
11021106
getFallbackColor() {
11031107
return searchColors(128, 128, 128);
11041108
}

0 commit comments

Comments
 (0)