Skip to content

Commit 2e4f731

Browse files
fix: sync the actual badge and preview
1 parent 3a5f37c commit 2e4f731

File tree

1 file changed

+13
-151
lines changed

1 file changed

+13
-151
lines changed

lib/badge_animation/ani_animation.dart

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

33
class AniAnimation extends BadgeAnimation {
44
@override
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-
}
18-
5+
void processAnimation(int badgeHeight, int badgeWidth, int animationIndex,
6+
List<List<bool>> processGrid, List<List<bool>> canvas) {
197
int newGridHeight = processGrid.length;
208
int newGridWidth = processGrid[0].length;
21-
22-
if (canvas.length < badgeHeight ||
23-
canvas.any((row) => row.length < badgeWidth)) {
24-
throw ArgumentError(
25-
'canvas must have at least $badgeHeight rows and $badgeWidth columns',
26-
);
27-
}
28-
29-
// Clear canvas first
309
for (int i = 0; i < badgeHeight; i++) {
3110
for (int j = 0; j < badgeWidth; j++) {
32-
canvas[i][j] = false;
33-
}
34-
}
35-
36-
// Find word boundaries by detecting spaces (multiple empty columns)
37-
List<Map<String, int>> words =
38-
_findWords(processGrid, newGridHeight, newGridWidth);
39-
40-
if (words.isEmpty) {
41-
// If no words found, show the entire grid
42-
_displaySegment(processGrid, canvas, 0, newGridWidth, badgeHeight,
43-
badgeWidth, newGridHeight);
44-
return;
45-
}
46-
47-
// Determine which word to show based on animation index
48-
int frameDisplayDuration =
49-
30; // Adjust this to control how long each word is shown
50-
int currentWordIndex =
51-
(animationIndex ~/ frameDisplayDuration) % words.length;
11+
// Calculate the total number of frames that fit the badge width
12+
int framesCount = (newGridWidth / badgeWidth).ceil();
5213

53-
// Get start and end positions for current word
54-
int wordStart = words[currentWordIndex]['start']!;
55-
int wordEnd = words[currentWordIndex]['end']!;
14+
// Determine the current frame based on the animation value
15+
int currentcountFrame = animationIndex ~/ badgeWidth % framesCount;
5616

57-
// Display the current word
58-
_displaySegment(processGrid, canvas, wordStart, wordEnd, badgeHeight,
59-
badgeWidth, newGridHeight);
60-
}
17+
// Calculate the starting column for the current frame in newGrid
18+
int startCol = currentcountFrame * badgeWidth;
6119

62-
List<Map<String, int>> _findWords(
63-
List<List<bool>> grid, int height, int width) {
64-
List<Map<String, int>> words = [];
65-
int minSpaceWidth =
66-
3; // Minimum number of empty columns to consider as word separator
20+
bool isNewGridCell = i < newGridHeight && (startCol + j) < newGridWidth;
6721

68-
int wordStart = -1;
69-
int emptyColumnCount = 0;
22+
// Update the grid based on the current frame's data
23+
bool animationCondition =
24+
(isNewGridCell && processGrid[i][startCol + j]);
7025

71-
for (int col = 0; col < width; col++) {
72-
bool hasPixel = false;
73-
74-
// Check if this column has any pixels
75-
for (int row = 0; row < height; row++) {
76-
if (grid[row][col]) {
77-
hasPixel = true;
78-
break;
79-
}
80-
}
81-
82-
if (hasPixel) {
83-
// This column has content
84-
if (wordStart == -1) {
85-
// Start of a new word
86-
wordStart = col;
87-
}
88-
emptyColumnCount = 0;
89-
} else {
90-
// This column is empty
91-
emptyColumnCount++;
92-
93-
// If we have enough empty columns and we were in a word, end the word
94-
if (emptyColumnCount >= minSpaceWidth && wordStart != -1) {
95-
words.add({
96-
'start': wordStart,
97-
'end': col - emptyColumnCount + 1,
98-
});
99-
wordStart = -1;
100-
}
101-
}
102-
}
103-
104-
// Handle the last word if it extends to the end
105-
if (wordStart != -1) {
106-
words.add({
107-
'start': wordStart,
108-
'end': width,
109-
});
110-
}
111-
112-
return words;
113-
}
114-
115-
void _displaySegment(
116-
List<List<bool>> source,
117-
List<List<bool>> canvas,
118-
int startCol,
119-
int endCol,
120-
int badgeHeight,
121-
int badgeWidth,
122-
int sourceHeight) {
123-
// Create temporary frame for the word
124-
List<List<bool>> tempFrame = List.generate(
125-
badgeHeight,
126-
(_) => List.filled(badgeWidth, false),
127-
);
128-
129-
// Copy the word segment
130-
int wordWidth = endCol - startCol;
131-
for (int i = 0; i < badgeHeight && i < sourceHeight; i++) {
132-
for (int j = 0; j < wordWidth && j < badgeWidth; j++) {
133-
int sourceCol = startCol + j;
134-
if (sourceCol < source[i].length) {
135-
tempFrame[i][j] = source[i][sourceCol];
136-
}
137-
}
138-
}
139-
140-
// Remove leading empty columns to left-align the word
141-
int shiftLeftBy =
142-
_countLeadingEmptyCols(tempFrame, badgeHeight, badgeWidth);
143-
144-
// Apply the shift and copy to canvas
145-
for (int i = 0; i < badgeHeight; i++) {
146-
for (int j = 0; j < badgeWidth; j++) {
147-
int sourceCol = j + shiftLeftBy;
148-
canvas[i][j] = sourceCol < badgeWidth ? tempFrame[i][sourceCol] : false;
149-
}
150-
}
151-
}
152-
153-
int _countLeadingEmptyCols(List<List<bool>> frame, int height, int width) {
154-
for (int col = 0; col < width; col++) {
155-
bool isColEmpty = true;
156-
for (int row = 0; row < height; row++) {
157-
if (frame[row][col]) {
158-
isColEmpty = false;
159-
break;
160-
}
161-
}
162-
if (!isColEmpty) {
163-
return col;
26+
canvas[i][j] = animationCondition;
16427
}
16528
}
166-
return 0;
16729
}
16830
}

0 commit comments

Comments
 (0)