Показать сообщение отдельно
  #2 (permalink)  
Старый 02.01.2020, 21:23
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от 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>

Последний раз редактировалось Malleys, 02.01.2020 в 22:13.
Ответить с цитированием