Сдвиг картинки при изменении окна браузера

Всем привет и с наступающим НГ. Проблема состоит в следующем. Имеется несколько картинок и текст. При изменении окна браузера все картинки (кроме одной) не меняют своего положения, а одна картинка (бык) сдвигается влево, текст уменьшается в размерах и сдвигается вниз. Стили у картинок одинаковые, но проблема с быком. Вставил в стили * {outline: 1px solid red;} , чтобы видеть блоки и наблюдаю, что у этого быка какой-то увеличенный блок. В чем причина понять не могу. У спецов прошу помощи. Сам я пока слабо разбираюсь в этих делах. Всем спасибо. Вот мой код:

<div id="container">

<div class="nedo"><img src="Небо.png"></div>

<canvas width="880" height="550" id="fireworks-canvas" class="fireworks"></canvas>

<div class="cloud"> 
<img src="https://i114.fastpic.ru/big/2020/1217/1d/036017afc5b3a5f4ec2bff96d9ca491d.png" alt="" class="cloud1">
<img src="https://i114.fastpic.ru/big/2020/1217/89/ef22cc02309acd1896fff62568b3ac89.png" alt="" class="cloud2">
<img src="https://i114.fastpic.ru/big/2020/1217/84/3bcf06cb1570ed3c77afb93821c88784.png" alt="" class="cloud3">
<img src="https://i114.fastpic.ru/big/2020/1217/88/60b2a64ae976c4553daa6f8fb323eb88.png" alt="" class="cloud4">
</div>

<div class="dom"><img src="https://i114.fastpic.ru/big/2020/1217/23/fda4a096a953899651c78371deeddc23.png"></div>
<div class="byk"><img src="https://i114.fastpic.ru/big/2020/1217/3c/48013036407b1716957f7fe061fb0a3c.gif" alt=""></div>
<div class="krysa"><img src="https://i114.fastpic.ru/big/2020/1217/20/21247a59ca83d64d4e4fcf5ca17bfe20.gif" alt=""></div>
<div class="elka"><img src="Елка.gif"></div>
<div class="https://i114.fastpic.ru/big/2020/1218/59/e6f74347e8dd32489a574bf0c09f1759.gif"><img src="Снеговик.gif"></div>
</div>

<div id="blunt_container">  
<div id="test">
Двадцать первый – год Быка<br>
Крысе он намнёт бока<br>
Високосный год заменит<br>
Эпидемии отменит !<br>
С облегчением вздохнём<br>
С Бычком прекрасно заживем !!!<br>
</div>

<div  class="smoke-group">
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
    <div class="smoke"></div>
  </div>
 </div> 


    * {
outline: 1px solid red;
}

#container {
  padding: 10px 30px;
  width: 100%;
  margin: auto auto;
  max-width: 880px;
}

.nebo {
margin-left: 0;
margin-top: 0;  
position: absolute;
z-index: 1;
  }

.dom {
margin-left: 0;
margin-top: -34.5em;
position: absolute;
z-index: 3;
  }

.cloud {     
left: 0.5em;
top: 0.5em;
 position: absolute;
z-index: 2;
  }

.fireworks {     
margin-top: -34.5em;
margin-left: 6em;
position: absolute;
z-index: 6; 
  }

.byk {
width: 100%;
margin-left: -20em;
margin-top: -20em;
transform: scale(0.5);
position: absolute;
z-index: 5;           
animation: BykAnimation 0s 3s forwards;
visibility: hidden;  
  }

@keyframes BykAnimation {
  to   { visibility: visible; }
}

.krysa {
width=100%;
margin-right: 35em;
margin-top: -21em;
transform: scale(0.2);
position: absolute;
opacity: 0;
z-index: 6; 
-webkit-animation: animKrysa 8s linear 6s forwards;
-o-animation: animKrysa 8s linear 6s forwards;
animation: animKrysa 8s linear 6s forwards; 
} 
  
