Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Canvas. Манипуляции с большим изображением (https://javascript.ru/forum/misc/75783-canvas-manipulyacii-s-bolshim-izobrazheniem.html)

Михаил_ 05.11.2018 21:05

Canvas. Манипуляции с большим изображением
 
Всех приветствую. Нужна помощь.
Есть canvas 500 х 500
Есть слой с картинкой 2000 х 1500.
Не получается сделать вращение слоя с картинкой в центре canvas-a после перемещений этого слоя.
Нужно дать возможность выбрать любой участок изображения, развернуть его, как понадобится, с возможностью масштабирования без ограничения повторов этих действий.
Чувствую, что дело в тригонометрии, но не могу ни как решить эту задачу
Наверняка уже кто-то с таким сталкивался, очень нужна помощь

рони 05.11.2018 21:28

Михаил_,
подожду переводчика или пример.

Михаил_ 05.11.2018 21:43

Цитата:

Сообщение от рони (Сообщение 497929)
Михаил_,
подожду переводчика или пример.

Я бы с удовольствием предоставил пример, но рабочего нет :( Все работает только по отдельности, а вот после вращения и перемещения повторное и последующие вращение в центре canvas-a не получается не уловлю, как использовать translate. Я воспользовался вращением слоя из-за необходимости в дальнейшем размещать там дополнительные объекты и работать с ними на выбранном участке изображения.
Это мой первый опыт с canvas-ом, но все равно не ожидал, что упрусь так плотно

рони 05.11.2018 22:22

Михаил_,
я не понимаю что вы хотите сделать.

Михаил_ 06.11.2018 01:32

Цитата:

Сообщение от рони (Сообщение 497931)
Михаил_,
я не понимаю что вы хотите сделать.

Спасибо, огромное за попытку помочь. Извините, если не очень понятно изъясняюсь.
В canvas-e показывается участок большого изображения, пользователь выбирает нужный ему участок по своему усмотрению перемещая, вращая, масштабируя большое изображение. Размеры canvas-a не изменяются.
При начальной загрузке картинки, центр canvas-a и центр картинки совмещены.

У меня все уперлось в совмещение центра canvas-a и центра вращения большого изображения после однократного перемещения и поворота картинки.

Удалось решить эту проблему для однократного перемещения и поворота изображения, но после повторного перемещения совместить центр canvas-a и новый центр вращения картинки не получается ну ни как.

Не могу понять алгоритм совмещения центра canvas-a с новым центром вращения изображения после многократных перемещений и вращений, пока без масштабирования, даже. Учитывая, что предыдущий центр вращения картинки может быть смещен, при ее перемещении пользователем, далеко за рамки canvas-a

Уже мозги кипят. Повторюсь, картинка размещена в отдельном слое в canvas-e

рони 06.11.2018 02:09

Михаил_,
не могу помочь, не понимаю.

MallSerg 06.11.2018 10:38

Цитата:

Сообщение от рони (Сообщение 497939)
Михаил_,
не могу помочь, не понимаю.

У топик стартера есть большая картинка на которую он смотрит через маленькое окно. Большую картинку на которую смотрят через окно можно перемещать и вращать точкой вращения является центр окна 500х500. Топик стартер не знает как найти точку( на большой фоновой картинке) вокруг которой нужно поворачивать эту картинку если большая картинка уже смещалась и вращалась.

Автор ищет синус и не может найти )). Ну а по хорошему такие задачи правильно решать с помощью сложения матриц трансформации после каждой операции смещения вращения.

Михаил_ 06.11.2018 10:47

Цитата:

Сообщение от MallSerg (Сообщение 497959)
У топик стартера есть большая картинка на которую он смотрит через маленькое окно. Большую картинку на которую смотрят через окно можно перемещать и вращать точкой вращения является центр окна 500х500. Топик стартер не знает как найти точку( на большой фоновой картинке) вокруг которой нужно поворачивать эту картинку если большая картинка уже смещалась и вращалась.

Да, Вы абсолютно правильно поняли!!!
Цитата:

Сообщение от MallSerg (Сообщение 497959)
Автор ищет синус и не может найти )). Ну а по хорошему такие задачи правильно решать с помощью сложения матриц трансформации после каждой операции смещения вращения.

Прошу прощения, а что это такое???
И вопрос, можно ли будет, после решения всех этих проблем сохранять текущее положение изображения, центров и других объектов с возможностью последующей загрузки? Без этого все усилия теряют смысл

Malleys 06.11.2018 11:00

Примерно так...
<!DOCTYPE html>
<html>
	<head>
		<style>

canvas {
	background: black;
}

form {
	display: grid;
	grid-template-columns: 1fr 2fr;
	margin: 1em;
	align-self: flex-start;
	align-items: center;
	grid-gap: .5em;
}

form label {
	display: contents;
}

body {
	display: flex;
	flex-flow: wrap;
}		

		</style>
	</head>
	<body>
		<canvas id="canvas" width="500" height="500"></canvas>
		<form>
			<label>
				angle
				<input type="range" id="angle" value="0" min="-180" max="180" step="any">
			</label>
			<label>
				cropX
				<input type="number" id="cropX" value="850" step="1">
			</label>
			<label>
				cropY
				<input type="number" id="cropY" value="600" step="1">
			</label>
			<label>
				cropWidth
				<input type="number" id="cropWidth" value="300" step="1">
			</label>
			<label>
				cropHeight
				<input type="number" id="cropHeight" value="300" step="1">
			</label>
			<label>
				scale
				<input type="range" id="scale" value="1" min="0.1" max="5" step="any">
			</label>
		</form>

		<script>
			
var ctx = document.getElementById("canvas").getContext("2d");

var image = new Image();
image.src = "https://placeimg.com/2000/1500/any";
image.onload = applyInputs;

document.addEventListener("input", applyInputs);

function applyInputs() {
	crop(ctx, image, $.reduce((m, { id, value }) => Object.assign(m, { [id]: value }), {}));
}

var $ = "cropX cropY cropWidth cropHeight scale angle"
	.split(/\s+/)
	.map(id => document.getElementById(id));

function crop(ctx, image, { cropX, cropY, cropWidth, cropHeight, scale, angle }) {
	ctx.save();
	ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
	ctx.translate(.5 * ctx.canvas.width, .5 * ctx.canvas.height);
	ctx.rotate(angle * Math.PI / 180);

	ctx.save();
	ctx.globalAlpha = 0.125;
	ctx.scale(scale, scale);
	ctx.translate(-.5 * cropWidth - cropX, -.5 * cropHeight - cropY);
	ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
	ctx.restore();

	ctx.save();
	ctx.scale(scale, scale);
	ctx.translate(-.5 * cropWidth - cropX, -.5 * cropHeight - cropY);
	ctx.drawImage(image, cropX, cropY, cropWidth, cropHeight, cropX, cropY, cropWidth, cropHeight);
	ctx.restore();

	ctx.restore();
}

		</script>
	</body>
</html>


В общем главная тут функция crop (строки 77-97), остальное чтобы показать, как оно действует

Если это действует так как нужно, то достаточно сохранить { cropX, cropY, cropWidth, cropHeight, scale, angle }, чтобы потом заново восстановить картинку.

рони 06.11.2018 11:31

:-? всем спасибо ...


Часовой пояс GMT +3, время: 19:11.