mirror of
				https://github.com/elyby/accounts-frontend.git
				synced 2025-05-31 14:11:58 +05:30 
			
		
		
		
	Переписана логика фона на странице бсода
This commit is contained in:
		@@ -5,6 +5,7 @@ import { FormattedMessage as Message } from 'react-intl';
 | 
			
		||||
import { IntlProvider } from 'components/i18n';
 | 
			
		||||
import appInfo from 'components/auth/appInfo/AppInfo.intl.json';
 | 
			
		||||
import messages from './BSoD.intl.json';
 | 
			
		||||
import { rAF as requestAnimationFrame } from 'functions';
 | 
			
		||||
 | 
			
		||||
import styles from './styles.scss';
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +15,7 @@ export default function BSoD({store}) {
 | 
			
		||||
    return (
 | 
			
		||||
        <IntlProvider store={store}>
 | 
			
		||||
            <div className={styles.body}>
 | 
			
		||||
                <canvas ref={(el) => createThatMagicEffect(el)} />
 | 
			
		||||
                <canvas className={styles.canvas} ref={(el) => new BoxesField(el)} />
 | 
			
		||||
 | 
			
		||||
                <div className={styles.wrapper}>
 | 
			
		||||
                    <div className={styles.title}>
 | 
			
		||||
@@ -38,176 +39,217 @@ export default function BSoD({store}) {
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {Node} c - canvas DOM node
 | 
			
		||||
 * @see http://codepen.io/mladen___/pen/gbvqBo
 | 
			
		||||
 */
 | 
			
		||||
function createThatMagicEffect(c) {
 | 
			
		||||
    var ctx = c.getContext("2d");
 | 
			
		||||
class Box {
 | 
			
		||||
 | 
			
		||||
    function resize() {
 | 
			
		||||
        var box = c.getBoundingClientRect();
 | 
			
		||||
        c.width = box.width;
 | 
			
		||||
        c.height = box.height;
 | 
			
		||||
    constructor({size, startX, startY, startRotate, color, shadowColor}) {
 | 
			
		||||
        this.color = color;
 | 
			
		||||
        this.shadowColor = shadowColor;
 | 
			
		||||
        this.setSize(size);
 | 
			
		||||
        this.x = startX;
 | 
			
		||||
        this.y = startY;
 | 
			
		||||
        this.angle = startRotate;
 | 
			
		||||
        this.shadowLength = 2000; // TODO: should be calculated
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var light = {
 | 
			
		||||
        x: 160,
 | 
			
		||||
        y: 200
 | 
			
		||||
    get size() {
 | 
			
		||||
        return this._initialSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var colors = ["#f5c156", "#e6616b", "#5cd3ad"];
 | 
			
		||||
    get dots() {
 | 
			
		||||
        const full = (Math.PI * 2) / 4;
 | 
			
		||||
 | 
			
		||||
    function drawLight() {
 | 
			
		||||
        ctx.beginPath();
 | 
			
		||||
        ctx.arc(light.x, light.y, 1000, 0, 2 * Math.PI);
 | 
			
		||||
        var gradient = ctx.createRadialGradient(light.x, light.y, 0, light.x, light.y, 1000);
 | 
			
		||||
        gradient.addColorStop(0, "#3b4654");
 | 
			
		||||
        gradient.addColorStop(1, "#2c343f");
 | 
			
		||||
        ctx.fillStyle = gradient;
 | 
			
		||||
        ctx.fill();
 | 
			
		||||
        const p1 = {
 | 
			
		||||
            x: this.x + this.halfSize * Math.sin(this.angle),
 | 
			
		||||
            y: this.y + this.halfSize * Math.cos(this.angle)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const p2 = {
 | 
			
		||||
            x: this.x + this.halfSize * Math.sin(this.angle + full),
 | 
			
		||||
            y: this.y + this.halfSize * Math.cos(this.angle + full)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const p3 = {
 | 
			
		||||
            x: this.x + this.halfSize * Math.sin(this.angle + full * 2),
 | 
			
		||||
            y: this.y + this.halfSize * Math.cos(this.angle + full * 2)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        const p4 = {
 | 
			
		||||
            x: this.x + this.halfSize * Math.sin(this.angle + full * 3),
 | 
			
		||||
            y: this.y + this.halfSize * Math.cos(this.angle + full * 3)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return { p1, p2, p3, p4 };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rotate() {
 | 
			
		||||
        const speed = (60 - this.halfSize) / 20;
 | 
			
		||||
        this.angle += speed * 0.002;
 | 
			
		||||
        this.x += speed;
 | 
			
		||||
        this.y += speed;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    draw(ctx) {
 | 
			
		||||
        const dots = this.dots;
 | 
			
		||||
        ctx.beginPath();
 | 
			
		||||
        ctx.arc(light.x, light.y, 20, 0, 2 * Math.PI);
 | 
			
		||||
        gradient = ctx.createRadialGradient(light.x, light.y, 0, light.x, light.y, 5);
 | 
			
		||||
        gradient.addColorStop(0, "#fff");
 | 
			
		||||
        gradient.addColorStop(1, "#3b4654");
 | 
			
		||||
        ctx.fillStyle = gradient;
 | 
			
		||||
        ctx.moveTo(dots.p1.x, dots.p1.y);
 | 
			
		||||
        ctx.lineTo(dots.p2.x, dots.p2.y);
 | 
			
		||||
        ctx.lineTo(dots.p3.x, dots.p3.y);
 | 
			
		||||
        ctx.lineTo(dots.p4.x, dots.p4.y);
 | 
			
		||||
        ctx.fillStyle = this.color;
 | 
			
		||||
        ctx.fill();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function Box() {
 | 
			
		||||
        this.half_size = Math.floor((Math.random() * 50) + 1);
 | 
			
		||||
        this.x = Math.floor((Math.random() * c.width) + 1);
 | 
			
		||||
        this.y = Math.floor((Math.random() * c.height) + 1);
 | 
			
		||||
        this.r = Math.random() * Math.PI;
 | 
			
		||||
        this.shadow_length = 2000;
 | 
			
		||||
        this.color = colors[Math.floor((Math.random() * colors.length))];
 | 
			
		||||
    drawShadow(ctx, light) {
 | 
			
		||||
        const dots = this.dots;
 | 
			
		||||
        const angles = [];
 | 
			
		||||
        const points = [];
 | 
			
		||||
 | 
			
		||||
        this.getDots = function() {
 | 
			
		||||
            var full = (Math.PI * 2) / 4;
 | 
			
		||||
 | 
			
		||||
            var p1 = {
 | 
			
		||||
                x: this.x + this.half_size * Math.sin(this.r),
 | 
			
		||||
                y: this.y + this.half_size * Math.cos(this.r)
 | 
			
		||||
            };
 | 
			
		||||
            var p2 = {
 | 
			
		||||
                x: this.x + this.half_size * Math.sin(this.r + full),
 | 
			
		||||
                y: this.y + this.half_size * Math.cos(this.r + full)
 | 
			
		||||
            };
 | 
			
		||||
            var p3 = {
 | 
			
		||||
                x: this.x + this.half_size * Math.sin(this.r + full * 2),
 | 
			
		||||
                y: this.y + this.half_size * Math.cos(this.r + full * 2)
 | 
			
		||||
            };
 | 
			
		||||
            var p4 = {
 | 
			
		||||
                x: this.x + this.half_size * Math.sin(this.r + full * 3),
 | 
			
		||||
                y: this.y + this.half_size * Math.cos(this.r + full * 3)
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
                p1: p1,
 | 
			
		||||
                p2: p2,
 | 
			
		||||
                p3: p3,
 | 
			
		||||
                p4: p4
 | 
			
		||||
            };
 | 
			
		||||
        for (const i in dots) {
 | 
			
		||||
            const dot = dots[i];
 | 
			
		||||
            const angle = Math.atan2(light.y - dot.y, light.x - dot.x);
 | 
			
		||||
            const endX = dot.x + this.shadowLength * Math.sin(-angle - Math.PI / 2);
 | 
			
		||||
            const endY = dot.y + this.shadowLength * Math.cos(-angle - Math.PI / 2);
 | 
			
		||||
            angles.push(angle);
 | 
			
		||||
            points.push({
 | 
			
		||||
                endX,
 | 
			
		||||
                endY,
 | 
			
		||||
                startX: dot.x,
 | 
			
		||||
                startY: dot.y
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        this.rotate = function() {
 | 
			
		||||
            var speed = (60 - this.half_size) / 20;
 | 
			
		||||
            this.r += speed * 0.002;
 | 
			
		||||
            this.x += speed;
 | 
			
		||||
            this.y += speed;
 | 
			
		||||
        }
 | 
			
		||||
        this.draw = function() {
 | 
			
		||||
            var dots = this.getDots();
 | 
			
		||||
 | 
			
		||||
        for (let i = points.length - 1; i >= 0; i--) {
 | 
			
		||||
            const n = i === 3 ? 0 : i + 1;
 | 
			
		||||
            ctx.beginPath();
 | 
			
		||||
            ctx.moveTo(dots.p1.x, dots.p1.y);
 | 
			
		||||
            ctx.lineTo(dots.p2.x, dots.p2.y);
 | 
			
		||||
            ctx.lineTo(dots.p3.x, dots.p3.y);
 | 
			
		||||
            ctx.lineTo(dots.p4.x, dots.p4.y);
 | 
			
		||||
            ctx.fillStyle = this.color;
 | 
			
		||||
            ctx.moveTo(points[i].startX, points[i].startY);
 | 
			
		||||
            ctx.lineTo(points[n].startX, points[n].startY);
 | 
			
		||||
            ctx.lineTo(points[n].endX, points[n].endY);
 | 
			
		||||
            ctx.lineTo(points[i].endX, points[i].endY);
 | 
			
		||||
            ctx.fillStyle = this.shadowColor;
 | 
			
		||||
            ctx.fill();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (this.y - this.half_size > c.height) {
 | 
			
		||||
                this.y -= c.height + 100;
 | 
			
		||||
            }
 | 
			
		||||
            if (this.x - this.half_size > c.width) {
 | 
			
		||||
                this.x -= c.width + 100;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.drawShadow = function() {
 | 
			
		||||
            var dots = this.getDots();
 | 
			
		||||
            var angles = [];
 | 
			
		||||
            var points = [];
 | 
			
		||||
 | 
			
		||||
            for (let dot in dots) {
 | 
			
		||||
                var angle = Math.atan2(light.y - dots[dot].y, light.x - dots[dot].x);
 | 
			
		||||
                var endX = dots[dot].x + this.shadow_length * Math.sin(-angle - Math.PI / 2);
 | 
			
		||||
                var endY = dots[dot].y + this.shadow_length * Math.cos(-angle - Math.PI / 2);
 | 
			
		||||
                angles.push(angle);
 | 
			
		||||
                points.push({
 | 
			
		||||
                    endX: endX,
 | 
			
		||||
                    endY: endY,
 | 
			
		||||
                    startX: dots[dot].x,
 | 
			
		||||
                    startY: dots[dot].y
 | 
			
		||||
                });
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            for (var i = points.length - 1; i >= 0; i--) {
 | 
			
		||||
                var n = i == 3 ? 0 : i + 1;
 | 
			
		||||
                ctx.beginPath();
 | 
			
		||||
                ctx.moveTo(points[i].startX, points[i].startY);
 | 
			
		||||
                ctx.lineTo(points[n].startX, points[n].startY);
 | 
			
		||||
                ctx.lineTo(points[n].endX, points[n].endY);
 | 
			
		||||
                ctx.lineTo(points[i].endX, points[i].endY);
 | 
			
		||||
                ctx.fillStyle = "#2c343f";
 | 
			
		||||
                ctx.fill();
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var boxes = [];
 | 
			
		||||
 | 
			
		||||
    function draw() {
 | 
			
		||||
        ctx.clearRect(0, 0, c.width, c.height);
 | 
			
		||||
        drawLight();
 | 
			
		||||
 | 
			
		||||
        for (var i = 0; i < boxes.length; i++) {
 | 
			
		||||
            boxes[i].rotate();
 | 
			
		||||
            boxes[i].drawShadow();
 | 
			
		||||
        };
 | 
			
		||||
        for (var i = 0; i < boxes.length; i++) {
 | 
			
		||||
            collisionDetection(i)
 | 
			
		||||
            boxes[i].draw();
 | 
			
		||||
        };
 | 
			
		||||
        requestAnimationFrame(draw);
 | 
			
		||||
    setSize(size) {
 | 
			
		||||
        this._initialSize = size;
 | 
			
		||||
        this.halfSize = Math.floor(size / 2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Основано на http://codepen.io/mladen___/pen/gbvqBo
 | 
			
		||||
 */
 | 
			
		||||
class BoxesField {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {Node} elem - canvas DOM node
 | 
			
		||||
     * @param {object} params
 | 
			
		||||
     */
 | 
			
		||||
    constructor(elem, params = {
 | 
			
		||||
        countBoxes: 14,
 | 
			
		||||
        boxMinSize: 20,
 | 
			
		||||
        boxMaxSize: 75,
 | 
			
		||||
        backgroundColor: '#233d49',
 | 
			
		||||
        lightColor: '#28555b',
 | 
			
		||||
        shadowColor: '#274451',
 | 
			
		||||
        boxColors: ['#207e5c', '#5b9aa9', '#e66c69', '#6b5b8c', '#8b5d79', '#dd8650']
 | 
			
		||||
    }) {
 | 
			
		||||
        this.elem = elem;
 | 
			
		||||
        this.ctx = elem.getContext('2d');
 | 
			
		||||
        this.params = params;
 | 
			
		||||
 | 
			
		||||
        this.light = {
 | 
			
		||||
            x: 160,
 | 
			
		||||
            y: 200
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.resize();
 | 
			
		||||
        this.drawLoop();
 | 
			
		||||
        this.bindWindowListeners();
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * @type {Box[]}
 | 
			
		||||
         */
 | 
			
		||||
        this.boxes = [];
 | 
			
		||||
        while (this.boxes.length < this.params.countBoxes) {
 | 
			
		||||
            this.boxes.push(new Box({
 | 
			
		||||
                size: Math.floor((Math.random() * (this.params.boxMaxSize - this.params.boxMinSize)) + this.params.boxMinSize),
 | 
			
		||||
                startX: Math.floor((Math.random() * elem.width) + 1),
 | 
			
		||||
                startY: Math.floor((Math.random() * elem.height) + 1),
 | 
			
		||||
                startRotate: Math.random() * Math.PI,
 | 
			
		||||
                color: this.getRandomColor(),
 | 
			
		||||
                shadowColor: this.params.shadowColor
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    resize() {
 | 
			
		||||
        const { width, height } = this.elem.getBoundingClientRect();
 | 
			
		||||
        this.elem.width = width;
 | 
			
		||||
        this.elem.height = height;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    drawLight(light) {
 | 
			
		||||
        const greaterSize = window.screen.width > window.screen.height ? window.screen.width : window.screen.height;
 | 
			
		||||
        // еее, теорема пифагора и описывание окружности вокруг квадрата, не зря в универ ходил!!!
 | 
			
		||||
        const lightRadius = greaterSize * Math.sqrt(2);
 | 
			
		||||
 | 
			
		||||
        this.ctx.beginPath();
 | 
			
		||||
        this.ctx.arc(light.x, light.y, lightRadius, 0, 2 * Math.PI);
 | 
			
		||||
        const gradient = this.ctx.createRadialGradient(light.x, light.y, 0, light.x, light.y, lightRadius);
 | 
			
		||||
        gradient.addColorStop(0, this.params.lightColor);
 | 
			
		||||
        gradient.addColorStop(1, this.params.backgroundColor);
 | 
			
		||||
        this.ctx.fillStyle = gradient;
 | 
			
		||||
        this.ctx.fill();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    drawLoop() {
 | 
			
		||||
        this.ctx.clearRect(0, 0, this.elem.width, this.elem.height);
 | 
			
		||||
        this.drawLight(this.light);
 | 
			
		||||
 | 
			
		||||
        for (let i in this.boxes) {
 | 
			
		||||
            const box = this.boxes[i];
 | 
			
		||||
            box.rotate();
 | 
			
		||||
            box.drawShadow(this.ctx, this.light);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (let i in this.boxes) {
 | 
			
		||||
            const box = this.boxes[i];
 | 
			
		||||
            box.draw(this.ctx);
 | 
			
		||||
 | 
			
		||||
            // Если квадратик вылетел за пределы экрана
 | 
			
		||||
            if (box.y - box.halfSize > this.elem.height) {
 | 
			
		||||
                box.y -= this.elem.height + 100;
 | 
			
		||||
                this.updateBox(box);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (box.x - box.halfSize > this.elem.width) {
 | 
			
		||||
                box.x -= this.elem.width + 100;
 | 
			
		||||
                this.updateBox(box);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        requestAnimationFrame(this.drawLoop.bind(this));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bindWindowListeners() {
 | 
			
		||||
        window.addEventListener('resize', this.resize.bind(this));
 | 
			
		||||
        window.addEventListener('mousemove', (event) => {
 | 
			
		||||
            this.light.x = event.clientX;
 | 
			
		||||
            this.light.y = event.clientY;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param {Box} box
 | 
			
		||||
     */
 | 
			
		||||
    updateBox(box) {
 | 
			
		||||
        box.color = this.getRandomColor();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getRandomColor() {
 | 
			
		||||
        return this.params.boxColors[Math.floor((Math.random() * this.params.boxColors.length))];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    resize();
 | 
			
		||||
    draw();
 | 
			
		||||
 | 
			
		||||
    while (boxes.length < 14) {
 | 
			
		||||
        boxes.push(new Box());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    window.addEventListener('resize', resize);
 | 
			
		||||
    c.onmousemove = function(e) {
 | 
			
		||||
        light.x = e.offsetX == undefined ? e.layerX : e.offsetX;
 | 
			
		||||
        light.y = e.offsetY == undefined ? e.layerY : e.offsetY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function collisionDetection(b) {
 | 
			
		||||
        for (var i = boxes.length - 1; i >= 0; i--) {
 | 
			
		||||
            if(i != b) {
 | 
			
		||||
                var dx = (boxes[b].x + boxes[b].half_size) - (boxes[i].x + boxes[i].half_size);
 | 
			
		||||
                var dy = (boxes[b].y + boxes[b].half_size) - (boxes[i].y + boxes[i].half_size);
 | 
			
		||||
                var d = Math.sqrt(dx * dx + dy * dy);
 | 
			
		||||
 | 
			
		||||
                if (d < boxes[b].half_size + boxes[i].half_size) {
 | 
			
		||||
                    boxes[b].half_size = boxes[b].half_size > 1 ? boxes[b].half_size-=1 : 1;
 | 
			
		||||
                    boxes[i].half_size = boxes[i].half_size > 1 ? boxes[i].half_size-=1 : 1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,14 +5,22 @@ $font-family-monospaced: 'Consolas', monospace;
 | 
			
		||||
.body {
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    background-color: $dark_blue;
 | 
			
		||||
    border-top: 50px solid darker($dark_blue);
 | 
			
		||||
    color: #fff;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    font-family: $font-family-monospaced;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.canvas {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.wrapper {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    margin: 85px auto 0;
 | 
			
		||||
    max-width: 500px;
 | 
			
		||||
    padding: 0 20px;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user