-
Notifications
You must be signed in to change notification settings - Fork 213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Added the right scroll animation #1000
Changes from all commits
bcdb92c
85da751
4be7e17
297dba7
ac4f9a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,3 +28,56 @@ List<int> hexStringToByteArray(String hexString) { | |
logger.d(data.length); | ||
return data; | ||
} | ||
|
||
List<List<int>> byteArrayToBinaryArray(List<int> byteArray) { | ||
List<List<int>> binaryArray = List.generate(11, (_) => []); | ||
|
||
int rowIndex = 0; | ||
for (int byte in byteArray) { | ||
List<int> binaryRepresentation = []; | ||
for (int i = 7; i >= 0; i--) { | ||
binaryRepresentation.add((byte >> i) & 1); | ||
} | ||
|
||
binaryArray[rowIndex].addAll(binaryRepresentation); | ||
|
||
rowIndex = (rowIndex + 1) % 11; | ||
} | ||
|
||
logger.d( | ||
"binaryArray: $binaryArray"); // Use print instead of logger for standalone example | ||
return binaryArray; | ||
} | ||
|
||
String hexToBin(String hex) { | ||
// Convert hex to binary string | ||
String binaryString = BigInt.parse(hex, radix: 16).toRadixString(2); | ||
|
||
// Pad the binary string with leading zeros if necessary to ensure it's a multiple of 8 bits | ||
int paddingLength = (8 - (binaryString.length % 8)) % 8; | ||
binaryString = binaryString.padLeft(binaryString.length + paddingLength, '0'); | ||
logger.d("binaryString: $binaryString"); | ||
return binaryString; | ||
} | ||
|
||
List<List<int>> binaryStringTo2DList(String binaryString) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Consider refactoring binaryStringTo2DList for improved readability and efficiency The current implementation uses nested loops with single-letter variables, which can be hard to follow. Consider using more descriptive variable names and simplifying the logic. You might also want to add error handling for cases where the input string length doesn't match the expected size.
|
||
int maxHeight = 11; | ||
List<List<int>> binary2DList = List.generate(maxHeight, (_) => []); | ||
|
||
for (int x = 0; x < binaryString.length; x++) { | ||
int a = 0; | ||
for (int y = a; y < 11; y++) { | ||
for (int z = 0; z < 8; z++) { | ||
binary2DList[y].add(int.parse(binaryString[x++])); | ||
if (x >= binaryString.length) { | ||
break; | ||
} | ||
} | ||
if (x >= binaryString.length) { | ||
break; | ||
} | ||
} | ||
} | ||
logger.d("binary2DList: $binary2DList"); | ||
return binary2DList; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ import 'package:badgemagic/bademagic_module/utils/byte_array_utils.dart'; | |
import 'package:badgemagic/bademagic_module/utils/data_to_bytearray_converter.dart'; | ||
import 'package:badgemagic/bademagic_module/utils/file_helper.dart'; | ||
import 'package:badgemagic/bademagic_module/utils/image_utils.dart'; | ||
import 'package:badgemagic/providers/badgeview_provider.dart'; | ||
import 'package:badgemagic/providers/imageprovider.dart'; | ||
import 'package:get_it/get_it.dart'; | ||
|
||
|
@@ -12,6 +13,7 @@ class Converters { | |
DataToByteArrayConverter converter = DataToByteArrayConverter(); | ||
ImageUtils imageUtils = ImageUtils(); | ||
FileHelper fileHelper = FileHelper(); | ||
DrawBadgeProvider badgeList = GetIt.instance.get<DrawBadgeProvider>(); | ||
|
||
int controllerLength = 0; | ||
|
||
|
@@ -23,10 +25,8 @@ class Converters { | |
var key = controllerData.imageCache.keys.toList()[index]; | ||
if (key is List) { | ||
String filename = key[0]; | ||
logger.d("Filename: $filename"); | ||
List<List<int>>? image = await fileHelper.readFromFile(filename); | ||
logger.d("Image: $image"); | ||
hexStrings = convertBitmapToLEDHex(image!, true); | ||
hexStrings += convertBitmapToLEDHex(image!, true); | ||
x += 5; | ||
} else { | ||
List<String> hs = | ||
|
@@ -43,6 +43,22 @@ class Converters { | |
return hexStrings; | ||
} | ||
|
||
void badgeAnimation(String message) async { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Separate concerns in badgeAnimation function This function is mixing data processing with UI updates. Consider splitting it into two functions: one for data conversion and another for updating the UI. This will improve maintainability and adhere better to the principle of separation of concerns.
|
||
if (message == "") { | ||
//geerate a 2d list with all values as 0 | ||
List<List<int>> image = | ||
List.generate(11, (i) => List.generate(44, (j) => 0)); | ||
badgeList.setNewGrid(image); | ||
badgeList.startAnimation(); | ||
} else { | ||
List<String> hexStrings = await messageTohex(message); | ||
List<int> byteArray = hexStringToByteArray(hexStrings.join()); | ||
List<List<int>> binaryArray = byteArrayToBinaryArray(byteArray); | ||
badgeList.setNewGrid(binaryArray); | ||
badgeList.startAnimation(); | ||
} | ||
} | ||
|
||
//function to convert the bitmap to the LED hex format | ||
//it takes the 2D list of pixels and converts it to the LED hex format | ||
static List<String> convertBitmapToLEDHex( | ||
|
@@ -145,7 +161,6 @@ class Converters { | |
|
||
allHexs.add(lineHex.toString()); // Store completed hexadecimal line | ||
} | ||
logger.d("All hexs: $allHexs"); | ||
return allHexs; // Return list of hexadecimal strings | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import 'package:badgemagic/badge_animation/animation_abstract.dart'; | ||
|
||
class RightAnimation extends BadgeAnimation { | ||
@override | ||
void animation( | ||
List<List<bool>> grid, | ||
List<List<int>> newGrid, | ||
int animationIndex, | ||
bool validMarquee, | ||
bool flashLEDOn, | ||
int currentcountFrame, | ||
int i, | ||
int j, | ||
int newHeight, | ||
int newWidth, | ||
int badgeHeight, | ||
int badgeWidth) { | ||
// Calculate the scroll offset to move from left to right | ||
int scrollOffset = animationIndex % (newWidth + badgeWidth); | ||
|
||
// Get the corresponding column in the new grid based on the reversed scroll position | ||
int sourceCol = newWidth - scrollOffset + j; | ||
|
||
// If sourceCol is within bounds of the new grid, display it, else blank space | ||
if (sourceCol >= 0 && sourceCol < newWidth) { | ||
grid[i][j] = | ||
validMarquee || flashLEDOn && newGrid[i % newHeight][sourceCol] == 1; | ||
} else { | ||
validMarquee ? grid[i][j] = true : grid[i][j] = false; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import 'package:badgemagic/badge_animation/animation_abstract.dart'; | ||
|
||
class LeftAnimation extends BadgeAnimation { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Consider unifying animation logic to reduce code duplication The LeftAnimation and RightAnimation classes have very similar logic. Consider creating a base class or a utility function that both can use, parameterizing the differences. This would reduce code duplication and make it easier to maintain and extend the animation system.
|
||
@override | ||
void animation( | ||
List<List<bool>> grid, | ||
List<List<int>> newGrid, | ||
int animationIndex, | ||
bool validMarquee, | ||
bool flashLEDOn, | ||
int currentcountFrame, | ||
int i, | ||
int j, | ||
int newHeight, | ||
int newWidth, | ||
int badgeHeight, | ||
int badgeWidth) { | ||
// Calculate how much of the new grid is currently visible in the grid | ||
int scrollOffset = animationIndex % (newWidth + badgeWidth); | ||
|
||
// Get the corresponding column in the new grid based on the scroll position | ||
int sourceCol = j + scrollOffset - badgeWidth; | ||
|
||
// If sourceCol is negative, display blank space (off-screen part of the grid) | ||
if (sourceCol >= 0 && sourceCol < newWidth) { | ||
// Ensure flashLEDOn and validMarquee effects are applied | ||
grid[i][j] = | ||
validMarquee || flashLEDOn && newGrid[i % newHeight][sourceCol] == 1; | ||
} else { | ||
validMarquee ? grid[i][j] = true : grid[i][j] = false; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
abstract class BadgeAnimation { | ||
void animation( | ||
List<List<bool>> grid, | ||
List<List<int>> newGrid, | ||
int animationIndex, | ||
bool validMarquee, | ||
bool flashLEDOn, | ||
int currentcountFrame, | ||
int i, | ||
int j, | ||
int newHeight, | ||
int newWidth, | ||
int badgeHeight, | ||
int badgeWidth); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,3 +15,15 @@ const String aniRight = 'assets/animations/ic_anim_right.gif'; | |
const String effFlash = 'assets/effects/ic_effect_flash.gif'; | ||
const String effInvert = 'assets/effects/ic_effect_invert.gif'; | ||
const String effMarque = 'assets/effects/ic_effect_marquee.gif'; | ||
|
||
//constants for the animation speed | ||
const Duration aniBaseSpeed = Duration(microseconds: 200000); // in uS | ||
const Duration aniMarqueSpeed = Duration(microseconds: 100000); // in uS | ||
const Duration aniFlashSpeed = Duration(microseconds: 500000); // in uS | ||
|
||
// Function to calculate animation speed based on speed level | ||
int aniSpeedStrategy(int speedLevel) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Consider using an enum for speed levels Instead of using raw integers for speed levels, consider defining an enum. This would make the code more type-safe and self-documenting.
|
||
int speedInMicroseconds = aniBaseSpeed.inMicroseconds - | ||
(speedLevel * aniBaseSpeed.inMicroseconds ~/ 8); | ||
return speedInMicroseconds; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (performance): Optimize hexToBin function for better performance
The current implementation using BigInt might be inefficient for large inputs. Consider implementing a direct hex to binary conversion using bitwise operations or a lookup table for better performance.