styles clean

This commit is contained in:
ntr 2019-08-10 15:53:15 +10:00
parent 89d2b39823
commit b15a494a4b
19 changed files with 425 additions and 541 deletions

View File

@ -11,6 +11,9 @@
* acp init
* DO postgres
* only clear effects on post_resolve
electrify doesn't work if you ko the construct
## SOON
*SERVER*
* modules

View File

@ -1,19 +1,16 @@
@import 'colours.less';
.account-page {
height: 100%;
.account {
margin-top: 2em;
grid-area: bottom;
display: grid;
grid-template-rows: minmax(min-content, 2fr) 1fr;
grid-template-columns: 1fr;
grid-template-areas:
"team"
"account";
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 0 1em;
button {
display: block;
height: 3em;
// height: 3em;
width: 75%;
}
@ -23,20 +20,20 @@
display: block;
}
.team {
grid-area: team;
/* poor man's <hr>*/
border-bottom: 0.1em solid #444;
}
.list {
letter-spacing: 0.25em;
text-transform: uppercase;
.account {
margin: 2em 2em 0 0;
grid-area: account;
figure {
font-size: 125%;
display: flex;
flex-flow: column;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 0 1em;
button {
width: 100%;
}
}
}
}

View File

@ -31,3 +31,33 @@ svg {
stroke: @blue;
}
}
.green {
color: @green;
stroke: @green;
}
.red {
color: @red;
stroke: @red;
}
.red-fill {
fill: @red;
}
.blue {
color: @blue;
stroke: @blue;
stroke-linecap: round;
}
.gray {
color: #333;
stroke: #333;
}
.white {
color: @white;
stroke: @white;
}

View File

@ -1,10 +1,17 @@
aside {
grid-area: ctrl;
display: grid;
grid-template-areas:
"timer controls"
"timer controls"
"timer controls";
grid-template-columns: min-content 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-gap: 0.5em 0;
padding: 1em;
padding: 1em 1em 1em 0;
div {
text-align: right;
@ -28,6 +35,30 @@ aside {
border-color: forestgreen;
}
}
.timer-container {
grid-area: timer;
display: flex;
flex: 1 1 100%;
height: 100%;
min-height: 100%;
width: 0.25em;
max-width: 0.25em;
margin: 0 1em 0 0;
border: none;
}
.timer {
background: whitesmoke;
transition-property: all;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
}
}
.ready-btn:hover, .ready-btn:focus, .ready-btn:active {

View File

@ -0,0 +1,51 @@
footer {
display: none;
flex-flow: row wrap;
grid-area: footer;
margin: 0;
button {
margin: 0;
border: none;
background: #222;
font-size: 1.5em;
padding: 0.25em;
&[disabled] {
color: #444;
}
&:not(:last-child) {
background: #222;
border-right: 1px solid black;
}
.ready {
background: forestgreen;
color: black;
}
}
.timer-container {
display: flex;
flex: 1 1 100%;
width: 100%;
height: 0.25em;
max-height: 0.25em;
border: none;
margin: 1em 0 0 0;
}
.timer {
background: whitesmoke;
transition-property: all;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
}
}
#nav-btn, #instance-nav {
display: none;
}

View File

@ -323,15 +323,6 @@
pointer-events: none;
}
/*@keyframes rotate {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(50deg);
}
}
*/
.resolving .skills button {
opacity: 0;
}
@ -339,80 +330,9 @@
.skill-animation {
opacity: 0;
stroke-width: 5px;
height: 5em;
}
/*
COMBAT ANIMATIONS
*/
/* ----------------------------------------------
* Generated by Animista on 2019-5-21 11:38:30
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/*.attack-cast {
-webkit-animation: attack-cast 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
animation: attack-cast 0.5s cubic-bezier(0.550, 0.085, 0.680, 0.530) both;
}
@-webkit-keyframes attack-cast {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
100% {
-webkit-transform: translateY(-5em);
transform: translateY(-5em);
opacity: 0;
}
}
@keyframes attack-cast {
0% {
-webkit-transform: translateY(0);
transform: translateY(0);
opacity: 1;
}
100% {
-webkit-transform: translateY(-5em);
transform: translateY(-5em);
opacity: 0;
}
}
.attack-hit {
-webkit-animation: attack-hit 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
animation: attack-hit 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@-webkit-keyframes attack-hit {
0% {
-webkit-transform: translateY(-5em) translateX(5em);
transform: translateY(-5em) translateX(5em);
opacity: 0;
}
100% {
-webkit-transform: translateY(0) translateX(0);
transform: translateY(0) translateX(0);
opacity: 1;
}
}
@keyframes attack-hit {
0% {
-webkit-transform: translateY(-5em) translateX(5em);
transform: translateY(-5em) translateX(5em);
opacity: 0;
}
100% {
-webkit-transform: translateY(0) translateX(0);
transform: translateY(0) translateX(0);
opacity: 1;
}
}
*/
@media (max-width: 1000px) {
.game {
grid-template-areas:

View File

@ -421,6 +421,12 @@
margin-top: 1em;
grid-area: playername;
}
.team {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
max-height: 100%;
}
}
/* Mobile Nav*/