@keyframes animKrysa {
  0% {
    transform: translateX(0) scale(0.4);
  }
  5% {
    opacity: 1;
  }
  25% {
    transform: translateX(calc(10vw + 10px)) scale(0.1);
  }
  50% {
    transform: translateX(calc(20vw + 20px)) scale(0.05);
  }
  100% {
    transform: translateX(calc(30vw + 30px)) scale(0.001);
  }
}

.elka {
width=100%;
margin-left: 13em;
margin-top: -33em; 
transform: scale(0.2);        
position: absolute;
z-index: 7;
  }

.snegovik {
width=100%;
margin-left: 35em;
margin-top: -30em; 
transform: scale(0.2);        
position: absolute;
z-index: 8;
  }

#blunt_container {
float: left;
margin-left: 12em; 
margin-top: -8em;
position: absolute;
z-index: 7;
  } 

#test{ width: 35vw;
height: 15vw;
position: absolute; 
top: 0;
left: 2em;
bottom: 25em;
right: 0;
margin: auto;

text-align: center;
  color: white;
  font:  500 30px/1.5 'Syncopate', sans-serif;
  font-style: italic;

  text-shadow: 
    0 1px 0 #ccc, 
        0 2px 0 #c9c9c9,
        0 3px 0 #bbb,
        0 4px 0 #b9b9b9,
        0 5px 0 #aaa,
        0 6px 1px   rgba(0,0,0, 0.10),
        0 0px 5px   rgba(0,0,0, 0.10),
        0 1px 3px   rgba(0,0,0, 0.30),
        0 3px 5px   rgba(0,0,0, 0.20),
        0 5px 10px  rgba(0,0,0, 0.25),
        0 10px 10px rgba(0,0,0, 0.20),
        0 20px 20px rgba(0,0,0, 0.15);
 text-transform: uppercase;
 font-size: 1.5vw; }


@-webkit-keyframes smoke1 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(6px, -36px);
            transform: scale(3) translate(6px, -36px);
    opacity: 0;
  }
}

@keyframes smoke1 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(6px, -36px);
            transform: scale(3) translate(6px, -36px);
    opacity: 0;
  }
}
@-webkit-keyframes smoke2 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(-8px, -50px);
            transform: scale(3) translate(-8px, -50px);
    opacity: 0;
  }
}
@keyframes smoke2 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(-8px, -50px);
            transform: scale(3) translate(-8px, -50px);
    opacity: 0;
  }
}
@-webkit-keyframes smoke3 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(-1px, -41px);
            transform: scale(3) translate(-1px, -41px);
    opacity: 0;
  }
}
@keyframes smoke3 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(-1px, -41px);
            transform: scale(3) translate(-1px, -41px);
    opacity: 0;
  }
}
@-webkit-keyframes smoke4 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(0px, -41px);
            transform: scale(3) translate(0px, -41px);
    opacity: 0;
  }
}
@keyframes smoke4 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(0px, -41px);
            transform: scale(3) translate(0px, -41px);
    opacity: 0;
  }
}
@-webkit-keyframes smoke5 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(-4px, -42px);
            transform: scale(3) translate(-4px, -42px);
    opacity: 0;
  }
}
@keyframes smoke5 {
  0% {
    -webkit-transform: scale(0.2);
            transform: scale(0.2);
    opacity: 0;
  }
  10% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3) translate(-4px, -42px);
            transform: scale(3) translate(-4px, -42px);
    opacity: 0;
  }
}
.smoke-group {
  width: 100px;
  height: 200px;
    margin-top: -20em;
    margin-left: 39em;
  position: absolute;
transform: skew(220deg, 0);; // наклон дыма 
}

