Звездное небо на canvas

Вступление

Нет на свете проблем, есть задачи и вопросы. Решил сделать для себя сайт, а на главной нужно было сделать звёздное небо. Как-то скучно было брать из макета картинку, по тому решил добавить немного динамики: сделать звёзды мерцающими. Этот код я написал давно, и он немного изменился: поправлял некоторые ошибки. По этому решил переписать статью и сразу же продемонстрировать резульат работы скрипта.

нет поддержки canvas в вашем браузере
пример получившегося кода.

Подготовка

Поскольку скрипт давно написан, я просто покажу из чего он состоит и для чего нужет тот или иной кусок кода))

Конечно всё начинается с HTML и CSS:

html

<canvas class="canvas" id="canvas" width="100%" height="100px">нет поддержки canvas в вашем браузере</canvas>

css

.canvas {
  width: 100%;
  height: 100px;
  background-color: #050818;
  background-image: radial-gradient(at bottom,#090f2d,#050818);
}

В примере не видно этот градиент, но на главной странице этого сайта градиент делает рисунок более реалистичным.

Следующий шаг — это объявить и вызвать функцию для создания нашего звездного неба на canvas.

js

window.addEventListener("load", () => {
  canvas();
});

function canvas() {
  //
}

Сам код:

js

const opts = {
  minRadius: 0.5,
  maxRadius: 1.5,
  colors: ["rgba(255, 255, 255, 0.5)", "rgba(252, 244, 201, 0.5)", "rgba(201, 252, 201, 0.5)", "rgba(201, 236, 252, 0.5)", "rgba(229, 201, 252, 0.5)", "rgba(252, 201, 201, 0.5)", "rgba(252, 201, 241, 0.5)", "rgba(252, 201, 201, 0.5)"],
  delay: 100,
  step: 0.05,
  trangles: 4,
  intervalRadius: 2.5,
}

let canvas = document.querySelector("#canvas");
let ctx = canvas.getContext("2d");
let w;
let h;
const arrStars = [];
let check;
let animations;

sizeCanvas();

function sizeCanvas() {
  w = canvas.width = window.innerWidth;
  h = canvas.height = window.innerHeight;
  return w, h;
}

window.addEventListener("resize", function() {
  windowResize();
});

function windowResize() {
  arrStars.length = 0;
  clearTimeout(check);
  check = setTimeout(function() {
    clearInterval(animations);
    sizeCanvas();
    setup();
  }, 100);
}

const Stars = function(w, h) {
  this.x = Math.random() * w;
  this.y = Math.random() * h;
  this.color = opts.colors[[Math.round(Math.random() * opts.colors.length)]];
  this.vector = Math.round(Math.random()) || -1;
  this.minRadius = opts.minRadius + Math.random() * (opts.maxRadius - opts.minRadius);
  this.maxRadius = this.minRadius + opts.intervalRadius;

  this.draw = function() {

    ctx.beginPath();

    ctx.moveTo(this.x, this.y + this.minRadius);

    for (var i = 0; i < 2 * opts.trangles + 1; i++) {
      var r = (i % 2 == 0) ? this.minRadius : this.maxRadius;
      var a = (Math.PI * i / opts.trangles) + 45 * Math.PI / 180;
      ctx.lineTo(this.x + r * Math.sin(a), this.y + r * Math.cos(a));
    };

    ctx.closePath();
    ctx.fillStyle = this.color;
    ctx.fill();

  }

  this.update = function() {
    this.check();
    this.minRadius += opts.step * this.vector;
    this.maxRadius += opts.step * this.vector;
  }

  this.check = function() {
    if (this.minRadius > opts.maxRadius || this.minRadius < opts.minRadius) {
      this.vector *= -1;
    }
  }

}

function setup() {
  for (let i = 0; i < (w / 150) * (h / 150); i++) {
    arrStars.push(new Stars(w, h));
    arrStars[i].draw();
  }
  loop();
}

setup();

function loop() {
  animations = setInterval(function() {
    ctx.clearRect(0, 0, w, h);
    for (let i = 0; i < arrStars.length; i++) {
      arrStars[i].update();
      arrStars[i].draw();
    }
  }, opts.delay);
}
  • opts = {} опции которые позволяют настроить цвета, размеры, скорость мерцания звёзд, ну и количество лучей.
  • 11-17 строки это необходимые дополнительные переменные, если у вас не строгий режим - практически всё можно удалить))
  • 19-39 строки - следят за размером холста, и при изменении размеров страницы перерисовывает точки используя "безопасный" ресайз
  • 41-79 функция которая создаёт звезду
    • 42-47 рандомно выбераем расположение, цвет и размеры звезды
    • 49-65 рисуем звезду, точка превращается в звезду на строках 55-59
    • 67-71 тут звезда изменяет свои размеры
    • 73-77 проходит проверка: если звезда меньше или больше нужного - то изменение размера меняется на противоположное
  • 81-89 расчитываем количество звёзд и рисуем их
  • ну и последняя функция loop() по сути анимирует звёзды.

По итогу:

Код получился не очень большой. Я не js разработчик, но судя по шуму ноутбука, если не увлекаться количеством звёзд, то страница требует меньше ресурсов чем youtube на главной странице, не воспроизводящий видео)). Осталось только украсить облаками и морским берегом для красивой анимированной картинки звездного неба: что можете посмотреть на главной странице.

Объявление

Если вы хотите обучаться вместе со мной, то приглашаю вас на индивидуальные курсы HTML Academy: «Профессиональная вёрстка сайтов» или «Адаптивная вёрстка и автоматизация».

Просто спросите у менеджера меня — наставника Зиновьева Александра. Обучение проходит в помесячном индивидуальном формате, и вы можете начать в любое удобное для вас время.

Кроме того, в HTML Academy вы получите профессию и даже сможете устроиться на работу с новой профессией.