View File

@ -0,0 +1,85 @@
@import 'colours.less';
.menu {
height: 100%;
display: grid;
grid-template-rows: minmax(min-content, 2fr) 1fr;
grid-template-columns: 1fr;
grid-template-areas:
"top"
"bottom";
.top {
padding: 0 0 0.5em 2em;
border-bottom: 0.1em solid #222;
box-sizing: border-box;
}
.team {
display: grid;
grid-area: top;
grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
max-height: 100%;
.team-select:not(:nth-child(3n)) {
margin-right: 0.5em;
}
.construct {
flex: 1 1 33%;
display: flex;
flex-flow: column;
text-align: center;
justify-content: center;
border: 1px solid black;
transition-property: border;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
button:not(:last-child) {
margin-bottom: 1em;
}
.avatar {
background-size: contain;
background-repeat: no-repeat;
background-position: center;
pointer-events: none;
height: 100%;
}
}
}
.inventory {
margin-top: 2em;
grid-area: bottom;
display: grid;
grid-template-columns: 1fr 1fr;
h1 {
margin-bottom: 0.5em;
}
.list {
letter-spacing: 0.25em;
text-transform: uppercase;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1em;
flex-flow: row wrap;
align-items: flex-end;
}
figure {
font-size: 125%;
display: flex;
flex-flow: column;
}
}
}

View File

@ -0,0 +1,98 @@
nav {
grid-area: nav;
padding-left: 2em;
margin-right: 2em;
max-height: 100%;
h1 {
margin-bottom: 0.5em;
}
h2:first-child {
margin: 0;
}
h2 {
margin-top: 2em;
}
hr {
margin: 1em 0;
border-color: #444;
}
button {
text-overflow: ellipsis;
display: block;
color: #888;
flex: 1 1 100%;
padding: 0;
margin: 0;
border-width: 0px;
}
button.active {
color: whitesmoke;
}
button[disabled], button[disabled]:hover {
color: #333;
text-decoration: none;
}
button:hover {
color: whitesmoke;
text-decoration: underline;
}
button:focus, button:active {
color: whitesmoke;
}
.account-info {
display: flex;
}
.account-header {
letter-spacing: 0.05em;
flex: 1;
display: inline;
}
.account-info svg {
margin: 0.5em 0 0 1em;
height: 1em;
background-color: black;
stroke: whitesmoke;
}
.ping-path {
fill: none;
stroke-width: 4px;
stroke-dasharray: 121, 242;
animation: saw 2s infinite linear;
transition-property: stroke-color;
transition-duration: 0.25s;
transition-timing-function: ease;
}
.ping-text {
margin-left: 1em;
min-width: 3em;
display: inline-block;
}
.play-btn {
font-size: 150%;
}
}
@keyframes saw {
0% {
stroke-dashoffset: 363;
}
100% {
stroke-dashoffset: 0;
}
}

View File

