Simplify names & improve HTML semantics

This commit is contained in:
Andras Schmelczer 2022-09-25 16:20:40 +02:00
parent 674cf4223b
commit ec804f2319
No known key found for this signature in database
GPG key ID: 0EA1BC97D0AB076E
31 changed files with 84 additions and 120 deletions

View file

@ -1,10 +1,10 @@
import { PageBackground } from '../page/background/background'; import { Background } from '../page/background/background';
import { Footer } from '../page/footer/footer.html'; import { Footer } from '../page/footer/footer.html';
import { PageHeader } from '../page/header/header'; import { Header } from '../page/header/header';
import { PageImageViewer } from '../page/image-viewer/image-viewer'; import { ImageViewer } from '../page/image-viewer/image-viewer';
import { Main } from '../page/main/main'; import { Main } from '../page/main/main';
import { PageElement } from '../page/page-element'; import { PageElement } from '../page/page-element';
import { PageTimeline } from '../page/timeline/timeline'; import { TimelineElement } from '../page/timeline-element/timeline-element';
import cvEnglish from './media/cv-andras-schmelczer.pdf'; import cvEnglish from './media/cv-andras-schmelczer.pdf';
import me from './media/me.jpg'; import me from './media/me.jpg';
import { adAstra } from './projects/ad-astra'; import { adAstra } from './projects/ad-astra';
@ -24,8 +24,8 @@ import { CV, Email, GitHubLink, LinkedIn } from './shared';
export const createPortfolio = (): Array<PageElement> => [ export const createPortfolio = (): Array<PageElement> => [
new Main( new Main(
new PageBackground(1, 1), new Background(1, 1),
new PageHeader({ new Header({
name: 'András Schmelczer', name: 'András Schmelczer',
image: me, image: me,
imageAltText: 'a picture of me', imageAltText: 'a picture of me',
@ -35,25 +35,23 @@ export const createPortfolio = (): Array<PageElement> => [
' Discover some of my more interesting earlier projects. They are all listed below. Further information about me can be found at the bottom of the page.', ' Discover some of my more interesting earlier projects. They are all listed below. Further information about me can be found at the bottom of the page.',
], ],
}), }),
new PageTimeline({
showMoreText: 'Show details', ...[
showLessText: 'Show less', greatAi,
elements: [ declared,
greatAi, sdf2d,
declared, adAstra,
sdf2d, forex,
adAstra, myNotes,
forex, towers,
myNotes, nuclear,
towers, nuclearEditor,
nuclear, citySimulation,
nuclearEditor, platformGame,
citySimulation, photos,
platformGame, leds,
photos, ].map((p) => new TimelineElement(p, 'Show details', 'Show less')),
leds,
],
}),
Footer({ Footer({
title: 'Learn more', title: 'Learn more',
links: [ links: [
@ -65,5 +63,5 @@ export const createPortfolio = (): Array<PageElement> => [
lastEditText: 'Last modified on ', lastEditText: 'Last modified on ',
}) })
), ),
new PageImageViewer(), new ImageViewer(),
]; ];

View file

@ -1,4 +1,4 @@
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import { Video } from '../../page/video/video'; import { Video } from '../../page/video/video';
import adAstraPoster from '../media/ad_astra.jpg'; import adAstraPoster from '../media/ad_astra.jpg';
import adAstraMp4 from '../media/mp4/ad_astra.mp4'; import adAstraMp4 from '../media/mp4/ad_astra.mp4';

View file

@ -1,4 +1,4 @@
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import { Video } from '../../page/video/video'; import { Video } from '../../page/video/video';
import citySimulationMp4 from '../media/mp4/simulation.mp4'; import citySimulationMp4 from '../media/mp4/simulation.mp4';
import citySimulationPoster from '../media/simulation.jpg'; import citySimulationPoster from '../media/simulation.jpg';

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import colorsPoster from '../media/color.jpg'; import colorsPoster from '../media/color.jpg';
export const colors: TimelineElementParameters = { export const colors: TimelineElementParameters = {

View file

@ -1,5 +1,5 @@
import { Preview } from '../../page/preview/preview'; import { Preview } from '../../page/preview/preview';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import declaredPoster from '../media/decla-red.png'; import declaredPoster from '../media/decla-red.png';
import bscThesis from '../media/sdf2d-andras-schmelczer.pdf'; import bscThesis from '../media/sdf2d-andras-schmelczer.pdf';
import { GitHub, Open, Thesis } from '../shared'; import { GitHub, Open, Thesis } from '../shared';

View file

@ -1,4 +1,4 @@
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import { Video } from '../../page/video/video'; import { Video } from '../../page/video/video';
import forexPoster from '../media/forex.jpg'; import forexPoster from '../media/forex.jpg';
import forexMp4 from '../media/mp4/forex.mp4'; import forexMp4 from '../media/mp4/forex.mp4';

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import mscThesis from '../media/great-ai-andras-schmelczer.pdf'; import mscThesis from '../media/great-ai-andras-schmelczer.pdf';
import greatAiPoster from '../media/great-ai.png'; import greatAiPoster from '../media/great-ai.png';
import { Open, PyPi, Thesis } from '../shared'; import { Open, PyPi, Thesis } from '../shared';

View file

@ -1,4 +1,4 @@
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import { Video } from '../../page/video/video'; import { Video } from '../../page/video/video';
import ledPoster from '../media/led.jpg'; import ledPoster from '../media/led.jpg';
import ledMp4 from '../media/mp4/led.mp4'; import ledMp4 from '../media/mp4/led.mp4';

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import myNotesPoster from '../media/my-notes.png'; import myNotesPoster from '../media/my-notes.png';
import { GitHub } from '../shared'; import { GitHub } from '../shared';

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import nuclearEditorPoster from '../media/process-simulator-input.jpg'; import nuclearEditorPoster from '../media/process-simulator-input.jpg';
export const nuclearEditor: TimelineElementParameters = { export const nuclearEditor: TimelineElementParameters = {

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import processSimulatorPoster from '../media/process-simulator.jpg'; import processSimulatorPoster from '../media/process-simulator.jpg';
export const nuclear: TimelineElementParameters = { export const nuclear: TimelineElementParameters = {

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import photosPoster from '../media/photos.jpg'; import photosPoster from '../media/photos.jpg';
import { Open } from '../shared'; import { Open } from '../shared';

View file

@ -1,4 +1,4 @@
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import { Video } from '../../page/video/video'; import { Video } from '../../page/video/video';
import platformMp4 from '../media/mp4/platform.mp4'; import platformMp4 from '../media/mp4/platform.mp4';
import platformPoster from '../media/platform.png'; import platformPoster from '../media/platform.png';

View file

@ -1,5 +1,5 @@
import { Preview } from '../../page/preview/preview'; import { Preview } from '../../page/preview/preview';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import sdf2dPoster from '../media/sdf2d.png'; import sdf2dPoster from '../media/sdf2d.png';
import { NPM, Open, Youtube } from '../shared'; import { NPM, Open, Youtube } from '../shared';

View file

@ -1,5 +1,5 @@
import { Image } from '../../page/image-viewer/image/image.html'; import { Image } from '../../page/image-viewer/image/image.html';
import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import { TimelineElementParameters } from '../../page/timeline-element/timeline-element-parameters';
import towersPoster from '../media/towers.png'; import towersPoster from '../media/towers.png';
import { GitHub, Open } from '../shared'; import { GitHub, Open } from '../shared';

View file

@ -6,7 +6,7 @@ import { sum } from '../../helper/sum';
import { PageElement } from '../page-element'; import { PageElement } from '../page-element';
import { generate } from './background.html'; import { generate } from './background.html';
export class PageBackground extends PageElement { export class Background extends PageElement {
private static readonly perspective = 5; private static readonly perspective = 5;
private static readonly zMin = 6; private static readonly zMin = 6;
private static readonly zMax = 50; private static readonly zMax = 50;
@ -22,11 +22,11 @@ export class PageBackground extends PageElement {
for (let i = 0; i < Math.max(30, window.innerWidth / 10); i++) { for (let i = 0; i < Math.max(30, window.innerWidth / 10); i++) {
const blob = document.createElement('div'); const blob = document.createElement('div');
const z = this.random.inInterval(PageBackground.zMin, PageBackground.zMax); const z = this.random.inInterval(Background.zMin, Background.zMax);
blob.style.zIndex = (-z).toFixed(0); blob.style.zIndex = (-z).toFixed(0);
blob.style.opacity = ( blob.style.opacity = (
1 - 1 -
(z - PageBackground.zMin) / (PageBackground.zMax - PageBackground.zMin) (z - Background.zMin) / (Background.zMax - Background.zMin)
).toString(); ).toString();
blob.style.height = `${this.random.inInterval(360, 740)}px`; blob.style.height = `${this.random.inInterval(360, 740)}px`;
this.blobs.push(blob); this.blobs.push(blob);
@ -85,36 +85,36 @@ export class PageBackground extends PageElement {
height: number height: number
): [number, number] { ): [number, number] {
const farTop = -( const farTop = -(
((this.windowHeight / 2 - topOffset) / PageBackground.perspective) * ((this.windowHeight / 2 - topOffset) / Background.perspective) *
(PageBackground.zMax + PageBackground.perspective) - (Background.zMax + Background.perspective) -
this.windowHeight / 2 this.windowHeight / 2
); );
const farBottom = Math.min( const farBottom = Math.min(
((this.windowHeight / 2 - bottomOffset) / PageBackground.perspective) * ((this.windowHeight / 2 - bottomOffset) / Background.perspective) *
(PageBackground.zMax + PageBackground.perspective) - (Background.zMax + Background.perspective) -
this.windowHeight / 2 + this.windowHeight / 2 +
this.contentHeight, this.contentHeight,
this.contentHeight - height this.contentHeight - height
); );
const endXSpan = const endXSpan =
((this.windowWidth / PageBackground.perspective) * ((this.windowWidth / Background.perspective) *
(PageBackground.zMax + PageBackground.perspective)) / (Background.zMax + Background.perspective)) /
2; 2;
return [ return [
this.random.inInterval( this.random.inInterval(
mix(0, -(endXSpan - this.windowWidth / 2), z / PageBackground.zMax), mix(0, -(endXSpan - this.windowWidth / 2), z / Background.zMax),
mix( mix(
this.windowWidth, this.windowWidth,
this.windowWidth + endXSpan - this.windowWidth / 2, this.windowWidth + endXSpan - this.windowWidth / 2,
z / PageBackground.zMax z / Background.zMax
) )
), ),
this.random.inInterval( this.random.inInterval(
mix(topOffset, farTop, z / PageBackground.zMax), mix(topOffset, farTop, z / Background.zMax),
mix(this.contentHeight - bottomOffset, farBottom, z / PageBackground.zMax) mix(this.contentHeight - bottomOffset, farBottom, z / Background.zMax)
), ),
]; ];
} }

View file

@ -13,7 +13,7 @@ export const Footer = ({
links: Array<html>; links: Array<html>;
lastEditText: string; lastEditText: string;
}): html => ` }): html => `
<footer id="footer"> <footer id="contact">
<h2>${title}</h2> <h2>${title}</h2>
<div class="links"> <div class="links">

View file

@ -1,6 +1,6 @@
@use '../../style/mixins' as *; @use '../../style/mixins' as *;
#footer { #contact {
text-align: center; text-align: center;
margin-top: var(--large-margin); margin-top: var(--large-margin);

View file

@ -50,7 +50,8 @@
$img-size: 190px; $img-size: 190px;
width: var(--body-width); width: var(--body-width);
margin: calc(#{var(--normal-margin)} + #{$img-size} * 1 / 3) auto 0 auto; margin: calc(#{var(--normal-margin)} + #{$img-size} * 1 / 3) auto var(--large-margin)
auto;
position: relative; position: relative;
border-radius: var(--border-radius); border-radius: var(--border-radius);

View file

@ -3,9 +3,9 @@ import { ResponsiveImage } from '../../types/responsive-image';
import { Image } from '../image-viewer/image/image.html'; import { Image } from '../image-viewer/image/image.html';
import { PageElement } from '../page-element'; import { PageElement } from '../page-element';
import { generate } from './header.html'; import { generate } from './header.html';
import { PageThemeSwitcher } from './theme-switcher/theme-switcher'; import { ThemeSwitcher } from './theme-switcher/theme-switcher';
export class PageHeader extends PageElement { export class Header extends PageElement {
public constructor({ public constructor({
name, name,
image, image,
@ -30,6 +30,6 @@ export class PageHeader extends PageElement {
}) })
) )
); );
this.attachElement(new PageThemeSwitcher()); this.attachElement(new ThemeSwitcher());
} }
} }

View file

@ -2,13 +2,13 @@ import { createElement } from '../../../helper/create-element';
import { PageElement } from '../../page-element'; import { PageElement } from '../../page-element';
import { generate } from './theme-switcher.html'; import { generate } from './theme-switcher.html';
export class PageThemeSwitcher extends PageElement { export class ThemeSwitcher extends PageElement {
private static readonly localStorageKey = 'dark-mode'; private static readonly localStorageKey = 'dark-mode';
public constructor() { public constructor() {
super(createElement(generate())); super(createElement(generate()));
const storedIsDark = PageThemeSwitcher.loadFromLocalStorage(); const storedIsDark = ThemeSwitcher.loadFromLocalStorage();
const isDark = storedIsDark ?? isSystemLevelDarkModeEnabled(); const isDark = storedIsDark ?? isSystemLevelDarkModeEnabled();
if (isDark) { if (isDark) {
@ -31,19 +31,16 @@ export class PageThemeSwitcher extends PageElement {
turnOnLightMode(); turnOnLightMode();
} }
PageThemeSwitcher.saveToLocalStorage(isDark); ThemeSwitcher.saveToLocalStorage(isDark);
} }
private static saveToLocalStorage(darkModeEnabled: boolean) { private static saveToLocalStorage(darkModeEnabled: boolean) {
localStorage?.setItem( localStorage?.setItem(ThemeSwitcher.localStorageKey, JSON.stringify(darkModeEnabled));
PageThemeSwitcher.localStorageKey,
JSON.stringify(darkModeEnabled)
);
} }
private static loadFromLocalStorage(): boolean | null { private static loadFromLocalStorage(): boolean | null {
try { try {
return JSON.parse(localStorage!.getItem(PageThemeSwitcher.localStorageKey)!); return JSON.parse(localStorage!.getItem(ThemeSwitcher.localStorageKey)!);
} catch { } catch {
return null; return null;
} }

View file

@ -3,8 +3,8 @@ import { html } from '../../types/html';
import './image-viewer.scss'; import './image-viewer.scss';
export const generate = (): html => ` export const generate = (): html => `
<section id="image-viewer"> <div id="image-viewer">
<img height="0" width="0" image-viewer-ignore /> <img height="0" width="0" image-viewer-ignore />
<div tabindex="2" id="cancel">${cancel}</div> <button id="cancel">${cancel}</button>
</section> </div>
`; `;

View file

@ -26,6 +26,8 @@
} }
#cancel { #cancel {
background: none;
border: none;
@include image-button(var(--large-icon-size)); @include image-button(var(--large-icon-size));
@include square(calc(var(--large-icon-size) + var(--normal-margin) * 2)); @include square(calc(var(--large-icon-size) + var(--normal-margin) * 2));
position: absolute; position: absolute;

View file

@ -2,7 +2,7 @@ import { createElement } from '../../helper/create-element';
import { PageElement } from '../page-element'; import { PageElement } from '../page-element';
import { generate } from './image-viewer.html'; import { generate } from './image-viewer.html';
export class PageImageViewer extends PageElement { export class ImageViewer extends PageElement {
public constructor() { public constructor() {
super(createElement(generate())); super(createElement(generate()));

View file

@ -1,6 +1,6 @@
import { html } from '../../../types/html'; import { html } from '../../types/html';
import { Preview } from '../../preview/preview'; import { Preview } from '../preview/preview';
import { Video } from '../../video/video'; import { Video } from '../video/video';
export interface TimelineElementParameters { export interface TimelineElementParameters {
date: string; date: string;

View file

@ -1,6 +1,6 @@
import info from '../../../../static/icons/info.svg'; import info from '../../../static/icons/info.svg';
import { titleToFragment } from '../../../helper/title-to-fragment'; import { titleToFragment } from '../../helper/title-to-fragment';
import { html } from '../../../types/html'; import { html } from '../../types/html';
import { TimelineElementParameters } from './timeline-element-parameters'; import { TimelineElementParameters } from './timeline-element-parameters';
import './timeline-element.scss'; import './timeline-element.scss';
@ -8,7 +8,7 @@ export const generate = (
{ date, title, description, more, links }: TimelineElementParameters, { date, title, description, more, links }: TimelineElementParameters,
showMore: string showMore: string
): html => ` ): html => `
<section id="${titleToFragment(title)}" class="timeline-element"> <article id="${titleToFragment(title)}" class="timeline-element">
<div class="line-container"> <div class="line-container">
<div class="line"></div> <div class="line"></div>
<p class="date">${date}</p> <p class="date">${date}</p>
@ -33,15 +33,16 @@ export const generate = (
<div class="buttons"> <div class="buttons">
${ ${
more && more
`<div tabindex=0 class="info-button"> ? `<div tabindex=0 class="info-button">
<div class="svg-container">${info}</div> <div class="svg-container">${info}</div>
<p>${showMore}</p> <p>${showMore}</p>
</div>` </div>`
: ''
} }
${links.join('')} ${links.join('')}
</div> </div>
</div> </div>
</div> </div>
</section> </article>
`; `;

View file

@ -1,4 +1,4 @@
@use '../../../style/mixins' as *; @use '../../style/mixins' as *;
@mixin q-dependent-line-container($q) { @mixin q-dependent-line-container($q) {
.line { .line {

View file

@ -1,9 +1,9 @@
import { createElement } from '../../../helper/create-element'; import { createElement } from '../../helper/create-element';
import { PageElement } from '../../page-element'; import { PageElement } from '../page-element';
import { TimelineElementParameters } from './timeline-element-parameters'; import { TimelineElementParameters } from './timeline-element-parameters';
import { generate } from './timeline-element.html'; import { generate } from './timeline-element.html';
export class PageTimelineElement extends PageElement { export class TimelineElement extends PageElement {
private isOpen = false; private isOpen = false;
private more: HTMLElement; private more: HTMLElement;

View file

@ -1,6 +0,0 @@
import { html } from '../../types/html';
import './timeline.scss';
export const generate = (): html => `
<div id="timeline"></div>
`;

View file

@ -1,7 +0,0 @@
@use '../../style/mixins' as *;
@include on-large-screen {
#timeline > :first-child {
margin-top: var(--large-margin);
}
}

View file

@ -1,22 +0,0 @@
import { createElement } from '../../helper/create-element';
import { PageElement } from '../page-element';
import { PageTimelineElement } from './timeline-element/timeline-element';
import { TimelineElementParameters } from './timeline-element/timeline-element-parameters';
import { generate } from './timeline.html';
export class PageTimeline extends PageElement {
public constructor({
elements,
showMoreText,
showLessText,
}: {
showMoreText: string;
showLessText: string;
elements: Array<TimelineElementParameters>;
}) {
super(createElement(generate()));
elements.forEach((e) =>
this.attachElement(new PageTimelineElement(e, showMoreText, showLessText))
);
}
}