Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Перетаскивание нижнего слоя (по z-index) (https://javascript.ru/forum/events/79929-peretaskivanie-nizhnego-sloya-po-z-index.html)

Newb 08.04.2020 18:21

Перетаскивание нижнего слоя (по z-index)
 
Доброго времени, форум. Не знаю, как правильно сформулировать задачу, поясню на примере.

Имеем 2 картинки, одна глухая с прозрачным кругом в середине (считай, иллюминатор, другая фон моря.

<img src="bg.jpg" id="draggable">
<canvas id="okno"></canvas>


Канвас с абсолютным позиционированием, чтобы накрывал собой море, оставляя в середине за счет прозрачности кусок (круг) моря.

Вопрос в функции draggable(). Если тащить фон (море) за края, выходящие за предел canvas, то перетаскивание норм. Но на самом канвасе я, само собой, таскать фон не могу, т.к. у канваса z-index выше.

Направьте, за счет чего можно сохранить порядок, при этом иметь возможность перетаскивать фон при нажатии в области canvas?

voraa 08.04.2020 18:50

Что за функция draggable()?
Тащить надо фон (img) отдельно от "илюминатора" (canvas) или вместе с ним?

Newb 08.04.2020 21:56

Цитата:

Сообщение от voraa (Сообщение 522476)
Что за функция draggable()?

$('#draggable').draggable();
Цитата:

Сообщение от voraa (Сообщение 522476)
Тащить надо фон (img) отдельно от "илюминатора" (canvas) или вместе с ним?

Отдельно. Фон "физически" лежит под канвасом. Выступающие области фона за канвас перетягиваются, на самом канвасе нет (и я понимаю, что так и должно быть).

Мне сложно сформулировать, т.к. я PHP программер и по части jquery работал прежде только с hide(),show() для мобильной адаптации и ajax-запросы.

Но тут задача требует прохождения этого этапа. Само собой, я сяду за полноценное изучение jquery, но хотелось бы уже разгрузить голову от этого момента.

Вот, что видится мне, но не знаю какие функции для этого изучать.

1. Есть главный блок (div), в котором лежат и canvas, и фон.
2. draggable вешаю на на главный div
3. При обработке события dragabble на главном диве событие переназначается фону.

Так возможно?

voraa 09.04.2020 12:01

Как это сделать с jquery и draggable я не знаю
Но в принципе идея верная. Но надо на главный div вешать события mousedown, mousemove, mouseup и по ним двигать фон
Как то так получается
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" lang="ru">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" >
 <style>
img {
	position: absolute;
	display: block;
	width: 300px;
	left: 150px;
	top: 100px;
}
canvas {
	position: absolute;
}

 
 </style>
<script>
document.addEventListener('DOMContentLoaded', async () => {
let par, fon, okno;

const imgloaded = (img) => {
	return new Promise ((res, rej) => {
		if (img.complete) res (img)
		img.onload = () => res (img)
	})
}

const drawokno = () => {
	const ctx = okno.getContext('2d')
	const w = okno.offsetWidth;
	const h = okno.offsetHeight;
	ctx.fillStyle = '#c0c0c0';
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(w, 0);
    ctx.lineTo(w, h);
    ctx.lineTo(0, h);
    ctx.lineTo(0, 0);
	ctx.arc(w/2, h/2, h/2, 0, Math.PI * 2, true);
	ctx.fill('nonzero');
}


const drag = () => {
	let x, y; 
	const msmove = (ev) => {
		let dx = ev.clientX - x;
		let dy = ev.clientY - y;
		fon.style.left = parseFloat(getComputedStyle(fon).left) + dx +'px';
		fon.style.top = parseFloat(getComputedStyle(fon).top) + dy +'px';
		x += dx;
		y += dy;
		ev.preventDefault()
	}

	const msup = (ev) => {
		par.removeEventListener ('mousemove', msmove)
		par.removeEventListener ('mouseup', msup)
	}
	
	par.addEventListener ('mousedown', (ev) => {
		const cr = fon.getBoundingClientRect()
		x = ev.clientX;
		y = ev.clientY;
		if (x < cr.left || cr.right < x || y < cr.top || cr.bottom < y) return;
		par.addEventListener ('mousemove', msmove)
		par.addEventListener ('mouseup', msup)
		ev.preventDefault()		  
	})
}
	
	
	fon = document.getElementById('fon')
	par = document.getElementById('par')
	okno = document.getElementById('okno')
	await imgloaded (fon)
		let fonst = getComputedStyle(fon)
		okno.style.left = fonst.left;
		okno.style.top = fonst.top;
		okno.width = parseFloat(fonst.width);
		okno.height = parseFloat(fonst.height);
		drawokno ()
		drag ()
})
</script>
</head>
<body>
<div id='par'>
	<img src="https://images.aif.ru/011/938/71c8b30142a321f2696bbf49a635d1c2.jpg" id="fon">
	<canvas id='okno'></canvas>
</body>
</html>

Newb 09.04.2020 17:38

Большое спасибо, что потратили время и реализовали. Я параллельно пошел аналогичным путём: подсчет смещения главного дива по осям. Ваш код я изучу подробно в плане функций, но пока продолжаю поиск.

Теперь могу сформулировать вопрос конкретно: как сделать элемент (класс) активным при наведении на область? Чтобы не смотря на вёрстку/позиционирование, произошло обращение к конкретному классу.

Вот еще аналогия на примере фотошопа: имеем несколько слоёв, выделен нижний. При использовании элемента перемещения двигается выделенный слой (нижний).

voraa 09.04.2020 23:28

Цитата:

Сообщение от Newb (Сообщение 522543)
Теперь могу сформулировать вопрос конкретно: как сделать элемент (класс) активным при наведении на область? Чтобы не смотря на вёрстку/позиционирование, произошло обращение к конкретному классу.

Вот еще аналогия на примере фотошопа: имеем несколько слоёв, выделен нижний. При использовании элемента перемещения двигается выделенный слой (нижний).

Не совсем понял вашу терминологию, что такое элемент - понятно. А что вы называете классом? Класс CSS? Что такое активный? Кто должен обращаться к классу? элементу?
Если можно конкретизируйте вопрос

Alexandroppolus 09.04.2020 23:32

Канве задать стиль

pointer-events: none

Тогда она станет прозрачной для мыши, и можно повесить draggable на картинку

Newb 11.04.2020 22:50

Цитата:

Сообщение от Alexandroppolus (Сообщение 522584)
Канве задать стиль

pointer-events: none

Тогда она станет прозрачной для мыши, и можно повесить draggable на картинку

Огромное спасибо!

Newb 11.04.2020 22:51

Цитата:

Сообщение от voraa (Сообщение 522583)
Не совсем понял вашу терминологию, что такое элемент - понятно. А что вы называете классом? Класс CSS? Что такое активный? Кто должен обращаться к классу? элементу?
Если можно конкретизируйте вопрос

Элемент с классом CSS. Активный - кто принимает событие (наведение мыши).

voraa 12.04.2020 07:26

Цитата:

Сообщение от Newb (Сообщение 522543)
Теперь могу сформулировать вопрос конкретно: как сделать элемент (класс) активным при наведении на область? Чтобы не смотря на вёрстку/позиционирование, произошло обращение к конкретному классу.

События от мыши всегда принимает тот элемент, над которым находится курсор. Если элемент перекрывается другим, то можно этот верхний исключить свойством pointer-events: none;, как посоветовал Alexandroppolus.


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