Бесконечная индивидуальная анимация div - PullRequest
1 голос
/ 17 июня 2020

Я хотел бы анимировать поведение моих эскизов div-ов. Я хочу, чтобы каждый отдельный div двигался по-разному. Сама сетка также имеет бесконечную прокрутку в обоих направлениях. На данный момент у меня возникла следующая проблема:

  • Все элементы div перемещаются в левую часть страницы
  • В какой-то момент анимация останавливается
  • Иногда сетка мерцает во время первой начальной прокрутки

Результат можно увидеть на этом пером: https://codepen.io/Dennisade/pen/OJymaKZ

Вот как я настроил css :

CSS:

.grid-image {
  text-align: center;
  width: 50%;
  margin-bottom: 18%;
  pointer-events: none;
  will-change: transform;
  transition: 20s linear
}

JS

//MOVING ANIMATION

setInterval(function() {
    $('.grid-image').each(function(index){
        var yAxis= index * Math.floor(Math.random()-2);
        var xAxis= index * Math.floor(Math.random()-1);
        $('.grid-image').css('transform', 'matrix(1, 0, 0, 1, ' + yAxis + ',' + xAxis + ')');
    });
}, 50);


//ENDLESS SCROLL

var origDocHeight = document.body.offsetHeight;

var clone = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone.prependTo(".wrapper");

$(document).scroll(function(){ 

    var scrollWindowPos = $(document).scrollTop(); 

    if(scrollWindowPos >= origDocHeight ) { 
        $(document).scrollTop(0); 
    }
    if(scrollWindowPos <= 0 ) { 
         $(document).scrollTop(origDocHeight); 
     }        
});

1 Ответ

0 голосов
/ 07 сентября 2020

здесь, кажется, есть две отдельные части. Во-первых, div движется неправильно, а затем вообще перестает двигаться. Во-вторых, прокрутка не работает должным образом.

Сначала посмотрим на движение div:

Я не знаком с jquery, но одна из ваших проблем, похоже, заключается в том, что эта строка

$('.grid-image').css('transform', 'matrix(1, 0, 0, 1, ' + yAxis + ',' + xAxis + ')');

не обновляет настройки преобразования для текущего элемента, но изменяет CSS для всех элементов класса grid-image. Чтобы гарантировать, что каждый div получит свою новую матрицу, вы можете изменить указанную выше строку на

this.style.transform='matrix(1, 0, 0, 1, ' + yAxis + ',' + xAxis + ')';//incidentally did you want the x and y this way round?

. Другая проблема заключается в том, что все div, кроме первого, по-прежнему будут иметь одинаковые xAxis и yAxis в своей матрице преобразования. Это связано с тем, что Math.floor (Math.random ()) эквивалентен Math.floor (Math.random () * 1), который дает случайное целое число от 0 (включительно) до 1 (исключая), поэтому оно всегда равно 0. В зависимости от того, насколько большими вы хотите, чтобы эти значения были, вы можете использовать более высокое целое число. Например, Math.floor (Math.random () * 10) дает случайное целое число от 0 до 9.

Я не знаю, планировали вы это или нет, но первый div никогда не получит своего преобразования изменен, поскольку его индекс равен 0, поэтому в этих строках всегда задаются xAxis и yAxis = 0

var yAxis= index * Math.floor(Math.random()-2);
var xAxis= index * Math.floor(Math.random()-1);

Добавление 1 к индексу, например, обеспечит получение первого div нового значения.

Теперь При более внимательном рассмотрении вычислений для осей, матрица преобразования CSS интерпретирует два последних своих параметра как translateX и translateY. Они относятся к текущему положению элемента. В оригинале значения всегда были отрицательными, поэтому все элементы постепенно сдвигались влево и (что менее заметно, так как приращение было меньше) вверх.

При использовании вашего Codepen мой ноутбук стал очень горячим, вентилятор сходил с ума - при матричном преобразовании такого количества элементов 20 раз в секунду происходит много вычислений. Я попытался смягчить это, заметив, что вы не масштабируете или не наклоняете элементы, поэтому подойдет преобразование translate вместо преобразования матрицы.

Объединение этих вещей, если мы заменим вызов setInterval на