@ -1,11 +1,6 @@
@import 'colours.less';
/*
GLOBAL
*/
html, body, #mnml {
/*width: 100%;*/
margin: 0;
background-color: black;
@ -66,6 +61,7 @@ h4 {
}
hr {
color: #222;
margin: 1.5em 0;
width: 100%;
}
@ -85,74 +81,11 @@ figure {
"nav main ctrl";
}
nav {
grid-area: nav;
padding-left: 2em;
margin-right: 2em;
max-height: 100%;
h1 {
margin-bottom: 0.5em;
}
}
nav h2:first-child {
margin: 0;
}
nav h2 {
margin-top: 2em;
}
nav hr {
margin: 1em 0;
border-color: #444;
}
nav button {
text-overflow: ellipsis;
display: block;
color: #888;
flex: 1 1 100%;
padding: 0;
margin: 0;
border-width: 0px;
}
nav button.active {
color: whitesmoke;
}
nav button[disabled], nav button[disabled]:hover {
color: #333;
text-decoration: none;
}
nav button:hover {
color: whitesmoke;
text-decoration: underline;
}
nav button:focus, nav button:active {
color: whitesmoke;
}
main {
padding: 1em;
grid-area: main;
}
tr.right:focus, tr.right:hover {
box-shadow: inset -0.5em 0 0 0 whitesmoke;
}
tr {
transition-property: color, background;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
}
button, input {
font-family: 'Jura';
color: whitesmoke;
@ -195,19 +128,6 @@ svg {
height: 2em;
}
.skill-animation {
height: 5em;
}
.team .avatar {
object-fit: contain;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
pointer-events: none;
}
table {
table-layout: fixed;
width: 100%;
@ -250,56 +170,6 @@ button[disabled] {
border-color: #222;
}
/*
COLOURS
*/
.green {
color: #1FF01F;
stroke: #1FF01F;
}
.red {
color: #a52a2a;
stroke: #a52a2a;
}
.red-fill {
fill: #a52a2a;
}
.blue {
color: #3050f8;
stroke: #3050f8;
stroke-linecap: round;
}
.yellow {
color: #FFD123;
stroke: #FFD123;
}
.purple {
color: #A25AC1;
stroke: #A25AC1;
}
.cyan {
color: #6AD1BF;
stroke: #6AD1BF;
}
.gray {
color: #333;
stroke: #333;
}
.white {
color: whitesmoke;
stroke: whitesmoke;
}
/*
LOGIN
*/
@ -320,229 +190,6 @@ button[disabled] {
border-color: #888;
}
/*
account
*/
header {
display: flex;
flex-flow: row;
grid-area: hd;
margin-bottom: 1.5em;
}
.header-title {
flex: 1;
letter-spacing: 0.05em;
}
.account-info {
display: flex;
}
.account-header {
letter-spacing: 0.05em;
flex: 1;
display: inline;
}
.account-info svg {
margin: 0.5em 0 0 1em;
height: 1em;
background-color: black;
stroke: whitesmoke;
}
.ping-path {
fill: none;
stroke-width: 4px;
stroke-dasharray: 121, 242;
animation: saw 2s infinite linear;
transition-property: stroke-color;
transition-duration: 0.25s;
transition-timing-function: ease;
}
.ping-text {
margin-left: 1em;
min-width: 3em;
display: inline-block;
}
@keyframes saw {
0% {
stroke-dashoffset: 363;
}
100% {
stroke-dashoffset: 0;
}
}
/*
TEAM
*/
.team {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min-content, 33%));
max-height: 100%;
}
.menu-construct {
margin: 0.5em;
flex: 1 1 auto;
display: flex;
flex-flow: column;
text-align: center;
justify-content: center;
border: 1px solid black;
transition-property: border;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
button:not(:last-child) {
margin-bottom: 1em;
}
.avatar {
background-size: contain;
background-repeat: no-repeat;
background-position: center;
pointer-events: none;
height: 100%;
}
}
.spawn-btn.menu-construct {
border: 1px solid #333;
color: #333;
display: flex;
flex-flow: row wrap;
align-content: center;
justify-content: center;
}
.spawn-btn.menu-construct.selected {
color: whitesmoke;
}
.spawn-btn.menu-construct:hover {
border: 1px solid whitesmoke;
}
.spawn-btn input {
flex: 1 1 100%;
width: 100%;
margin: 1em;
}
.spawn-btn button {
flex: 1 1 100%;
margin: 0.5em 1em;
padding: 0 0.5em;
}
.spawn-btn input[disabled], .spawn-btn button[disabled] {
opacity: 0
}
.play {
height: 100%;
display: grid;
grid-template-rows: minmax(min-content, 2fr) 1fr;
grid-template-columns: 1fr;
grid-template-areas:
"team"
"inventory";
.team {
grid-area: team;
/* poor man's <hr>*/
padding: 0.5em 2em 0 0;
border-bottom: 0.1em solid #444;
}
.menu-construct {
flex: 1 0 33%;
}
.inventory {
margin: 2em 2em 0 0;
grid-area: inventory;
display: grid;
grid-template-columns: 1fr 1fr;
h1 {
margin-bottom: 0.5em;
}
.list {
letter-spacing: 0.25em;
text-transform: uppercase;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1em;
flex-flow: row wrap;
align-items: flex-end;
}
figure {
font-size: 125%;
display: flex;
flex-flow: column;
}
}
}
.menu-instance-btn {
flex: 1 1 100%;
font-size: 1.2em;
}
.play-btn {
font-size: 150%;
}
.refresh-btn {
border: 1px solid #222;
float: right;
font-size: 1.5em;
}
.create-form {
grid-area: create;
flex: 1;
justify-self: flex-end;
display: flex;
flex-flow: row wrap;
margin-bottom: 1.5em;
}
.create-form button {
flex: 1;
font-size: 1.5em;
}
.create-form button:first-child {
margin-right: 1em;
}
.create-form button:hover, .create-form button:focus {
border-color: whitesmoke;
text-decoration: none;
}
figure.gray {
color: #333;
stroke-color: #333;
@ -553,63 +200,11 @@ figure.gray {
fill: none;
}
main .top button {
width: 100%;
}
.credits {
color: @yellow;
font-weight: 800;
}
.timer-container {
display: flex;
flex: 1 1 100%;
width: 100%;
height: 0.25em;
max-height: 0.25em;
border: none;
margin: 1em 0 0 0;
}
.timer {
background: whitesmoke;
transition-property: all;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
}
footer {
display: none;
flex-flow: row wrap;
grid-area: footer;
margin: 0;
}
footer button {
margin: 0;
border: none;
background: #222;
font-size: 1.5em;
padding: 0.25em;
}
footer button:disabled {
color: #444;
}
footer button:not(:last-child) {
background: #222;
border-right: 1px solid black;
}
footer button .ready {
background: forestgreen;
color: black;
}
@media (max-width: 1500px) {
#mnml {
font-size: 75%;
@ -620,10 +215,6 @@ footer button .ready {
}
}
#nav-btn, #instance-nav {
display: none;
}
.mobile-title {
display: none;
}
}

View File

@ -1,9 +1,12 @@
require('./assets/styles/styles.less');
require('./assets/styles/menu.less');
require('./assets/styles/nav.less');
require('./assets/styles/footer.less');
require('./assets/styles/account.less');
require('./assets/styles/controls.less');
require('./assets/styles/instance.less');
require('./assets/styles/vbox.less');
require('./assets/styles/game.less');
require('./assets/styles/controls.less');
require('./assets/styles/account.less');
require('./assets/styles/styles.mobile.css');
require('./assets/styles/instance.mobile.css');

View File

@ -1,6 +1,8 @@
const { connect } = require('preact-redux');
const preact = require('preact');
const SpawnButton = require('./spawn.button');
const { postData } = require('./../utils');
const actions = require('../actions');
@ -9,6 +11,7 @@ const addState = connect(
const {
account,
ping,
ws,
} = state;
@ -16,10 +19,15 @@ const addState = connect(
postData('/logout').then(() => window.location.reload(true));
}
function sendConstructSpawn(name) {
return ws.sendMtxConstructSpawn(name);
}
return {
account,
ping,
logout,
sendConstructSpawn,
};
},
);
@ -30,6 +38,7 @@ function AccountStatus(args) {
account,
ping,
logout,
sendConstructSpawn,
} = args;
if (!account) return null;
@ -83,6 +92,14 @@ function AccountStatus(args) {
/>
<button>Change</button>
</form>
<div class="list">
<figure>
<figcaption>spawn new construct</figcaption>
<button onClick={() => sendConstructSpawn()} type="submit">
¤50
</button>
</figure>
</div>
</section>
);
}

View File

