Добавляем все файлы

This commit is contained in:
2025-11-06 19:41:55 +02:00
parent 235d6a3a18
commit 2e5aaec307
218 changed files with 79015 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
// src/infrastructure/svg-to-png.js
/**
* @param {SVGElement} svg - виртуальный SVG (готовый для рендеринга)
* @param {{x:number,y:number,width:number,height:number}} rect - область в единицах SVG user units
* @param {number} scale - множитель (вызов передаёт, например, 3)
* @param {(blob:Blob|null)=>void} callBack
*/
export function svgToPng(svg, rect, scale, callBack) {
if (!svg || !rect || rect.width <= 0 || rect.height <= 0) {
callBack(null);
return;
}
// output размеры с учётом devicePixelRatio
const dpr = window.devicePixelRatio || 1;
const outputWidth = Math.round(rect.width * scale * dpr);
const outputHeight = Math.round(rect.height * scale * dpr);
// Сериализуем svg в строку и делаем blob/url
let svgString;
try {
svgString = new XMLSerializer().serializeToString(svg);
} catch (e) {
callBack(null);
return;
}
let url;
try {
url = URL.createObjectURL(new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' }));
} catch (e) {
callBack(null);
return;
}
const img = new Image();
// crossOrigin можно добавить, если нужно: img.crossOrigin = 'anonymous';
img.onload = function () {
try {
const canvas = document.createElement('canvas');
canvas.width = outputWidth;
canvas.height = outputHeight;
canvas.style.width = `${outputWidth}px`;
canvas.style.height = `${outputHeight}px`;
const ctx = canvas.getContext('2d');
if (!ctx) {
URL.revokeObjectURL(url);
callBack(null);
return;
}
ctx.imageSmoothingEnabled = false;
// Если rect.x/rect.y отрицательные => смещение исходного изображения внутри canvas
const sx = Math.max(0, rect.x * scale * dpr);
const sy = Math.max(0, rect.y * scale * dpr);
const sWidth = rect.width * scale * dpr;
const sHeight = rect.height * scale * dpr;
// dx/dy: смещение на canvas (если rect.x < 0, то мы сдвигаем вправо)
const dx = rect.x < 0 ? -rect.x * scale * dpr : 0;
const dy = rect.y < 0 ? -rect.y * scale * dpr : 0;
// drawImage с указанием исходной области и целевой области
ctx.drawImage(
img,
sx, // sx
sy, // sy
sWidth, // sWidth
sHeight, // sHeight
dx, // dx (на canvas)
dy, // dy
outputWidth, // dWidth
outputHeight // dHeight
);
URL.revokeObjectURL(url);
canvas.toBlob(blob => {
callBack(blob);
}, 'image/png');
} catch (err) {
URL.revokeObjectURL(url);
callBack(null);
}
};
img.onerror = function () {
try { URL.revokeObjectURL(url); } catch (e) {}
callBack(null);
};
img.src = url;
}