Взрывающаяся частица: анимация с CSS - PullRequest
3 голосов
/ 22 марта 2020

Я хотел бы смоделировать взрыв частицы, от центра экрана к краям (в CSS, и я обещаю не использовать это в гнусных целях)

Вот визуальный Вы понимаете, о чем я говорю:

ДО:

BEFORE

ПОСЛЕ:

AFTER

Я пытался использовать следующий HTML / CSS / JS, но он не работает (точки остаются в центре экрана):

HTML это просто:

<div id="animated"></div>

CSS:

// SCSS
#animated {
  position: relative; 
  width: 100%;
  height: 100%;
  overflow: hidden;

  .particle {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 10px;
    height: 10px;
    transition: transform 1s ease-in-out;

    &.on {
      transform: translate(-30vw, -30vh);
    }

    &::after {
      position: absolute;
      content: "";
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background: red;
    }
  }
}

И Javascript:

document.addEventListener('DOMContentLoaded', onLoad);

function onLoad() {
  // animate
  for(var i = 0; i < 360; i+=5) {
    const particle = createParticle(animated, i);
  }
}

function createParticle(parentElem, rotation) {
  const particle = document.createElement('div');
  particle.style.transform = `rotate(${rotation}deg)`;
  particle.classList.add('particle');
  particle.classList.add('on'); // turn on
  parentElem.appendChild(particle);

  return particle;
}

Вот ссылка на CodePen: https://codepen.io/floatingrock/pen/KKpxpvJ

1 Ответ

4 голосов
/ 22 марта 2020

Вот идея с переменной CSS, которую легко настроить с небольшим количеством кода.

Запуск на полном экране для лучшего результата:

document.addEventListener('DOMContentLoaded', onLoad);

function onLoad() {
  let parentElem = document.querySelector('.container');
  for (var i = 0; i < 360; i += 10) {
    const particle = document.createElement('div');
    particle.style = `--r:${i}deg`;
    parentElem.appendChild(particle);
  }
}
.container {
  width: 20px;
  height: 20px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.container>div {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: red;
  transform: rotate(var(--r, 0deg)) translate(0);
  animation: splash 1s infinite alternate 1s;
}

@keyframes splash {
  to {
    transform: rotate(var(--r, 0deg)) translate(44vmin);
  }
}
<div class="container">
</div>

Можно рассмотреть различные задержки для другого вида анимации:

document.addEventListener('DOMContentLoaded', onLoad);

function onLoad() {
  let parentElem = document.querySelector('.container');
  for (var i = 0; i < 360; i += 10) {
    const particle = document.createElement('div');
    particle.style = `--r:${i}deg;--d:${(i/360)}s`;
    parentElem.appendChild(particle);
  }
}
.container {
  width: 20px;
  height: 20px;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.container>div {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: red;
  transform: rotate(var(--r, 0deg)) translate(0);
  animation: splash 1s infinite alternate var(--d,0s);
}

@keyframes splash {
  to {
    transform: rotate(var(--r, 0deg)) translate(44vmin);
  }
}
<div class="container">
</div>

Мы все еще можем оптимизировать код с меньшим CSS:

document.addEventListener('DOMContentLoaded', onLoad);

function onLoad() {
  let parentElem = document.querySelector('.container');
  for (var i = 0; i < 360; i += 10) {
    const particle = document.createElement('div');
    particle.style = `--r:${i}deg`;
    parentElem.appendChild(particle);
  }
}
.container > div {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: red;
  transform:translate(-50%, -50%) rotate(var(--r, 0deg)) translate(0);
  animation: splash 1s infinite alternate 1s;
}

@keyframes splash {
  to {
    transform:translate(-50%, -50%) rotate(var(--r, 0deg)) translate(calc(50vmin - 10px));
  }
}


/* Irrelevant styles */
html {
  height:100%;
  border:1px solid blue; /* screen border*/
  box-sizing:border-box;
  background:linear-gradient(green,green) center/10px 10px no-repeat; /* the center of the screen */
}
body {
 margin:0;
}
<div class="container">
</div>

Порядок трансформации важен. Похожие: Почему порядок преобразований имеет значение? вращение / масштабирование не дает тот же результат, что и масштабирование / поворот

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