Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Как создать анимированные звёзды в космосе?

#javascript #css3 #svg #анимация


Делаю анимацию вращения планет солнечной системы.   

https://ru.stackoverflow.com/a/918238/28748  

Не хватает реалистичного, анимированного фона звездного неба.  



Величина звёзд их яркость, взаимное расположение должно быть случайным. 

Желательно добавить мерцание более крупных звёзд. 

С помощью svg smil я не могу реализовать такое, так как в этом языке нет ничего подобного,
как в JS Math.random()  

Как реализовать подобную анимацию на Javascript?
    


Ответы

Ответ 1



В качестве одного из вариантов, можно создать кучу элементов, которые будут звездами, поставить им случайную позицию и размер. Для некоторых, например размер которых больше установленного значения, добавить класс css, добавляющий мерцание. Например так: function createStar(center, radius, animation) { var star = document.createElement('div'); star.className = 'star'; star.style.width = `${radius}px`; star.style.height = `${radius}px`; star.style.top = `${center.top-radius/2}px`; star.style.left = `${center.left-radius/2}px`; star.style.animationDelay = `${animation.delay}s`; star.style.animationDuration = `${animation.duration}s`; if (radius > 6) { star.classList.add('shine'); } return star; } var container = document.getElementById("d"); for (var i = 0; i < 200; i++) { container.appendChild(createStar({ top: getRandom(0, container.offsetHeight), left: getRandom(0, container.offsetWidth) }, getRandom(2, 7), { duration: getRandom(3, 15, false), delay: getRandom(0, 7, false) })); } function getRandom(min, max, notFloor) { return (!notFloor && Math.floor || (a => a))(Math.random() * (max - min + 1) + min); } html, body { margin: 0; padding: 0; } #d { width: 100vw; height: 100vh; background: #040e17; position: relative; overflow: hidden; } .star::before { content: ''; background-color: #fff; position: absolute; border-radius: 50%; background-color: rgba(255, 255, 255, 1); position: absolute; top: 50%; left: 50%; width: 50%; height: 50%; transform: translate(-50%, -50%); } .star { border-radius: 50%; background-color: rgba(255, 255, 255, 0.7); position: absolute; box-shadow: 0px 0px 2px 1px rgba(255, 255, 255, .5); } .shine { animation: shine infinite alternate; } @keyframes shine { from { box-shadow: 0px 0px 2px 1px rgba(255, 255, 255, .5); } to { box-shadow: 0px 0px 5px 10px rgba(255, 255, 255, .5); } }
Вместо обычных элементов, можно так же работать и с элементами svg с настроенной анимацией, возможно даже лучше будет.

Ответ 2



Приблизил к оригиналу насколько смог. Собственно, что делают звезды на небе? Ну, максимум, пульсируют или исчезают на время. Применив одну и ту же анимацию с разной длительностью получаем довольно реалистичный эффект. Размер звезд от одного до пяти пикселей, но с вероятностью в десять процентов мы генерируем звезду размеров giant - их в десять раз меньше и они немного больше остальных. В #root>div можно раскоментировать blur для большей реалистичности, но все будет лагать. Желательно развернуть на всю страницу. const params = { amount: 200, size: { min: 1, max: 5, giant: 9 }, duration: { min: 5, max: 25, } } const randomBetween = (a, b) => { return (a + (Math.random() * (b - a))); } for (let i = 0; i < params.amount; i++) { let star = $("
"); let size = Math.round(Math.random() * 10) === 0 ? params.size.giant : randomBetween(params.size.min, params.size.max); star.css({ "width": size + "px", "height": size + "px", "left": randomBetween(0, 100) + "%", "top": randomBetween(0, 100) + "%", "box-shadow": "0 0 " + size + "px " + size / 2 + "px #043668", "animation-duration": randomBetween(params.duration.min, params.duration.max) + "s" }); $("#root").append(star); } body, html { margin: 0; width: 100%; height: 100%; background: radial-gradient(ellipse at center, rgba(8, 25, 42, 1) 19%, rgba(1, 4, 6, 1) 100%); } #root { position: absolute; width: 100%; height: 100%; overflow: hidden; } #root>div { position: absolute; background: radial-gradient(ellipse at center, rgba(177, 198, 219, 1) 2%, rgba(5, 63, 118, 1) 100%); border-radius: 100%; /* filter:blur(1px); */ animation: shine infinite alternate; } @keyframes shine { 0% { transform: scale(1); opacity: 1; } 20% { transform: scale(.9); opacity: .8; } 40% { transform: scale(1); opacity: .9; } 40% { transform: scale(.2); opacity: .2; } 60% { transform: scale(.2); opacity: .1; } 80% { transform: scale(.5); opacity: .5; } 100% { transform: scale(.9); opacity: .9; } }


Ответ 3



Мои 5 копеек на WebGL =) Чтобы использовать это в реальной жизни, нужно как минимум еще математический шум заменить на текстуру. Seed для шума можно поменять вот в этой строчке #define r(x) fract(1e4*sin((x) * 541.121)) и расположение звезд изменится Вариант попроще, тут меньше итераций цикла в шейдере, меньше звезд и тормозов.

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

Отправить комментарий