setInterval(function() {
    $('.grid-image').each(function(index){
        var yAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
        var xAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
        this.style.transform='translate('+xAxis+'px,'+yAxis+'px)';
    });
}, 50);

мы получаем случайное движение всех div. Количество движения, конечно, зависит как от временного интервала, так и от вычислений для приращений x и y, и у меня здесь * 1000, чтобы получить легко заметное движение. Его должно быть больше, если вы хотите, чтобы элементы больше перемещались по экрану. Я сохранил индекс в расчетах, но не уверен, что вы рассчитывали именно так - элементы ниже перемещаются больше, чем те, что вверху, а затем, когда вы прокручиваете, вы снова обнаруживаете более медленные (так что общий эффект должен иметь намек на узор, а не на полную случайность). Используя этот код, я не видел остановки анимации - и запускал ее в течение многих минут. Ноутбук нагрелся, но не так сильно. Я полагаю, может возникнуть вопрос, смогут ли менее мощные процессоры выполнить все преобразования матриц за указанный промежуток времени. Если это окажется проблемой, то переход на setTimeout будет полезным, как и любые CSS изменения, поощряющие использование графических процессоров.

Надеюсь, это поможет с вашими первыми двумя пунктами.

А теперь перейдем к посмотрите на прокрутку. Этот код

var clone = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone.prependTo(".wrapper");

помещает только одну копию содержимого div в div .wrapper. Я думаю, это потому, что он добавляется, а затем добавляется, что означает, что он больше не добавляется, т.е. он не может быть в двух местах одновременно. Замена этого кода на этот код дает 3 копии содержимого div, которые, как я думаю, вы знаете, будет достаточно для размеров дисплея, на котором будет использоваться ваш код

var clone = $(".wrapper").contents().clone();
var clone2 = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone2.prependTo(".wrapper");

Прокрутка назад теперь работает, но вперед есть проблема. В этом коде

$(document).scroll(function(){ 

    var scrollWindowPos = $(document).scrollTop(); 

    if(scrollWindowPos >= origDocHeight ) { 
        $(document).scrollTop(0); 
    }
    if(scrollWindowPos <= 0 ) { 
         $(document).scrollTop(origDocHeight); 
     }        
});

где scrollWindowPos> = origDocHeight он прокручивается до 0, что означает, что в следующий раз scrollWindowPos <= 0 истинно, и он перескакивает. Замена на этот код включает прокрутку вперед </p>

$ (document) .scroll (function () {

var scrollWindowPos = $(document).scrollTop(); 

if(scrollWindowPos >= origDocHeight ) { 
    $(document).scrollTop(1); /* used to be 0 - using 1 is a bit hacky but it does the job */
}
else if(scrollWindowPos <= 0 ) { 
     $(document).scrollTop(origDocHeight); 
 }        

});

Это не идеально. Прокрутка, захватывая полосу прокрутки и перемещая ее вниз, вызывает «мигание», но прокрутка путем выбора стрелки вниз на полосе прокрутки дает плавную прокрутку, без миганий (Windows 10, Edge и Chrome). В настоящий момент я не могу думать, как исследовать это дальше.

Мне пришлось удалить display: none на теле, которое находится в CSS на Codepen, чтобы получить полосу прокрутки, поэтому он может быть, я неправильно понял, что вы хотели от прокрутки.

Вот полный код JS со всеми вышеперечисленными изменениями

//MOVING ANIMATION

    setInterval(function() {
        $('.grid-image').each(function(index){
            var yAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
            var xAxis= (index+1) * Math.floor(Math.random()*1000) * (Math.random() < 0.5 ? -1 : 1);
            this.style.transform='translate('+xAxis+'px,'+yAxis+'px)';
        });
    }, 50);

//ENDLESS SCROLL

var origDocHeight = document.body.offsetHeight;
var clone1 = $(".wrapper").contents().clone();
var clone = $(".wrapper").contents().clone();
clone.appendTo(".wrapper");
clone1.prependTo(".wrapper");

$(document).scroll(function(){ 

    var scrollWindowPos = $(document).scrollTop(); 

    if(scrollWindowPos >= origDocHeight ) { 
        $(document).scrollTop(1); 
    }
    else if(scrollWindowPos <=0 ) { 
              $(document).scrollTop(origDocHeight); 
     }        
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...