Refactor file structure

This commit is contained in:
schmelczerandras 2020-07-09 21:19:28 +02:00
parent 5f73c2ac82
commit 3f3e654ea9
26 changed files with 71 additions and 215 deletions

5
frontend/.dockerignore Normal file
View file

@ -0,0 +1,5 @@
node_modules
dist
target
package-lock.json
.*

1
frontend/.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.psd filter=lfs diff=lfs merge=lfs -text

2
frontend/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
**/node_modules
**/dist

9
frontend/Dockerfile Normal file
View file

@ -0,0 +1,9 @@
FROM node:latest as build
WORKDIR /home/node
COPY . .
RUN npm install
RUN npm run build
FROM nginx:alpine
COPY --from=build /home/node/dist/ /usr/share/nginx/html

BIN
frontend/media/declared.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
frontend/media/declared.psd (Stored with Git LFS) Normal file

Binary file not shown.

10485
frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

49
frontend/package.json Normal file
View file

@ -0,0 +1,49 @@
{
"name": "decla.red",
"version": "1.0.0",
"description": "![logo](media/declared.png)",
"private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "András Schmelczer",
"license": "UNLICENSED",
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"defaults"
],
"devDependencies": {
"autoprefixer": "^9.7.6",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.5.2",
"cssnano": "latest",
"file-loader": "^5.1.0",
"html-webpack-inline-source-plugin": "0.0.10",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^6.0.0",
"mini-css-extract-plugin": "^0.9.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"prettier": "^1.19.1",
"resolve-url-loader": "^3.1.1",
"responsive-loader": "^1.2.0",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"sharp": "^0.23.4",
"style-loader": "^1.1.4",
"svg-url-loader": "^3.0.3",
"terser-webpack-plugin": "^2.3.5",
"ts-loader": "^6.2.2",
"typescript": "^3.8.3",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
}
}

19
frontend/src/index.html Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" />
<meta name="theme-color" content="#b7455e" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<title>Test</title>
</head>
<body>
<main>
<noscript><h1>Javascript is required for this website.</h1></noscript>
</main>
</body>
</html>

9
frontend/src/index.ts Normal file
View file

@ -0,0 +1,9 @@
function component() {
const element = document.createElement('div');
element.innerHTML = 'Hello world';
return element;
}
document.body.appendChild(component());

View file

@ -0,0 +1,157 @@
#ifdef GL_ES
precision mediump float;
#endif
#define INFINITY 1.0 / 0.0
#define WORLD_SIZE 4
#define LIGHTS_SIZE 2
#define LIGHT_PENETRATION 0.95
#define ANTIALIASING_RADIUS 1.0
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
struct Light {
vec2 center;
float radius;
vec3 color;
float intensity;
};
struct Circle {
vec2 center;
float radius;
vec3 color;
};
Light lights[LIGHTS_SIZE];
Circle world[WORLD_SIZE];
vec3 red = vec3(5.0, 0.0, 2.0);
vec3 blue = vec3(0.0, 0.0, 3.0);
float circleDistance(in vec2 position, in Circle circle)
{
return length(position - circle.center) - circle.radius;
}
float circleDistance(in vec2 position, in Light circle)
{
return length(position - circle.center) - circle.radius;
}
float getDistance(in vec2 target) {
float distance = INFINITY;
for (int i = 0; i < WORLD_SIZE; i++) {
distance = min(distance, circleDistance(target, world[i]));
}
return distance;
}
float getDistance(in vec2 target, out Circle nearest) {
float distance = INFINITY;
for (int i = 0; i < WORLD_SIZE; i++) {
float distanceToCurrent = circleDistance(target, world[i]);
if (distanceToCurrent < distance) {
distance = distanceToCurrent;
nearest = world[i];
}
}
return distance;
}
void createWorld() {
lights[0] = Light(u_mouse, 40.5, vec3(1.0), 25.0);
lights[1] = Light(vec2(100.0, 350.0), 52.5,vec3(2.0, 1.0, 0.25), 20.5);
world[0] = Circle(vec2(250.0, 100.0), 12.5, blue);
world[1] = Circle(vec2(150.0, 50.0), 32.5, red);
world[2] = Circle(vec2(300.0, 350.0), 52.5, blue);
}
float escapeFromObject(inout vec2 position, in vec2 direction) {
float fractionOfLightPenetrating = 1.0;
float rayLength = 0.0;
for (int i = 0; i < 64; i++) {
float minDistance = getDistance(position);
if (minDistance >= 0.0) {
return fractionOfLightPenetrating;
}
fractionOfLightPenetrating *= pow(LIGHT_PENETRATION, -minDistance);
rayLength += max(1.0, -minDistance);
position += direction * rayLength;
}
return 0.0;
}
float getFractionOfLightArriving(in vec2 position, in vec2 direction, in float lightDistance, in float lightRadius) {
float fractionOfLightArriving = 1.0;
float rayLength = 0.0;
for (int j = 0; j < 64; j++) {
float minDistance = getDistance(position + direction * rayLength);
fractionOfLightArriving = min(fractionOfLightArriving, minDistance / rayLength);
rayLength += max(1.0, abs(minDistance));
if (rayLength > lightDistance) {
fractionOfLightArriving = (fractionOfLightArriving * lightDistance + lightRadius) / (2.0 * lightRadius);
return smoothstep(0.0, 1.0, fractionOfLightArriving);
}
}
return 0.0;
}
vec3 getPixelColor(in vec2 position, in bool startsInside, in vec3 colorBias) {
vec3 result = vec3(0.0);
for (int i = 0; i < LIGHTS_SIZE; i++) {
Light light = lights[i];
float lightDistance = circleDistance(position, light);
vec3 lightColor = normalize(light.color) * light.intensity / mix(1.0, lightDistance, clamp(lightDistance, 0.0, 1.0));
if (lightDistance < 0.0) {
return lightColor;
}
vec2 lightDirection = normalize(light.center - position);
vec2 rayStart = position;
float fractionOfLightPenetrating = 1.0;
if (startsInside) {
fractionOfLightPenetrating = escapeFromObject(rayStart, lightDirection);
lightColor *= colorBias;
}
float fractionOfLightArriving = getFractionOfLightArriving(rayStart, lightDirection, lightDistance, light.radius);
result += lightColor * fractionOfLightArriving * fractionOfLightPenetrating;
}
return clamp(result, 0.0, 1.0);
}
vec3 getPixelColorAntialiased(in vec2 position) {
Circle nearest;
float minDistance = getDistance(position, nearest);
if (0.0 < minDistance && minDistance < 1.0) {
vec2 closerDirection = normalize(nearest.center - position);
return mix(getPixelColor(position + closerDirection, true, nearest.color), getPixelColor(position - closerDirection, false, nearest.color), minDistance);
}
return getPixelColor(position, minDistance < 0.0, minDistance < 0.0 ? nearest.color : vec3(1.0));
}
void main() {
createWorld();
vec2 position = gl_FragCoord.xy + vec2(0.5);
vec3 color = getPixelColorAntialiased(position);
gl_FragColor = vec4(color, 1.0);
}

11
frontend/tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": false,
"module": "es6",
"target": "es5",
"downlevelIteration": true,
"allowJs": true
}
}

173
frontend/webpack.config.js Normal file
View file

@ -0,0 +1,173 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
const Sharp = require('responsive-loader/sharp');
const Sass = require('sass');
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
watchOptions: {
ignored: /node_modules/,
},
devServer: {
host: '0.0.0.0',
disableHostCheck: true,
},
optimization: {
minimizer: [
new TerserJSPlugin({
sourceMap: !isProduction,
}),
new OptimizeCSSAssetsPlugin({}),
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
xhtml: true,
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
},
inlineSource: '.(js|css)$',
}),
new HtmlWebpackInlineSourcePlugin(),
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
}),
],
entry: {
index: './src/index.ts',
},
module: {
rules: [
{
test: /\.(jpe?g|png)$/i,
loader: 'responsive-loader',
options: {
adapter: Sharp,
outputPath: 'static/',
sizes: [200, 400, 800, 1200, 2000],
placeholder: false,
},
},
{
test: /\.(webm|mp4|gif)$/i,
use: [
{
loader: 'file-loader',
query: {
outputPath: 'static/',
},
},
{
loader: 'image-webpack-loader',
options: {
disable: !isProduction,
mozjpeg: {
progressive: true,
quality: 65,
},
optipng: {
enabled: true,
},
pngquant: {
quality: [0.65, 0.9],
speed: 4,
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 65,
},
},
},
],
},
{
test: /\.svg$/,
loader: 'svg-url-loader',
options: {
limit: 10 * 1024,
noquotes: true,
},
},
{
test: /\.(pdf)$/i,
use: {
loader: 'file-loader',
query: {
outputPath: 'static/',
name: '[name].[ext]',
},
},
},
{
test: /\.ico$/i,
use: {
loader: 'file-loader',
query: {
outputPath: '/',
name: '[name].[ext]',
},
},
},
{
test: /\.scss$/i,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
{
loader: 'resolve-url-loader',
options: {
keepQuery: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
implementation: Sass,
},
},
],
},
{
test: /\.(woff2?|ttf|eot|svg)(?:[?#].+)?$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'static/fonts/',
},
},
include: /fonts/,
},
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.ts', '.js'],
},
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
},
};