Skip to content

Commit bddc6f8

Browse files
fix: Behaviour change in the Snowflake animation
fix: Guard against zero framesCount to avoid modulo by zero in SnowFlakeAnimation fix: blicking illusion back fix: added input validation
1 parent f401ac4 commit bddc6f8

File tree

1 file changed

+62
-15
lines changed

1 file changed

+62
-15
lines changed

lib/badge_animation/ani_snowflake.dart

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,76 @@ import 'package:badgemagic/badge_animation/animation_abstract.dart';
22

33
class SnowFlakeAnimation extends BadgeAnimation {
44
@override
5-
void processAnimation(int badgeHeight, int badgeWidth, int animationIndex,
6-
List<List<bool>> processGrid, List<List<bool>> canvas) {
5+
void processAnimation(
6+
int badgeHeight,
7+
int badgeWidth,
8+
int animationIndex,
9+
List<List<bool>> processGrid,
10+
List<List<bool>> canvas,
11+
) {
12+
if (processGrid.isEmpty ||
13+
processGrid.any((row) => row.length != processGrid[0].length)) {
14+
throw ArgumentError(
15+
'processGrid must be a non-empty rectangular 2D list',
16+
);
17+
}
718
int newGridHeight = processGrid.length;
819
int newGridWidth = processGrid[0].length;
9-
for (int i = 0; i < badgeHeight; i++) {
10-
for (int j = 0; j < badgeWidth; j++) {
11-
// Calculate the total number of frames that fit the badge width
12-
int framesCount = (newGridWidth / badgeWidth).ceil();
1320

14-
// Determine the current frame based on the animation value
15-
int currentcountFrame = animationIndex ~/ badgeWidth % framesCount;
21+
if (canvas.length < badgeHeight ||
22+
canvas.any((row) => row.length < badgeWidth)) {
23+
throw ArgumentError(
24+
'canvas must have at least $badgeHeight rows and $badgeWidth columns',
25+
);
26+
}
27+
int framesCount = (newGridWidth / badgeWidth).ceil();
28+
framesCount = framesCount == 0 ? 1 : framesCount;
29+
30+
int currentFrame = (animationIndex ~/ badgeWidth) % framesCount;
1631

17-
// Calculate the starting column for the current frame in newGrid
18-
int startCol = currentcountFrame * badgeWidth;
32+
int startCol = currentFrame * badgeWidth;
33+
if (startCol + badgeWidth > newGridWidth) {
34+
startCol = newGridWidth - badgeWidth;
35+
if (startCol < 0) startCol = 0;
36+
}
37+
38+
List<List<bool>> tempFrame = List.generate(
39+
badgeHeight,
40+
(_) => List.filled(badgeWidth, false),
41+
);
42+
43+
for (int i = 0; i < badgeHeight; i++) {
44+
for (int j = 0; j < badgeWidth; j++) {
45+
int gridCol = startCol + j;
46+
bool isValid = i < newGridHeight && gridCol < newGridWidth;
47+
tempFrame[i][j] = isValid ? processGrid[i][gridCol] : false;
48+
}
49+
}
1950

20-
bool isNewGridCell = i < newGridHeight && (startCol + j) < newGridWidth;
51+
int shiftLeftBy =
52+
_countLeadingEmptyCols(tempFrame, badgeHeight, badgeWidth);
2153

22-
// Update the grid based on the current frame's data
23-
bool snowflakeCondition =
24-
(isNewGridCell && processGrid[i][startCol + j]);
54+
for (int i = 0; i < badgeHeight; i++) {
55+
for (int j = 0; j < badgeWidth; j++) {
56+
int sourceCol = j + shiftLeftBy;
57+
canvas[i][j] = sourceCol < badgeWidth ? tempFrame[i][sourceCol] : false;
58+
}
59+
}
60+
}
2561

26-
canvas[i][j] = snowflakeCondition;
62+
int _countLeadingEmptyCols(List<List<bool>> frame, int height, int width) {
63+
for (int col = 0; col < width; col++) {
64+
bool isColEmpty = true;
65+
for (int row = 0; row < height; row++) {
66+
if (frame[row][col]) {
67+
isColEmpty = false;
68+
break;
69+
}
70+
}
71+
if (!isColEmpty) {
72+
return col;
2773
}
2874
}
75+
return 0;
2976
}
3077
}

0 commit comments

Comments
 (0)