Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.04.2020, 13:00
Интересующийся
Отправить личное сообщение для Perepelenok Посмотреть профиль Найти все сообщения от Perepelenok
 
Регистрация: 16.07.2016
Сообщений: 26

Случайное положение дочерних елементов
Всем привет! Есть скрипт, дающий возможность зажиманием мышки передвигаться( скролить блок), и рандомно распологая дочерние елементы (img) в этом блоке. Картинок будет много. Как расположить дочерние елементы рандомно, но с растоянием между ними? Проблема на картинках :

Так на данный момент


как добиться этого?


Вот разметка:

<style>
.dragscroll{
    position:relative;
    overflow: hidden;
    width: 100%;
    height: 100vh;
    padding: 20px;
    cursor: -webkit-grab;
    cursor: -moz-grab;
    cursor: -o-grab;
    cursor: grab;
    color: #fff;
    }

</style>
<div class="dragscroll">	
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
 <img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
</div>


И вот сам скрипт

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['exports'], factory);
    } else if (typeof exports !== 'undefined') {
        factory(exports);
    } else {
        factory((root.dragscroll = {}));
    }
}(this, function (exports) {
    var _window = window;
    var _document = document;
    var mousemove = 'mousemove';
    var mouseup = 'mouseup';
    var mousedown = 'mousedown';
    var EventListener = 'EventListener';
    var addEventListener = 'add'+EventListener;
    var removeEventListener = 'remove'+EventListener;
    var newScrollX, newScrollY;

    var dragged = [];
    var reset = function(i, el) {
        for (i = 0; i < dragged.length;) {
            el = dragged[i++];
            el = el.container || el;
            el[removeEventListener](mousedown, el.md, 0);
            _window[removeEventListener](mouseup, el.mu, 0);
            _window[removeEventListener](mousemove, el.mm, 0);
        }

        // cloning into array since HTMLCollection is updated dynamically
        dragged = [].slice.call(_document.getElementsByClassName('dragscroll'));
        for (i = 0; i < dragged.length;) {
            (function(el, lastClientX, lastClientY, pushed, scroller, cont){
                (cont = el.container || el)[addEventListener](
                    mousedown,
                    cont.md = function(e) {
                        if (!el.hasAttribute('nochilddrag') ||
                            _document.elementFromPoint(
                                e.pageX, e.pageY
                            ) == cont
                        ) {
                            pushed = 1;
                            lastClientX = e.clientX;
                            lastClientY = e.clientY;

                            e.preventDefault();
                        }
                    }, 0
                );

                _window[addEventListener](
                    mouseup, cont.mu = function() {pushed = 0;}, 0
                );

                _window[addEventListener](
                    mousemove,
                    cont.mm = function(e) {
                        if (pushed) {
                            (scroller = el.scroller||el).scrollLeft -=
                                newScrollX = (- lastClientX + (lastClientX=e.clientX));
                            scroller.scrollTop -=
                                newScrollY = (- lastClientY + (lastClientY=e.clientY));
                            if (el == _document.body) {
                                (scroller = _document.documentElement).scrollLeft -= newScrollX;
                                scroller.scrollTop -= newScrollY;
                            }
                        }
                    }, 0
                );
             })(dragged[i++]);
        }
    }

      
    if (_document.readyState == 'complete') {
        reset();
    } else {
        _window[addEventListener]('load', reset, 0);
    }

    exports.reset = reset;
}));

$( document ).ready(function() {
    $( '.dragscroll img' ).each(function() {

        $holder    = $(this).parent();
        $divWidth  = $holder.width();
        $divHeight = $holder.height();

           $(this).css({
                'left': Math.floor( Math.random() * Number( $divWidth ) ),
                'top' : Math.floor( Math.random() * Number( $divHeight ) )
           });        

    })
});

Последний раз редактировалось Perepelenok, 29.04.2020 в 13:14.
Ответить с цитированием
  #2 (permalink)  
Старый 29.04.2020, 14:22
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

Perepelenok,
https://javascript.ru/forum/misc/351...tml#post230736
Ответить с цитированием
  #3 (permalink)  
