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

Сообщение от Perepelenok
елементы налазяют друг на друга, чаще всего те у которых высота больше ширины, как можно исправить?
Постройте сначала сетку, а потом «встряхните её» слегка, например, масштабом...

<!doctype html>
<html lang="ru">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">

	<style>
		html,
		body {
			margin: 0;
			height: 100%;
			width: 100%;
			display: flex;
			justify-content: center;
			align-items: center;
		}

		.dragscroll {
			position: relative;
			width: 80%;
			height: 80%;
			border-radius: 0.5em;
			cursor: move;
			color: #fff;
			background: black;
			overflow: auto;
			padding: 0.5em;
			box-sizing: border-box;
		}

		.dragscroll.loading {
			overflow: hidden;
		}

		.dragscroll::-webkit-scrollbar {
			width: 15px;
			height: 15px;
			background: black;
		}

		.dragscroll::-webkit-scrollbar-corner {
			background: black;
		}

		.dragscroll::-webkit-scrollbar-thumb {
			background: rgba(128, 128, 128, 0.5);
			border-radius: 15px;
			border: 2px solid transparent;
			background-clip: content-box;
		}

		.dragscroll img {
			border: 2px solid #fff;
			border-radius: 4px;
			transition: 1s;
			margin: 0.1em;
			object-fit: cover;
			box-sizing: border-box;
			position: absolute;
		}

		.dragscroll>splash-screen {
			position: absolute;
			background: black;
			z-index: 2000;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			height: 100%;
			display: flex;
			justify-content: center;
			align-items: center;
			cursor: default;
		}

		.dragscroll progress {
			-webkit-appearance: none;
			appearance: none;
			border: none;
			width: 50%;
			height: 20px;
			background-color: #222;
			border-radius: 10px;
			color: #222;
			position: relative;
			margin: 0 0 1.5em;
		}

		.dragscroll progress::-webkit-progress-bar {
			background: #222;
			border-radius: 10px;
		}

		.dragscroll progress::-webkit-progress-value {
			position: relative;
			background: #666;
			border-radius: 10px;
		}

		.dragscroll progress::-moz-progress-bar {
			background: #666;
			border-radius: 10px;
		}
	</style>

	<script>
		const SELECTOR = ".dragscroll";
		const GAP = 5;
		const MAX_WIDTH = 320;
		const INNER_SCALE_Y = 2.5;
		document.addEventListener("DOMContentLoaded", event => {
			for (const root of document.querySelectorAll(SELECTOR)) {
				let processed = 0;
				root.classList.add("loading");
				const rects = Array.from(root.querySelectorAll("img"), image => {
					return {
						width: image.naturalWidth || 1,
						height: image.naturalHeight || 1,
						element: image
					};
				});
				for (const rect of rects) {
					rect.element.addEventListener("load", event => {
						rect.element.style.transform = `scale(${0.7 + 0.3 * Math.random()})`;
						rect.width = rect.element.naturalWidth;
						rect.height = rect.element.naturalHeight;
						updateProcessed();
					});
					rect.element.addEventListener("error", updateProcessed);
				}
				data.push([root, rects]);

				function updateProcessed() {
					processed++;
					progressBar.value = processed / rects.length;
					if (processed == rects.length) {
						renderAllRects();
						root.classList.remove("loading");
						splashScreen.remove();
					}
				}
				const splashScreen = document.createElement("splash-screen");
				root.append(splashScreen);
				const progressBar = document.createElement("progress");
				splashScreen.append(progressBar);
			}
		});
		addEventListener("resize", renderAllRects);
		const data = [];

		function renderAllRects() {
			for (const datum of data)
				renderRects(...datum);
		}

		function renderRow({
			x,
			y,
			row,
			GAP,
			root
		}) {
			const rowHeight = y;
			const ratio = Math.min((INNER_SCALE_Y * root.clientHeight - (row.length + 1) * GAP) / rowHeight, 1);
			let rowY = GAP;
			row.forEach(({
				width,
				height,
				element
			}) => {
				element.style.cssText += `
				position: absolute;
				top: ${rowY}px;
				left: ${x}px;
				width: ${ratio * width}px;
				height: ${ratio * height}px;
			`;
				rowY += ratio * height + GAP;
			});
			return ratio;
		}

		function renderRects(root, rects) {
			let x = GAP,
				y = 0,
				row = [];
			rects.forEach(({
				width,
				height,
				element
			}) => {
				const scaledHeight = (MAX_WIDTH / width) * height;
				y += scaledHeight;
				row.push({
					height: scaledHeight,
					width: MAX_WIDTH,
					element
				});
				if (y >= INNER_SCALE_Y * root.clientHeight) {
					const ratio = renderRow({
						x,
						y,
						row,
						GAP,
						root
					});
					row = [];
					y = 0;
					x += ratio * MAX_WIDTH + GAP;
				}
			});
			renderRow({
				x,
				y,
				row,
				GAP,
				root
			});
		}
		document.addEventListener("DOMContentLoaded", event => {
			let node, isActive = false,
				x, y;

			function mousedown(event) {
				event.preventDefault();
				node = this;
				isActive = true;
				x = event.screenX;
				y = event.screenY;
				addEventListener("mousemove", mousemove);
				addEventListener("mouseup", mouseup);
			}

			function mousemove(event) {
				event.preventDefault();
				node.scrollBy((x - (x = event.screenX)) / devicePixelRatio, (y - (y = event.screenY)) / devicePixelRatio);
			}

			function mouseup(event) {
				isActive = false;
				removeEventListener("mousemove", mousemove);
				removeEventListener("mouseup", mouseup);
			}
			for (const node of document.querySelectorAll(SELECTOR)) {
				node.addEventListener("mousedown", mousedown);
			}
		});
	</script>

</head>

<body>
	<div class="dragscroll">
		<script>
			for (var i = 0, w, h; i < 50; i++) {
				w = Math.round(320 + 160 * Math.random());
				h = Math.round(100 + 400 * Math.random());
				document.write(`<img src="https://loremflickr.com/${w}/${h}/kitty,kitten?random=${i}">`);
			}
		</script>
	</div>
</body>

</html>

Последний раз редактировалось Malleys, 02.05.2020 в 20:50. Причина: Добавил экран загрузки изображении, т. к. динамическое обновление сетки выглядит ужасно, а сейчас правильная сетка сразу
Ответить с цитированием