Última atividade 3 months ago

Revisão f0deff32d5e90f9d5d3925cbb89e81822d2200e0

example.js Bruto
1function generateSVG(grid) {
2 // Размер ячейки для каждого кружка (в пикселях) - как в первой версии
3 const cellSize = 22.5;
4 // Радиус кружка
5 const radius = 10;
6 // Ширина обводки для кружков
7 const strokeWidth = 2;
8 // Ширина и высота SVG
9 const width = grid[0].length * cellSize;
10 const height = grid.length * cellSize;
11
12 // Начало SVG
13 let svg = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">`;
14
15 // Проходим по 2D массиву (true - закрашенный, false - пустой)
16 for (let row = 0; row < grid.length; row++) {
17 for (let col = 0; col < grid[row].length; col++) {
18 // Центр кружка
19 const cx = col * cellSize + cellSize / 2;
20 const cy = row * cellSize + cellSize / 2;
21
22 // Длина окружности для stroke-dasharray
23 const circumference = 2 * Math.PI * radius;
24
25 // Направление: шахматное (чётная сумма row+col - по часовой, нечётная - против)
26 const isClockwise = (row + col) % 2 === 0;
27 const initialOffset = isClockwise ? circumference : -circumference;
28
29 // Квадрат для финальной анимации, начальный rx=ry=radius, opacity=0
30 const squareSize = 2 * radius;
31 const squareX = cx - radius;
32 const squareY = cy - radius;
33 svg += `<rect x="${squareX}" y="${squareY}" width="${squareSize}" height="${squareSize}" rx="${radius}" ry="${radius}" fill="black" opacity="0" id="square_${row}_${col}"></rect>`;
34
35 if (grid[row][col]) { // true - закрашенный
36 // Закрашенный кружок: дуга без заливки, затем внутренний чёрный кружок
37 svg += `<circle cx="${cx}" cy="${cy}" r="${radius}" fill="none" stroke="black" stroke-width="${strokeWidth}" stroke-dasharray="${circumference}" stroke-dashoffset="${initialOffset}" id="circle_${row}_${col}"></circle>`;
38
39 // Внутренний кружок для расширения и заполнения чёрным из центра, начальный r=0
40 svg += `<circle cx="${cx}" cy="${cy}" r="0" fill="black" id="inner_${row}_${col}"></circle>`;
41 } else { // false - пустой
42 // Пустой кружок: только дуга без заливки
43 svg += `<circle cx="${cx}" cy="${cy}" r="${radius}" fill="none" stroke="black" stroke-width="${strokeWidth}" stroke-dasharray="${circumference}" stroke-dashoffset="${initialOffset}" id="circle_${row}_${col}"></circle>`;
44 }
45 }
46 }
47
48 // Конец SVG
49 svg += '</svg>';
50 return svg;
51}
52
53// Функция для замены первого SVG на странице и запуска анимации
54function replaceAndAnimate(grid) {
55 const svgString = generateSVG(grid);
56 const existingSVG = document.querySelector('svg');
57 if (existingSVG) {
58 existingSVG.outerHTML = svgString;
59 // Теперь запускаем анимацию
60 animateCircles(grid);
61 } else {
62 console.log('SVG не найден на странице');
63 }
64}
65
66// Функция анимации через JS
67function animateCircles(grid) {
68 const radius = 10;
69 const arcDur = 500; // Длительность рисования дуги (мс)
70 const arcDelayStep = 100; // Задержка между кружками (мс)
71 const fillDur = 500; // Длительность расширения внутреннего (мс)
72 const fillDelayStep = 100; // Задержка для расширения (мс)
73 const squareDur = 2000; // Длительность превращения в квадрат (мс)
74
75 // Центр сетки
76 const centerRow = Math.floor(grid.length / 2);
77 const centerCol = Math.floor(grid[0].length / 2);
78
79 // Максимальная задержка для первого этапа (рисование дуг)
80 const maxDelayFirst = (grid.length + grid[0].length - 2) * arcDelayStep;
81
82 // Анимация рисования дуг для всех кружков
83 for (let row = 0; row < grid.length; row++) {
84 for (let col = 0; col < grid[row].length; col++) {
85 const delay = (row + col) * arcDelayStep;
86 const circle = document.getElementById(`circle_${row}_${col}`);
87 if (circle) {
88 const isClockwise = (row + col) % 2 === 0;
89 setTimeout(() => {
90 animateDashOffset(circle, isClockwise, 2 * Math.PI * radius, arcDur);
91 }, delay);
92 }
93 }
94 }
95
96 // Анимация расширения для закрашенных после первого этапа
97 setTimeout(() => {
98 for (let row = 0; row < grid.length; row++) {
99 for (let col = 0; col < grid[row].length; col++) {
100 if (grid[row][col]) { // true - закрашенный
101 const distance = Math.sqrt((row - centerRow) ** 2 + (col - centerCol) ** 2);
102 const delay = distance * fillDelayStep;
103 const innerCircle = document.getElementById(`inner_${row}_${col}`);
104 if (innerCircle) {
105 setTimeout(() => {
106 animateRadius(innerCircle, 0, radius, fillDur);
107 }, delay);
108 }
109 }
110 }
111 }
112
113 // Финальная анимация превращения в квадраты после расширения
114 const maxDelaySecond = Math.max(...grid.flatMap((row, r) => row.map((_, c) => Math.sqrt((r - centerRow) ** 2 + (c - centerCol) ** 2)))) * fillDelayStep;
115 setTimeout(() => {
116 for (let row = 0; row < grid.length; row++) {
117 for (let col = 0; col < grid[row].length; col++) {
118 const circle = document.getElementById(`circle_${row}_${col}`);
119 const square = document.getElementById(`square_${row}_${col}`);
120 if (grid[row][col]) { // Только для закрашенных
121 animateToSquare(circle, square, radius, squareDur);
122 } else { // Для незакрашенных - плавное исчезновение
123 animateFadeOut(circle, squareDur);
124 }
125 }
126 }
127 }, maxDelaySecond + fillDur);
128 }, maxDelayFirst + arcDur);
129}
130
131// Вспомогательная функция для анимации stroke-dashoffset (рисование дуги)
132function animateDashOffset(element, isClockwise, circumference, duration) {
133 const startTime = performance.now();
134 const from = isClockwise ? circumference : -circumference;
135 const to = 0;
136 const step = () => {
137 const elapsed = performance.now() - startTime;
138 const progress = Math.min(elapsed / duration, 1);
139 const currentOffset = from + (to - from) * progress;
140 element.setAttribute('stroke-dashoffset', currentOffset);
141 if (progress < 1) {
142 requestAnimationFrame(step);
143 }
144 };
145 requestAnimationFrame(step);
146}
147
148// Вспомогательная функция для плавной анимации радиуса
149function animateRadius(element, from, to, duration) {
150 const startTime = performance.now();
151 const step = () => {
152 const elapsed = performance.now() - startTime;
153 const progress = Math.min(elapsed / duration, 1);
154 const currentRadius = from + (to - from) * progress;
155 element.setAttribute('r', currentRadius);
156 if (progress < 1) {
157 requestAnimationFrame(step);
158 }
159 };
160 requestAnimationFrame(step);
161}
162
163// Вспомогательная функция для плавного превращения в квадрат (теперь с border-radius эффектом)
164function animateToSquare(circle, square, radius, duration) {
165 const startTime = performance.now();
166 const step = () => {
167 const elapsed = performance.now() - startTime;
168 const progress = Math.min(elapsed / duration, 1);
169 const currentRxRy = radius * (1 - progress);
170 const currentOpacity = progress; // opacity от 0 до 1
171 square.setAttribute('rx', currentRxRy);
172 square.setAttribute('ry', currentRxRy);
173 square.setAttribute('opacity', currentOpacity);
174 // Скрываем круг, устанавливая opacity=0
175 circle.setAttribute('opacity', 1 - progress);
176 if (progress < 1) {
177 requestAnimationFrame(step);
178 }
179 };
180 requestAnimationFrame(step);
181}
182
183// Вспомогательная функция для плавного исчезновения круга
184function animateFadeOut(element, duration) {
185 const startTime = performance.now();
186 const step = () => {
187 const elapsed = performance.now() - startTime;
188 const progress = Math.min(elapsed / duration, 1);
189 const currentOpacity = 1 - progress; // opacity от 1 до 0
190 element.setAttribute('opacity', currentOpacity);
191 if (progress < 1) {
192 requestAnimationFrame(step);
193 }
194 };
195 requestAnimationFrame(step);
196}
197
198// Пример использования:
199replaceAndAnimate([[true, true, true, true, true, true, true, false, true, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, true, false, true, false, false, false, true, true, true, true, true, true, true], [true, false, false, false, false, false, true, false, false, false, true, false, false, true, true, true, true, true, false, false, true, true, false, true, true, false, false, false, true, false, true, false, false, false, false, false, true], [true, false, true, true, true, false, true, false, true, true, true, true, false, true, true, false, false, true, true, false, false, false, true, true, true, false, true, true, false, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, false, false, false, true, true, false, false, false, false, true, false, true, false, false, true, true, true, false, false, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, false, true, false, false, false, true, true, true, false, false, true, false, true, false, false, false, true, true, false, true, true, false, true, false, true, true, true, false, true], [true, false, false, false, false, false, true, false, true, false, false, true, false, false, false, true, true, false, false, true, false, true, false, false, true, true, true, true, false, false, true, false, false, false, false, false, true], [true, true, true, true, true, true, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, true, true, true, true, true, true], [false, false, false, false, false, false, false, false, true, false, false, true, true, true, true, false, true, true, false, false, false, true, false, true, false, false, true, true, true, false, false, false, false, false, false, false, false], [false, true, false, true, false, true, true, true, true, true, false, false, true, false, false, true, true, false, false, true, false, false, true, true, true, false, false, false, true, true, true, true, false, true, true, false, true], [true, false, false, false, false, false, false, true, true, false, false, true, true, true, false, false, true, true, false, true, true, false, true, true, true, true, true, true, true, false, false, true, false, false, true, true, false], [true, false, false, false, true, false, true, false, false, false, true, false, true, true, false, false, true, false, true, false, false, true, true, true, true, false, false, true, false, true, false, false, true, false, true, true, false], [false, true, false, true, true, false, false, true, true, false, true, true, false, true, true, true, false, false, false, true, true, false, false, true, true, true, false, false, true, false, false, true, true, false, true, false, true], [false, true, false, true, true, true, true, true, true, true, false, true, true, true, false, true, true, true, false, true, true, false, false, true, true, true, false, true, true, true, true, true, true, false, true, true, false], [true, false, false, false, true, true, false, true, false, false, true, false, false, true, false, false, false, true, true, false, false, false, true, false, true, false, false, true, false, true, true, false, false, true, false, false, false], [true, true, true, false, false, true, true, true, true, false, false, true, true, false, false, false, false, true, true, false, false, true, false, true, true, false, false, true, true, true, true, true, false, false, true, true, true], [true, false, true, true, true, true, false, true, true, false, true, false, false, false, true, true, false, true, false, true, true, false, false, true, true, true, true, false, true, false, false, true, false, false, false, false, false], [false, true, false, false, false, true, true, false, true, true, true, false, false, false, false, true, false, true, false, false, false, false, true, true, true, true, true, true, true, false, true, true, true, false, true, false, true], [false, false, true, true, false, false, false, true, true, false, false, false, true, false, false, true, false, false, true, false, false, true, false, false, true, false, false, true, false, true, false, false, false, false, true, false, false], [true, true, true, true, false, false, true, true, true, true, false, false, false, true, true, true, true, false, false, false, true, false, true, true, true, true, false, false, false, true, false, false, false, false, false, true, true], [false, true, false, false, true, true, false, false, false, true, false, false, false, true, true, true, true, true, true, false, false, true, false, false, true, true, false, true, true, true, true, true, true, false, false, false, false], [true, false, true, false, false, false, true, false, false, true, false, false, false, false, false, false, true, true, true, true, true, false, true, false, true, false, true, false, true, false, false, false, true, false, true, false, false], [false, true, true, false, true, false, false, true, false, true, false, true, true, false, false, false, true, false, false, false, true, false, false, true, true, false, false, false, false, true, false, false, false, true, false, false, false], [true, false, true, false, true, true, true, false, true, true, true, false, false, false, true, false, true, true, false, true, true, true, true, true, true, false, false, false, false, true, false, true, true, true, false, false, true], [false, false, false, true, true, false, false, true, true, false, true, true, false, false, false, false, false, true, false, true, true, false, false, true, true, false, true, true, true, false, true, false, false, true, false, true, false], [true, false, false, true, false, false, true, false, false, true, false, true, true, false, true, true, true, true, true, true, false, false, false, true, false, false, false, true, false, true, false, false, true, true, true, false, true], [false, false, false, true, true, false, false, true, true, false, false, true, true, true, false, true, true, true, false, false, true, true, true, true, false, true, false, true, true, true, false, true, true, true, true, false, false], [true, false, false, true, true, false, true, true, false, true, false, true, false, false, false, false, true, false, true, false, false, false, true, true, false, true, true, false, false, false, false, false, true, true, true, true, true], [false, true, false, false, false, false, false, false, true, true, false, true, true, true, true, true, false, false, false, false, false, true, true, true, false, true, true, true, false, false, true, false, true, true, false, false, false], [true, true, true, true, false, false, true, false, false, true, true, true, true, true, false, true, false, false, true, true, true, false, false, false, true, false, false, false, true, true, true, true, true, true, false, false, true], [false, false, false, false, false, false, false, false, true, false, true, false, false, false, false, true, false, false, true, true, true, true, true, true, true, false, false, false, true, false, false, false, true, false, false, false, false], [true, true, true, true, true, true, true, false, true, true, false, true, true, true, false, false, true, true, true, true, false, false, true, false, true, true, false, false, true, false, true, false, true, true, true, true, false], [true, false, false, false, false, false, true, false, true, true, true, false, true, false, true, true, true, false, false, false, false, true, false, false, false, true, false, true, true, false, false, false, true, false, true, true, true], [true, false, true, true, true, false, true, false, false, true, false, true, false, true, true, true, true, true, true, false, false, false, true, true, false, false, true, false, true, true, true, true, true, false, false, false, false], [true, false, true, true, true, false, true, false, true, true, true, true, true, true, true, false, false, true, true, true, true, false, true, true, false, true, false, false, false, true, false, true, false, true, false, true, false], [true, false, true, true, true, false, true, false, false, true, false, false, true, false, true, false, false, true, true, false, true, true, true, false, false, true, true, false, false, false, false, false, false, true, false, false, true], [true, false, false, false, false, false, true, false, true, true, true, true, false, true, true, true, true, false, false, false, false, false, false, false, false, true, false, true, false, true, true, true, false, true, false, false, false], [true, true, true, true, true, true, true, false, false, true, true, false, false, false, false, true, false, false, true, true, true, false, false, false, false, false, true, true, false, false, false, true, false, true, true, true, true]]);
text2json_qr.py Bruto
1import qrcode, json
2
3def generate_qr_boolean_array(text):
4 """
5 Generates a QR code for the given text using version 5 and error correction level Q,
6 then converts it to a 2D boolean array where each element represents a module (square):
7 - True for black (dark) modules
8 - False for white (light) modules
9
10 Note: QR version 5 has a fixed size of 37x37 modules (excluding borders).
11 If the text is too long, it may not fit; adjust version or error correction as needed.
12 """
13 # Create QR code object with specified parameters
14 qr = qrcode.QRCode(
15 version=5, # Fixed to version 5
16 error_correction=qrcode.constants.ERROR_CORRECT_Q, # Q level error correction
17 box_size=1, # Each module is 1 pixel (not relevant for boolean array)
18 border=0, # No border to get raw 37x37 modules
19 )
20
21 # Add data and generate the QR code
22 qr.add_data(text)
23 qr.make(fit=True) # This will attempt to fit, but version is fixed to 5
24
25 # Generate the image (black and white)
26 img = qr.make_image(fill_color="black", back_color="white")
27
28 # Get image dimensions (should be 37x37 for version 5 with border=0)
29 width, height = img.size
30
31 # Convert to 2D boolean list
32 boolean_array = []
33 for y in range(height):
34 row = []
35 for x in range(width):
36 pixel = img.getpixel((x, y))
37 # Check if pixel is black (0 for grayscale, or (0,0,0) for RGB)
38 if pixel == 0 or pixel == (0, 0, 0):
39 row.append(True) # Black module
40 else:
41 row.append(False) # White module
42 boolean_array.append(row)
43
44 return boolean_array
45
46# Example usage:
47print(json.dumps(generate_qr_boolean_array("Hello, world!")))