2016-07-29 23:25:19 +05:30
|
|
|
import React from 'react';
|
|
|
|
|
2016-11-12 05:03:12 +05:30
|
|
|
import { FormattedMessage as Message } from 'react-intl';
|
|
|
|
|
2016-11-12 14:35:38 +05:30
|
|
|
import { IntlProvider } from 'components/i18n';
|
2016-11-12 05:03:12 +05:30
|
|
|
import appInfo from 'components/auth/appInfo/AppInfo.intl.json';
|
|
|
|
import messages from './BSoD.intl.json';
|
|
|
|
|
|
|
|
import styles from './styles.scss';
|
|
|
|
|
2016-11-12 14:35:38 +05:30
|
|
|
// TODO: probably it is better to render this view from the App view
|
|
|
|
// to remove dependencies from store and IntlProvider
|
|
|
|
export default function BSoD({store}) {
|
2016-07-29 23:25:19 +05:30
|
|
|
return (
|
2016-11-12 14:35:38 +05:30
|
|
|
<IntlProvider store={store}>
|
|
|
|
<div className={styles.body}>
|
2016-11-12 14:45:23 +05:30
|
|
|
<canvas ref={(el) => createThatMagicEffect(el)} />
|
|
|
|
|
2016-11-12 14:35:38 +05:30
|
|
|
<div className={styles.wrapper}>
|
|
|
|
<div className={styles.title}>
|
|
|
|
<Message {...appInfo.appName} />
|
|
|
|
</div>
|
|
|
|
<div className={styles.lineWithMargin}>
|
|
|
|
<Message {...messages.criticalErrorHappened} />
|
|
|
|
</div>
|
|
|
|
<div className={styles.line}>
|
|
|
|
<Message {...messages.reloadPageOrContactUs} />
|
|
|
|
</div>
|
|
|
|
<a href="mailto:support@ely.by" className={styles.support}>
|
|
|
|
support@ely.by
|
|
|
|
</a>
|
|
|
|
<div className={styles.easterEgg}>
|
|
|
|
<Message {...messages.alsoYouCanInteractWithBackground}/>
|
|
|
|
</div>
|
2016-11-12 05:03:12 +05:30
|
|
|
</div>
|
|
|
|
</div>
|
2016-11-12 14:35:38 +05:30
|
|
|
</IntlProvider>
|
2016-07-29 23:25:19 +05:30
|
|
|
);
|
|
|
|
}
|
2016-11-12 14:45:23 +05:30
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {Node} c - canvas DOM node
|
|
|
|
* @see http://codepen.io/mladen___/pen/gbvqBo
|
|
|
|
*/
|
|
|
|
function createThatMagicEffect(c) {
|
|
|
|
var ctx = c.getContext("2d");
|
|
|
|
|
|
|
|
function resize() {
|
|
|
|
var box = c.getBoundingClientRect();
|
|
|
|
c.width = box.width;
|
|
|
|
c.height = box.height;
|
|
|
|
}
|
|
|
|
|
|
|
|
var light = {
|
|
|
|
x: 160,
|
|
|
|
y: 200
|
|
|
|
}
|
|
|
|
|
|
|
|
var colors = ["#f5c156", "#e6616b", "#5cd3ad"];
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
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.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))];
|
|
|
|
|
|
|
|
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
|
|
|
|
};
|
|
|
|
}
|
|
|
|
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();
|
|
|
|
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.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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|