Старый 29.04.2020, 15:32
Интересующийся
Отправить личное сообщение для Perepelenok Посмотреть профиль Найти все сообщения от Perepelenok
 
Регистрация: 16.07.2016
Сообщений: 26

Сообщение от рони Посмотреть сообщение
Perepelenok,
https://javascript.ru/forum/misc/351...tml#post230736
Спасибо. Подскажи, как сделать без ограничения пространства, и как функцию направить для уже заранее созданых елементов, с заданой высотой и шириной, а не создавать их? Пробую - не получается никак(

Последний раз редактировалось Perepelenok, 29.04.2020 в 15:44.
Ответить с цитированием
  #4 (permalink)  
Старый 29.04.2020, 16:19
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

Perepelenok,
1. проверять координаты на пересечение и генерировать новые, если условие не подходит.
или
2.делать сетку (таблицу) и вставлять в ячейки со сдвигом.
других вариантов не знаю. https://javascript.ru/forum/dom-wind...tml#post523032
Ответить с цитированием
  #5 (permalink)  
Старый 29.04.2020, 16:21
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

Сообщение от Perepelenok
<img src="image.jpg  width="200px" height="auto" style="position:absolute;"></img>
на всякий случай, в src здесь чего-то не хватает, а закрывающий тег лишний.
Ответить с цитированием
  #6 (permalink)  
Старый 29.04.2020, 18:05
Интересующийся
Отправить личное сообщение для Perepelenok Посмотреть профиль Найти все сообщения от Perepelenok
 
Регистрация: 16.07.2016
Сообщений: 26

Сообщение от рони Посмотреть сообщение
Perepelenok,
1. проверять координаты на пересечение и генерировать новые, если условие не подходит.
или
2.делать сетку (таблицу) и вставлять в ячейки со сдвигом.
других вариантов не знаю. https://javascript.ru/forum/dom-wind...tml#post523032
https://codepen.io/kotya_ra/pen/pojrNxN

Можешь, если свободное время есть, написать код? А то я совсем никак разобраться не могу(

Последний раз редактировалось Perepelenok, 29.04.2020 в 18:15.
Ответить с цитированием
  #7 (permalink)  
Старый 29.04.2020, 19:42
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

рандомный вывод блоков без наложения по сетке
Perepelenok,

<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
html, body{
width: 100%;
height: 100vh;
}
.dragscroll{
    position:relative;
    width: 100%;
    height: 100vh;
    padding: 20px;
    cursor: -webkit-grab;
    cursor: -moz-grab;
    cursor: -o-grab;
    cursor: grab;
    color: #fff;
    }
.dragscroll img{
position:absolute;

}
    </style>

  <script>
window.addEventListener( "load" , function() {
var parent = document.querySelector(".dragscroll");
var imgs = parent.querySelectorAll("img");
var arrayOfSectors = [],
    column = parent.scrollWidth / 250 | 0,
    length = imgs.length,
    row = length / column | 0,
    sectorWidth = Math.max(parent.scrollWidth / column , 200),
    sectorHeight = Math.max(parent.scrollHeight / row , 180) ;
    console.log(column, row, length)
function getPos() {
    if (!arrayOfSectors.length) {
        arrayOfSectors = Array.from({
            length
        }, (v, i) => i);

    }
    var i = arrayOfSectors.splice((Math.random() * arrayOfSectors.length | 0), 1)[0];
    var h = i / column | 0;
    var w = i % column;
    var left = sectorWidth * w,
        top = sectorHeight * h;
    return {left, top}
}
imgs.forEach(img => {
var {style} = img;
var {left, top} = getPos(); console.log(left, top)
var {width, height} = img.getBoundingClientRect();
left += Math.floor((Math.random() * (sectorWidth - width)));
top += Math.floor((Math.random() * (sectorHeight - height)));
left += "px";
top += "px";
Object.assign(style, {left, top})
})

 });
  </script>

</head>
<body>
<div class="dragscroll">
 <img src="https://ichef.bbci.co.uk/news/1024/cpsprodpb/83D7/production/_111515733_gettyimages-1208779325.jpg"  width="200px" height="auto">
 <img src="https://sjferret.com/wp-content/uploads/Thinking-of-getting-a-cat.png"  width="200px" height="auto">
   <img src="https://img.webmd.com/dtmcms/live/webmd/consumer_assets/site_images/article_thumbnails/other/cat_relaxing_on_patio_other/1800x1200_cat_relaxing_on_patio_other.jpg"  width="200px" height="auto">
     <img src="https://www.interfax.ru/ftproot/textphotos/2019/05/17/700gc.jpg"  width="200px" height="auto">
   <img src="https://ichef.bbci.co.uk/news/1024/cpsprodpb/83D7/production/_111515733_gettyimages-1208779325.jpg"  width="200px" height="auto">
 <img src="https://sjferret.com/wp-content/uploads/Thinking-of-getting-a-cat.png"  width="200px" height="auto">
   <img src="https://img.webmd.com/dtmcms/live/webmd/consumer_assets/site_images/article_thumbnails/other/cat_relaxing_on_patio_other/1800x1200_cat_relaxing_on_patio_other.jpg"  width="200px" height="auto">
     <img src="https://www.interfax.ru/ftproot/textphotos/2019/05/17/700gc.jpg"  width="200px" height="auto">
   <img src="https://ichef.bbci.co.uk/news/1024/cpsprodpb/83D7/production/_111515733_gettyimages-1208779325.jpg"  width="200px" height="auto">
 <img src="https://sjferret.com/wp-content/uploads/Thinking-of-getting-a-cat.png"  width="200px" height="auto">
   <img src="https://img.webmd.com/dtmcms/live/webmd/consumer_assets/site_images/article_thumbnails/other/cat_relaxing_on_patio_other/1800x1200_cat_relaxing_on_patio_other.jpg"  width="200px" height="auto">
     <img src="https://www.interfax.ru/ftproot/textphotos/2019/05/17/700gc.jpg"  width="200px" height="auto">
   <img src="https://ichef.bbci.co.uk/news/1024/cpsprodpb/83D7/production/_111515733_gettyimages-1208779325.jpg"  width="200px" height="auto">
 <img src="https://sjferret.com/wp-content/uploads/Thinking-of-getting-a-cat.png"  width="200px" height="auto">
   <img src="https://img.webmd.com/dtmcms/live/webmd/consumer_assets/site_images/article_thumbnails/other/cat_relaxing_on_patio_other/1800x1200_cat_relaxing_on_patio_other.jpg"  width="200px" height="auto">
     <img src="https://www.interfax.ru/ftproot/textphotos/2019/05/17/700gc.jpg"  width="200px" height="auto">
   <img src="https://ichef.bbci.co.uk/news/1024/cpsprodpb/83D7/production/_111515733_gettyimages-1208779325.jpg"  width="200px" height="auto">
 <img src="https://sjferret.com/wp-content/uploads/Thinking-of-getting-a-cat.png"  width="200px" height="auto">
   <img src="https://img.webmd.com/dtmcms/live/webmd/consumer_assets/site_images/article_thumbnails/other/cat_relaxing_on_patio_other/1800x1200_cat_relaxing_on_patio_other.jpg"  width="200px" height="auto">
     <img src="https://www.interfax.ru/ftproot/textphotos/2019/05/17/700gc.jpg"  width="200px" height="auto">
   <img src="https://ichef.bbci.co.uk/news/1024/cpsprodpb/83D7/production/_111515733_gettyimages-1208779325.jpg"  width="200px" height="auto">
 <img src="https://sjferret.com/wp-content/uploads/Thinking-of-getting-a-cat.png"  width="200px" height="auto">
   <img src="https://img.webmd.com/dtmcms/live/webmd/consumer_assets/site_images/article_thumbnails/other/cat_relaxing_on_patio_other/1800x1200_cat_relaxing_on_patio_other.jpg"  width="200px" height="auto">
     <img src="https://www.interfax.ru/ftproot/textphotos/2019/05/17/700gc.jpg"  width="200px" height="auto">

</div>
</body>
</html>

Последний раз редактировалось рони, 29.04.2020 в 21:46.
Ответить с цитированием
  #8 (permalink)  
Старый 30.04.2020, 00:41
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

вывод картинок без наложения
Perepelenok,
показ всех картинок не гарантирован, можно задать время поиска свободных мест(строка 119), изменение фона это конец "поиска", можно таскать за чёрный фон.
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>

    <style type="text/css">

.dragscroll{
    overflow: hidden;
    position:relative;
    width: 100vw;
    height: 100vh;
    cursor: -webkit-grab;
    cursor: -moz-grab;
    cursor: -o-grab;
    cursor: grab;
    color: #fff;
    }
.dragscroll img{
position:absolute;
width: 200px;
opacity: 0;
left: 50%;
top: 50%;
box-sizing: border-box;
display: block;
}
.dragscroll img.add{
transition: 1s;
opacity: 1;

}
.dragscroll.add{
    background-color: #000000;
}
.dragscroll.add img.add{
    border: 2px solid #FFFFFF;
    border-radius: 4px;
}

#app{
max-width: 600px;
height: 400px;
box-shadow: 0 0 1em black;
overflow: hidden;
border-radius: 4px;
margin: 20px auto;
}

</style>

  <script>
window.addEventListener("load", function() {
    function random(length) {
        return Math.trunc(Math.random() * length)
    }

    function dataAcquisition(parent, elem) {
        var width = elem.offsetWidth + 6;
        var height = elem.offsetHeight + 6;
        var left = random(parent.clientWidth - width);
        var top = random(parent.clientHeight - height);
        return [left, top, width, height]
    }

    function collisionDetection(x1, y1, w1, h1, x2, y2, w2, h2) {
        return x1 < x2 + w2 && y1 < y2 + h2 && x1 + w1 > x2 && y1 + h1 > y2
    }

    function reshuffle(parent, duration) {
        cancelAnimationFrame(timer);
        parent.classList.remove("add");
        var imgs = [...parent.querySelectorAll("img")];
        imgs.forEach(elem => elem.classList.remove("add"));
        var beginTime = performance.now();
        var arrayAdd = [];

        function addPos(currentTime) {
            var i = random(imgs.length);
            var elem = imgs[i];
            var {style} = elem;
            var a = dataAcquisition(parent, elem);
            var add = arrayAdd.every(b => !collisionDetection(...a, ...b))
            if (add) {
                var w = (parent.clientWidth  - a[0])/2, h = (parent.clientHeight - a[1])/2, temp = a.slice(0);
                for (var k = 0; k < 1; k+= .05) {
                var c = a.slice(0);
                c[1] += (h - c[1]) * k;
                add = arrayAdd.every(b => !collisionDetection(...c, ...b));
                if(add) temp = c.slice(0);
                else break;
                };
                a = temp.slice(0);
                for (var k = 0; k < 1; k+= .05) {
                var c = a.slice(0);
                c[0] += (w - c[0]) * k;
                add = arrayAdd.every(b => !collisionDetection(...c, ...b));
                if(add) temp = c.slice(0);
                else break;
                };



                arrayAdd.push(temp);
                imgs.splice(i, 1);
                var [left, top] = temp;
                left += "px";
                top += "px";
                Object.assign(style, {left, top});
                elem.classList.add("add")
            };
            if (imgs.length && currentTime - beginTime < duration) timer = requestAnimationFrame(addPos);
            else parent.classList.add("add");
        }
       timer = requestAnimationFrame(addPos)
    }
    var parent = document.querySelector(".dragscroll");
    var duration = 10 * 1000;
    reshuffle(parent, duration);
    var timer;
    window.addEventListener("resize", function() {
        cancelAnimationFrame(timer);
        clearTimeout(timer);
        timer = window.setTimeout(() => reshuffle(parent, duration), 100)
    });
    var _startX, _startY, _scrollLeft, _scrollTop;
    function pointerHandler(event)
    {
      const { screenX, screenY } = event;

        if(event.type === "pointerdown") {
            document.addEventListener("pointermove", pointerHandler);
            document.addEventListener("pointerup", pointerHandler);

            _startX = screenX;
            _startY = screenY;

            _scrollLeft = app.scrollLeft;
            _scrollTop = app.scrollTop;
        }

        if(event.type === "pointerup") {
            document.removeEventListener("pointermove", pointerHandler);
            document.removeEventListener("pointerup", pointerHandler);
        }

        if(event.type === "pointermove") {
            const dx = (screenX - _startX) ;
            const dy = (screenY - _startY) ;
            app.scrollLeft = _scrollLeft - dx;
            app.scrollTop = _scrollTop - dy;
        }

        event.preventDefault();
    }

    var app = document.querySelector("#app");
    app.addEventListener("pointerdown", pointerHandler);



});
  </script>

</head>
<body>
<div id="app">
<div class="dragscroll">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=1" alt="">
<img src="https://loremflickr.com/320/400/kitty,kitten?random=2" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=3" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=4" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=5" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=6" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=7" alt="">
<img src="https://loremflickr.com/320/400/kitty,kitten?random=8" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=9" alt="">
<img src="https://loremflickr.com/320/500/kitty,kitten?random=10" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=11" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=12" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=13" alt="">
<img src="https://loremflickr.com/320/400/kitty,kitten?random=14" alt="">
<img src="https://loremflickr.com/320/100/kitty,kitten?random=15" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=16" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=17" alt="">
<img src="https://loremflickr.com/320/400/kitty,kitten?random=18" alt="">
<img src="https://loremflickr.com/320/200/kitty,kitten?random=19" alt="">
<img src="https://loremflickr.com/320/100/kitty,kitten?random=20" alt="">
</div>
</div>
</body>
</html>

Последний раз редактировалось рони, 30.04.2020 в 11:27.
Ответить с цитированием
  #9 (permalink)  
Старый 02.05.2020, 14:01
Интересующийся
Отправить личное сообщение для Perepelenok Посмотреть профиль Найти все сообщения от Perepelenok
 
Регистрация: 16.07.2016
Сообщений: 26

Спасибо огромное тебе! Очень выручил, вопрос по 1 коду еще - иногда
елементы налазяют друг на друга, чаще всего те у которых высота больше ширины, как можно исправить? Сейчас код такой, я поигрался со значениями, чтобы больший промежуток был между элементами...И по 2му - как сделать, чтобы елементы появлялись в нограниченом количестве и пространстве?Сенк ю еще раз)

window.addEventListener( "load" , function() {
var parent = document.querySelector(".dragscroll");
var imgs = parent.querySelectorAll("div.item");
var arrayOfSectors = [],
    column = parent.scrollWidth / 2000| 15,
    length = imgs.length,
    row = length / column | 0,
    sectorWidth = Math.max(parent.scrollWidth / column , 1000),
    sectorHeight = Math.max(parent.scrollHeight / row , 800) ;
function getPos() {
    if (!arrayOfSectors.length) {
        arrayOfSectors = Array.from({
            length
        }, (v, i) => i);

    }
    var i = arrayOfSectors.splice((Math.random() * arrayOfSectors.length | 0), 1)[0];
    var h = i / column | 0;
    var w = i % column;
    var left = sectorWidth * w + 200,
        top = sectorHeight * h;
    return {left, top}
}
imgs.forEach(img => {
var {style} = img;
var {left, top} = getPos();
var {width, height} = img.getBoundingClientRect();
left += Math.floor((Math.random() * (sectorWidth - width)));
top += Math.floor((Math.random() * (sectorHeight - height)));
left += "px";
top += "px";
Object.assign(style, {left, top})
})
 });
Ответить с цитированием
  #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. Причина: Добавил экран загрузки изображении, т. к. динамическое обновление сетки выглядит ужасно, а сейчас правильная сетка сразу
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Возвращение в исходное положение страницы alex72bel Javascript под браузер 0 25.07.2015 02:04
вибрать всех елементов кроме заданного () dadli Общие вопросы Javascript 2 15.06.2012 16:45
jQuery. Положение всех элементов Valdemor Общие вопросы Javascript 1 05.06.2012 15:09
Блокировка событий всех дочерних элементов moreo Элементы интерфейса 4 26.05.2012 23:58