Главная » Web и Технологии » Летающие привидения на сайт к Хэллоуину

Летающие привидения на сайт к Хэллоуину

Не бойтесь врагов, бойтесь друзей. Предают друзья, а не враги.

55 0

18-ноября-2022, 20:33   Web и Технологии

Летающие привидения на сайт к Хэллоуину

Хотите украсить свой сайт к Хэллоуину, тогда вам должен понравится небольшой сниппет к празднику Хэллоуин . Скрипт можно использовать для добавления летающих призраков на вашу веб-страницу. Призраки появляются внизу страницы и поднимаются вверх. Не так давно мы публиковали капли слизи которые также можно использовать для украшения сайта ко дню всех мертвых и ведьму варящую зелье. 

HTML

<div class="container">
  <svg id="svg"></svg>
</div>


SCSS

@import 'https://fonts.googleapis.com/css?family=Catamaran';

html, body
{
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  font-family: 'Catamaran', sans-serif;
}

body {
  background: #222;
  background: linear-gradient(to bottom, #111 , #222);
}

.container
{
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

svg
{
  z-index: 10;
}




TYPESCRIPT

interface point
{
  x: number;
  y: number;
}

class Ghost
{
  private group: any;
  private startPoint: Point;
  private endPoint: Point;
  private startThickness: number;
  private endThickness: number;
  private guidePosition: number;
  private frequency: number;
  private amplitude: number;
  private height: number;
  private endHeight: number;
  private y: number;
  
  private body: any;
  private eyeLeft: any;
  private eyeRight: any;
  private mouth: any;
  private guide: Point[];
  
  id: string;
  
  constructor(svg: any, start:Point, end:Point) 
  {
    this.id = String(Math.round(Math.random() * 999999999999999));
    this.group = svg.group();
    this.startPoint = start;
    this.endPoint = end;
    this.startThickness = 0;
    this.endThickness = 150 + Math.round(Math.random() * 50);
    this.guidePosition = Math.random() * 1000;
    this.frequency = 0.01 + Math.random() * 0.01;
    this.amplitude = 20 + Math.random() * 40;
    this.height = 0;
    this.endHeight = 150 + Math.round(Math.random() * 100);
    this.y = 0;
    
    var faceAttr = {
      fill: '#111111',
      opacity: 0.9,
            stroke: 'none'
    }
    
    this.body = this.group.path().attr(
        {
            fill: '#eeeeee',
      opacity: 0.8,
            stroke: 'none'
        });
    
    this.eyeLeft = this.group.path().attr(faceAttr);
    this.eyeRight = this.group.path().attr(faceAttr);
    this.mouth = this.group.path().attr(faceAttr);
    
    this.updateGuide();
    }
  
  remove()
  {
    this.group.remove();
  }

  updateGuide()
  {
    this.guide = [];
    let height: number = this.startPoint.y - this.endPoint.y;
    let widthChange: number = this.startPoint.x - this.endPoint.x;
    let y = this.startPoint.y;
    
    while (y-- >= this.endPoint.y) 
        {        
      var x = this.startPoint.x + (widthChange - (widthChange / height) * y);
            var wave = Math.sin(y * this.frequency + this.guidePosition)
            this.guide.push({y: y, x: x + (wave * this.amplitude / 2 + this.amplitude / 2)})
        }
    
    //console.log(this.guide)
  }

  start(onComplete:Function)
  {
    TweenMax.to(this, 2, {y: this.guide.length, height: this.endHeight, position: '+=6', ease:SlowMo.ease.config(0.3, 0.3, false), onComplete: onComplete, onCompleteParams: [this]})
  }

  getPointAlongGuide(y:number, offsetXPercentage: number):Point
  {
    if(this.guide.length)
    {
      if(y >= this.guide.length) y = this.guide.length - 1;
      if(y < 0) y = 0;
        
      var thicknessDifference = this.endThickness - this.startThickness;
      var percentageAlongGuide = (y / this.guide.length) * 100;
      var thickness = this.startThickness + ((thicknessDifference / 100) * percentageAlongGuide);
      var xOffset = ((thickness / 2) / 100) * offsetXPercentage;
      
      return {x: this.guide[y].x + xOffset, y: this.guide[y].y}
    }
    return {x: 0, y: 0};
  }
  
  private drawPath(pathPoints)
  {
    var points = [];
      
    for(var i = 0; i < pathPoints.length; i++)
    {
      var subPoints = [];
      for(var j = 0; j < pathPoints[i].points.length / 2; j++)
      {
        var p = pathPoints[i].points.slice(j*2, j*2 + 2);
        //console.log(i, p)
        var point = this.getPointAlongGuide(Math.round(p[1]), p[0])
        subPoints.push(point.x);
        subPoints.push(point.y);
      }
      points.push(pathPoints[i].type + subPoints.join(' ')); 
    }
    
    return points.join(' ') + 'Z';
  }
  
  draw()
  { 
    
    if(this.height > 0)
    {
      var y = Math.round(this.y)
      var height = Math.round(this.height)
      var heightChunks = height / 6;
      
      var body = [
        {type: 'M', points: [10, y]},
        {type: 'Q', points: [75, y, 80, y - heightChunks * 2]},
        {type: 'L', points: [ 85, y - heightChunks * 3,
                    90, y - heightChunks * 4,
                    95, y - heightChunks * 5,
                    100, y - heightChunks * 6,
                    75, y - heightChunks * 5,
                    50, y - heightChunks * 6,
                    25, y - heightChunks * 5,
                    0, y - heightChunks * 6,
                    -25, y - heightChunks * 5,
                    -50, y - heightChunks * 6,
                    -75, y - heightChunks * 5,
                    -100, y - heightChunks * 6,
                    -95, y - heightChunks * 5,
                    -90, y - heightChunks * 4,
                    -85, y - heightChunks * 3,
                    -80, y - heightChunks * 2
                  ]},
        {type: 'Q', points: [-75, y, 10, y]},
      ]
      
      this.body.attr({d: this.drawPath(body)})
      
        
      var leftEye = [
        {type: 'M', points: [-40, y - heightChunks * 2]},
        {type: 'Q', points: [-50, y - heightChunks * 2, -50, y - heightChunks * 2.5]},
        {type: 'Q', points: [-50, y - heightChunks * 3, -40, y - heightChunks * 3]},
        {type: 'Q', points: [-30, y - heightChunks * 3, -30, y - heightChunks * 2.5]},
        {type: 'Q', points: [-30, y - heightChunks * 2, -40, y - heightChunks * 2]}
      ]
      
      this.eyeLeft.attr({d: this.drawPath(leftEye)})
      
      var rightEye = [
        {type: 'M', points: [40, y - heightChunks * 2]},
        {type: 'Q', points: [50, y - heightChunks * 2, 50, y - heightChunks * 2.5]},
        {type: 'Q', points: [50, y - heightChunks * 3, 40, y - heightChunks * 3]},
        {type: 'Q', points: [30, y - heightChunks * 3, 30, y - heightChunks * 2.5]},
        {type: 'Q', points: [30, y - heightChunks * 2, 40, y - heightChunks * 2]}
      ]
      
      this.eyeRight.attr({d: this.drawPath(rightEye)})
      
      var mouth = [
        {type: 'M', points: [0, y - heightChunks * 3]},
        {type: 'Q', points: [20, y - heightChunks * 3, 20, y - heightChunks * 3.5]},
        {type: 'Q', points: [20, y - heightChunks * 4.5, 0, y - heightChunks * 4.5]},
        {type: 'Q', points: [-20, y - heightChunks * 4.5, -20, y - heightChunks * 3.5]},
        {type: 'Q', points: [-20, y - heightChunks * 3, 0, y - heightChunks * 3]}
      ]
      
      this.mouth.attr({d: this.drawPath(mouth)})
    }
    
  }
}

class StageManager
{
  svg: any;
  size: {width: number, height: number};
  ghosts: any;

  constructor(svg: any) 
  {
        this.svg = svg;
    this.ghosts = {};
    this.size = {width: 0, height: 0};
    }

  init()
  {
    window.addEventListener('resize', () => this.onresize(), true);
    this.onresize();
    this.tick();
  }
  
  onresize()
  {
    this.size.width = window.innerWidth;
    this.size.height = window.innerHeight;
    
    this.svg
      .attr('width', this.size.width)
      .attr('height', this.size.height)
    
    // for(let i in this.ghosts)
    // {
    //  this.ghosts[i].updateGuide();
    // }
  }

  addGhost()
  {
    let start:Point = {x: this.size.width / 2, y: this.size.height};
    let end:Point = {x: (this.size.width / 4) +  Math.random() * (this.size.width / 2), y: -300};
    
    let ghost = new Ghost(this.svg, start, end, this.onGhostComplete);
    ghost.start((ghost:Ghost) => this.removeGhost(ghost));
    this.ghosts[ghost.id] = ghost;
  }
  
  removeGhost(ghost: Ghost)
  {
    delete this.ghosts[ghost.id];
    ghost.remove();
    ghost = null;
  }

  tick()
  {
    for(let i in this.ghosts)
    {
      this.ghosts[i].draw();
    }
    
    requestAnimationFrame(() => this.tick());
  }
}

let stageManager = new StageManager(Snap('svg'));
stageManager.init();

makeGhost();

function makeGhost()
{
  stageManager.addGhost();
  setTimeout(makeGhost, Math.random() * 500);
}


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
Человек быстро решит загадку пять умножить на пять и минус 25 ?