从圆心起波纹
Ripple from center of circles
我将每个圆圈作为一个点数组,我正在尝试使用来自中心的 Anime.js 创建涟漪效果。我已经尝试了各种方法并努力让它发挥作用,有人知道我该怎么做吗?
到目前为止我的代码,这里有一个 CodePen the animation part is at the bottom. I'd like it to ripple like this 但不能让它在这种情况下工作。
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")
}
这是我的建议:使用 css 动画!它们总是比库更流畅、更高效,比如 anime.js。您可以通过为 .dot
元素设置不同的 animation-delay
属性,根据它们所在的层,使点一次波纹一层,从内圈传播到最外层。
我认为以下内容看起来还不错。请注意,这实际上仅使用 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;
}
我将每个圆圈作为一个点数组,我正在尝试使用来自中心的 Anime.js 创建涟漪效果。我已经尝试了各种方法并努力让它发挥作用,有人知道我该怎么做吗?
到目前为止我的代码,这里有一个 CodePen the animation part is at the bottom. I'd like it to ripple like this 但不能让它在这种情况下工作。
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")
}
这是我的建议:使用 css 动画!它们总是比库更流畅、更高效,比如 anime.js。您可以通过为 .dot
元素设置不同的 animation-delay
属性,根据它们所在的层,使点一次波纹一层,从内圈传播到最外层。
我认为以下内容看起来还不错。请注意,这实际上仅使用 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;
}