! Сегодня

Главная » Web и Технологии » Блуждающие огни - гирлянда для сайта на JS

Блуждающие огни - гирлянда для сайта на JS

Заведите себе «идиотскую» привычку радоваться неудачам. Это гораздо веселей, чем раздражаться и ныть по любому поводу.

24-декабря-2023, 21:49   11   0

Блуждающие огни - гирлянда для сайта на JS

Это красивый эффект рождественских огней на  CSS. Этот модуль  гирлянды может создавать некоторые сложные формы. Анимация освещения пространства огнями выглядит очень интересно. Вы можете настроить различные параметры, чтобы изменить цвета, скорость вращения движения и т. д. Значения позволяют добиться необходимого эффекта. Обязательно попробуйте использовать гирлянду у себя на сайте для придания новогоднего настроения.

CSS

/* style.css */

html, body {
  height: 100%;
}

body {
  margin: 0;
  display: flex;

  /* This centers our sketch horizontally. */
  justify-content: center;

  /* This centers our sketch vertically. */
  align-items: center;
  
  background-color: black;
}


JS


const WANDERER_MOVE_MULTIPLIER = 8;
const WANDERER_ROTATE_SPEED = 0.03; // very sensitive

const PATH_WIDTH = 5;
const PATH_HIGHLIGHT_WIDTH = 4;

const LIGHT_GRAPHICS_WIDTH_HEIGHT = 60;

const MAX_BULBS = 300;
const BULB_COLORS = [
  '#00d9ff',
  '#ff0d0d',
  '#59ff9d',
  '#b959ff'
];
const BULB_LAST_INDEX = BULB_COLORS.length - 1;
const BULB_FREQUENCY = 200;

let node;
let pathGraphics;
let bulbGraphics = [];

let bulbs = [];
let bulbTick = 0;
let bulbFlip = false;
let bulbColorIndex = 0;
let bulbInterval = null;
let done = false;

function setup()  {
  createCanvas(600, 600);
  background(20);
  
  node = new Wanderer();
  
  pathGraphics = createGraphics(width, height);
  pathGraphics.noFill();
  pathGraphics.strokeCap(PROJECT);
  
  BULB_COLORS.forEach((color) => {
    bulbGraphics.push(getBulbGraphics(color));
  });
  
  bulbInterval = setInterval(() => {
    if(bulbs.length < MAX_BULBS) {
       addBulb();
    } else {
      clearInterval(bulbInterval);
      done = true;
    }
  }, BULB_FREQUENCY)
}

function draw() {
  background(20);
  
  if(!done) {
    node.render();
  }
  
  image(pathGraphics, 0, 0);
  bulbs.forEach((bulb) => bulb.render());
}

function addBulb() {
  const pos = node.getPosition();
  const direction = node.getDirection();
  bulbs.push(new Bulb(pos.x, pos.y, direction - (bulbFlip ? PI : 0), bulbGraphics[bulbColorIndex]));
  bulbFlip = !bulbFlip;
  bulbColorIndex += 1;
  
  if(bulbColorIndex > BULB_LAST_INDEX) {
    bulbColorIndex = 0;
  }
}

function drawBulb(graphics, color) {
  graphics.fill(color);
  graphics.noStroke();
  
  graphics.beginShape();
  graphics.vertex(-4, 0);
  graphics.vertex(-6, -5);
  graphics.vertex(-7, -10);
  graphics.vertex(-8, -15);
  graphics.vertex(0 - 7, -20);
  graphics.vertex(-4, -25);
  graphics.vertex(0, -27);
  graphics.vertex(0, 0);
  graphics.endShape();
  graphics.beginShape();
  graphics.vertex(4, 0);
  graphics.vertex(6, -5);
  graphics.vertex(7, -10);
  graphics.vertex(8, -15);
  graphics.vertex(7, -20);
  graphics.vertex(4, -25);
  graphics.vertex(0, -27);
  graphics.vertex(0, 0);
  graphics.endShape();
  
  graphics.fill('#378a2e');
  graphics.rect(0, 0, 10, 5);
}

