Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified assets/animations/ic_anim_animation.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/animations/ic_anim_picture.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/animations/ic_anim_snowflake.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 10 additions & 8 deletions lib/bademagic_module/models/messages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,25 @@ class Message {
final bool marquee;
final Speed speed;
final Mode mode;
final int? animationIndex; // 👈 NEW

Message({
required this.text,
this.flash = false,
this.marquee = false,
this.speed = Speed.one, // Default speed
this.mode = Mode.left, // Default mode
this.speed = Speed.one,
this.mode = Mode.left,
this.animationIndex, // 👈 NEW
});

// Convert Message object to JSON
Map<String, dynamic> toJson() => {
'text': text,
'flash': flash,
'marquee': marquee,
'speed': speed.hexValue, // Use hexValue for serialization
'mode': mode.hexValue, // Use hexValue for serialization
'speed': speed.hexValue,
'mode': mode.hexValue,
if (animationIndex != null) 'animationIndex': animationIndex, // 👈 NEW
};

// Convert JSON to Message object
Expand Down Expand Up @@ -52,10 +55,9 @@ class Message {
text: List<String>.from(textList),
flash: (json['flash'] as bool?) ?? false,
marquee: (json['marquee'] as bool?) ?? false,
speed: Speed.fromHex(
json['speed'] as String), // Using helper method for safety
mode: Mode.fromHex(
json['mode'] as String), // Using helper method for safety
speed: Speed.fromHex(json['speed'] as String),
mode: Mode.fromHex(json['mode'] as String),
animationIndex: json['animationIndex'] as int?, // 👈 NEW
);
}
}
19 changes: 10 additions & 9 deletions lib/bademagic_module/models/mode.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@ enum Mode {
up('0x02'),
down('0x03'),
fixed('0x04'),
snowflake('0x05'),
picture('0x06'),
animation('0x07'),
animation('0x05'),
snowflake('0x06'),
picture('0x07'),
laser('0x08');

final String hexValue;
const Mode(this.hexValue);

//method to get the integer value of the mode
static int getIntValue(Mode mode) {
String hexValue = mode.hexValue.substring(3, 4);
int intValue = int.parse(hexValue, radix: 10);
return intValue;
return int.parse(mode.hexValue.substring(2), radix: 16);
}

// Helper method to safely parse hex value
static Mode fromHex(String hexValue) {
return Mode.values.firstWhere(
(mode) => mode.hexValue == hexValue,
orElse: () => Mode.left, // Default to Mode.left if no match
orElse: () => Mode.left,
);
}

static Mode fromInt(int value) {
final hex = value.toRadixString(16).padLeft(2, '0');
return fromHex('0x$hex');
}
}
61 changes: 13 additions & 48 deletions lib/badge_animation/ani_animation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,61 +4,26 @@ class AniAnimation extends BadgeAnimation {
@override
void processAnimation(int badgeHeight, int badgeWidth, int animationIndex,
List<List<bool>> processGrid, List<List<bool>> canvas) {
int newWidth = processGrid[0].length;
int newHeight = processGrid.length;
int verticalOffset = (badgeHeight - newHeight) ~/ 2;
int displayWidth = newWidth > badgeWidth ? badgeWidth : newWidth;
int horizontalOffset = (badgeWidth - displayWidth) ~/ 2;
var totalAnimationLength = badgeWidth;
int frame = animationIndex % totalAnimationLength;
var firstHalf = frame < badgeWidth ~/ 2;
var secondHalf = frame >= badgeWidth ~/ 2;

int newGridHeight = processGrid.length;
int newGridWidth = processGrid[0].length;
for (int i = 0; i < badgeHeight; i++) {
for (int j = 0; j < badgeWidth; j++) {
bool lineShow = false;
bool bitmapShowcenter = false;
bool bitmapShowOut = false;

int sourceRow = i - verticalOffset;
int sourceCol = j - horizontalOffset;

bool isWithinNewGrid = sourceRow >= 0 &&
sourceRow < newHeight &&
sourceCol >= 0 &&
sourceCol < displayWidth;

int leftCenterCol = badgeWidth ~/ 2 - 1;
int rightCenterCol = badgeWidth ~/ 2;

int maxDistance = leftCenterCol;

int currentAnimationIndex = animationIndex % (maxDistance + 1);
// Calculate the total number of frames that fit the badge width
int framesCount = (newGridWidth / badgeWidth).ceil();

int leftColPos = leftCenterCol - currentAnimationIndex;
int rightColPos = rightCenterCol + currentAnimationIndex;
// Determine the current frame based on the animation value
int currentcountFrame = animationIndex ~/ badgeWidth % framesCount;

if (leftColPos < 0) leftColPos += badgeWidth;
if (rightColPos >= badgeWidth) rightColPos -= badgeWidth;
// Calculate the starting column for the current frame in newGrid
int startCol = currentcountFrame * badgeWidth;

if (j == leftColPos || j == rightColPos) {
lineShow = true;
} else {
lineShow = false;
}
bool isNewGridCell = i < newGridHeight && (startCol + j) < newGridWidth;

if (firstHalf) {
if (isWithinNewGrid && j > leftColPos && j < rightColPos) {
bitmapShowcenter = processGrid[sourceRow][sourceCol];
}
}
if (secondHalf) {
if (isWithinNewGrid && (j < leftColPos || j > rightColPos)) {
bitmapShowOut = processGrid[sourceRow][sourceCol];
}
}
// Update the grid based on the current frame's data
bool animationCondition =
(isNewGridCell && processGrid[i][startCol + j]);

canvas[i][j] = (lineShow || bitmapShowOut || bitmapShowcenter);
canvas[i][j] = animationCondition;
}
}
}
Expand Down
86 changes: 43 additions & 43 deletions lib/badge_animation/ani_picture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,60 @@ class PictureAnimation extends BadgeAnimation {
void processAnimation(int badgeHeight, int badgeWidth, int animationIndex,
List<List<bool>> processGrid, List<List<bool>> canvas) {
int newWidth = processGrid[0].length;
int totalAnimationLength = badgeHeight * 16;
int newHeight = processGrid.length;
int verticalOffset = (badgeHeight - newHeight) ~/ 2;
int displayWidth = newWidth > badgeWidth ? badgeWidth : newWidth;
int horizontalOffset = (badgeWidth - displayWidth) ~/ 2;
var totalAnimationLength = badgeWidth;
int frame = animationIndex % totalAnimationLength;
var firstHalf = frame < badgeWidth ~/ 2;
var secondHalf = frame >= badgeWidth ~/ 2;

int horizontalOffset = (badgeWidth - newWidth) ~/ 2;
for (int i = 0; i < badgeHeight; i++) {
for (int j = 0; j < badgeWidth; j++) {
bool lineShow = false;
bool bitmapShowcenter = false;
bool bitmapShowOut = false;

bool phase1 = frame < badgeHeight * 4;
bool phase2 = frame >= badgeHeight * 4 && frame < badgeHeight * 8;
int sourceRow = i - verticalOffset;
int sourceCol = j - horizontalOffset;

if (phase1) {
for (int row = badgeHeight - 1; row >= 0; row--) {
int fallPosition = frame - (badgeHeight - 1 - row) * 2;
int stoppingPosition = row;
fallPosition =
fallPosition >= stoppingPosition ? stoppingPosition : fallPosition;
bool isWithinNewGrid = sourceRow >= 0 &&
sourceRow < newHeight &&
sourceCol >= 0 &&
sourceCol < displayWidth;

if (fallPosition >= 0 && fallPosition < badgeHeight) {
for (int col = 0; col < badgeWidth; col++) {
int sourceCol = col - horizontalOffset;
bool isWithinNewGrid = sourceCol >= 0 && sourceCol < newWidth;
if (isWithinNewGrid) {
canvas[fallPosition][col] = processGrid[row][sourceCol];
}
}
}
}
} else if (phase2) {
for (int row = badgeHeight - 1; row >= 0; row--) {
int fallOutStartFrame = (badgeHeight - 1 - row) * 2;
int fallOutPosition =
row + (frame - badgeHeight * 4 - fallOutStartFrame);
int leftCenterCol = badgeWidth ~/ 2 - 1;
int rightCenterCol = badgeWidth ~/ 2;

if (fallOutPosition < row) {
for (int col = 0; col < badgeWidth; col++) {
int sourceCol = col - horizontalOffset;
bool isWithinNewGrid = sourceCol >= 0 && sourceCol < newWidth;
if (isWithinNewGrid) {
canvas[row][col] = processGrid[row][sourceCol];
}
}
int maxDistance = leftCenterCol;

int currentAnimationIndex = animationIndex % (maxDistance + 1);

int leftColPos = leftCenterCol - currentAnimationIndex;
int rightColPos = rightCenterCol + currentAnimationIndex;

if (leftColPos < 0) leftColPos += badgeWidth;
if (rightColPos >= badgeWidth) rightColPos -= badgeWidth;

if (j == leftColPos || j == rightColPos) {
lineShow = true;
} else {
lineShow = false;
}

if (fallOutPosition >= row && fallOutPosition < badgeHeight) {
for (int col = 0; col < badgeWidth; col++) {
canvas[row][col] = false;
if (firstHalf) {
if (isWithinNewGrid && j > leftColPos && j < rightColPos) {
bitmapShowcenter = processGrid[sourceRow][sourceCol];
}

for (int col = 0; col < badgeWidth; col++) {
int sourceCol = col - horizontalOffset;
bool isWithinNewGrid = sourceCol >= 0 && sourceCol < newWidth;
if (isWithinNewGrid && fallOutPosition < badgeHeight) {
canvas[fallOutPosition][col] = processGrid[row][sourceCol];
}
}
if (secondHalf) {
if (isWithinNewGrid && (j < leftColPos || j > rightColPos)) {
bitmapShowOut = processGrid[sourceRow][sourceCol];
}
}

canvas[i][j] = (lineShow || bitmapShowOut || bitmapShowcenter);
}
}
}
Expand Down
65 changes: 50 additions & 15 deletions lib/badge_animation/ani_snowflake.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,61 @@ class SnowFlakeAnimation extends BadgeAnimation {
@override
void processAnimation(int badgeHeight, int badgeWidth, int animationIndex,
List<List<bool>> processGrid, List<List<bool>> canvas) {
int newGridHeight = processGrid.length;
int newGridWidth = processGrid[0].length;
for (int i = 0; i < badgeHeight; i++) {
for (int j = 0; j < badgeWidth; j++) {
// Calculate the total number of frames that fit the badge width
int framesCount = (newGridWidth / badgeWidth).ceil();
int newWidth = processGrid[0].length;
int totalAnimationLength = badgeHeight * 16;
int frame = animationIndex % totalAnimationLength;

// Determine the current frame based on the animation value
int currentcountFrame = animationIndex ~/ badgeWidth % framesCount;
int horizontalOffset = (badgeWidth - newWidth) ~/ 2;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Guard against zero framesCount to avoid divide/modulo by zero

Clamping framesCount to at least 1 ensures animationIndex % framesCount won't cause a crash when newGridWidth is 0.

// Calculate the starting column for the current frame in newGrid
int startCol = currentcountFrame * badgeWidth;
bool phase1 = frame < badgeHeight * 4;
bool phase2 = frame >= badgeHeight * 4 && frame < badgeHeight * 8;

bool isNewGridCell = i < newGridHeight && (startCol + j) < newGridWidth;
if (phase1) {
for (int row = badgeHeight - 1; row >= 0; row--) {
int fallPosition = frame - (badgeHeight - 1 - row) * 2;
int stoppingPosition = row;
fallPosition =
fallPosition >= stoppingPosition ? stoppingPosition : fallPosition;

// Update the grid based on the current frame's data
bool snowflakeCondition =
(isNewGridCell && processGrid[i][startCol + j]);
if (fallPosition >= 0 && fallPosition < badgeHeight) {
for (int col = 0; col < badgeWidth; col++) {
int sourceCol = col - horizontalOffset;
bool isWithinNewGrid = sourceCol >= 0 && sourceCol < newWidth;
if (isWithinNewGrid) {
canvas[fallPosition][col] = processGrid[row][sourceCol];
}
}
}
}
} else if (phase2) {
for (int row = badgeHeight - 1; row >= 0; row--) {
int fallOutStartFrame = (badgeHeight - 1 - row) * 2;
int fallOutPosition =
row + (frame - badgeHeight * 4 - fallOutStartFrame);

if (fallOutPosition < row) {
for (int col = 0; col < badgeWidth; col++) {
int sourceCol = col - horizontalOffset;
bool isWithinNewGrid = sourceCol >= 0 && sourceCol < newWidth;
if (isWithinNewGrid) {
canvas[row][col] = processGrid[row][sourceCol];
}
}
}

if (fallOutPosition >= row && fallOutPosition < badgeHeight) {
for (int col = 0; col < badgeWidth; col++) {
canvas[row][col] = false;
}

canvas[i][j] = snowflakeCondition;
for (int col = 0; col < badgeWidth; col++) {
int sourceCol = col - horizontalOffset;
bool isWithinNewGrid = sourceCol >= 0 && sourceCol < newWidth;
if (isWithinNewGrid && fallOutPosition < badgeHeight) {
canvas[fallOutPosition][col] = processGrid[row][sourceCol];
}
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const String aniLaser = 'assets/animations/ic_anim_laser.gif';
const String aniPicture = 'assets/animations/ic_anim_picture.gif';
const String aniUp = 'assets/animations/ic_anim_up.gif';
const String aniRight = 'assets/animations/ic_anim_right.gif';
const String aniSnowflake = 'assets/animations/ic_anim_snowflake.gif';

//path to all the effects assets used
const String effFlash = 'assets/effects/ic_effect_flash.gif';
Expand Down
6 changes: 3 additions & 3 deletions lib/providers/animation_badge_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ Map<int, BadgeAnimation?> animationMap = {
2: UpAnimation(),
3: DownAnimation(),
4: FixedAnimation(),
5: SnowFlakeAnimation(),
6: PictureAnimation(),
7: AniAnimation(),
5: AniAnimation(),
6: SnowFlakeAnimation(),
7: PictureAnimation(),
8: LaserAnimation(),
};

Expand Down
6 changes: 3 additions & 3 deletions lib/providers/badge_message_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Map<int, Mode> modeValueMap = {
2: Mode.up,
3: Mode.down,
4: Mode.fixed,
5: Mode.snowflake,
6: Mode.picture,
7: Mode.animation,
5: Mode.animation,
6: Mode.snowflake,
7: Mode.picture,
8: Mode.laser
};

Expand Down
Loading
Loading