Пульсация от центра кругов

#javascript #animation #anime.js

#javascript #Анимация #anime.js

Вопрос:

У меня каждый круг представлен в виде массива точек, и я пытаюсь создать эффект пульсации, используя Anime.js исходящая из центра. Я перепробовал все виды и изо всех сил пытаюсь заставить это работать, есть ли у кого-нибудь идеи, как я могу это сделать?

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

 var container     = document.getElementById('container');
var numberOfDots    = 512;
var numberOfCircles = 8;
var dotsPerCircle   = numberOfDots / numberOfCircles;
var circles         = [];

function createDot(i, circleDepth) {
    var rotation  = (360 / dotsPerCircle) * i;
    var height    = "calc( 30%   "   (circleDepth * 10)   "px)";
    var container = document.createElement('div');
          container.classList = 'dot';
          container.style.height = height;
          container.style.transform = 'rotate('   rotation   'deg) translateY(-50%)';

    var dot       = document.createElement('span');
        container.appendChild(dot);

    return container;
}

function createCircle(circleDepth) {
    var dotArray = [];
    for (var i = 1; i <= dotsPerCircle; i  ) {
        var dot = createDot(i, circleDepth);
        container.appendChild(dot);
        dotArray.push(dot.querySelector('span'));
    }
    return dotArray;
}

for (var i = 1; i <= numberOfCircles; i  ) {
    circles.push(createCircle(i));
}

// Animation
var duration   = 6000;
var delay      = duration / numberOfDots;
var myTimeline = anime.timeline({
    complete: function() { myTimeline.restart(); }
});
for (var i = 0; i < circles.length; i  ) {
    var dotArray = circles[i];
    myTimeline.add({
        targets: dotArray,
        easing: 'easeInOutSine',
        direction: 'alternate',
        duration: duration * .1,
        scale: [
            {value: 1.6, easing: 'spring(1, 80, 10, 0)', duration: 1000},
            {value: 1, easing: 'spring(1, 80, 10, 0)', duration: 1000}
        ],
    }, "-=990")
}
  

введите описание изображения здесь

Комментарии:

1. Вы должны включить свой код, чтобы мы могли его использовать!

2. @GershomMaes мой плохой, обновлен ссылками и примерами.

Ответ №1:

Вот мое предложение: используйте css-анимацию! Они всегда будут более плавными и производительными, чем библиотека, например anime.js . Вы можете заставить точки пульсировать по одному слою за раз, от внутреннего круга распространяясь к самому внешнему, задавая различные animation-delay свойства для .dot элементов, в зависимости от того, в каком слое они находятся.

Я не думаю, что следующее выглядит слишком плохо. Обратите внимание, что это, по сути, использует только html и css; javascript используется только для генерации html!

 let makeRipple = (numRings=8, dotsPerRing=64, ringEndAmt=0.5, rippleMs=1000) => {
  
  // ringEndAmt: The portion of ripple filled by rings (0.5 = half the radius is empty of dots)
  // rippleMs: The amount of time between the inner layer and outer layer pulsing
  
  let ripple = document.createElement('div');
  ripple.classList.add('ripple');
  
  for (let r = 0; r < numRings; r  ) { for (let d = 0; d < dotsPerRing; d  ) {
    
    // `r` indexes the layer we're in, from inner to outermost
    // `d` indexes the specific dot within layer `r`
    
    let radius = 1 - ((r / numRings) * ringEndAmt);
    let angAmt = (d / dotsPerRing) * Math.PI * 2;
    
    let [ x, y ] = [ Math.cos(angAmt), Math.sin(angAmt) ].map(v => v * radius);
    
    let dot = document.createElement('div');
    dot.classList.add('dot');
    dot.style.left = `${(x   1) * 50}%`;
    dot.style.top = `${(y   1) * 50}%`;
    dot.style.animationDelay = `${Math.round((1 - ((r   1) / numRings)) * rippleMs)}ms`;
    ripple.appendChild(dot);
    
  }}
  
  return ripple;
  
};

document.body.appendChild(makeRipple());  
 @keyframes pulseRipple {
  0%   { transform: scale(0.8); }
  12%  { transform: scale(0.8); }
  16%  { transform: scale(0.82); }
  24%  { transform: scale(0.993); }
  26%  { transform: scale(1); }
  33%  { transform: scale(0.8); }
  100% { transform: scale(0.8); }
}

@keyframes pulseDot {
  0%  { background-color: rgba(0, 150, 0, 0.1); transform: translate(0px, 0px) scale(1); }
  10% { background-color: rgba(0, 150, 0, 0.1); transform: translate(0px, 0px) scale(1); }
  20% { background-color: rgba(0, 150, 0, 0.8); transform: translate(2px, 2px) scale(2); }
  30% { background-color: rgba(0, 150, 0, 0.1); transform: translate(0px, 0px) scale(1); }
}

.ripple {
  position: relative;
  background-color: rgba(0, 150, 0, 0.02);
  border-radius: 100%;
  width: 45%; padding-bottom: 45%;
  box-shadow: 0 0 0 2px rgba(0, 150, 0, 0.02);
    
  animation-name: pulseRipple;
  animation-duration: 8000ms;
  animation-iteration-count: infinite;
  animation-timing-function: ease-in;
}
.ripple > .dot {
  position: absolute;
  background-color: rgba(0, 150, 0, 0.1);
  width: 4px;
  height: 4px;
  margin-left: -2px; margin-top: -2px; /* Dots are centered */
  border-radius: 100%;
  
  animation-name: pulseDot;
  animation-duration: 8000ms;
  animation-iteration-count: infinite;
  animation-timing-function: ease-in-out;
}