.smoke {
  position: absolute;
  bottom: 0;
  left: calc(50% - 15px / 2);
  width: 15px;
  height: 15px;
  background-color: #FFFFFF;
  border-radius: 7.5px;
  -webkit-filter: blur(6px);
          filter: blur(6px);
  opacity: 0;
}
.smoke:nth-child(1) {
  -webkit-animation-name: smoke3;
          animation-name: smoke3;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 0.4s;
          animation-delay: 0.4s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(2) {
  -webkit-animation-name: smoke2;
          animation-name: smoke2;
  -webkit-animation-duration: 3s;
          animation-duration: 3s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 0.8s;
          animation-delay: 0.8s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(3) {
  -webkit-animation-name: smoke4;
          animation-name: smoke4;
  -webkit-animation-duration: 5s;
          animation-duration: 5s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 1.2s;
          animation-delay: 1.2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(4) {
  -webkit-animation-name: smoke2;
          animation-name: smoke2;
  -webkit-animation-duration: 5s;
          animation-duration: 5s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 1.6s;
          animation-delay: 1.6s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(5) {
  -webkit-animation-name: smoke3;
          animation-name: smoke3;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 2s;
          animation-delay: 2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(6) {
  -webkit-animation-name: smoke3;
          animation-name: smoke3;
  -webkit-animation-duration: 4s;
          animation-duration: 4s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 2.4s;
          animation-delay: 2.4s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(7) {
  -webkit-animation-name: smoke1;
          animation-name: smoke1;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 2.8s;
          animation-delay: 2.8s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(8) {
  -webkit-animation-name: smoke1;
          animation-name: smoke1;
  -webkit-animation-duration: 5s;
          animation-duration: 5s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 3.2s;
          animation-delay: 3.2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(9) {
  -webkit-animation-name: smoke5;
          animation-name: smoke5;
  -webkit-animation-duration: 5s;
          animation-duration: 5s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 3.6s;
          animation-delay: 3.6s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(10) {
  -webkit-animation-name: smoke4;
          animation-name: smoke4;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 4s;
          animation-delay: 4s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(11) {
  -webkit-animation-name: smoke5;
          animation-name: smoke5;
  -webkit-animation-duration: 3s;
          animation-duration: 3s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 4.4s;
          animation-delay: 4.4s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(12) {
  -webkit-animation-name: smoke4;
          animation-name: smoke4;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 4.8s;
          animation-delay: 4.8s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(13) {
  -webkit-animation-name: smoke5;
          animation-name: smoke5;
  -webkit-animation-duration: 4s;
          animation-duration: 4s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 5.2s;
          animation-delay: 5.2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(14) {
  -webkit-animation-name: smoke2;
          animation-name: smoke2;
  -webkit-animation-duration: 4s;
          animation-duration: 4s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 5.6s;
          animation-delay: 5.6s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(15) {
  -webkit-animation-name: smoke5;
          animation-name: smoke5;
  -webkit-animation-duration: 4s;
          animation-duration: 4s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 6s;
          animation-delay: 6s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(16) {
  -webkit-animation-name: smoke3;
          animation-name: smoke3;
  -webkit-animation-duration: 3s;
          animation-duration: 3s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 6.4s;
          animation-delay: 6.4s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(17) {
  -webkit-animation-name: smoke5;
          animation-name: smoke5;
  -webkit-animation-duration: 4s;
          animation-duration: 4s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 6.8s;
          animation-delay: 6.8s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(18) {
  -webkit-animation-name: smoke1;
          animation-name: smoke1;
  -webkit-animation-duration: 4s;
          animation-duration: 4s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 7.2s;
          animation-delay: 7.2s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(19) {
  -webkit-animation-name: smoke1;
          animation-name: smoke1;
  -webkit-animation-duration: 2s;
          animation-duration: 2s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 7.6s;
          animation-delay: 7.6s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}
.smoke:nth-child(20) {
  -webkit-animation-name: smoke4;
          animation-name: smoke4;
  -webkit-animation-duration: 3s;
          animation-duration: 3s;
  -webkit-animation-timing-function: ease-out;
          animation-timing-function: ease-out;
  -webkit-animation-delay: 8s;
          animation-delay: 8s;
  -webkit-animation-iteration-count: infinite;
          animation-iteration-count: infinite;
}

@keyframes animCloud {
  0% {
    transform: translateX(0);
  }
  49.99% {
    transform: translateX(calc(-50vw - 100px));
  }
  50% {
    transform: translateX(calc(50vw + 100px));
  }
  100% {
    transform: translateX(0);
  }
}
.cloud1 {
    -webkit-animation: animCloud 40s infinite linear;
    -moz-animation: animCloud 40s infinite linear;
    animation: animCloud 40s infinite linear
}
.cloud2 {
    -webkit-animation: animCloud 60s infinite linear;
    -moz-animation: animCloud 60s infinite linear;
    animation: animCloud 60s infinite linear
}
.cloud3 {
    -webkit-animation: animCloud 80s infinite linear;
    -moz-animation: animCloud 80s infinite linear;
    animation: animCloud 80s infinite linear
}
.cloud4 {
    -webkit-animation: animCloud 80s infinite linear;
    -moz-animation: animCloud 80s infinite linear;
    animation: animCloud 80s infinite linear
@-webkit-keyframes feelingit {
    50% { -webkit-transform: translateY(-20px); transform: translateY(-20px); }
    100% { -webkit-transform: translateY(0); transform: translateY(0); }
}
@keyframes feelingit {
    50% { -webkit-transform: translateY(-20px); transform: translateY(-20px); }
    100% { -webkit-transform: translateY(0); transform: translateY(0); }
}
var textNodes = [];
var textNodes_data = [];
var i=0;
function search_textNodes(b) {
    b = b.childNodes;
    for (var c = 0, d = b.length; c < d; c++) {
        var a = b[c];
        if (a.nodeType == 3) {
            textNodes.push(a);
            textNodes_data.push(a.data);
            a.data = ""
        } else a.hasChildNodes() && search_textNodes(a)
    }
};

var d = document.getElementById('test');
search_textNodes(d);
function str_write() {
    var a = textNodes_data[i];
    if (a) {
        textNodes[i].data += a.charAt(0);
        textNodes_data[i] = a.substr(1)
    } else i++;
    i < textNodes.length && setTimeout(arguments.callee, 100)
};
str_write()


//салют
window.onload = function () {
    var firework = JS_FIREWORKS.Fireworks({
        id : 'fireworks-canvas',
        hue : 120,
        particleCount : 50,
        delay : 0,
        minDelay : 10,
        maxDelay : 10,
        boundaries : {
            top: 0,
            bottom: 150,
            left: 70,
            right: 590
        },
        fireworkSpeed : 1,
        fireworkAcceleration : 1.05,
        particleFriction : .95,
        particleGravity : 1.5
    });
    firework.start();
};


/**
 * @required: 
 */


var JS_FIREWORKS = JS_FIREWORKS || {};

JS_FIREWORKS.Fireworks = function (options) {

    'use strict';

    if (!(this instanceof JS_FIREWORKS.Fireworks)) {
        return new JS_FIREWORKS.Fireworks(options);
    }

    options = options || {};

    var _self   = this,
        _NS     = JS_FIREWORKS,
        _Class  = _NS.Fireworks,
        _proto  = _Class.prototype,
        _canvas = document.getElementById(options.id || 'fireworks-canvas'),
        _ctx    = _canvas.getContext ? _canvas.getContext('2d') : null,
        _width  = _canvas.width,
        _height = _canvas.height,
        _hue        = options.hue || 120,
        _isRunning  = false,
        _fireworks  = [],
        _particles  = [],
        _particleCount = options.particleCount || 50,
        _tick       = 0,
        _delay      = options.delay || 30,
        _minDelay   = options.minDelay || 30,
        _maxDelay   = options.maxDelay || 90,
        _boundaries = options.boundaries || {
            top    : 50,
            bottom : _height * .5,
            left   : 50,
            right  : _width - 50
        },
        _loop         = _NS.getRenderLoop(),
        _randRange    = _NS.randomRange,
        _randIntRange = _NS.randomIntRange,
        _Firework     = _NS.Firework,
        _Particle     = _NS.Particle;


    _Class.settings = {
        fireworkSpeed : options.fireworkSpeed || 2,
        fireworkAcceleration : options.fireworkAcceleration || 1.05,
        particleFriction : options.particleFriction || .95,
        particleGravity : options.particleGravity || 1.5
    };

    _Class.version = '1.0.2';


    _self.start = function () {
        _isRunning = true;
        _fireworks = [];
        _particles = [];
        _render();
    };

    _self.stop = function () {
        _isRunning = false;
        _self.clear();
    };

    _self.isRunning = function () {
        return _isRunning;
    };

    _self.clear = function () {
        if (!_ctx) {
            return;
        }
        _ctx.globalCompositeOperation = 'source-over';
        _ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        _ctx.fillRect(0, 0, _width, _height);
    };



    var _render = function () {
        if (!_ctx || !_isRunning) {
            return;
        }
        var tmp, count;
        _loop(_render);
        _hue += 0.5;
        _ctx.globalCompositeOperation = 'destination-out';
        _ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        _ctx.fillRect(0, 0, _width, _height);
        _ctx.globalCompositeOperation = 'lighter';
        tmp = _fireworks.length;
        // render fireworks
        while (tmp--) {
            _fireworks[tmp].draw();
            _fireworks[tmp].update( function (x, y, hue) {
                count = _particleCount;
                while (count--) {
                    _particles.push(_Particle(x, y, _ctx, hue));
                }
                _fireworks.splice(tmp, 1);
            });
        }
        // render particles
        tmp = _particles.length;
        while (tmp--) {
            _particles[tmp].draw();
            _particles[tmp].update( function () {
                _particles.splice(tmp, 1);
            });
        }
        // spawn firework
        if (_tick === _delay) {
            _fireworks.push(_Firework(
                _width * .5,
                _height,
                _randIntRange(_boundaries.left, _boundaries.right),
                _randIntRange(_boundaries.top, _boundaries.bottom),
                _ctx,
                _hue
            ));
            _delay = _randIntRange(_minDelay, _maxDelay);
            _tick = 0;
        }
        _tick++;
    };


    return _self;

};

/**
 * 
 */
JS_FIREWORKS.Firework = function (x1, y1, x2, y2, context, hue) {

    'use strict';

    if (!(this instanceof JS_FIREWORKS.Firework)) {
        return new JS_FIREWORKS.Firework(x1, y1, x2, y2, context, hue);
    }

    var _self     = this,
        _NS       = JS_FIREWORKS,
        _Class    = _NS.Firework,
        _proto    = _Class.prototype,
        _settings = JS_FIREWORKS.Fireworks.settings,
        _x   = x1,
        _y   = y1,
        _sx  = x1,
        _sy  = y1,
        _dx  = x2,
        _dy  = y2,
        _ctx = context,
        _totalDistance   = 0,
        _currentDistance = 0,
        _coordinates     = [],
        _coordinateCount = 3,
        _angle           = 0,
        _speed           = _settings.fireworkSpeed,
        _acceleration    = _settings.fireworkAcceleration,
        _hue             = hue,
        _brightness      = 0,
        _randIntRange = _NS.randomIntRange,
        _distance     = _NS.distance,
        _sin          = Math.sin,
        _cos          = Math.cos;


    _self.update = function (callback) {
        _coordinates.pop();
        _coordinates.unshift([_x, _y]);
        _speed *= _acceleration;
        var vx = _cos(_angle) * _speed,
            vy = _sin(_angle) * _speed;
        _currentDistance = _distance(_sx, _sy, _x + vx, _y + vy);
        if (_currentDistance >= _totalDistance) {
            callback(_dx, _dy, _hue);
        } else {
            _x += vx;
            _y += vy;
        }
    };

    _self.draw = function () {
        var last = _coordinates.length - 1;
        _ctx.beginPath();
        _ctx.moveTo(_coordinates[last][0], _coordinates[last][1]);
        _ctx.lineTo(_x, _y);
        _ctx.strokeStyle = 'hsl(' + _hue + ', 100%, ' + _brightness + '%)';
        _ctx.stroke();
    };


    ( function () {
        _totalDistance = _distance(_sx, _sy, _dx, _dy);
        while (_coordinateCount--) {
            _coordinates.push([_x, _y]);
        }
        _angle = Math.atan2(_dy - _sy, _dx - _sx);
        _brightness = _randIntRange(50, 70);
    })();

    return _self;

};

/**
 * 
 */
JS_FIREWORKS.Particle = function (x, y, context, hue) {

    'use strict';

    if (!(this instanceof JS_FIREWORKS.Particle)) {
        return new JS_FIREWORKS.Particle(x, y, context, hue);
    }

    var _self     = this,
        _NS       = JS_FIREWORKS,
        _Class    = _NS.Particle,
        _proto    = _Class.prototype,
        _settings = JS_FIREWORKS.Fireworks.settings,
        _x        = x,
        _y        = y,
        _ctx      = context,
        _coordinates     = [],
        _coordinateCount = 5,
        _angle    = 0,
        _speed    = 0,
        _friction   = _settings.particleFriction,
        _gravity    = _settings.particleGravity,
        _hue        = hue,
        _brightness = 0,
        _alpha      = 1,
        _decay      = 0,
        _randRange    = _NS.randomRange,
        _randIntRange = _NS.randomIntRange,
        _2PI          = Math.PI * 2,
        _sin          = Math.sin,
        _cos          = Math.cos;

    _self.update = function (callback) {
        _coordinates.pop();
        _coordinates.unshift([_x, _y]);
        _speed *= _friction;
        _x += _cos(_angle) * _speed;
        _y += _sin(_angle) * _speed + _gravity;
        _alpha -= _decay;
        if (_alpha <= _decay) {
            callback();
        }
    };

    _self.draw = function () {
        var last = _coordinates.length - 1;
        _ctx.beginPath();
        _ctx.moveTo(_coordinates[last][0], _coordinates[last][1]);
        _ctx.lineTo(_x, _y);
        _ctx.strokeStyle = 'hsla(' + _hue + ', 100%, ' + _brightness + '%, ' + _alpha + ')';
        _ctx.stroke();
    };


    ( function () {
        while (_coordinateCount--) {
            _coordinates.push([_x, _y ]);
        }
        _angle = _randRange(0, _2PI);
        _speed = _randIntRange(1, 10);
        _hue   = _randIntRange(_hue - 20, _hue + 20);
        _brightness = _randIntRange(50, 80);
        _decay = _randRange(.015, .03);
    })();

    return _self;

};

/**
 * 
 */
JS_FIREWORKS.randomRange = function (min, max) {
    return (Math.random() * ( max - min ) + min);
};

/**
 * 
 */
JS_FIREWORKS.randomIntRange = function (min, max) {
    return JS_FIREWORKS.randomRange(min, max)|0;
};

/**
 * 
 */
JS_FIREWORKS.distance = function (x1, y1, x2, y2) {
    var pow = Math.pow;
    return Math.sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
};

/**
 * 
 */
JS_FIREWORKS.getRenderLoop = function () {
    return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame || 
        window.oRequestAnimationFrame || 
        window.msRequestAnimationFrame || 
        function (callback) { 
            return window.setTimeout(callback, 1000 / 60); 
        }
    );
};

Ответы (0 шт):