#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;
}