Сообщение от laimas
|
Не в интерполяции дело, да и к данной теме это не имеет отношения.
|
Как не имеет к теме отношения? Давай разбираться!
Сообщение от laimas
|
Создаем документ в Inkscape в пикселях 2048х1367, проверяем это в см, показывает 57,79911 х 38,57978, что уже не равно рассчитанному 54.19х36.17 (собственно для 96dpi размеры 57,79911 х 38,57978 не верны).
|
Всё верно, SVG-документ размером 2048×1367 единиц при 96 ppi будет иметь размеры ≈54.19×36.17 см, а при 90 ppi (которое очевидно используется в Inkscape) — ≈57.80×38.58см.
Ваши 2 сантиметра при различных значениях точек на дюйм (в данном случае нет никаких точек, а есть безразмерные единицы в пространстве SVG, так что грубо говоря, я считаю, что ваш 1 пиксель на растеризированной картинке раскрытой в полном размере соответствует 1 единице в SVG) будут иметь разные размеры в SVG — при 90 ppi будет ≈70.9 ед., при 96 ppi будет ≈75.6 ед. и при 300 ppi будет ≈236.2 ед.
S в
SVG значит — масштабируемая. Единственное отношение, которое вы можете установить — использовать внутри SVG абстрактные единицы (добавив «px» при необходимости, чтобы CSS был верен), а затем установить ширину и высоту SVG в сантиметрах.
SVG не имеет никакого разрешения, это ведь векторная графика — SVG (Scalable Vector Graphics). Так что ваш SVG-документ может быть напечатан одинаково качественно и на маленькую марку, и на большой плакат на стене здания! Так что если вы хотите 2 см, вам нужно...
- принять, что одна единица равна одному сантиметру
- или пересчитать размер рамки в безразмерные единицы учитывая ppi
...и при печати использовать правильный размер бумаги — A2 в данном случае, а размер документа (≈54.19×36.17 см) указан в SVG.
Вот пример SVG размером 2048×1367 единиц, который отрисовывается на экране, занимая ≈1000×667.47 пикселей и имеет физический размер ≈54.19×36.17 см при разрешении 96 ppi...
Рамка нарисована на расстоянии 2 см (при 96 ppi) от краёв документа, а выделения мышкой рисуются в документ (devicePixelRatio нужен для правильного соответствия, когда страница отмасштабирована при помощи Ctrl+/-)! Также учтено, что документ при отрисовке может занимать меньшее место, как тут на форуме.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html, body {
background: #9CA3B1;
width: 100%;
height: 100%;
display: grid;
place-content: center;
margin: 0;
}
svg {
background: white;
box-shadow: .1em .1em .5em .2em rgba(0, 0, 0, .3);
cursor: crosshair;
width: 90%;
max-width: 1000px;
display: inline-block;
height: auto;
margin: auto;
}
svg rect {
pointer-events: none;
}
@media print {
html, body {
background: initial;
display: initial;
}
svg {
box-shadow: initial;
width: auto;
border: thin dashed rgba(0, 0, 0, 0.5);
}
}
</style>
</head>
<body>
<svg
xmlns="http://www.w3.org/2000/svg"
version="1.1"
id="canvas"
fill="rgba(33, 150, 243, 0.25)"
stroke="rgba(0, 0, 0, 0.5)"
></svg>
<script>
const size = { width: 2048, height: 1367 };
const ppi = 96;
const ppcm = ppi / 2.54;
canvas.setAttribute("width", `${size.width / ppcm}cm`);
canvas.setAttribute("height", `${size.height / ppcm}cm`);
canvas.setAttribute("viewBox", [0, 0, size.width, size.height].join(" "));
const borderRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
borderRect.setAttribute("x", 2 * ppcm);
borderRect.setAttribute("y", 2 * ppcm);
borderRect.setAttribute("width", size.width - 4 * ppcm);
borderRect.setAttribute("height", size.height - 4 * ppcm);
borderRect.setAttribute("fill", "white");
canvas.appendChild(borderRect);
let activeRect = null;
const event0 = {};
canvas.addEventListener("pointerdown", event => {
activeRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
event0.screenX = event.screenX;
event0.screenY = event.screenY;
event0.offsetX = event.offsetX;
event0.offsetY = event.offsetY;
canvas.appendChild(activeRect);
});
addEventListener("pointermove", event => {
if(!activeRect) return;
const ρ = size.width / canvas.clientWidth;
const α = 1 / devicePixelRatio;
const Δx = event.screenX - event0.screenX;
const Δy = event.screenY - event0.screenY;
const x = Math.min(0, Δx * α) + event0.offsetX;
const y = Math.min(0, Δy * α) + event0.offsetY;
const width = Math.abs(Δx) * α;
const height = Math.abs(Δy) * α;
activeRect.setAttribute("x", x * ρ);
activeRect.setAttribute("y", y * ρ);
activeRect.setAttribute("width", width * ρ);
activeRect.setAttribute("height", height * ρ);
});
addEventListener("pointerup", event => {
if(activeRect) activeRect = null;
});
</script>
</body>
</html>