@ -23,7 +23,7 @@ function Account(args) {
} = args;
return (
<main class="account-page">
<main class="menu">
<Team />
<AccountManagement />
</main>

View File

@ -20,16 +20,22 @@ const addState = connect(
return ws.sendGameReady(game.id);
}
function getInstanceState() {
return ws.sendInstanceState(game.instance);
}
return {
game,
sendReady,
account,
getInstanceState,
animating,
};
},
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setNav('transition'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
@ -74,6 +80,7 @@ function Controls(args) {
animating,
sendReady,
quit,
getInstanceState,
} = args;
if (!game) return false;
@ -81,11 +88,43 @@ function Controls(args) {
const opponent = game.players.find(t => t.id !== account.id);
const player = game.players.find(t => t.id === account.id);
function quitClick() {
getInstanceState();
quit();
}
const zero = Date.parse(game.phase_start);
const now = Date.now();
const end = Date.parse(game.phase_end);
const timerPct = game.phase_end
? ((now - zero) / (end - zero) * 100)
: 100;
const displayColour = !game.phase_end
? '#222'
: player.ready
? 'forestgreen'
: timerPct > 80
? 'red'
: 'whitesmoke';
const timerStyles = {
height: `${timerPct > 100 ? 100 : timerPct}%`,
background: displayColour,
};
const timer = (
<div class="timer-container">
<div class="timer" style={timerStyles} >&nbsp;</div>
</div>
);
const readyBtn = <button disabled={animating} class="ready" onClick={() => sendReady()}>Ready</button>;
const quitBtn = <button disabled={animating} onClick={() => quit()}>Back</button>;
const quitBtn = <button disabled={animating} onClick={quitClick}>Back</button>;
return (
<aside class="controls">
{timer}
{scoreboard(game, opponent, true)}
{game.phase === 'Finish' ? quitBtn : readyBtn}
{scoreboard(game, player)}

View File

@ -66,8 +66,35 @@ function Controls(args) {
const opponent = instance.players.find(t => t.id !== account.id);
const player = instance.players.find(t => t.id === account.id);
const zero = Date.parse(instance.phase_start);
const now = Date.now();
const end = Date.parse(instance.phase_end);
const timerPct = instance.phase_end
? ((now - zero) / (end - zero) * 100)
: 100;
const displayColour = !instance.phase_end
? '#222'
: player.ready
? 'forestgreen'
: timerPct > 80
? 'red'
: 'whitesmoke';
const timerStyles = {
height: `${timerPct > 100 ? 100 : timerPct}%`,
background: displayColour,
};
const timer = (
<div class="timer-container">
<div class="timer" style={timerStyles} >&nbsp;</div>
</div>
);
return (
<aside class="controls">
{timer}
{scoreboard(instance, opponent, true)}
<button class="ready" onClick={() => sendReady()}>Ready</button>
{scoreboard(instance, player)}

View File

@ -27,7 +27,8 @@ function JoinButtons(args) {
} = args;
return (
<aside>
<aside class='play-ctrl'>
<div class="timer-container"></div>
<button
class='pvp ready'
onClick={() => sendInstanceQueue()}

View File

@ -97,7 +97,7 @@ function Play(args) {
if (mtxActive === 'Rename') return setConstructRename(construct.id);
return sendConstructAvatarReroll(construct.id);
}}
class="menu-construct" >
class="construct">
<ConstructAvatar construct={construct} />
{constructName}
{confirm}
@ -107,8 +107,8 @@ function Play(args) {
});
return (
<main class="play">
<div class="team">
<main class="menu">
<div class="team top">
{constructPanels}
</div>
<Inventory />

View File

@ -29,6 +29,7 @@ function TeamCtrl(args) {
return (
<aside>
<div class="timer-container"></div>
<button
class='ready'
disabled={teamSelect.some(c => !c)}

View File

@ -1,11 +1,8 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const range = require('lodash/range');
const actions = require('./../actions');
const { COLOURS } = require('./../utils');
const { stringSort } = require('./../utils');
const SpawnButton = require('./spawn.button');
const { ConstructAvatar } = require('./construct');
const addState = connect(
@ -19,7 +16,6 @@ const addState = connect(
return {
constructs,
teamSelect,
sendConstructSpawn,
};
},
function receiveDispatch(dispatch) {
@ -31,7 +27,6 @@ const addState = connect(
setTeam,
};
}
);
function Team(args) {
@ -39,7 +34,6 @@ function Team(args) {
constructs,
teamSelect,
setTeam,
sendConstructSpawn,
} = args;
if (!constructs) return <div></div>;
@ -70,28 +64,18 @@ function Team(args) {
return (
<div
key={construct.id}
class="menu-construct"
class="construct team-select"
style={ { 'border-color': borderColour || 'whitesmoke' } }
onClick={() => selectConstruct(construct.id)} >
<div class="controls">
<h2>
{construct.name}
</h2>
</div>
<ConstructAvatar construct={construct} />
<h2>{construct.name}</h2>
</div>
);
});
const spawnButtonsNum = (3 - constructs.length % 3);
const spawnButtons = range(spawnButtonsNum)
.map(i => <SpawnButton key={constructs.length + i} spawn={() => sendConstructSpawn()} />);
return (
<section class="team">
<section class="team top">
{constructPanels}
{spawnButtons}
</section>
);
}