@Bersonazh

Поможете понять как и когда работают функции?

Всем привет! Ранее подобный вопрос мною уже задавался, но был забракован за его объемность ) Поэтому на этот раз прошу понять как работают некоторые моменты в коде. И так, есть три состояния, 1 - момент сбора по пикселям, 2 - момент разбития на пиксели, 3 - ускоренный сбор. Так вот, прошу помочь найти и объяснить вообще как работают этот ускоренный сбор и каким образом задается время к нему

ДЕМО

Код целиком
function Particle(x, y, color) {
        this.finished = false;
        this.color = color;
        this.des = { x: x, y: y };
        this.init = { x: 0, y: 0 };
        this.offset = { x: 0, y: 0 };
        this.current = { x: 0, y: 0 };
        this.prev = { x: 0, y: 0 };
        this.started = false;
        this.percent = 0;
        this.timePass = 0;
        this.dur = 2000 + Math.random() * 4000;
        this.easing = function(t, b, c, d) {
            if ((t/=d/2) < 1) return c/2*t*t*t + b;
            return c/2*((t-=2)*t*t + 2) + b;
        };
    }
    Particle.prototype = {
        update: function(delta) {
            if (!this.started && !this.finished) return;
            this.timePass += delta;
            this.percent = this.easing(this.timePass, 0, 1, this.dur);
            this.prev = this.current;
            this.current = {
                x: this.init.x + this.offset.x * this.percent,
                y: this.init.y + this.offset.y * this.percent
            };
            if (this.percent >= 1) {
                this.percent = 1;
                this.finished = true;
                this.current.x = this.des.x;
                this.current.y = this.des.y;
            }
        },
        start: function(startX, startY) {
            var width = window.innerWidth * 5;
            var height = window.innerHeight * 5;
            var angle = Math.PI * 2 * Math.random();
            var radius = Math.sqrt(width*width + height*height)/2;
            startX = startX || (Math.cos(angle) * radius) + window.innerWidth/2;
            startY = startY || (Math.sin(angle) * radius) + window.innerHeight/2;
            this.started = true;
            this.timePass = 0;
            this.finished = false;
            this.init = {x: startX, y: startY};
            this.current = this.prev = this.init;
            this.offset = { x: this.des.x - this.init.x, y: this.des.y - this.init.y }
        },
        reset: function(x, y) {
            this.timePass = 0;
            this.finished = false;
            this.percent = 0;
            this.timePass = 0;
            this.dur = 4000 + Math.random() * 6000;
            this.current = this.prev = this.init;
            this.offset = { x: this.des.x - this.init.x, y: this.des.y - this.init.y }
        }
    }
    function Ani() {
        this.particles = [];
        this.wrap = document.querySelector('body');
        this.cvs;
        this.ctx;
        this.offlineCtx;
        this.offlineCvs;
        this.background = '#000000';
        this.img;
        this.imgPos;
        this.mouse = { x: 0, y: 0 };
        this.screen = { width: window.innerWidth, height: window.innerHeight };
        this.T;
        this.init();
    }
    Ani.prototype = {
        init: function() {
            var that = this;
            var img = new Image();
            this.img = document.querySelector('.logo');
            img.src = document.querySelector('.logo').src;
            img.onload = function() {
                that.create();
                that.wrap.addEventListener('mousemove', that.mouseHandle());
                that.tick();
            }
            window.addEventListener('resize', this.resize())
        },
        mouseHandle: function() {
            var that = this;
            function mouseHandle(e) {
                that.mouse.x = e.offsetX;
                that.mouse.y = e.offsetY;
            }
            that.mouseHandle = mouseHandle;
            return mouseHandle;
        },
        resize: function() {
            var that = this;
            function resize() {
                that.screen = { width: window.innerWidth, height: window.innerHeight };
                that.cvs.width = that.screen.width;
                that.cvs.height = that.screen.height;
                that.offlineCvs.width = that.screen.width;
                that.offlineCvs.height = that.screen.height;
                var lastImgPos = that.imgPos;
                that.imgPos = that.img.getBoundingClientRect();
                that.imgPos = { top: that.img.offsetTop, left: that.img.getBoundingClientRect().left };
                var imgPosOffset = {
                    left: that.imgPos.left - lastImgPos.left,
                    top: that.imgPos.top - lastImgPos.top
                };
                that.particles.forEach(function(particle) {
                    particle.des.x += imgPosOffset.left;
                    particle.des.y += imgPosOffset.top;
                });
            }
            this.resize = resize;
            return resize;
        },
        create: function() {
            var imgPos = { top: this.img.offsetTop, left: this.img.getBoundingClientRect().left };
            this.imgPos = imgPos;
            this.cvs = this.wrap.querySelector('canvas');
            this.offlineCvs = document.createElement('canvas');
            this.resize();
            this.ctx = this.cvs.getContext('2d');
            this.offlineCtx = this.offlineCvs.getContext('2d');
            var imgCvs = document.createElement('canvas');
            imgCvs.width = this.img.width;
            imgCvs.height = this.img.height;
            var imgCtx = imgCvs.getContext('2d');
            imgCtx.drawImage(this.img, 0, 0);
            var pixs = imgCtx.getImageData(0, 0, this.img.width, this.img.height).data;
            for (var i = 0; i < pixs.length; i += 4) {
                var r = pixs[i],
                    g = pixs[i + 1],
                    b = pixs[i + 2],
                    a = pixs[i + 3];
                if (a > 0) {
                    var x = (i % (4 * this.img.width)) / 4;
                    var y = parseInt(i / (4 * this.img.width));
                    this.particles.push(new Particle(imgPos.left + x, imgPos.top + y, 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'));
                }
            }
        },
        tick: function() {
            var that = this;
            var start = 3;
            var startCount = 0;
            var now = (new Date()).getTime();
            var last = now;
            var delta;
            var reset = false;
            function _tick() {
                now = (new Date()).getTime();
                delta = now - last;
                delta = delta > 50 ? 16 : delta;
                that.cvs.innerHTML = delta;
                last = now;
                startCount = 0;
                if (!that.particles.length) { that.finish();
                    return; }
                that.particles.forEach(function(particle) {
                    if (!particle.started && startCount < start && Math.random() > 0.5) {
                        startCount++;
                        particle.start(/* that.mouse.x, that.mouse.y */); // no mouse ...
                    } else {
                        particle.update(delta);
                    }
                });
                that.draw();
                if (!reset && that.particles.every(function(particle) {
                    return particle.finished })) {
                    var tmp;
                    reset = true;
                    setTimeout(function() {
                        reset = false;
                        that.particles.forEach(function(particle) {
                            tmp = particle.des;
                            particle.des = particle.init;
                            particle.init = tmp;
                            particle.reset();
                        });
                    }, 1000);
                }
                window.requestAnimationFrame(_tick);
            }
            _tick();
        },

        draw: function() {
            var particle;
            var r = 1;
            this.offlineCtx.save();
            this.offlineCtx.globalCompositeOperation = 'destination-in';
            this.offlineCtx.globalAlpha = 0.8;
            this.offlineCtx.strokeStyle = this.offlineCtx.fillStyle = '#ffffff';
            this.offlineCtx.fillRect(0, 0, this.screen.width, this.screen.height);
            this.offlineCtx.restore();
            this.offlineCtx.save();
            this.offlineCtx.beginPath();
            this.offlineCtx.lineWidth = r;
            this.offlineCtx.lineCap = this.offlineCtx.lineJoin = 'round';
            for (var i = 0; i < this.particles.length; i++) {
                particle = this.particles[i];
                this.offlineCtx.beginPath();
                this.offlineCtx.lineWidth = r;
                this.offlineCtx.moveTo(particle.current.x, particle.current.y);
                this.offlineCtx.lineTo(particle.prev.x, particle.prev.y);
                this.offlineCtx.strokeStyle = particle.color;
                this.offlineCtx.stroke();
            }

            this.offlineCtx.restore();
            this.ctx.fillStyle = this.background;
            this.ctx.fillRect(0, 0, this.screen.width, this.screen.height);
            this.ctx.drawImage(this.offlineCvs, 0, 0);
        },
        finish: function() {
            this.wrap.removeEventListener('mousemove', this.mouseHandle);
            window.removeEventListener('resize', this.resize);
            window.cancelAnimationFrame(this.T);
        }
    }
  • Вопрос задан
  • 127 просмотров
Решения вопроса 1
twobomb
@twobomb
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
SilenceOfWinter
@SilenceOfWinter
та еще зажигалка...
это задание, а не вопрос. пиши конкретнее какие моменты в коде не понятны. если не понятен весь код, то вначале стоит освоить мануал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы