Случайное появление и автоматическое перемещение элементов html с помощью js
Всем привет. Хочу сделать, чтобы изображения(сердца) появлялись случайным образом на экране, перемещались вверх, немного в бок разные стороны и исчезали, становясь прозрачными, затем они начинают анимацию с нового места.
<div class="serdca">
<img class="serdce_img" src="img/serce.png">
<img class="serdce_img" src="img/serce.png">
<img class="serdce_img" src="img/serce.png">
<img class="serdce_img" src="img/serce.png">
<img class="serdce_img" src="img/serce.png">
</div> `
let img = document.querySelectorAll(".serdce_img");
let arr = new Array(img.length).fill(0).map((_, i) => i).sort(() => Math.random() - 0.5);
for (let i = 0; i < 5; i++) {
let rand_img = img[ arr[i] ];
rand_img.classList.remove(".serdce_img");
rand_img.parentNode.appendChild(rand_img);
}
// попытался сделать рандом, но не вышло. Кто поможет тому буду очень благодарен!
Ответы (2 шт):
Автор решения: UModeL
→ Ссылка
Если сердец единовременно не более двадцати, то простейшие CSS-анимации (с перезапуском путём клонирования и замены) вполне справятся:
window.addEventListener('animationend', function(ev) {
if (ev.animationName === 'rise_up') {
let target = ev.target;
target.style.setProperty('--ad', `${4 + Math.random() * 5}s`);
let newone = target.cloneNode(true);
target.parentNode.replaceChild(newone, target);
}
});
let imgs = document.querySelectorAll('.serdce_img');
[...imgs].forEach(function(img) {
img.style.setProperty('--ad', `${4 + Math.random() * 5}s`);
});
.serdca {
display: flex;
justify-content: space-around;
align-items: flex-end;
height: 90vh;
overflow: hidden;
filter: drop-shadow(0 25px 4px #0002);
}
.serdce_img {
--ad: 5s;
opacity: 0;
animation: rise_up var(--ad) linear forwards, side_to_side var(--ad) ease-in-out infinite;
height: 24px;
aspect-ratio: 1;
background: radial-gradient(circle at 60% 65%, #fccf 10%, #f000 50%) top -15% left -20%, radial-gradient(circle at 40% 65%, #faaf 0%, #f000 35%) top -30% right 15%, radial-gradient(circle at 60% 65%, #f00f 64%, #f000 65%) top left, radial-gradient(circle at 40% 65%, #f00f 64%, #f000 65%) top right, linear-gradient(to bottom left, #f00f 43%, #f000 43%) bottom left, linear-gradient(to bottom right, #f00f 43%, #f000 43%) bottom right;
background-size: 50% 50%;
background-repeat: no-repeat;
}
@keyframes rise_up {
from { transform: translatey(0); }
25%, 85% { opacity: 1; }
to { transform: translatey(-80vh); }
}
@keyframes side_to_side {
0%, 100% { translate: 0; }
10% { translate: -10px; }
25% { translate: 20px; }
40% { translate: -40px; }
60% { translate: 65px; }
85% { translate: -70px; }
}
<div class="serdca">
<div class="serdce_img"></div><div class="serdce_img"></div><div class="serdce_img"></div>
<div class="serdce_img"></div><div class="serdce_img"></div><div class="serdce_img"></div>
<div class="serdce_img"></div><div class="serdce_img"></div><div class="serdce_img"></div>
<div class="serdce_img"></div><div class="serdce_img"></div><div class="serdce_img"></div>
<div class="serdce_img"></div><div class="serdce_img"></div><div class="serdce_img"></div>
</div>
Автор решения: Rudi
→ Ссылка
Можно сделать что-то такое и поиграть с значениями в setTimeout и randomPos...
let count = 60;
function createHeart() {
const heart = document.createElement('img');
heart.setAttribute('class', 'serdce_img');
heart.setAttribute('src', 'https://img.freepik.com/free-psd/red-heart-isolated-transparent-background_191095-27355.jpg');
heart.addEventListener('animationend', (event) => {
event.target.remove();
setTimeout(createHeart, Math.floor(Math.random() * (1500 - 700) + 500));
});
randomPos(heart);
document.querySelector('.serdca').appendChild(heart);
}
function randomPos(heart) {
heart.style.top = Math.floor(Math.random() * (window.innerHeight - 10) + 30) + 'px';
heart.style.left = Math.floor(Math.random() * (window.innerWidth - 200) + 90) + 'px';
}
function initHearts() {
for (let i = 0; i < count; i++) {
setTimeout(createHeart, Math.floor(Math.random() * (1500 - 700) + 500))
}
}
initHearts();
.serdca {
position: relative;
height: 100px;
}
.serdce_img {
position: absolute;
width: 30px;
height: 30px;
animation: moveHearts 3s forwards;
}
@keyframes moveHearts {
0% {
opacity: 1;
transform: translateY(0) translateX(0);
}
25% {
opacity: 0.75;
transform: translateY(-50px) translateX(10px);
}
50% {
opacity: 0.5;
transform: translateY(-100px) translateX(-10px);
}
75% {
opacity: 0.25;
transform: translateY(-150px) translateX(20px);
}
100% {
opacity: 0;
transform: translateY(-200px) translateX(-20px);
}
}
<div class="serdca">
<img class="serdce_img" src="https://img.freepik.com/free-psd/red-heart-isolated-transparent-background_191095-27355.jpg">
<img class="serdce_img" src="https://img.freepik.com/free-psd/red-heart-isolated-transparent-background_191095-27355.jpg">
<img class="serdce_img" src="https://img.freepik.com/free-psd/red-heart-isolated-transparent-background_191095-27355.jpg">
<img class="serdce_img" src="https://img.freepik.com/free-psd/red-heart-isolated-transparent-background_191095-27355.jpg">
<img class="serdce_img" src="https://img.freepik.com/free-psd/red-heart-isolated-transparent-background_191095-27355.jpg">
</div>