export default function canvasBg() {
    var canvas,
        ctx,
        width,
        height,
        size,
        lines,
        tick;

    function line() {
        this.path = [];
        this.speed = rand(10, 20);
        this.count = randInt(10, 30);
        this.x = width / 2, +1;
        this.y = height / 2 + 1;
        this.target = {
            x: width / 2,
            y: height / 2
        };
        this.dist = 0;
        this.angle = 0;
        this.hue = tick / 5;
        this.life = 1;
        this.updateAngle();
        this.updateDist();
    }

    line.prototype.step = function(i) {
        this.x += Math.cos(this.angle) * this.speed;
        this.y += Math.sin(this.angle) * this.speed;

        this.updateDist();

        if (this.dist < this.speed) {
            this.x = this.target.x;
            this.y = this.target.y;
            this.changeTarget();
        }

        this.path.push({
            x: this.x,
            y: this.y
        });
        if (this.path.length > this.count) {
            this.path.shift();
        }

        this.life -= 0.001;

        if (this.life <= 0) {
            this.path = null;
            lines.splice(i, 1);
        }
    };

    line.prototype.updateDist = function() {
        var dx = this.target.x - this.x,
            dy = this.target.y - this.y;
        this.dist = Math.sqrt(dx * dx + dy * dy);
    }

    line.prototype.updateAngle = function() {
        var dx = this.target.x - this.x,
            dy = this.target.y - this.y;
        this.angle = Math.atan2(dy, dx);
    }

    line.prototype.changeTarget = function() {
        var randStart = randInt(0, 3);
        switch (randStart) {
            case 0: // up
                this.target.y = this.y - size;
                break;
            case 1: // right
                this.target.x = this.x + size;
                break;
            case 2: // down
                this.target.y = this.y + size;
                break;
            case 3: // left
                this.target.x = this.x - size;
        }
        this.updateAngle();
    };

    line.prototype.draw = function(i) {
        ctx.beginPath();
        var rando = rand(0, 10);
        for (var j = 0, length = this.path.length; j < length; j++) {
            ctx[(j === 0) ? 'moveTo' : 'lineTo'](this.path[j].x + rand(-rando, rando), this.path[j].y +
                rand(-rando, rando));
        }
        ctx.strokeStyle = 'hsla(' + rand(this.hue, this.hue + 30) + ', 80%, 55%, ' + (this.life / 3) + ')';
        ctx.lineWidth = rand(0.1, 2);
        ctx.stroke();
    };

    function rand(min, max) {
        return Math.random() * (max - min) + min;
    }

    function randInt(min, max) {
        return Math.floor(min + Math.random() * (max - min + 1));
    };

    function init() {
        canvas = document.getElementById('canvas');
        ctx = canvas.getContext('2d');
        size = 30;
        lines = [];
        reset();
        loop();
    }

    function reset() {
        width = Math.ceil(window.innerWidth / 2) * 2;
        height = Math.ceil(window.innerHeight / 2) * 2;
        tick = 0;

        lines.length = 0;
        canvas.width = width;
        canvas.height = height;
    }

    function create() {
        if (tick % 10 === 0) {
            lines.push(new line());
        }
    }

    function step() {
        var i = lines.length;
        while (i--) {
            lines[i].step(i);
        }
    }

    function clear() {
        ctx.globalCompositeOperation = 'destination-out';
        ctx.fillStyle = 'hsla(0, 0%, 0%, 0.1)';
        ctx.fillRect(0, 0, width, height);
        ctx.globalCompositeOperation = 'lighter';
    }

    function draw() {
        ctx.save();
        ctx.translate(width / 2, height / 2);
        ctx.rotate(tick * 0.001);
        var scale = 0.8 + Math.cos(tick * 0.02) * 0.2;
        ctx.scale(scale, scale);
        ctx.translate(-width / 2, -height / 2);
        var i = lines.length;
        while (i--) {
            lines[i].draw(i);
        }
        ctx.restore();
    }

    function loop() {
        requestAnimationFrame(loop);
        create();
        step();
        clear();
        draw();
        tick++;
    }

    function onresize() {
        reset();
    }

    window.addEventListener('resize', onresize);

    init();
}
