example.js
· 16 KiB · SVG
Ham
function generateSVG(grid, config) {
const { cellSize, radius, strokeWidth } = config;
const width = grid[0].length * cellSize;
const height = grid.length * cellSize;
let svg = `<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">`;
for (let row = 0; row < grid.length; row++) {
for (let col = 0; col < grid[row].length; col++) {
const cx = col * cellSize + cellSize / 2;
const cy = row * cellSize + cellSize / 2;
const circumference = 2 * Math.PI * radius;
const isClockwise = (row + col) % 2 === 0;
const initialOffset = isClockwise ? circumference : -circumference;
const squareX = cx - radius;
const squareY = cy - radius;
const squareSize = 2 * radius;
svg += `<rect x="${squareX}" y="${squareY}" width="${squareSize}" height="${squareSize}" rx="${radius}" ry="${radius}" fill="black" opacity="0" id="square_${row}_${col}"></rect>`;
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>`;
if (grid[row][col]) {
svg += `<circle cx="${cx}" cy="${cy}" r="0" fill="black" id="inner_${row}_${col}"></circle>`;
}
}
}
svg += '</svg>';
return svg;
}
function replaceAndAnimate(grid, config) {
const svgString = generateSVG(grid, config);
const existingSVG = document.querySelector('svg');
if (existingSVG) {
existingSVG.outerHTML = svgString;
animateCircles(grid, config);
} else {
console.log('SVG не найден на странице');
}
}
function animateCircles(grid, config) {
const { radius, cellSize, arcDur, arcDelayStep, fillDur, fillDelayStep, squareDur, shrinkDur, moveDur, shrinkFactor, moveFactor } = config;
const rows = grid.length;
const cols = grid[0].length;
const centerRow = Math.floor(rows / 2);
const centerCol = Math.floor(cols / 2);
const centerX = centerCol * cellSize + cellSize / 2 - radius;
const centerY = centerRow * cellSize + cellSize / 2 - radius;
const circles = [];
const squares = [];
const inners = [];
for (let row = 0; row < rows; row++) {
circles[row] = [];
squares[row] = [];
inners[row] = [];
for (let col = 0; col < cols; col++) {
circles[row][col] = document.getElementById(`circle_${row}_${col}`);
squares[row][col] = document.getElementById(`square_${row}_${col}`);
inners[row][col] = grid[row][col] ? document.getElementById(`inner_${row}_${col}`) : null;
}
}
const arcDelays = [];
for (let row = 0; row < rows; row++) {
arcDelays[row] = [];
for (let col = 0; col < cols; col++) {
arcDelays[row][col] = (row + col) * arcDelayStep;
}
}
const maxDelayFirst = (rows + cols - 2) * arcDelayStep;
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const circle = circles[row][col];
if (circle) {
const isClockwise = (row + col) % 2 === 0;
setTimeout(() => {
animateDashOffset(circle, isClockwise, 2 * Math.PI * radius, arcDur);
}, arcDelays[row][col]);
}
}
}
setTimeout(() => {
const fillDelays = [];
let maxDistance = 0;
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
if (grid[row][col]) {
const distance = Math.sqrt((row - centerRow) ** 2 + (col - centerCol) ** 2);
fillDelays.push({ row, col, delay: distance * fillDelayStep });
maxDistance = Math.max(maxDistance, distance);
}
}
}
const maxDelaySecond = maxDistance * fillDelayStep;
fillDelays.forEach(({ row, col, delay }) => {
const innerCircle = inners[row][col];
if (innerCircle) {
setTimeout(() => {
animateRadius(innerCircle, 0, radius, fillDur);
}, delay);
}
});
setTimeout(() => {
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const circle = circles[row][col];
const square = squares[row][col];
const inner = inners[row][col];
if (grid[row][col]) {
animateToSquare(circle, square, inner, radius, squareDur);
} else {
animateFadeOut(circle, squareDur);
square.remove();
}
}
}
setTimeout(() => {
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
if (grid[row][col]) {
const square = squares[row][col];
animateShrink(square, 2 * radius, 2 * radius * shrinkFactor, shrinkDur);
}
}
}
setTimeout(() => {
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
if (grid[row][col]) {
const square = squares[row][col];
const currentX = parseFloat(square.getAttribute('x'));
const currentY = parseFloat(square.getAttribute('y'));
const toX = currentX + (centerX - currentX) * moveFactor;
const toY = currentY + (centerY - currentY) * moveFactor;
animateMove(square, currentX, currentY, toX, toY, moveDur);
}
}
}
setTimeout(() => {
const svg = document.querySelector('svg');
svg.style.borderRadius = '10%';
svg.style.border = '5px black dotted';
}, moveDur);
}, shrinkDur);
}, squareDur);
}, maxDelaySecond + fillDur);
}, maxDelayFirst + arcDur);
}
function animateDashOffset(element, isClockwise, circumference, duration) {
const startTime = performance.now();
const from = isClockwise ? circumference : -circumference;
const to = 0;
const step = () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentOffset = from + (to - from) * progress;
element.setAttribute('stroke-dashoffset', currentOffset);
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
}
function animateRadius(element, from, to, duration) {
const startTime = performance.now();
const step = () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentRadius = from + (to - from) * progress;
element.setAttribute('r', currentRadius);
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
}
function animateToSquare(circle, square, inner, radius, duration) {
const startTime = performance.now();
const step = () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentRxRy = radius * (1 - progress);
const currentOpacity = progress;
square.setAttribute('rx', currentRxRy);
square.setAttribute('ry', currentRxRy);
square.setAttribute('opacity', currentOpacity);
circle.setAttribute('opacity', 1 - progress);
if (progress < 1) {
requestAnimationFrame(step);
} else {
circle.remove();
if (inner) inner.remove();
if (currentOpacity === 1) square.removeAttribute('opacity');
}
};
requestAnimationFrame(step);
}
function animateFadeOut(element, duration) {
const startTime = performance.now();
const step = () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentOpacity = 1 - progress;
element.setAttribute('opacity', currentOpacity);
if (progress < 1) {
requestAnimationFrame(step);
} else {
element.remove();
}
};
requestAnimationFrame(step);
}
function animateShrink(element, fromSize, toSize, duration) {
const startTime = performance.now();
const step = () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentSize = fromSize + (toSize - fromSize) * progress;
element.setAttribute('width', currentSize);
element.setAttribute('height', currentSize);
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
}
function animateMove(element, fromX, fromY, toX, toY, duration) {
const startTime = performance.now();
const step = () => {
const elapsed = performance.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentX = fromX + (toX - fromX) * progress;
const currentY = fromY + (toY - fromY) * progress;
element.setAttribute('x', currentX);
element.setAttribute('y', currentY);
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
}
// Пример использования:
const config = {
cellSize: 22.5,
radius: 10,
strokeWidth: 2,
arcDur: 500,
arcDelayStep: 100,
fillDur: 500,
fillDelayStep: 100,
squareDur: 2000,
shrinkDur: 300,
moveDur: 1000,
shrinkFactor: 0.9,
moveFactor: 0.2
};
const arr = [[true, true, true, true, true, true, true, false, false, false, false, true, false, false, true, true, false, false, true, true, false, false, true, true, true, true, true, true, true], [true, false, false, false, false, false, true, false, true, true, false, false, true, true, false, false, true, false, false, false, true, false, true, false, false, false, false, false, true], [true, false, true, true, true, false, true, false, false, false, true, true, true, false, false, false, false, false, true, false, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, false, true, true, true, false, false, false, false, true, false, true, true, false, true, false, true, true, true, false, true], [true, false, true, true, true, false, true, false, true, true, false, true, false, true, true, false, false, true, true, true, false, false, true, false, true, true, true, false, true], [true, false, false, false, false, false, true, false, false, false, false, true, true, false, false, true, false, true, true, false, 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, true, true, true, true, true, true], [false, false, false, false, false, false, false, false, true, true, false, true, false, true, false, false, true, false, false, false, true, false, false, false, false, false, false, false, false], [false, true, false, true, true, true, true, false, true, true, false, false, false, false, false, false, false, false, true, true, true, true, true, false, true, true, false, true, false], [false, true, true, true, false, true, false, false, true, false, true, true, false, true, true, true, false, false, false, false, true, true, true, false, true, false, true, false, false], [false, false, true, true, false, true, true, false, true, false, true, true, true, true, true, true, true, true, false, false, false, false, true, false, true, true, true, false, false], [false, true, true, false, false, false, false, true, false, false, true, true, false, true, true, false, true, true, true, false, false, false, true, true, true, false, false, false, true], [false, false, true, false, true, false, true, true, true, true, false, false, false, false, false, true, false, true, true, true, false, true, true, true, false, false, true, true, false], [true, true, false, false, false, true, false, false, false, true, false, false, true, false, false, true, false, true, true, false, false, false, true, false, true, false, true, false, false], [false, false, true, true, false, true, true, false, false, false, false, true, true, true, true, false, true, true, false, true, true, false, false, true, false, false, false, false, false], [false, true, true, true, true, false, false, false, true, false, true, false, true, true, false, true, false, true, true, true, false, false, false, true, false, true, true, false, false], [true, false, false, true, true, false, true, false, false, false, false, true, false, true, true, true, true, true, false, true, true, false, true, true, true, false, false, false, true], [true, false, false, true, true, true, false, true, false, true, true, false, false, false, false, false, true, false, true, false, true, false, true, false, false, true, true, false, true], [true, true, true, true, true, false, true, true, false, true, true, false, true, false, false, true, false, false, false, false, true, true, true, true, false, true, false, false, true], [true, true, false, true, false, true, false, true, false, false, true, false, false, false, true, false, false, true, true, false, false, false, false, true, false, false, false, false, false], [true, true, false, true, true, true, true, false, true, false, true, true, true, false, true, true, true, false, false, false, true, true, true, true, true, true, false, false, false], [false, false, false, false, false, false, false, false, true, false, false, true, true, false, false, false, false, false, true, false, true, false, false, false, true, true, false, true, true], [true, true, true, true, true, true, true, false, false, false, false, false, true, true, true, false, false, true, true, true, true, false, true, false, true, false, true, true, false], [true, false, false, false, false, false, true, false, true, true, true, false, true, true, false, true, false, true, false, true, true, false, false, false, true, true, false, true, true], [true, false, true, true, true, false, true, false, true, true, false, false, true, false, true, false, true, true, true, true, true, true, true, true, true, true, false, true, true], [true, false, true, true, true, false, true, false, true, true, true, true, true, true, false, false, true, false, false, false, false, true, false, false, false, true, true, false, false], [true, false, true, true, true, false, true, false, false, false, true, false, false, false, true, false, true, false, true, false, false, false, false, true, true, false, false, true, true], [true, false, false, false, false, false, true, false, true, true, false, false, true, true, true, true, false, false, false, true, true, false, true, false, true, false, true, false, true], [true, true, true, true, true, true, true, false, false, true, false, false, true, false, false, false, true, true, true, false, true, false, false, false, false, true, true, false, false]];
replaceAndAnimate(arr, config);
text2json_qr.py
· 724 B · Python
Ham
import qrcode, json
def generate_qr_boolean_array(text):
qr = qrcode.QRCode(
version=5,
error_correction=qrcode.constants.ERROR_CORRECT_Q,
box_size=1,
border=0,
)
qr.add_data(text)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
width, height = img.size
boolean_array = []
for y in range(height):
row = []
for x in range(width):
pixel = img.getpixel((x, y))
if pixel == 0 or pixel == (0, 0, 0): row.append(True)
else: row.append(False)
boolean_array.append(row)
return boolean_array
print(json.dumps(generate_qr_boolean_array("Hello, world!")))
| 1 | import qrcode, json |
| 2 | |
| 3 | def generate_qr_boolean_array(text): |
| 4 | qr = qrcode.QRCode( |
| 5 | version=5, |
| 6 | error_correction=qrcode.constants.ERROR_CORRECT_Q, |
| 7 | box_size=1, |
| 8 | border=0, |
| 9 | ) |
| 10 | |
| 11 | qr.add_data(text) |
| 12 | qr.make(fit=True) |
| 13 | |
| 14 | img = qr.make_image(fill_color="black", back_color="white") |
| 15 | width, height = img.size |
| 16 | |
| 17 | boolean_array = [] |
| 18 | for y in range(height): |
| 19 | row = [] |
| 20 | for x in range(width): |
| 21 | pixel = img.getpixel((x, y)) |
| 22 | if pixel == 0 or pixel == (0, 0, 0): row.append(True) |
| 23 | else: row.append(False) |
| 24 | boolean_array.append(row) |
| 25 | |
| 26 | return boolean_array |
| 27 | |
| 28 | print(json.dumps(generate_qr_boolean_array("Hello, world!"))) |