feat: style processing

This commit is contained in:
cha0s 2019-09-22 21:25:43 -05:00
parent e1ec01947f
commit 6169ae1d92
36 changed files with 2003 additions and 448 deletions

View File

@ -3,63 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Humus</title>
<style>
* {
box-sizing: border-box;
}
html, body {
background-color: #333333;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
ins {
text-decoration: none;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.app {
display: flex;
align-items: center;
height: 100%;
width: 100%;
}
.app .avocado-stage {
margin: auto;
outline: none;
transform: scale(1);
transform-origin: 0 0;
transition-property: transform;
transition-duration: 0.125s;
}
.app .avocado-stage canvas {
image-rendering: optimizeSpeed; /* Older versions of FF */
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
image-rendering: -webkit-optimize-contrast; /* Safari */
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
image-rendering: pixelated; /* Awesome future-browsers */
-ms-interpolation-mode: nearest-neighbor; /* IE */
}
.debug .ui {
background-image: url(/debug.png);
}
@font-face {
font-family: "joystix";
src:
url("/joystix-monospace.ttf") format("truetype")
;
}
</style>
</head>
<body>
<div class="app">

58
client/index.scss Normal file
View File

@ -0,0 +1,58 @@
@import '~graphics.scss';
* {
box-sizing: border-box;
}
html, body {
background-color: #333;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
ins {
text-decoration: none;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.app {
display: flex;
align-items: center;
height: 100%;
width: 100%;
.avocado-stage {
margin: auto;
outline: none;
transform: scale(1);
transform-origin: 0 0;
transition-property: transform;
transition-duration: 0.125s;
canvas {
@include pixelated;
}
}
}
.debug .ui {
background-image: url(/debug.png);
}
@font-face {
font-family: "joystix";
src:
url("/joystix-monospace.ttf") format("truetype")
;
}

View File

@ -6,8 +6,7 @@ import {compose} from '@avocado/core';
import contempo from 'contempo';
const decorate = compose(
contempo(`
`),
contempo(require('./index.raw.scss').default),
);
const ChatComponent = () => {

View File

View File

@ -6,31 +6,7 @@ import {compose} from '@avocado/core';
import contempo from 'contempo';
const decorate = compose(
contempo(`
.connection-status {
display: none;
}
.connection-status.interrupted {
background-color: rgba(0, 0, 0, .75);
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: relative;
}
.connection-status.interrupted .message {
color: white;
font-family: monospace;
font-size: 0.7em;
text-align: center;
text-transform: uppercase;
}
.connection-status.interrupted .message .dots {
color: rgb(150, 150, 150);
font-size: 0.5em;
}
`),
contempo(require('./connection-status.raw.scss').default),
);
const ConnectionStatusComponent = ({socket}) => {

View File

@ -0,0 +1,26 @@
.connection-status {
display: none;
&.interrupted {
background-color: rgba(0, 0, 0, .75);
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
position: relative;
.message {
color: white;
font-family: monospace;
font-size: 0.7em;
text-align: center;
text-transform: uppercase;
.dots {
color: rgb(150, 150, 150);
font-size: 0.5em;
}
}
}
}

View File

@ -8,22 +8,8 @@ import {AFFINITY_NONE} from '../../common/combat/constants';
import {AFFINITY_FIRE} from '../../common/combat/constants';
const decorate = compose(
contempo(require('./damage.raw.scss').default),
contempo(`
.damage {
position: absolute;
top: 0;
left: 0;
}
.particle {
position: absolute;
will-change: transform, opacity;
}
.particle .text {
display: inline-block;
font-family: joystix;
font-weight: bold;
text-shadow: 1px 1px 0px black;
}
.particle .text.affinity-${AFFINITY_NONE}.is-damage {
color: #FF0000;
text-shadow:
@ -32,6 +18,7 @@ const decorate = compose(
-0px -0px 3px #FF2200
;
}
.particle .text.affinity-${AFFINITY_FIRE}.is-damage {
color: #FFA500;
text-shadow:
@ -40,16 +27,6 @@ const decorate = compose(
-0px -0px 3px #FFDD00,
-0px -0px 10px #FFFF00
;
}
.particle .text.is-healing {
color: #00FF77;
text-shadow: -0.25px -0.25px 0px #0077FF, 0.5px 0.5px black;
text-shadow:
0.75px 0.75px black,
-0.125px -0.125px black,
-0px -0px 3px #00DDFF,
-0px -0px 10px #0000FF
;
}
`),
);

28
client/ui/damage.raw.scss Normal file
View File

@ -0,0 +1,28 @@
.damage {
position: absolute;
top: 0;
left: 0;
}
.particle {
position: absolute;
will-change: transform, opacity;
.text {
display: inline-block;
font-family: joystix;
font-weight: bold;
text-shadow: 1px 1px 0px black;
&.is-healing {
color: #00FF77;
text-shadow: -0.25px -0.25px 0px #0077FF, 0.5px 0.5px black;
text-shadow:
0.75px 0.75px black,
-0.125px -0.125px black,
-0px -0px 3px #00DDFF,
-0px -0px 10px #0000FF
;
}
}
}

View File

@ -8,30 +8,7 @@ import contempo from 'contempo';
import Throughput from './throughput';
const decorate = compose(
contempo(`
.connection {
background-color: rgba(0, 0, 0, .3);
border: 1px solid white;
color: white;
position: absolute;
top: 4px;
right: 4px;
padding: 1px;
font-size: 6px;
}
.connection > p {
border-bottom: 1px solid rgb(180, 180, 180);
margin: 0.25em;
padding-bottom: 0.25em;
text-transform: uppercase;
}
.connection > p.connected {
color: rgb(0, 255, 0);
}
.connection > p.not-connected {
color: rgb(255, 0, 0);
}
`),
contempo(require('./index.raw.scss').default),
);
const ConnectionComponent = ({

View File

@ -0,0 +1,25 @@
.connection {
background-color: rgba(0, 0, 0, .3);
border: 1px solid white;
color: white;
position: absolute;
top: 4px;
right: 4px;
padding: 1px;
font-size: 6px;
> p {
border-bottom: 1px solid rgb(180, 180, 180);
margin: 0.25em;
padding-bottom: 0.25em;
text-transform: uppercase;
&.connected {
color: rgb(0, 255, 0);
}
&.not-connected {
color: rgb(255, 0, 0);
}
}
}

View File

@ -7,33 +7,7 @@ import {Vector} from '@avocado/math';
import contempo from 'contempo';
const decorate = compose(
contempo(`
.throughput {
background-color: rgba(0, 0, 0, .3);
color: white;
line-height: 1em;
width: 60px;
padding: 0.125em;
}
.throughput .kbps:before {
color: rgb(0, 255, 0);
content: 'kb/s ';
}
.throughput .mbps:before {
color: rgb(255, 180, 0);
content: 'mb/s ';
}
.throughput .input:before {
content: '\\a0in: ';
}
.throughput .output:before {
content: 'out: ';
}
.throughput p {
font-size: 4px;
margin: 0 1px;
}
`),
contempo(require('./throughput.raw.scss').default),
);
function formatKbps(bps) {

View File

@ -0,0 +1,30 @@
.throughput {
background-color: rgba(0, 0, 0, .3);
color: white;
line-height: 1em;
width: 60px;
padding: 0.125em;
.kbps:before {
color: rgb(0, 255, 0);
content: 'kb/s ';
}
.mbps:before {
color: rgb(255, 180, 0);
content: 'mb/s ';
}
.input:before {
content: '\\a0in: ';
}
.output:before {
content: 'out: ';
}
p {
font-size: 4px;
margin: 0 1px;
}
}

View File

@ -12,11 +12,7 @@ import SelfEntity from './self-entity';
import Timers from './timers';
const decorate = compose(
contempo(`
.debug .ui {
font-family: joystix;
}
`),
contempo(require('./index.raw.scss').default),
hot,
);

View File

@ -0,0 +1,3 @@
.debug .ui {
font-family: joystix;
}

View File

@ -8,36 +8,7 @@ import contempo from 'contempo';
import {usePropertyChange} from '../hooks/use-property-change';
const decorate = compose(
contempo(`
.self-entity {
background-color: rgba(0, 0, 0, .3);
border: 1px solid white;
color: white;
font-size: 5px;
position: absolute;
bottom: 4px;
left: 4px;
line-height: 5px;
width: 84px;
padding: 1px;
}
.location {
}
.x {
display: inline-block;
width: 40px;
}
.y {
display: inline-block;
width: 40px;
}
.x:before {
content: 'x: ';
}
.y:before {
content: 'y: ';
}
`),
contempo(require('./self-entity.raw.scss').default),
);
const SelfEntityComponent = ({app}) => {

View File

@ -0,0 +1,30 @@
.self-entity {
background-color: rgba(0, 0, 0, .3);
border: 1px solid white;
color: white;
font-size: 5px;
position: absolute;
bottom: 4px;
left: 4px;
line-height: 5px;
width: 84px;
padding: 1px;
}
.x {
display: inline-block;
width: 40px;
&:before {
content: 'x: ';
}
}
.y {
display: inline-block;
width: 40px;
&:before {
content: 'y: ';
}
}

View File

@ -7,39 +7,7 @@ import contempo from 'contempo';
import {usePropertyChange} from '../hooks/use-property-change';
const decorate = compose(
contempo(`
.timers {
left: 164px;
position: absolute;
color: white;
font-size: 4px;
top: 4px;
border: 1px solid white;
padding: 2px;
}
.tps:before {
content: 'TPS: ';
}
.rps:before {
content: 'RPS: ';
}
.count {
margin-right: 2px;
}
.jitter::before {
content: '+/-: ';
}
.down, .up {
display: inline-block;
width: 16px;
}
.down {
margin-right: 2px;
}
.up {
margin: 0px 2px;
}
`),
contempo(require('./timers.raw.scss').default),
);
const TimersComponent = ({app}) => {

View File

@ -0,0 +1,38 @@
.timers {
left: 164px;
position: absolute;
color: white;
font-size: 4px;
top: 4px;
border: 1px solid white;
padding: 2px;
}
.tps:before {
content: 'TPS: ';
}
.rps:before {
content: 'RPS: ';
}
.count {
margin-right: 2px;
}
.jitter::before {
content: '+/-: ';
}
.down, .up {
display: inline-block;
width: 16px;
}
.down {
margin-right: 2px;
}
.up {
margin: 0px 2px;
}

View File

@ -11,35 +11,7 @@ import {usePropertyChange} from '../hooks/use-property-change';
import ItemSlot from './item-slot';
const decorate = compose(
contempo(`
.hotbar {
position: absolute;
width: 200px;
height: 20px;
left: 50%;
top: 2px;
}
.hotbar-inner {
transform: translateX(-50%);
height: 100%;
}
.hotbar-key {
color: white;
text-shadow: 0.25px 0.25px 0 black;
font-family: joystix;
position: absolute;
top: -1.5px;
left: -1px;
font-size: 4px;
line-height: 4px;
}
.hotbar .item-slot.active {
border: 1px solid rgba(255, 255, 0, 1);
}
.hotbar .item-slot.active:hover {
transition: none;
}
`),
contempo(require('./hotbar.raw.scss').default),
);
const HotbarComponent = ({app}) => {

View File

@ -0,0 +1,31 @@
.hotbar {
position: absolute;
width: 200px;
height: 20px;
left: 50%;
top: 2px;
.item-slot.active {
border: 1px solid rgba(255, 255, 0, 1);
&:hover {
transition: none;
}
}
}
.hotbar-inner {
transform: translateX(-50%);
height: 100%;
}
.hotbar-key {
color: white;
text-shadow: 0.25px 0.25px 0 black;
font-family: joystix;
position: absolute;
top: -1.5px;
left: -1px;
font-size: 4px;
line-height: 4px;
}

View File

@ -11,21 +11,7 @@ import Inventory from './inventory';
import WorldTime from './world-time';
const decorate = compose(
contempo(`
.menu {
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
}
.menu-inner {
transition: transform 0.125s;
will-change: transform;
}
.menu-inner.open {
transform: translateY(156px);
}
`),
contempo(require('./index.raw.scss').default),
);
const MenuComponent = ({app}) => {

View File

@ -0,0 +1,15 @@
.menu {
width: 100%;
height: 100%;
overflow: hidden;
position: absolute;
}
.menu-inner {
transition: transform 0.125s;
will-change: transform;
&.open {
transform: translateY(156px);
}
}

View File

@ -7,32 +7,7 @@ import contempo from 'contempo';
import ItemSlot from './item-slot';
const decorate = compose(
contempo(`
.inventory {
position: absolute;
left: 50%;
transform: translateY(-80px);
}
.inventory-inner {
width: 250px;
height: 150px;
position: relative;
transform: translateX(-50%);
}
.bag, .equipment {
position: absolute;
}
.bag {
width: 200px;
height: 80px;
transform: translateX(25px);
}
.equipment {
width: 20px;
height: 80px;
transform: translateX(0px);
}
`),
contempo(require('./inventory.raw.scss').default),
);
const InventoryComponent = () => {

View File

@ -0,0 +1,28 @@
.inventory {
position: absolute;
left: 50%;
transform: translateY(-80px);
}
.inventory-inner {
width: 250px;
height: 150px;
position: relative;
transform: translateX(-50%);
}
.bag, .equipment {
position: absolute;
}
.bag {
width: 200px;
height: 80px;
transform: translateX(25px);
}
.equipment {
width: 20px;
height: 80px;
transform: translateX(0px);
}

View File

@ -6,59 +6,7 @@ import {compose} from '@avocado/core';
import contempo from 'contempo';
const decorate = compose(
contempo(`
.item-slot {
position: relative;
border: 1px solid rgba(0, 0, 0, 1);
box-sizing: border-box;
display: inline-block;
width: 16px;
height: 16px;
margin: 2px;
background-color: rgba(255, 255, 255, .2);
transition: box-shadow 0.125s;
}
.item-slot:hover {
box-shadow:
-.5px -.5px 1px rgba(255, 255, 255, 1),
.5px .5px 1px rgba(255, 255, 255, 1),
-.5px .5px 1px rgba(255, 255, 255, 1),
.5px -.5px 1px rgba(255, 255, 255, 1)
;
}
.item-slot-inner {
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 100%;
height: 100%;
image-rendering: optimizeSpeed; /* Older versions of FF */
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
image-rendering: -webkit-optimize-contrast; /* Safari */
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
image-rendering: pixelated; /* Awesome future-browsers */
-ms-interpolation-mode: nearest-neighbor; /* IE */
}
.item-slot-inner .qty {
color: white;
text-shadow: 0.25px 0.25px 0 black;
font-family: joystix;
position: absolute;
bottom: 0px;
right: 0.5px;
font-size: 5px;
line-height: 5px;
}
.qty.e3 {
font-size: 4px;
}
.qty.e4 {
font-size: 3px;
bottom: -1px;
}
`),
contempo(require('./item-slot.raw.scss').default),
);
const ItemSlotComponent = (props) => {

View File

@ -0,0 +1,55 @@
.item-slot {
position: relative;
border: 1px solid rgba(0, 0, 0, 1);
box-sizing: border-box;
display: inline-block;
width: 16px;
height: 16px;
margin: 2px;
background-color: rgba(255, 255, 255, .2);
transition: box-shadow 0.125s;
&:hover {
box-shadow:
-.5px -.5px 1px rgba(255, 255, 255, 1),
.5px .5px 1px rgba(255, 255, 255, 1),
-.5px .5px 1px rgba(255, 255, 255, 1),
.5px -.5px 1px rgba(255, 255, 255, 1)
;
}
}
.item-slot-inner {
background-position: center;
background-repeat: no-repeat;
background-size: contain;
width: 100%;
height: 100%;
image-rendering: optimizeSpeed; /* Older versions of FF */
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
image-rendering: -webkit-optimize-contrast; /* Safari */
image-rendering: -o-crisp-edges; /* OS X & Windows Opera (12.02+) */
image-rendering: pixelated; /* Awesome future-browsers */
-ms-interpolation-mode: nearest-neighbor; /* IE */
.qty {
color: white;
text-shadow: 0.25px 0.25px 0 black;
font-family: joystix;
position: absolute;
bottom: 0px;
right: 0.5px;
font-size: 5px;
line-height: 5px;
&.e3 {
font-size: 4px;
}
&.e4 {
font-size: 3px;
bottom: -1px;
}
}
}

View File

@ -8,32 +8,7 @@ import contempo from 'contempo';
import {usePropertyChange} from '../hooks/use-property-change';
const decorate = compose(
contempo(`
.status {
color: white;
display: inline-block;
font-family: joystix;
font-size: 5px;
text-shadow: 0.5px 0.5px 0px black;
position: absolute;
top: 4px;
right: 261px;
}
.status .health {
}
.status .health-inner {
border: 1px solid rgba(0, 0, 0, 1);
display: inline-block;
padding: 1px 3px;
line-height: 6px;
}
.status .currency {
}
.status .health:before {
opacity: 0.75;
color: red;
}
`),
contempo(require('./quick-status.raw.scss').default),
);
const QuickStatusComponent = ({app}) => {

View File

@ -0,0 +1,22 @@
.status {
color: white;
display: inline-block;
font-family: joystix;
font-size: 5px;
text-shadow: 0.5px 0.5px 0px black;
position: absolute;
top: 4px;
right: 261px;
.health-inner {
border: 1px solid rgba(0, 0, 0, 1);
display: inline-block;
padding: 1px 3px;
line-height: 6px;
}
.health:before {
opacity: 0.75;
color: red;
}
}

View File

@ -7,24 +7,7 @@ import contempo from 'contempo';
import {WorldTime} from '../../../common/world-time.synchronized';
const decorate = compose(
contempo(`
.time {
background-color: rgba(255, 255, 255, .2);
box-sizing: border-box;
border: 1px solid rgba(0, 0, 0, 1);
color: white;
position: absolute;
top: 4px;
right: 4px;
padding: 5px;
font-family: joystix;
font-size: 6px;
text-shadow: 0.5px 0.5px 0px black;
line-height: 4px;
width: 52px;
text-align: right;
}
`),
contempo(require('./world-time.raw.scss').default),
);
const WorldTimeComponent = ({worldTime}) => {

View File

@ -0,0 +1,16 @@
.time {
background-color: rgba(255, 255, 255, .2);
box-sizing: border-box;
border: 1px solid rgba(0, 0, 0, 1);
color: white;
position: absolute;
top: 4px;
right: 4px;
padding: 5px;
font-family: joystix;
font-size: 6px;
text-shadow: 0.5px 0.5px 0px black;
line-height: 4px;
width: 52px;
text-align: right;
}

View File

@ -16,7 +16,15 @@
"@babel/preset-env": "7.3.4",
"@babel/preset-react": "7.0.0",
"babel-loader": "8.0.5",
"contempo": "1.x",
"css-loader": "3.1.0",
"extract-css-chunks-webpack-plugin": "4.5.6",
"html-webpack-plugin": "3.2.0",
"node-sass": "4.12.0",
"node-sass-glob-importer": "5.3.2",
"postcss-loader": "3.0.0",
"raw-loader": "3.1.0",
"sass-loader": "7.1.0",
"start-server-webpack-plugin": "2.2.5",
"webpack": "4.29.6",
"webpack-cli": "3.2.3",
@ -42,7 +50,6 @@
"@avocado/timing": "1.x",
"@avocado/topdown": "1.x",
"classnames": "2.2.6",
"contempo": "1.x",
"glob": "^7.1.3",
"immutable": "4.0.0-rc.12",
"immutablediff": "0.4.4",

4
postcss.config.js Normal file
View File

@ -0,0 +1,4 @@
module.exports = {
plugins: {
},
};

14
scss/graphics.scss Normal file
View File

@ -0,0 +1,14 @@
@mixin pixelated {
/* Older versions of FF */
image-rendering: optimizeSpeed;
/* FF 6.0+ */
image-rendering: -moz-crisp-edges;
/* Safari */
image-rendering: -webkit-optimize-contrast;
/* OS X & Windows Opera (12.02+) */
image-rendering: -o-crisp-edges;
/* Awesome future-browsers */
image-rendering: pixelated;
/* IE */
-ms-interpolation-mode: nearest-neighbor;
}

View File

@ -12,6 +12,7 @@ config.entry = {
'register-synchronizeds',
'register-traits',
'@avocado/behavior/item/initialize',
path.join(__dirname, 'client', 'index.scss'),
path.join(__dirname, 'client', 'index.js'),
],
};

View File

@ -1,5 +1,7 @@
const path = require('path');
const ExtractCssChunks = require('extract-css-chunks-webpack-plugin');
const globImporter = require('node-sass-glob-importer');
const webpack = require('webpack');
const isProduction = !!process.argv.find((arg) => '--production' === arg);
@ -69,6 +71,53 @@ const config = {
},
},
},
// Styles.
{
test: /\.(?:sa|sc|c)ss$/,
exclude: /\.raw\./,
use: [
{
loader: ExtractCssChunks.loader,
options: {
hot: true,
},
},
{
loader: 'css-loader',
options: {
// 2 because postcss & sass.
importLoaders: 2,
},
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
importer: globImporter(),
},
},
],
},
{
test: /\.(?:sa|sc|c)ss$/,
include: /\.raw\./,
use: [
{
loader: 'raw-loader',
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
importer: globImporter(),
},
},
],
},
],
},
output: {
@ -77,17 +126,26 @@ const config = {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
},
plugins: [],
plugins: [
new ExtractCssChunks({
filename: '[name].css',
}),
],
resolve: {
alias: {
'register-packets': path.join(__dirname, 'register-packets'),
'register-synchronizeds': path.join(__dirname, 'register-synchronizeds'),
'register-traits': path.join(__dirname, 'register-traits'),
},
modules: [path.resolve(__dirname, 'node_modules')],
modules: [
path.join(__dirname, 'node_modules'),
path.join(__dirname, 'scss'),
],
},
resolveLoader: {
modules: [path.resolve(__dirname, 'node_modules')],
modules: [
path.join(__dirname, 'node_modules'),
],
},
};

1545
yarn.lock

File diff suppressed because it is too large Load Diff