function getBulbGraphics(color) {
  const graphics = createGraphics(LIGHT_GRAPHICS_WIDTH_HEIGHT, LIGHT_GRAPHICS_WIDTH_HEIGHT);
  graphics.rectMode(CENTER);
  
  const startX = graphics.width * 0.5;
  const startY = graphics.height - 10;
  
  graphics.translate(startX, startY - 45);
  graphics.rotate(PI);
  graphics.scale(1.2);
  
  // draw the bulb once
  drawBulb(graphics, color);
  
  // blur the bulb
  graphics.filter(BLUR, 8);
  graphics.scale(0.8);
  
  // draw the bulb again to give a glow effect
  drawBulb(graphics, color);
  return graphics;
}

class Wanderer {
  constructor() {
    this.pos = { x: random(width), y: random(height) };
    this.lastPos = { ...this.pos }
    this.direction = random(TWO_PI);
    this.noiseValue = 0;
  }
  getPosition() {
    return { x: this.pos.x, y: this.pos.y };
  }
  getDirection() {
    return this.direction;
  }
  render() {
    this.lastPos = { ...this.pos }
    
    const xx = cos(this.direction) * WANDERER_MOVE_MULTIPLIER;
    const yy = sin(this.direction) * WANDERER_MOVE_MULTIPLIER;
    
    this.pos.x += xx;
    this.pos.y += yy;
    this.direction = noise(this.noiseValue += WANDERER_ROTATE_SPEED) * TWO_PI;
    
    let pathBroken = false;
    if(this.pos.y > height) {
      pathBroken = true;
      this.pos.y = 0;
    } else if(this.pos.y < 0) {
      pathBroken = true;
      this.pos.y = height;
    }
    
    if(this.pos.x > width) {
      pathBroken = true;
      this.pos.x = 0;
    } else if(this.pos.x < 0) {
      pathBroken = true;
      this.pos.x = width;
    }
    
    if(pathBroken) {
      this.lastPos = { ...this.pos }
    }
    
    pathGraphics.strokeWeight(PATH_WIDTH);
    pathGraphics.stroke('#378a2e');
    pathGraphics.line(this.pos.x, this.pos.y, this.lastPos.x, this.lastPos.y);
    pathGraphics.strokeWeight(PATH_HIGHLIGHT_WIDTH);
    pathGraphics.stroke('#42c134');
    pathGraphics.line(this.pos.x + 1, this.pos.y - 2, this.lastPos.x + 1, this.lastPos.y - 2);
  }
}

class Bulb {
  constructor(x, y, direction, bulbImage) {
    this.bulbImage = bulbImage;
    this.pos = { x, y };
    this.direction = direction;
    this.halfImageWidth = this.bulbImage.width * 0.5;
  }
  render() {
    push();
    translate(this.pos.x, this.pos.y);
    
    // const dir = atan2(this.pos.y - mouseY, this.pos.x - mouseX);
    rotate(this.direction);
    image(this.bulbImage, -this.halfImageWidth, 0);
    pop();
  }
}


Так же подключаем скрипт ( можно скопировать к себе на сайт и подключить отдельным файлом)

https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js


Поделиться

Tags

  • bowtiesmilelaughingblushsmileyrelaxedsmirk
    heart_eyeskissing_heartkissing_closed_eyesflushedrelievedsatisfiedgrin
    winkstuck_out_tongue_winking_eyestuck_out_tongue_closed_eyesgrinningkissingstuck_out_tonguesleeping
    worriedfrowninganguishedopen_mouthgrimacingconfusedhushed
    expressionlessunamusedsweat_smilesweatdisappointed_relievedwearypensive
    disappointedconfoundedfearfulcold_sweatperseverecrysob
    joyastonishedscreamtired_faceangryragetriumph
    sleepyyummasksunglassesdizzy_faceimpsmiling_imp
    neutral_faceno_mouthinnocent
2+2*2= ?

Редакторы выбирают

Web и Технологии