CSS transform: translateX (справа); - PullRequest
       4

CSS transform: translateX (справа);

2 голосов
/ 15 марта 2020

Я хочу создать систему частиц для моей домашней страницы. Синие маленькие круглые точки должны go слева направо, а затем вновь появиться слева, так что получается oop. Изображение частиц

Приведенный ниже код сгенерирует 150 точек, которые имеют различные свойства, такие как скорость цвета и размер, и будут появляться в случайных позициях при загрузке страницы. Либо, зациклив анимацию, либо добавляя новые точки, я хочу продолжать анимацию бесконечно.

// ========== JAVASCRIPT ==========
function Dot(){
    var colors = [
        "#313146",
        "#36364f",
        "#3d3d5c",
        "#404066"
    ];
    var speed = Math.floor(Math.random() * 20) + 2;

    this.obj = document.createElement("div");
    this.obj.classList.add("dot");
    this.obj.style.top = (window.innerHeight * Math.random()) + 'px'; // random Y-position after page load
    this.obj.style.left = (window.innerWidth * Math.random()) + 'px'; // random X-position after page load
    this.size = Math.floor(Math.random() * 5) + 4; // random size
    this.obj.style.height =  this.size + 'px';
    this.obj.style.width = this.size + 'px';
    this.obj.style.backgroundColor = colors[Math.floor(Math.random()*colors.length)]; // random color
    this.obj.style.animation = `move ${speed}s linear`; // start animation
    document.body.appendChild(this.obj);

    setTimeout(del, speed*1000, this.obj); // THIS FUNCTION SHOULD BE REMOVED IF ANIMATION GETS A LOOP
    function del(element) {
        element.parentNode.removeChild(element);
    };
};

for(var i = 0 ; i < 151 ; i++ ){ // creating 150 dots
    new Dot();
};

// ========== CSS ==========

.dot {
    border-radius: 50%;
    z-index: -1;
}

@keyframes move {
    0% {
        transform: translateX(0vw);
    }
    100% {
        transform: translateX(100vw);
    }
}

Моя проблема в том, что, когда точки появляются со случайными позициями, и все они получают transform: translateX(100vw);, они на некоторое время выйдет за пределы экрана, а затем будет удален или снова отображен. Мое второе изображение показывает красным, куда движется точка и куда она должна двигаться.

image

Что я уже пробовал:

1. JS: this.obj.style.animation = `move ${speed}s linear infinite`; добавил бесконечный и удалил код, который удаляет точки.

CSS:

@keyframes move {
    0% {
        transform: translateX(0vw);
    }
    100% {
        transform: translateX(right); 
    }
}

<= Не существует, и не может найти рабочий код равно этой идее. Это было бы решением. </p>

2. Добавление второй анимации с точками, идущими слева, когда другие были удалены. Завершается разрывом между 150 точками первого анимации и входящими точками второй анимации.

Есть ли какая-либо другая возможность перемещения точек слева направо с различными свойствами?

С наилучшими пожеланиями

Ответы [ 2 ]

2 голосов
/ 15 марта 2020

Так как вы устанавливаете положение с помощью JS, вы можете точно знать, где каждый элемент появится, и использовать эту информацию для настройки анимации.

Вот базовый c пример для иллюстрации:

.dot {
  background: blue;
  position:fixed;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  z-index: -1;
  left:var(--x,0px);
  animation:move 2s linear infinite;
}

@keyframes move {
  0% {
    transform: translateX(0vw);
  }
  100% {
    transform: translateX(calc(100vw - var(--x,0px)));
  }
}
<div class="dot" style="top:10px;--x:80px;"></div>

<div class="dot" style="top:20px;--x:150px;"></div>

<div class="dot" style="top:100px;--x:350px;"></div>

Переменная --x определит левую и будет вычтена из 100vw


Для лучшей поддержки и с тех пор, как вы используя JS, вы можете избавиться от calc() и CSS переменных. Просто сделайте небольшое вычисление, чтобы найти значение преобразования.

Вот пример, где я использую jQuery для простоты, но вы можете легко сделать его JS -только кодом:

$('.dot').each(function() {
  $(this).css('transform','translateX('+ ($(window).width() - parseInt($(this).css('left')))+'px)');
});
.dot {
  background: blue;
  position:fixed;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  z-index: -1;
  animation:move 2s linear infinite;
}

@keyframes move {
  0% {
    transform: translateX(0px);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dot" style="top:10px;left:80px;"></div>

<div class="dot" style="top:20px;left:150px;"></div>

<div class="dot" style="top:100px;left:350px;"></div>

Стоит отметить, что вам нужно обновить значение при изменении размера окна


Еще одна идея сохранить l oop Эффект состоит в том, чтобы иметь одинаковую позицию и одинаковую анимацию для всех, и вы настраиваете задержку для имитации другой позиции:

.dot {
  background: blue;
  position:fixed;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  z-index: -1;
  left:0;
  animation:move 2s linear infinite;
}

@keyframes move {
  0% {
    transform: translateX(0px);
  }
  100% {
    transform: translateX(100vw);
  }
}
<div class="dot" style="top:10px;animation-delay:-1s;"></div>

<div class="dot" style="top:20px;animation-delay:-0.1s;animation-duration:1s"></div>

<div class="dot" style="top:100px;animation-delay:-0.5s;animation-duration:4s"></div>

Расчет прост. Если продолжительность анимации составляет D, то задержка в -D/2 будет помещать элемент в центр по существу. -D*0.1 поместит изображение в 10% и т. Д.

1 голос
/ 15 марта 2020

Я бы предложил вам использовать requestAnimationFrame для анимации ваших частиц. Посмотрите на следующий пример. Я добавил метод move к частице, которая вызывается из анимации l oop и изменяет положение частицы. Он также проверяет, достигла ли частица конца экрана, и в этом случае сбрасывает ее положение на -10.

function Dot(){
    var colors = [
        "yellow",
        "red",
        "green",
        "black"
    ];
    this.x = window.innerWidth * Math.random();
    this.speed = Math.floor(Math.random() * 20) + 2;
    this.obj = document.createElement("div");
    this.obj.classList.add("dot");
    this.obj.style.position = "fixed";
    this.obj.style.top = (window.innerHeight * Math.random()) + 'px'; 
    this.obj.style.left = this.x + 'px'; 
    this.size = Math.floor(Math.random() * 5) + 4; // random size
    this.obj.style.height =  this.size + 'px';
    this.obj.style.width = this.size + 'px';
    this.obj.style.background = colors[Math.floor(Math.random()*colors.length)]; // random color
    document.body.appendChild(this.obj);
    this.move = function() {
      this.x += this.speed;
      if (this.x > window.innerWidth) {
        this.x = -10;
      }
      this.obj.style.left = this.x + 'px';
    };
};

var dots = Array.apply(null, Array(150)).map(a => new Dot());

requestAnimationFrame(paint);

function paint() {
  requestAnimationFrame(paint);
  for (dot of dots) {
    dot.move();
  }
}
.dot {
    border-radius: 50%;
    z-index: -1;
}

Я также рекомендую вам эту великую книгу о системах частиц. Он показывает, как реализовать силы, взаимодействие и сложное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...