task2 frontend

main
Nikita Tokarchuk 4 years ago
parent 799ee3d6c8
commit 8fb2789461
  1. 549
      task2/css/main.css
  2. 2993
      task2/css/util.css
  3. BIN
      task2/images/icons/favicon.ico
  4. 64
      task2/index.html
  5. 464
      task2/js/main.js

@ -0,0 +1,549 @@
#game {width: auto;}
.hidden {display: none;}
/*//////////////////////////////////////////////////////////////////
[ RESTYLE TAG ]*/
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body, html {
height: 100%;
font-family: 'Roboto', sans-serif;
}
/*---------------------------------------------*/
a {
font-family: 'Roboto', sans-serif;
font-size: 14px;
line-height: 1.7;
color: #666666;
margin: 0px;
transition: all 0.4s;
-webkit-transition: all 0.4s;
-o-transition: all 0.4s;
-moz-transition: all 0.4s;
}
a:focus {
outline: none !important;
}
a:hover {
text-decoration: none;
}
/*---------------------------------------------*/
h1,h2,h3,h4,h5,h6 {
margin: 0px;
}
p {
font-family: 'Roboto', sans-serif;
font-size: 14px;
line-height: 1.7;
color: #666666;
margin: 0px;
}
ul, li {
margin: 0px;
list-style-type: none;
}
/*---------------------------------------------*/
input {
outline: none;
border: none;
}
textarea {
outline: none;
border: none;
}
textarea:focus, input:focus {
border-color: transparent !important;
}
input:focus::-webkit-input-placeholder { color:transparent; }
input:focus:-moz-placeholder { color:transparent; }
input:focus::-moz-placeholder { color:transparent; }
input:focus:-ms-input-placeholder { color:transparent; }
textarea:focus::-webkit-input-placeholder { color:transparent; }
textarea:focus:-moz-placeholder { color:transparent; }
textarea:focus::-moz-placeholder { color:transparent; }
textarea:focus:-ms-input-placeholder { color:transparent; }
input::-webkit-input-placeholder { color: #adadad;}
input:-moz-placeholder { color: #adadad;}
input::-moz-placeholder { color: #adadad;}
input:-ms-input-placeholder { color: #adadad;}
textarea::-webkit-input-placeholder { color: #adadad;}
textarea:-moz-placeholder { color: #adadad;}
textarea::-moz-placeholder { color: #adadad;}
textarea:-ms-input-placeholder { color: #adadad;}
/*---------------------------------------------*/
button {
outline: none !important;
border: none;
background: transparent;
}
button:hover {
cursor: pointer;
}
iframe {
border: none !important;
}
/*---------------------------------------------*/
.container {
max-width: 1200px;
}
/*//////////////////////////////////////////////////////////////////
[ Contact ]*/
.container-contact100 {
width: 100%;
min-height: 100vh;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
padding: 15px;
background: #a64bf4;
background: -webkit-linear-gradient(45deg, #00dbde, #fc00ff);
background: -o-linear-gradient(45deg, #00dbde, #fc00ff);
background: -moz-linear-gradient(45deg, #00dbde, #fc00ff);
background: linear-gradient(45deg, #00dbde, #fc00ff);
}
.wrap-contact100 {
width: 500px;
background: #fff;
border-radius: 10px;
overflow: hidden;
padding: 42px 55px 45px 55px;
}
.wrap-contact150 {
width: 750px;
background: #fff;
border-radius: 10px;
overflow: hidden;
padding: 42px 55px 45px 55px;
}
/*------------------------------------------------------------------
[ Form ]*/
.contact100-form {
width: 100%;
}
.contact100-form-title {
display: block;
font-family: 'Roboto', sans-serif;
font-size: 39px;
color: #333333;
line-height: 1.2;
text-align: center;
padding-bottom: 44px;
}
/*------------------------------------------------------------------
[ Input ]*/
.wrap-input100 {
width: 100%;
position: relative;
border-bottom: 2px solid #d9d9d9;
padding-bottom: 13px;
margin-bottom: 27px;
}
.label-input100 {
font-family: 'Roboto', sans-serif;
font-size: 13px;
color: #666666;
line-height: 1.5;
padding-left: 5px;
}
.input100 {
display: block;
width: 100%;
background: transparent;
font-family: 'Roboto', sans-serif;
font-size: 18px;
color: #333333;
line-height: 1.2;
padding: 0 5px;
}
.focus-input100 {
position: absolute;
display: block;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
}
.focus-input100::before {
content: "";
display: block;
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
-webkit-transition: all 0.4s;
-o-transition: all 0.4s;
-moz-transition: all 0.4s;
transition: all 0.4s;
background: #7f7f7f;
}
/*---------------------------------------------*/
input.input100 {
height: 40px;
}
textarea.input100 {
min-height: 110px;
padding-top: 9px;
padding-bottom: 13px;
}
.input100:focus + .focus-input100::before {
width: 100%;
}
.has-val.input100 + .focus-input100::before {
width: 100%;
}
/*------------------------------------------------------------------
[ Button ]*/
.container-contact100-form-btn {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
justify-content: center;
padding-top: 13px;
}
.wrap-contact100-form-btn {
width: 100%;
display: block;
position: relative;
z-index: 1;
border-radius: 25px;
overflow: hidden;
margin: 0 auto;
}
.contact100-form-bgbtn {
position: absolute;
z-index: -1;
width: 300%;
height: 100%;
background: #a64bf4;
background: -webkit-linear-gradient(left, #00dbde, #fc00ff, #00dbde, #fc00ff);
background: -o-linear-gradient(left, #00dbde, #fc00ff, #00dbde, #fc00ff);
background: -moz-linear-gradient(left, #00dbde, #fc00ff, #00dbde, #fc00ff);
background: linear-gradient(left, #00dbde, #fc00ff, #00dbde, #fc00ff);
top: 0;
left: -100%;
-webkit-transition: all 0.4s;
-o-transition: all 0.4s;
-moz-transition: all 0.4s;
transition: all 0.4s;
}
.contact100-form-btn {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
justify-content: center;
align-items: center;
padding: 0 20px;
width: 100%;
height: 50px;
font-family: 'Roboto', sans-serif;
font-size: 16px;
color: #fff;
line-height: 1.2;
}
.wrap-contact100-form-btn:hover .contact100-form-bgbtn {
left: 0;
}
.contact100-form-btn i {
-webkit-transition: all 0.4s;
-o-transition: all 0.4s;
-moz-transition: all 0.4s;
transition: all 0.4s;
}
.contact100-form-btn:hover i {
-webkit-transform: translateX(10px);
-moz-transform: translateX(10px);
-ms-transform: translateX(10px);
-o-transform: translateX(10px);
transform: translateX(10px);
}
/*------------------------------------------------------------------
[ Responsive ]*/
@media (max-width: 576px) {
.wrap-contact100 {
padding: 72px 15px 65px 15px;
}
}
/*------------------------------------------------------------------
[ Alert validate ]*/
.validate-input {
position: relative;
}
.alert-validate::before {
content: attr(data-validate);
position: absolute;
max-width: 70%;
background-color: #fff;
border: 1px solid #c80000;
border-radius: 2px;
padding: 4px 25px 4px 10px;
top: 58%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
right: 2px;
pointer-events: none;
font-family: 'Roboto', sans-serif;
color: #c80000;
font-size: 13px;
line-height: 1.4;
text-align: left;
visibility: hidden;
opacity: 0;
-webkit-transition: opacity 0.4s;
-o-transition: opacity 0.4s;
-moz-transition: opacity 0.4s;
transition: opacity 0.4s;
}
.alert-validate::after {
content: "\f06a";
font-family: 'Roboto', sans-serif;
display: block;
position: absolute;
color: #c80000;
font-size: 16px;
top: 58%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
right: 8px;
}
.alert-validate:hover:before {
visibility: visible;
opacity: 1;
}
@media (max-width: 992px) {
.alert-validate::before {
visibility: visible;
opacity: 1;
}
}
/*//////////////////////////////////////////////////////////////////
[ Restyle Select2 ]*/
.select2-container {
display: block;
max-width: 100% !important;
width: auto !important;
}
.select2-container .select2-selection--single {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
align-items: center;
background-color: transparent;
border: none;
height: 40px;
outline: none;
position: relative;
}
/*------------------------------------------------------------------
[ in select ]*/
.select2-container .select2-selection--single .select2-selection__rendered {
font-family: 'Roboto', sans-serif;
font-size: 18px;
color: #333333;
line-height: 1.2;
padding-left: 5px ;
background-color: transparent;
}
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 100%;
top: 50%;
transform: translateY(-50%);
right: 10px;
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.select2-selection__arrow b {
display: none;
}
.select2-selection__arrow::before {
content: '';
display: block;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-bottom: 5px solid #999999;
margin-bottom: 2px;
}
.select2-selection__arrow::after {
content: '';
display: block;
border-right: 5px solid transparent;
border-left: 5px solid transparent;
border-top: 5px solid #999999;
}
/*------------------------------------------------------------------
[ Dropdown option ]*/
.select2-container--open .select2-dropdown {
z-index: 1251;
border: 0px solid #e5e5e5;
border-radius: 0px;
background-color: white;
box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.2);
-o-box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.2);
-ms-box-shadow: 0 3px 10px 0px rgba(0, 0, 0, 0.2);
}
.select2-dropdown--above {top: -30px;}
.select2-dropdown--below {top: 8px;}
.select2-container .select2-results__option[aria-selected] {
padding-top: 10px;
padding-bottom: 10px;
}
.select2-container .select2-results__option[aria-selected="true"] {
background: #a64bf4;
background: -webkit-linear-gradient(right, #00dbde, #fc00ff);
background: -o-linear-gradient(right, #00dbde, #fc00ff);
background: -moz-linear-gradient(right, #00dbde, #fc00ff);
background: linear-gradient(right, #00dbde, #fc00ff);
color: white;
}
.select2-container .select2-results__option--highlighted[aria-selected] {
background: #a64bf4;
background: -webkit-linear-gradient(right, #00dbde, #fc00ff);
background: -o-linear-gradient(right, #00dbde, #fc00ff);
background: -moz-linear-gradient(right, #00dbde, #fc00ff);
background: linear-gradient(right, #00dbde, #fc00ff);
color: white;
}
.select2-results__options {
font-family: 'Roboto', sans-serif;
font-size: 15px;
color: #333333;
line-height: 1.2;
}
.select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: none;
font-family: 'Roboto', sans-serif;
font-size: 15px;
color: #333333;
line-height: 1.2;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>по следам анонимного деда мороза</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="images/icons/favicon.ico" />
<link href="//fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">
</head>
<body>
<div id="q">
<div class="container-contact100">
<div class="wrap-contact100">
<form id="q-form" class="contact100-form" validate-form>
<span class="contact100-form-title">
предлагаю поиграть, простая игра пинг-понг, вводи ключ и понеслась! первому месту в рейтинге открывается
скрытое знание.
</span>
<div class="wrap-input100 validate-input" data-validate="Нужен ключ">
<input class="input100" type="text" name="key" required>
</div>
<div class="container-contact100-form-btn">
<div class="wrap-contact100-form-btn">
<div class="contact100-form-bgbtn"></div>
<button class="contact100-form-btn" onclick="return playGame(this)">
<span>
поехали
</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div id="a" class="hidden">
<div class="container-contact100">
<div id="game" class="wrap-contact100">
<canvas width="640" height="480" id="canvas"></canvas>
</div>
</div>
</div>
<script src="./js/main.js"></script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="//www.googletagmanager.com/gtag/js?id=UA-23581568-13"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-23581568-13');
</script>
</body>
</html>

@ -0,0 +1,464 @@
import jQuery from 'jquery';
import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.css';
import '../css/main.css';
import '../css/util.css';
// RequestAnimFrame: a browser API for getting smooth animations
window.requestAnimFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 1000 / 60);
};
})();
window.cancelRequestAnimFrame = (function () {
return window.cancelAnimationFrame ||
window.webkitCancelRequestAnimationFrame ||
window.mozCancelRequestAnimationFrame ||
window.oCancelRequestAnimationFrame ||
window.msCancelRequestAnimationFrame ||
clearTimeout
})();
(function ($) {
"use strict";
var P = (function () {
var PP = [];
var A = function () { PP.push(null); };
var B = function () { return PP.length; };
var C = function () { PP = []; };
return { A: A, B: B, C: C };
})()
var A = P.A, B = P.B, C = P.C;
// Initialize canvas and required variables
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"), // Create canvas context
W = 640, // Window's width
H = 480, // Window's height
particles = [], // Array containing particles
ball = {}, // Ball object
paddles = [2], // Array containing two paddles
mouse = {}, // Mouse object to store it's current position
points = 0, // Varialbe to store points
fps = 60, // Max FPS (frames per second)
particlesCount = 20, // Number of sparks when ball strikes the paddle
flag = 0, // Flag variable which is changed on collision
particlePos = {}, // Object to contain the position of collision
multipler = 1, // Varialbe to control the direction of sparks
startBtn = {}, // Start button object
restartBtn = {}, // Restart button object
over = 0, // flag varialbe, cahnged when the game is over
init, // variable to initialize animation
paddleHit;
// Add mousemove and mousedown events to the canvas
canvas.addEventListener("mousemove", trackPosition, true);
canvas.addEventListener("mousedown", btnClick, true);
// Initialise the collision sound
var collision = document.getElementById("collide");
// Set the canvas's height and width to full screen
canvas.width = W;
canvas.height = H;
// Function to paint canvas
function paintCanvas() {
ctx.fillStyle = "black";
ctx.fillRect(0, 0, W, H);
}
// Function for creating paddles
function Paddle(pos) {
// Height and width
this.h = 5;
this.w = 150;
// Paddle's position
this.x = W / 2 - this.w / 2;
this.y = (pos == "top") ? 0 : H - this.h;
}
// Push two new paddles into the paddles[] array
paddles.push(new Paddle("bottom"));
paddles.push(new Paddle("top"));
// Ball object
ball = {
x: 50,
y: 50,
r: 5,
c: "green",
vx: 4,
vy: 8,
// Function for drawing ball on canvas
draw: function () {
ctx.beginPath();
ctx.fillStyle = this.c;
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
ctx.fill();
}
};
// Start Button object
startBtn = {
w: 100,
h: 50,
x: W / 2 - 50,
y: H / 2 - 25,
draw: function () {
ctx.strokeStyle = "blue";
ctx.lineWidth = "2";
ctx.strokeRect(this.x, this.y, this.w, this.h);
ctx.font = "18px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStlye = "Green";
ctx.fillText("Start", W / 2, H / 2);
}
};
// Restart Button object
restartBtn = {
w: 100,
h: 50,
x: W / 2 - 50,
y: H / 2 - 50,
draw: function () {
ctx.strokeStyle = "green";
ctx.lineWidth = "2";
ctx.strokeRect(this.x, this.y, this.w, this.h);
ctx.font = "18px Arial, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStlye = "white";
ctx.fillText("Restart", W / 2, H / 2 - 25);
}
};
// Function for creating particles object
function createParticles(x, y, m) {
this.x = x || 0;
this.y = y || 0;
this.radius = 1.2;
this.vx = -1.5 + Math.random() * 3;
this.vy = m * Math.random() * 1.5;
}
// Draw everything on canvas
function draw() {
paintCanvas();
for (var i = 0; i < paddles.length; i++) {
var p = paddles[i];
ctx.fillStyle = "green";
ctx.fillRect(p.x, p.y, p.w, p.h);
}
ball.draw();
update();
}
// Function to increase speed after every 5 points
function increaseSpd() {
if (B() % 4 == 0) {
if (Math.abs(ball.vx) < 15) {
ball.vx += (ball.vx < 0) ? -1 : 1;
ball.vy += (ball.vy < 0) ? -2 : 2;
}
}
}
// Track the position of mouse cursor
function trackPosition(e) {
mouse.x = e.offsetX;
mouse.y = e.offsetY;
}
// Function to update positions, score and everything.
// Basically, the main game logic is defined here
function update() {
// Update scores
updateScore();
// Move the paddles on mouse move
if (mouse.x && mouse.y) {
for (var i = 1; i < paddles.length; i++) {
var p = paddles[i];
p.x = mouse.x - p.w / 2;
}
}
// Move the ball
ball.x += ball.vx;
ball.y += ball.vy;
// Collision with paddles
var p1 = paddles[1];
var p2 = paddles[2];
// If the ball strikes with paddles,
// invert the y-velocity vector of ball,
// increment the points, play the collision sound,
// save collision's position so that sparks can be
// emitted from that position, set the flag variable,
// and change the multiplier
if (collides(ball, p1)) {
collideAction(ball, p1);
}
else if (collides(ball, p2)) {
collideAction(ball, p2);
}
else {
// Collide with walls, If the ball hits the top/bottom,
// walls, run gameOver() function
if (ball.y + ball.r > H) {
ball.y = H - ball.r;
gameOver();
}
else if (ball.y < 0) {
ball.y = ball.r;
gameOver();
}
// If ball strikes the vertical walls, invert the
// x-velocity vector of ball
if (ball.x + ball.r > W) {
ball.vx = -ball.vx;
ball.x = W - ball.r;
}
else if (ball.x - ball.r < 0) {
ball.vx = -ball.vx;
ball.x = ball.r;
}
}
// If flag is set, push the particles
if (flag == 1) {
for (var k = 0; k < particlesCount; k++) {
particles.push(new createParticles(particlePos.x, particlePos.y, multipler));
}
}
// Emit particles/sparks
emitParticles();
// reset flag
flag = 0;
}
//Function to check collision between ball and one of
//the paddles
function collides(b, p) {
if (b.x + ball.r >= p.x && b.x - ball.r <= p.x + p.w) {
if (b.y >= (p.y - p.h) && p.y > 0) {
paddleHit = 1;
return true;
}
else if (b.y <= p.h && p.y == 0) {
paddleHit = 2;
return true;
}
else return false;
}
}
//Do this when collides == true
function collideAction(ball, p) {
ball.vy = -ball.vy;
if (paddleHit == 1) {
ball.y = p.y - p.h;
particlePos.y = ball.y + ball.r;
multipler = -1;
}
else if (paddleHit == 2) {
ball.y = p.h + ball.r;
particlePos.y = ball.y - ball.r;
multipler = 1;
}
A();
increaseSpd();
if (collision) {
if (B() > 0)
collision.pause();
collision.currentTime = 0;
collision.play();
}
particlePos.x = ball.x;
flag = 1;
}
// Function for emitting particles
function emitParticles() {
for (var j = 0; j < particles.length; j++) {
var par = particles[j];
ctx.beginPath();
ctx.fillStyle = "white";
if (par.radius > 0) {
ctx.arc(par.x, par.y, par.radius, 0, Math.PI * 2, false);
}
ctx.fill();
par.x += par.vx;
par.y += par.vy;
// Reduce radius so that the particles die after a few seconds
par.radius = Math.max(par.radius - 0.05, 0.0);
}
}
// Function for updating score
function updateScore() {
ctx.fillStlye = "white";
ctx.font = "16px Arial, sans-serif";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Score: " + B(), 20, 20);
}
// Function for running the whole animation
function animloop() {
init = requestAnimFrame(animloop);
draw();
}
// Function to execute at startup
function startScreen() {
draw();
startBtn.draw();
}
// On button click (Restart and start)
function btnClick(e) {
// Variables for storing mouse position on click
var mx = e.offsetX,
my = e.offsetY;
// Click start button
if (mx >= startBtn.x && mx <= startBtn.x + startBtn.w) {
animloop();
// Devare the start button after clicking it
startBtn = {};
}
// If the game is over, and the restart button is clicked
if (over == 1) {
if (mx >= restartBtn.x && mx <= restartBtn.x + restartBtn.w) {
ball.x = 20;
ball.y = 20;
ball.vx = 4;
ball.vy = 8;
animloop();
C();
over = 0;
}
}
}
window.gameOver = function () {
ctx.fillStlye = "white";
ctx.font = "20px Roboto, sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Сохраняю результат...", W / 2, H / 2 + 25);
var key = sessionStorage.getItem("key");
fetch('//127.0.0.1:8081/answer/check', {
method: 'POST',
body: JSON.stringify({ key: key, score: B() }),
})
.then(function (data) { return data.json() })
.catch(function () { })
.then(function (approval) {
if (!approval) {
ctx.fillText("Не удалось сохранить с этим ключем", W / 2, H / 2 + 65);
return
}
var top = approval.top;
for (var i = 0; i < top.length; i++) {
var score = top[i].Score;
var name = top[i].Member.substr(20);
ctx.fillText(name + " → " + score, W / 2, H / 2 - 150 + 20 * i);
}
var msg = approval.msg;
for (var i = 0; i < msg.length; i++) {
ctx.fillText(msg[i], W / 2, H / 2 + 65 + 20 * i);
}
})
// Stop the Animation
cancelRequestAnimFrame(init);
// Set the over flag
over = 1;
// Show the restart button
restartBtn.draw();
}
window.playGame = function (_this) {
var key = $("#q-form").find("input[name='key']")
if (!key.val().trim().length) {
key.parent().addClass("alert-validate");
return false;
}
sessionStorage.setItem("key", key.val().trim());
var q = $("#q");
var a = $("#a");
q.addClass("hidden");
a.removeClass("hidden");
return false;
}
startScreen();
})(jQuery);
Loading…
Cancel
Save