Optimizations
This commit is contained in:
parent
10015a4ebe
commit
3febd3fca8
24 changed files with 215 additions and 99 deletions
4
.idea/dictionaries/Schme.xml
generated
4
.idea/dictionaries/Schme.xml
generated
|
|
@ -2,18 +2,22 @@
|
||||||
<dictionary name="Schme">
|
<dictionary name="Schme">
|
||||||
<words>
|
<words>
|
||||||
<w>contenthash</w>
|
<w>contenthash</w>
|
||||||
|
<w>cybersecurity</w>
|
||||||
<w>ffffff</w>
|
<w>ffffff</w>
|
||||||
<w>gifsicle</w>
|
<w>gifsicle</w>
|
||||||
<w>imagemin</w>
|
<w>imagemin</w>
|
||||||
<w>jpegtran</w>
|
<w>jpegtran</w>
|
||||||
<w>lato</w>
|
<w>lato</w>
|
||||||
|
<w>markwon</w>
|
||||||
<w>mozjpeg</w>
|
<w>mozjpeg</w>
|
||||||
<w>noquotes</w>
|
<w>noquotes</w>
|
||||||
<w>opacify</w>
|
<w>opacify</w>
|
||||||
<w>optipng</w>
|
<w>optipng</w>
|
||||||
<w>pngquant</w>
|
<w>pngquant</w>
|
||||||
<w>raleway</w>
|
<w>raleway</w>
|
||||||
|
<w>screenshot</w>
|
||||||
<w>transparentize</w>
|
<w>transparentize</w>
|
||||||
|
<w>webm</w>
|
||||||
<w>webp</w>
|
<w>webp</w>
|
||||||
</words>
|
</words>
|
||||||
</dictionary>
|
</dictionary>
|
||||||
|
|
|
||||||
28
.idea/workspace.xml
generated
28
.idea/workspace.xml
generated
|
|
@ -2,28 +2,30 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="8edc47ab-1265-4111-9771-536b24cc9310" name="Default Changelist" comment="">
|
<list default="true" id="8edc47ab-1265-4111-9771-536b24cc9310" name="Default Changelist" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/static/media/forex.mp4" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/static/media/forex.webm" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/static/media/led.mp4" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/static/media/led.webm" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/dictionaries/Schme.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dictionaries/Schme.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/dictionaries/Schme.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dictionaries/Schme.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/custom.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/custom.d.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/index.html" beforeDir="false" afterPath="$PROJECT_DIR$/src/index.html" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/framework/helper.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/framework/helper.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/about/about.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/about/about.scss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/content.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/content.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/background/background.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/background.scss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/misc.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/misc.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/background/background.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/background.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/portfolio.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/portfolio.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/background/blob.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/background/blob.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/about/about.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/about/about.html.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/page/about/about.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/about/about.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/page/content/content.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/content/content.scss" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/content/content.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/content/content.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/content/content.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/content/content.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/footer/footer.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/footer/footer.html.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/footer/footer.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/footer/footer.html.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/footer/footer.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/footer/footer.scss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/footer/footer.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/footer/footer.scss" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/image-viewer/image-viewer.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/index.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/index.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.html.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.html.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.html.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.scss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.scss" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline-element/timeline-element.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/portfolio.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/portfolio.ts" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/page/timeline/timeline.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/page/timeline/timeline.scss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/static/media/led720.mp4" beforeDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/style/a.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/a.scss" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/style/fonts.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/fonts.scss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/style/fonts.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/fonts.scss" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/style/mixins.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/mixins.scss" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/style/vars.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/vars.scss" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/styles.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/styles.scss" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/webpack.config.js" beforeDir="false" afterPath="$PROJECT_DIR$/webpack.config.js" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/webpack.config.js" beforeDir="false" afterPath="$PROJECT_DIR$/webpack.config.js" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
|
@ -120,7 +122,7 @@
|
||||||
<workItem from="1577348003642" duration="4876000" />
|
<workItem from="1577348003642" duration="4876000" />
|
||||||
<workItem from="1577451432189" duration="11000" />
|
<workItem from="1577451432189" duration="11000" />
|
||||||
<workItem from="1577469180612" duration="18000" />
|
<workItem from="1577469180612" duration="18000" />
|
||||||
<workItem from="1577526744211" duration="38046000" />
|
<workItem from="1577526744211" duration="44201000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|
|
||||||
27
custom.d.ts
vendored
27
custom.d.ts
vendored
|
|
@ -1,34 +1,47 @@
|
||||||
declare module "*.svg" {
|
declare module "*.svg" {
|
||||||
const content: string;
|
import { url } from "src/model/misc";
|
||||||
|
const content: url;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.png" {
|
declare module "*.png" {
|
||||||
const content: string;
|
import { ResponsiveImage } from "src/model/misc";
|
||||||
|
const content: ResponsiveImage;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.jpg" {
|
declare module "*.jpg" {
|
||||||
const content: string;
|
import { ResponsiveImage } from "src/model/misc";
|
||||||
|
const content: ResponsiveImage;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.jpeg" {
|
declare module "*.jpeg" {
|
||||||
const content: string;
|
import { ResponsiveImage } from "src/model/misc";
|
||||||
|
const content: ResponsiveImage;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.gif" {
|
declare module "*.gif" {
|
||||||
const content: string;
|
import { url } from "src/model/misc";
|
||||||
|
const content: url;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.mp4" {
|
declare module "*.mp4" {
|
||||||
const content: string;
|
import { url } from "src/model/misc";
|
||||||
|
const content: url;
|
||||||
|
export default content;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*.webm" {
|
||||||
|
import { url } from "src/model/misc";
|
||||||
|
const content: url;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module "*.pdf" {
|
declare module "*.pdf" {
|
||||||
const content: string;
|
import { url } from "src/model/misc";
|
||||||
|
const content: url;
|
||||||
export default content;
|
export default content;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
"description": "An easily configurable portfolio.",
|
"description": "An easily configurable portfolio.",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
|
||||||
"start": "webpack-dev-server --mode development",
|
"start": "webpack-dev-server --mode development",
|
||||||
"build": "webpack"
|
"build": "webpack"
|
||||||
},
|
},
|
||||||
|
|
@ -35,7 +34,9 @@
|
||||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"resolve-url-loader": "^3.1.1",
|
"resolve-url-loader": "^3.1.1",
|
||||||
|
"responsive-loader": "^1.2.0",
|
||||||
"sass-loader": "^8.0.0",
|
"sass-loader": "^8.0.0",
|
||||||
|
"sharp": "^0.23.4",
|
||||||
"style-loader": "^1.0.2",
|
"style-loader": "^1.0.2",
|
||||||
"svg-url-loader": "^3.0.3",
|
"svg-url-loader": "^3.0.3",
|
||||||
"terser-webpack-plugin": "^2.3.1",
|
"terser-webpack-plugin": "^2.3.1",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { html } from "../model/misc";
|
import { html, ResponsiveImage } from "../model/misc";
|
||||||
|
|
||||||
export const createElement = (from: html): HTMLElement => {
|
export const createElement = (from: html): HTMLElement => {
|
||||||
const element: HTMLElement = document.createElement("div");
|
const element: HTMLElement = document.createElement("div");
|
||||||
|
|
@ -88,3 +88,6 @@ export const range = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const last = <T>(list: Array<T>): T =>
|
||||||
|
list.length > 0 ? list[list.length - 1] : undefined;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { url } from "./misc";
|
import { ResponsiveImage, url } from "./misc";
|
||||||
|
|
||||||
interface Anchor {
|
interface Anchor {
|
||||||
type: "a";
|
type: "a";
|
||||||
|
|
@ -6,11 +6,19 @@ interface Anchor {
|
||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Video {
|
export type Video = {
|
||||||
type: "video";
|
type: "video";
|
||||||
src: url;
|
mp4: url;
|
||||||
}
|
webm: url;
|
||||||
|
options?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type TypedContent = Anchor | Video;
|
export type Image = {
|
||||||
|
type: "img";
|
||||||
|
alt: string;
|
||||||
|
image: ResponsiveImage;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TypedContent = Anchor | Video | Image;
|
||||||
|
|
||||||
export type Content = Array<String | TypedContent>;
|
export type Content = Array<String | TypedContent>;
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,16 @@
|
||||||
export type url = string;
|
export type url = string;
|
||||||
|
|
||||||
export type html = string;
|
export type html = string;
|
||||||
|
|
||||||
|
export type ResponsiveImage = {
|
||||||
|
srcSet: string;
|
||||||
|
src: url;
|
||||||
|
placeholder: string;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
images: Array<{
|
||||||
|
path: url;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { url } from "./misc";
|
import { url } from "./misc";
|
||||||
import { Content } from "./content";
|
import { Content, Image, Video } from "./content";
|
||||||
|
|
||||||
export interface Portfolio {
|
export interface Portfolio {
|
||||||
config: Config;
|
config: Config;
|
||||||
|
|
@ -11,19 +11,18 @@ export interface Portfolio {
|
||||||
export interface Config {
|
export interface Config {
|
||||||
showMore: string;
|
showMore: string;
|
||||||
showLess: string;
|
showLess: string;
|
||||||
aPictureOf: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Header {
|
export interface Header {
|
||||||
name: string;
|
name: string;
|
||||||
picture: url;
|
picture: Image;
|
||||||
about: Content;
|
about: Content;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TimelineElement {
|
export interface TimelineElement {
|
||||||
title: string;
|
title: string;
|
||||||
date: string;
|
date: string;
|
||||||
picture: url;
|
figure: Image | Video;
|
||||||
description: string;
|
description: string;
|
||||||
more?: Content;
|
more?: Content;
|
||||||
link?: url;
|
link?: url;
|
||||||
|
|
@ -34,8 +33,6 @@ export interface Footer {
|
||||||
email: string;
|
email: string;
|
||||||
cv: url;
|
cv: url;
|
||||||
cvName: string;
|
cvName: string;
|
||||||
githubLinkName: string;
|
|
||||||
githubLink: url;
|
|
||||||
lastEditName: string;
|
lastEditName: string;
|
||||||
lastEdit: Date;
|
lastEdit: Date;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import { Header } from "../../model/portfolio";
|
import { Header } from "../../model/portfolio";
|
||||||
import { html } from "../../model/misc";
|
import { html } from "../../model/misc";
|
||||||
|
import { PageContent } from "../content/content";
|
||||||
|
|
||||||
import "./about.scss";
|
import "./about.scss";
|
||||||
|
|
||||||
export const generate = (
|
export const generate = ({ name, picture }: Header): html => `
|
||||||
{ name, picture, about }: Header,
|
|
||||||
aPictureOf: string
|
|
||||||
): html => `
|
|
||||||
<section id="about">
|
<section id="about">
|
||||||
<img alt="${aPictureOf} ${name}" src="${picture}"/>
|
${PageContent.parseTypedContent(picture, true)}
|
||||||
<div class="placeholder"></div>
|
<div class="placeholder"></div>
|
||||||
<h1>${name}</h1>
|
<h1>${name}</h1>
|
||||||
</section>`;
|
</section>`;
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import { generate } from "./about.html";
|
||||||
import { createElement } from "../../framework/helper";
|
import { createElement } from "../../framework/helper";
|
||||||
|
|
||||||
export class PageHeader extends PageElement {
|
export class PageHeader extends PageElement {
|
||||||
public constructor(header: Header, aPictureOf: string) {
|
public constructor(header: Header) {
|
||||||
const root = createElement(generate(header, aPictureOf));
|
const root = createElement(generate(header));
|
||||||
const content = new PageContent(header.about);
|
const content = new PageContent(header.about);
|
||||||
|
|
||||||
super([content]);
|
super([content]);
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,15 @@
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
font-size: 0;
|
||||||
|
box-shadow: inset $shadow1, inset $shadow2;
|
||||||
|
pointer-events: none;
|
||||||
|
img {
|
||||||
|
pointer-events: all;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
z-index: -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,44 @@
|
||||||
import { Content, TypedContent } from "../../model/content";
|
import { Content, TypedContent } from "../../model/content";
|
||||||
import "./content.scss";
|
import "./content.scss";
|
||||||
import { PageElement } from "../../framework/page-element";
|
import { PageElement } from "../../framework/page-element";
|
||||||
import { createElement } from "../../framework/helper";
|
import { createElement, last } from "../../framework/helper";
|
||||||
|
import { html } from "../../model/misc";
|
||||||
|
|
||||||
export class PageContent extends PageElement {
|
export class PageContent extends PageElement {
|
||||||
private static isTyped(content): content is TypedContent {
|
private static isTyped(content): content is TypedContent {
|
||||||
return (content as TypedContent).type !== undefined;
|
return (content as TypedContent).type !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static parseTypedContent(
|
||||||
|
element: TypedContent,
|
||||||
|
disableInnerShadow?: boolean
|
||||||
|
): html {
|
||||||
|
if (element.type === "a") {
|
||||||
|
return `<a href="${element.href}" rel="noreferrer" target="_blank"> ${element.text} </a>`;
|
||||||
|
}
|
||||||
|
if (element.type === "video") {
|
||||||
|
return `
|
||||||
|
<video ${element.options}>
|
||||||
|
<source src="${element.webm}" type="video/webm"/>
|
||||||
|
<source src="${element.mp4}" type="video/mp4"/>
|
||||||
|
</video>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
if (element.type === "img") {
|
||||||
|
return `
|
||||||
|
${!disableInnerShadow ? `<div class="image-container">` : ""}
|
||||||
|
<img
|
||||||
|
srcset="${element.image.srcSet}"
|
||||||
|
src="${last(element.image.images).path}"
|
||||||
|
alt="${element.alt}"
|
||||||
|
/>
|
||||||
|
${!disableInnerShadow ? `</div>` : ""}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Unhandled type.");
|
||||||
|
}
|
||||||
|
|
||||||
public constructor(content: Content) {
|
public constructor(content: Content) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
@ -15,18 +46,11 @@ export class PageContent extends PageElement {
|
||||||
createElement(`
|
createElement(`
|
||||||
<div class="content">
|
<div class="content">
|
||||||
${content
|
${content
|
||||||
.map(element => {
|
.map(element =>
|
||||||
if (PageContent.isTyped(element)) {
|
PageContent.isTyped(element)
|
||||||
if (element.type === "a") {
|
? PageContent.parseTypedContent(element)
|
||||||
return `<a href="${element.href}" rel="noreferrer" target="_blank"> ${element.text} </a>`;
|
: `<p>${element}</p>`
|
||||||
}
|
)
|
||||||
if (element.type === "video") {
|
|
||||||
return `<video controls><source src="${element.src}" /></video>`;
|
|
||||||
}
|
|
||||||
throw new Error("Unhandled type.");
|
|
||||||
}
|
|
||||||
return `<p>${element}</p>`;
|
|
||||||
})
|
|
||||||
.join("\n")}
|
.join("\n")}
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { Footer } from "../../model/portfolio";
|
import { Footer } from "../../model/portfolio";
|
||||||
import { html, url } from "../../model/misc";
|
import { html } from "../../model/misc";
|
||||||
|
import emailIcon from "../../static/icons/at.svg";
|
||||||
|
import cvIcon from "../../static/icons/cv.svg";
|
||||||
|
|
||||||
import "./footer.scss";
|
import "./footer.scss";
|
||||||
import cvIcon from "../../static/icons/cv.svg";
|
|
||||||
import emailIcon from "../../static/icons/at.svg";
|
|
||||||
|
|
||||||
export const generate = ({
|
export const generate = ({
|
||||||
title,
|
title,
|
||||||
|
|
@ -11,9 +11,7 @@ export const generate = ({
|
||||||
cv,
|
cv,
|
||||||
cvName,
|
cvName,
|
||||||
lastEditName,
|
lastEditName,
|
||||||
lastEdit,
|
lastEdit
|
||||||
githubLinkName,
|
|
||||||
githubLink
|
|
||||||
}: Footer): html => `
|
}: Footer): html => `
|
||||||
<footer id="page-footer">
|
<footer id="page-footer">
|
||||||
<h2>${title}</h2>
|
<h2>${title}</h2>
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ footer#page-footer {
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
@include insignificant-font();
|
@include insignificant-font();
|
||||||
opacity: 0.4;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { PageImageViewer } from "./image-viewer/image-viewer";
|
||||||
import { Page } from "../framework/page";
|
import { Page } from "../framework/page";
|
||||||
|
|
||||||
export const create = ({ config, header, timeline, footer }: Portfolio) => {
|
export const create = ({ config, header, timeline, footer }: Portfolio) => {
|
||||||
const pageHeader = new PageHeader(header, config.aPictureOf);
|
const pageHeader = new PageHeader(header);
|
||||||
const pageFooter = new PageFooter(footer);
|
const pageFooter = new PageFooter(footer);
|
||||||
|
|
||||||
const bg = new PageBackground(pageHeader, pageFooter);
|
const bg = new PageBackground(pageHeader, pageFooter);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
import { TimelineElement } from "../../../model/portfolio";
|
import { TimelineElement } from "../../../model/portfolio";
|
||||||
import { html } from "../../../model/misc";
|
import { html } from "../../../model/misc";
|
||||||
|
import { PageContent } from "../../content/content";
|
||||||
|
|
||||||
import "./timeline-element.scss";
|
import "./timeline-element.scss";
|
||||||
|
|
||||||
export const generate = (
|
export const generate = (
|
||||||
{ date, title, picture, description, more, link }: TimelineElement,
|
{ date, title, figure, description, more, link }: TimelineElement,
|
||||||
showMore: string,
|
showMore: string,
|
||||||
showLess: string
|
showLess: string
|
||||||
): html => `
|
): html => `
|
||||||
|
|
@ -13,9 +15,7 @@ export const generate = (
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>${title}</h2>
|
<h2>${title}</h2>
|
||||||
<div class="image-container">
|
${PageContent.parseTypedContent(figure)}
|
||||||
<img src="${picture}" alt="${picture}"/>
|
|
||||||
</div>
|
|
||||||
<p class="description">${description}</p>
|
<p class="description">${description}</p>
|
||||||
${
|
${
|
||||||
more
|
more
|
||||||
|
|
|
||||||
|
|
@ -75,18 +75,6 @@
|
||||||
@include sub-title-font();
|
@include sub-title-font();
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-container {
|
|
||||||
font-size: 0;
|
|
||||||
box-shadow: inset $shadow1, inset $shadow2;
|
|
||||||
pointer-events: none;
|
|
||||||
img {
|
|
||||||
pointer-events: all;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
z-index: -2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
.description {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { Portfolio } from "./model/portfolio";
|
import { Portfolio } from "./model/portfolio";
|
||||||
|
|
||||||
import me from "./static/media/me.jpg";
|
import me from "./static/media/me.jpg";
|
||||||
import forex from "./static/media/forex.gif";
|
import forexMP4 from "./static/media/forex.mp4";
|
||||||
|
import forexWEBM from "./static/media/forex.webm";
|
||||||
import myNotes from "./static/media/my-notes.jpg";
|
import myNotes from "./static/media/my-notes.jpg";
|
||||||
import processSimulator from "./static/media/process-simulator.jpg";
|
import processSimulator from "./static/media/process-simulator.jpg";
|
||||||
import processSimulatorInput from "./static/media/process-simulator-input.jpg";
|
import processSimulatorInput from "./static/media/process-simulator-input.jpg";
|
||||||
|
|
@ -11,17 +12,21 @@ import platform from "./static/media/platform.png";
|
||||||
import photos from "./static/media/photos.jpg";
|
import photos from "./static/media/photos.jpg";
|
||||||
import led from "./static/media/led.jpg";
|
import led from "./static/media/led.jpg";
|
||||||
import cv from "./static/cv/andras_schmelczer_cv_2020_01.pdf";
|
import cv from "./static/cv/andras_schmelczer_cv_2020_01.pdf";
|
||||||
import ledVideo from "./static/media/led720.mp4";
|
import ledMP4 from "./static/media/led.mp4";
|
||||||
|
import ledWEBM from "./static/media/led.webm";
|
||||||
|
|
||||||
export const portfolio: Portfolio = {
|
export const portfolio: Portfolio = {
|
||||||
config: {
|
config: {
|
||||||
showMore: `Show details`,
|
showMore: `Show details`,
|
||||||
showLess: `Show less`,
|
showLess: `Show less`
|
||||||
aPictureOf: `a picture of`
|
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
name: `András Schmelczer`,
|
name: `András Schmelczer`,
|
||||||
picture: me,
|
picture: {
|
||||||
|
type: `img`,
|
||||||
|
image: me,
|
||||||
|
alt: `a picture of me`
|
||||||
|
},
|
||||||
about: [
|
about: [
|
||||||
`I have always been fascinated by the engineering feats that surround us.
|
`I have always been fascinated by the engineering feats that surround us.
|
||||||
When I realized that someday I might be able to contribute to these achievements,
|
When I realized that someday I might be able to contribute to these achievements,
|
||||||
|
|
@ -34,7 +39,12 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
title: `Predicting foreign exchange rates`,
|
title: `Predicting foreign exchange rates`,
|
||||||
date: `2019 Autumn`,
|
date: `2019 Autumn`,
|
||||||
picture: forex,
|
figure: {
|
||||||
|
type: `video`,
|
||||||
|
options: `autoplay loop muted playsinline`,
|
||||||
|
webm: forexWEBM,
|
||||||
|
mp4: forexMP4
|
||||||
|
},
|
||||||
description: `From the animation we can see that my algorithm does a somewhat acceptable job at
|
description: `From the animation we can see that my algorithm does a somewhat acceptable job at
|
||||||
predicting (blue graph) the EUR/USD rates (green graph).`,
|
predicting (blue graph) the EUR/USD rates (green graph).`,
|
||||||
more: [
|
more: [
|
||||||
|
|
@ -49,7 +59,11 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
date: `2019 November`,
|
date: `2019 November`,
|
||||||
title: `My Notes`,
|
title: `My Notes`,
|
||||||
picture: myNotes,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: myNotes,
|
||||||
|
alt: `two screenshots of the application`
|
||||||
|
},
|
||||||
description: `A minimalist note organizer and editor powered by Markwon.`,
|
description: `A minimalist note organizer and editor powered by Markwon.`,
|
||||||
more: [
|
more: [
|
||||||
{
|
{
|
||||||
|
|
@ -65,7 +79,11 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
date: `2018 October - November`,
|
date: `2018 October - November`,
|
||||||
title: `Simulating the cooling system of a nuclear facility`,
|
title: `Simulating the cooling system of a nuclear facility`,
|
||||||
picture: processSimulator,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: processSimulator,
|
||||||
|
alt: `a screenshot of the simulator`
|
||||||
|
},
|
||||||
description: `Dynamically calculating the temperatures and flow velocities
|
description: `Dynamically calculating the temperatures and flow velocities
|
||||||
in a fluid based cooling system based on a simple model.`,
|
in a fluid based cooling system based on a simple model.`,
|
||||||
more: [
|
more: [
|
||||||
|
|
@ -79,7 +97,11 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
date: `2018 October - November`,
|
date: `2018 October - November`,
|
||||||
title: `Graph editing application`,
|
title: `Graph editing application`,
|
||||||
picture: processSimulatorInput,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: processSimulatorInput,
|
||||||
|
alt: `a picture of the simulator's UI`
|
||||||
|
},
|
||||||
description: `An intuitive editor to create and edit input files for the nuclear facility simulator.`,
|
description: `An intuitive editor to create and edit input files for the nuclear facility simulator.`,
|
||||||
more: [
|
more: [
|
||||||
`Nodes can be moved with drag&drop gestures. Editing the parameters of elements
|
`Nodes can be moved with drag&drop gestures. Editing the parameters of elements
|
||||||
|
|
@ -91,7 +113,11 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
date: `2018 July - August`,
|
date: `2018 July - August`,
|
||||||
title: `City simulation`,
|
title: `City simulation`,
|
||||||
picture: citySimulation,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: citySimulation,
|
||||||
|
alt: `a picture of a low-poly city`
|
||||||
|
},
|
||||||
description: `Simulating a city where car crashes are more frequent than usual.`,
|
description: `Simulating a city where car crashes are more frequent than usual.`,
|
||||||
more: [
|
more: [
|
||||||
`Through a REST API the state of the traffic lights can be changed.
|
`Through a REST API the state of the traffic lights can be changed.
|
||||||
|
|
@ -109,7 +135,11 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
date: `2018 June`,
|
date: `2018 June`,
|
||||||
title: `Photo color grader`,
|
title: `Photo color grader`,
|
||||||
picture: color,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: color,
|
||||||
|
alt: `a picture of the app`
|
||||||
|
},
|
||||||
description: `An innovative (at least I thought so) color grader web application.`,
|
description: `An innovative (at least I thought so) color grader web application.`,
|
||||||
more: [
|
more: [
|
||||||
`The most noteworthy feature of this application is the color selector UI.
|
`The most noteworthy feature of this application is the color selector UI.
|
||||||
|
|
@ -126,7 +156,11 @@ export const portfolio: Portfolio = {
|
||||||
date: `2017 autumn`,
|
date: `2017 autumn`,
|
||||||
|
|
||||||
title: `Platform game`,
|
title: `Platform game`,
|
||||||
picture: platform,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: platform,
|
||||||
|
alt: `a picture of the app`
|
||||||
|
},
|
||||||
description: `A 3D game written in C with the help of SDL 1.2 (I haven't heard of GPU programming at the time).`,
|
description: `A 3D game written in C with the help of SDL 1.2 (I haven't heard of GPU programming at the time).`,
|
||||||
more: [
|
more: [
|
||||||
`The maps are randomly generated and fully destroyable.
|
`The maps are randomly generated and fully destroyable.
|
||||||
|
|
@ -137,14 +171,22 @@ export const portfolio: Portfolio = {
|
||||||
{
|
{
|
||||||
date: `2016 summer`,
|
date: `2016 summer`,
|
||||||
title: `Photos`,
|
title: `Photos`,
|
||||||
picture: photos,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: photos,
|
||||||
|
alt: `a picture of the website`
|
||||||
|
},
|
||||||
description: `A simple web page where you can view my photos.`,
|
description: `A simple web page where you can view my photos.`,
|
||||||
link: `schmelczer.dev/photos`
|
link: `schmelczer.dev/photos`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
date: `2016 spring`,
|
date: `2016 spring`,
|
||||||
title: `Lights synchronised to music`,
|
title: `Lights synchronised to music`,
|
||||||
picture: led,
|
figure: {
|
||||||
|
type: `img`,
|
||||||
|
image: led,
|
||||||
|
alt: `a picture from the video`
|
||||||
|
},
|
||||||
description: `A full stack application with a built-in
|
description: `A full stack application with a built-in
|
||||||
music player which music controls the color of some RGB LED strips.`,
|
music player which music controls the color of some RGB LED strips.`,
|
||||||
more: [
|
more: [
|
||||||
|
|
@ -154,7 +196,7 @@ export const portfolio: Portfolio = {
|
||||||
A quite simple frontend for accessing the music player and changing
|
A quite simple frontend for accessing the music player and changing
|
||||||
the settings also got built using vanilla web development technologies.`,
|
the settings also got built using vanilla web development technologies.`,
|
||||||
`Below is a video showing the system in work.`,
|
`Below is a video showing the system in work.`,
|
||||||
{ type: `video`, src: ledVideo }
|
{ type: `video`, mp4: ledMP4, webm: ledWEBM, options: "controls" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -163,9 +205,7 @@ export const portfolio: Portfolio = {
|
||||||
cv,
|
cv,
|
||||||
email: `andras@schmelczer.dev`,
|
email: `andras@schmelczer.dev`,
|
||||||
cvName: `Curriculum vitae`,
|
cvName: `Curriculum vitae`,
|
||||||
githubLinkName: `view source`,
|
|
||||||
githubLink: `https://github.com/schmelczerandras/timeline`,
|
|
||||||
lastEditName: `Last modified on `,
|
lastEditName: `Last modified on `,
|
||||||
lastEdit: new Date(2019, 11, 27) // months are 0 indexed
|
lastEdit: new Date(2019, 11, 29) // months are 0 indexed
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
BIN
src/static/media/forex.mp4
Normal file
BIN
src/static/media/forex.mp4
Normal file
Binary file not shown.
BIN
src/static/media/forex.webm
Normal file
BIN
src/static/media/forex.webm
Normal file
Binary file not shown.
BIN
src/static/media/led.webm
Normal file
BIN
src/static/media/led.webm
Normal file
Binary file not shown.
|
|
@ -1,10 +1,12 @@
|
||||||
// https://google-webfonts-helper.herokuapp.com/fonts/montserrat?subsets=latin
|
// https://google-webfonts-helper.herokuapp.com/fonts/montserrat?subsets=latin
|
||||||
|
// add font-display: swap;
|
||||||
|
|
||||||
/* lato-regular - latin */
|
/* lato-regular - latin */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Lato";
|
font-family: "Lato";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
src: url("../static/fonts/lato/lato-v16-latin-regular.eot"); /* IE9 Compat Modes */
|
src: url("../static/fonts/lato/lato-v16-latin-regular.eot"); /* IE9 Compat Modes */
|
||||||
src: local("Lato Regular"), local("Lato-Regular"),
|
src: local("Lato Regular"), local("Lato-Regular"),
|
||||||
url("../static/fonts/lato/lato-v16-latin-regular.eot?#iefix")
|
url("../static/fonts/lato/lato-v16-latin-regular.eot?#iefix")
|
||||||
|
|
@ -23,6 +25,7 @@
|
||||||
font-family: "Lato";
|
font-family: "Lato";
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
src: url("../static/fonts/lato/lato-v16-latin-italic.eot"); /* IE9 Compat Modes */
|
src: url("../static/fonts/lato/lato-v16-latin-italic.eot"); /* IE9 Compat Modes */
|
||||||
src: local("Lato Italic"), local("Lato-Italic"),
|
src: local("Lato Italic"), local("Lato-Italic"),
|
||||||
url("../static/fonts/lato/lato-v16-latin-italic.eot?#iefix")
|
url("../static/fonts/lato/lato-v16-latin-italic.eot?#iefix")
|
||||||
|
|
@ -42,6 +45,7 @@
|
||||||
font-family: "Montserrat";
|
font-family: "Montserrat";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
src: url("../static/fonts/montserrat/montserrat-v14-latin-regular.eot"); /* IE9 Compat Modes */
|
src: url("../static/fonts/montserrat/montserrat-v14-latin-regular.eot"); /* IE9 Compat Modes */
|
||||||
src: local("Montserrat Regular"), local("Montserrat-Regular"),
|
src: local("Montserrat Regular"), local("Montserrat-Regular"),
|
||||||
url("../static/fonts/montserrat/montserrat-v14-latin-regular.eot?#iefix")
|
url("../static/fonts/montserrat/montserrat-v14-latin-regular.eot?#iefix")
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,17 @@ module.exports = {
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|mp4)$/i,
|
test: /\.(jpe?g|png)$/i,
|
||||||
|
loader: "responsive-loader",
|
||||||
|
options: {
|
||||||
|
adapter: require("responsive-loader/sharp"),
|
||||||
|
outputPath: "static/",
|
||||||
|
sizes: [300, 600, 1200, 2000],
|
||||||
|
placeholder: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(webm|mp4)$/i,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: "file-loader",
|
loader: "file-loader",
|
||||||
|
|
@ -49,7 +59,7 @@ module.exports = {
|
||||||
disable: !isProduction,
|
disable: !isProduction,
|
||||||
mozjpeg: {
|
mozjpeg: {
|
||||||
progressive: true,
|
progressive: true,
|
||||||
quality: 65
|
quality: 45
|
||||||
},
|
},
|
||||||
optipng: {
|
optipng: {
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
@ -61,9 +71,8 @@ module.exports = {
|
||||||
gifsicle: {
|
gifsicle: {
|
||||||
interlaced: false
|
interlaced: false
|
||||||
},
|
},
|
||||||
// the webp option will enable WEBP
|
|
||||||
webp: {
|
webp: {
|
||||||
quality: 75
|
quality: 65
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue