diff --git a/src/data/portfolio.ts b/src/data/portfolio.ts index 8d9a509..8168b57 100644 --- a/src/data/portfolio.ts +++ b/src/data/portfolio.ts @@ -1,78 +1,76 @@ +import { PageBackground } from '../page/background/background'; +import { Image } from '../page/basics/image/image'; +import { PageFooter } from '../page/footer/footer'; +import { PageHeader } from '../page/header/header'; +import { PageImageViewer } from '../page/image-viewer/image-viewer'; +import { Main } from '../page/main/main'; +import { PageElement } from '../page/page-element'; +import { PageTimeline } from '../page/timeline/timeline'; +import cvEnglish from './media/cv-andras-schmelczer.pdf'; import meJpeg from './media/me.jpg?format=jpg'; import meWebP from './media/me.jpg?format=webp'; -import cvEnglish from './media/cv-andras-schmelczer.pdf'; - -import { PageFooter } from '../page/footer/footer'; -import { Image } from '../page/basics/image/image'; -import { PageHeader } from '../page/header/header'; -import { PageTimeline } from '../page/timeline/timeline'; -import { PageImageViewer } from '../page/image-viewer/image-viewer'; -import { PageBackground } from '../page/background/background'; -import { Main } from '../page/main/main'; -import { Body } from '../page/body/body'; -import { declaredTimelineElement } from './projects/declared'; -import { sdf2dTimelineElement } from './projects/sdf2d'; import { adAstraTimelineElement } from './projects/ad-astra'; +import { citySimulationTimelineElement } from './projects/city-simulation'; +import { declaredTimelineElement } from './projects/declared'; import { forexTimelineElement } from './projects/forex'; +import { greatAiTimelineElement } from './projects/great-ai'; +import { ledsTimelineElement } from './projects/leds'; import { myNotesTimelineElement } from './projects/my-notes'; import { nuclearTimelineElement } from './projects/nuclear'; import { nuclearEditorTimelineElement } from './projects/nuclear-editor'; -import { citySimulationTimelineElement } from './projects/city-simulation'; -import { platformGameTimelineElement } from './projects/platform-game'; import { photosTimelineElement } from './projects/photos'; -import { ledsTimelineElement } from './projects/leds'; +import { platformGameTimelineElement } from './projects/platform-game'; +import { sdf2dTimelineElement } from './projects/sdf2d'; import { towersTimelineElement } from './projects/towers'; -import { greatAiTimelineElement } from './projects/great-ai'; -export const create = () => - new Body( - new Main( - new PageBackground(1, 1), - new PageHeader({ - name: `András Schmelczer`, - photo: new Image(meWebP, meJpeg, `a picture of me`, false), - about: [ - ` +export const create = (): Array => [ + new Main( + new PageBackground(1, 1), + new PageHeader({ + name: `András Schmelczer`, + photo: new Image(meWebP, meJpeg, `a picture of me`, false), + about: [ + ` I have always been fascinated by the engineering feats that surround us and pervade every aspect of our lives. When I realised I might someday be able to contribute to this field, I knew that this would become my life's ambition. As I am starting my third semester at Leiden University, I feel I am getting closer to my ambition every day. `, - ` + ` Discover some of my more interesting 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`, - elements: [ - greatAiTimelineElement, - declaredTimelineElement, - sdf2dTimelineElement, - adAstraTimelineElement, - forexTimelineElement, - myNotesTimelineElement, - towersTimelineElement, - nuclearTimelineElement, - nuclearEditorTimelineElement, - citySimulationTimelineElement, - platformGameTimelineElement, - photosTimelineElement, - ledsTimelineElement, - ], - }), - new PageFooter({ - title: `Learn more`, - curriculaVitae: [{ name: `Curriculum vitae`, url: cvEnglish }], - email: `andras@schmelczer.dev`, - linkedin: `https://www.linkedin.com/in/andras-schmelczer-35487017b`, - lastEditText: `Last modified on `, - // @ts-ignore: injected by webpack - lastEdit: new Date(__CURRENT_DATE__), - }) - ), - new PageImageViewer() - ); + ], + }), + new PageTimeline({ + showMoreText: `Show details`, + showLessText: `Show less`, + elements: [ + greatAiTimelineElement, + declaredTimelineElement, + sdf2dTimelineElement, + adAstraTimelineElement, + forexTimelineElement, + myNotesTimelineElement, + towersTimelineElement, + nuclearTimelineElement, + nuclearEditorTimelineElement, + citySimulationTimelineElement, + platformGameTimelineElement, + photosTimelineElement, + ledsTimelineElement, + ], + }), + new PageFooter({ + title: `Learn more`, + curriculaVitae: [{ name: `Curriculum vitae`, url: cvEnglish }], + email: `andras@schmelczer.dev`, + linkedin: `https://www.linkedin.com/in/andras-schmelczer-35487017b`, + lastEditText: `Last modified on `, + // @ts-ignore: injected by webpack + lastEdit: new Date(__CURRENT_DATE__), + }) + ), + new PageImageViewer(), +]; diff --git a/src/data/projects/ad-astra.ts b/src/data/projects/ad-astra.ts index 40cc12d..3ee9642 100644 --- a/src/data/projects/ad-astra.ts +++ b/src/data/projects/ad-astra.ts @@ -1,5 +1,5 @@ import { Video } from '../../page/basics/video/video'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import adAstraJpeg from '../media/ad_astra.jpg?format=jpg'; import adAstraWebP from '../media/ad_astra.jpg?format=webp'; import adAstraMp4 from '../media/mp4/ad_astra.mp4'; @@ -38,5 +38,5 @@ export const adAstraTimelineElement: TimelineElementParameters = { This can also be found on GitHub along with the entire project. `, ], - links: [new GitHub('https://github.com/schmelczerandras/ad_astra')], + links: [GitHub('https://github.com/schmelczerandras/ad_astra')], }; diff --git a/src/data/projects/city-simulation.ts b/src/data/projects/city-simulation.ts index 7a65382..6c0357c 100644 --- a/src/data/projects/city-simulation.ts +++ b/src/data/projects/city-simulation.ts @@ -1,5 +1,5 @@ import { Video } from '../../page/basics/video/video'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import citySimulationMp4 from '../media/mp4/simulation.mp4'; import citySimulationPosterJpeg from '../media/simulation.jpg?format=jpg'; import citySimulationPosterWebP from '../media/simulation.jpg?format=webp'; diff --git a/src/data/projects/colors.ts b/src/data/projects/colors.ts index dfebd38..365225a 100644 --- a/src/data/projects/colors.ts +++ b/src/data/projects/colors.ts @@ -1,5 +1,5 @@ import { Image } from '../../page/basics/image/image'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import colourJpeg from '../media/color.jpg?format=jpg'; import colourWebP from '../media/color.jpg?format=webp'; diff --git a/src/data/projects/declared.ts b/src/data/projects/declared.ts index 5fd124b..1009d70 100644 --- a/src/data/projects/declared.ts +++ b/src/data/projects/declared.ts @@ -1,10 +1,9 @@ +import { Preview } from '../../page/basics/preview/preview'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import declaredJpeg from '../media/decla-red.png?format=jpg'; import declaredWebP from '../media/decla-red.png?format=webp'; -import thesis from '../media/thesis-andras-schmelczer.pdf'; - -import { Preview } from '../../page/basics/preview/preview'; -import { GitHub, Thesis, Open } from '../shared'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import bscThesis from '../media/sdf2d-andras-schmelczer.pdf'; +import { GitHub, Open, Thesis } from '../shared'; export const declaredTimelineElement: TimelineElementParameters = { title: `Multiplayer game`, @@ -34,8 +33,8 @@ export const declaredTimelineElement: TimelineElementParameters = { `, ], links: [ - new GitHub('https://github.com/schmelczerandras/decla.red'), - new Thesis(thesis), - new Open('https://decla.red'), + GitHub('https://github.com/schmelczerandras/decla.red'), + Thesis(bscThesis), + Open('https://decla.red'), ], }; diff --git a/src/data/projects/forex.ts b/src/data/projects/forex.ts index d32eec8..f0aa8f5 100644 --- a/src/data/projects/forex.ts +++ b/src/data/projects/forex.ts @@ -1,5 +1,5 @@ import { Video } from '../../page/basics/video/video'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import forexPosterJpeg from '../media/forex.jpg?format=jpg'; import forexPosterWebP from '../media/forex.jpg?format=webp'; import forexMp4 from '../media/mp4/forex.mp4'; diff --git a/src/data/projects/leds.ts b/src/data/projects/leds.ts index b50bb1c..e2ae5bc 100644 --- a/src/data/projects/leds.ts +++ b/src/data/projects/leds.ts @@ -1,5 +1,5 @@ import { Video } from '../../page/basics/video/video'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import ledPosterJpeg from '../media/led.jpg?format=jpg'; import ledPosterWebP from '../media/led.jpg?format=webp'; import ledMp4 from '../media/mp4/led.mp4'; diff --git a/src/data/projects/my-notes.ts b/src/data/projects/my-notes.ts index e5279a8..5da8b18 100644 --- a/src/data/projects/my-notes.ts +++ b/src/data/projects/my-notes.ts @@ -1,5 +1,5 @@ import { Image } from '../../page/basics/image/image'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import myNotesJpeg from '../media/my-notes.png?format=jpg'; import myNotesWebP from '../media/my-notes.png?format=webp'; import { GitHub } from '../shared'; @@ -20,5 +20,5 @@ export const myNotesTimelineElement: TimelineElementParameters = { adventure. `, ], - links: [new GitHub('https://github.com/schmelczerandras/my-notes')], + links: [GitHub('https://github.com/schmelczerandras/my-notes')], }; diff --git a/src/data/projects/nuclear-editor.ts b/src/data/projects/nuclear-editor.ts index 02e5584..3a681a6 100644 --- a/src/data/projects/nuclear-editor.ts +++ b/src/data/projects/nuclear-editor.ts @@ -1,5 +1,5 @@ import { Image } from '../../page/basics/image/image'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import processSimulatorInputJpeg from '../media/process-simulator-input.jpg?format=jpg'; import processSimulatorInputWebP from '../media/process-simulator-input.jpg?format=webp'; diff --git a/src/data/projects/nuclear.ts b/src/data/projects/nuclear.ts index 39a65ee..ad18019 100644 --- a/src/data/projects/nuclear.ts +++ b/src/data/projects/nuclear.ts @@ -1,5 +1,5 @@ import { Image } from '../../page/basics/image/image'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import processSimulatorJpeg from '../media/process-simulator.jpg?format=jpg'; import processSimulatorWebP from '../media/process-simulator.jpg?format=webp'; diff --git a/src/data/projects/photos.ts b/src/data/projects/photos.ts index aff0ffc..bde8031 100644 --- a/src/data/projects/photos.ts +++ b/src/data/projects/photos.ts @@ -1,5 +1,5 @@ import { Image } from '../../page/basics/image/image'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import photosJpeg from '../media/photos.jpg?format=jpg'; import photosWebP from '../media/photos.jpg?format=webp'; import { Open } from '../shared'; @@ -20,5 +20,5 @@ export const photosTimelineElement: TimelineElementParameters = { automatic resizing to multiple quality settings is also part of the pipeline. `, ], - links: [new Open('https://photo.schmelczer.dev')], + links: [Open('https://photo.schmelczer.dev')], }; diff --git a/src/data/projects/platform-game.ts b/src/data/projects/platform-game.ts index da91c4d..a0c3a23 100644 --- a/src/data/projects/platform-game.ts +++ b/src/data/projects/platform-game.ts @@ -1,5 +1,5 @@ import { Video } from '../../page/basics/video/video'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import platformMp4 from '../media/mp4/platform.mp4'; import platformPosterJpeg from '../media/platform.png?format=jpg'; import platformPosterWebP from '../media/platform.png?format=webp'; diff --git a/src/data/projects/sdf2d.ts b/src/data/projects/sdf2d.ts index 2512841..dec111c 100644 --- a/src/data/projects/sdf2d.ts +++ b/src/data/projects/sdf2d.ts @@ -1,5 +1,5 @@ import { Preview } from '../../page/basics/preview/preview'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import sdf2dJpeg from '../media/sdf2d.png?format=jpg'; import sdf2dWebP from '../media/sdf2d.png?format=webp'; import { NPM, Open, Youtube } from '../shared'; @@ -34,8 +34,8 @@ export const sdf2dTimelineElement: TimelineElementParameters = { `, ], links: [ - new NPM('https://www.npmjs.com/package/sdf-2d'), - new Youtube('https://www.youtube.com/watch?v=K3cEtnZUNR0'), - new Open('https://sdf2d.schmelczer.dev'), + NPM('https://www.npmjs.com/package/sdf-2d'), + Youtube('https://www.youtube.com/watch?v=K3cEtnZUNR0'), + Open('https://sdf2d.schmelczer.dev'), ], }; diff --git a/src/data/projects/towers.ts b/src/data/projects/towers.ts index f195157..9e9ae84 100644 --- a/src/data/projects/towers.ts +++ b/src/data/projects/towers.ts @@ -1,5 +1,5 @@ import { Image } from '../../page/basics/image/image'; -import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element'; +import { TimelineElementParameters } from '../../page/timeline/timeline-element/timeline-element-parameters'; import towersJpeg from '../media/towers.png?format=jpg'; import towersWebP from '../media/towers.png?format=webp'; import { GitHub, Open } from '../shared'; @@ -22,7 +22,7 @@ export const towersTimelineElement: TimelineElementParameters = { `, ], links: [ - new GitHub('https://github.com/schmelczerandras/life-towers/'), - new Open('https://towers.schmelczer.dev'), + GitHub('https://github.com/schmelczerandras/life-towers/'), + Open('https://towers.schmelczer.dev'), ], }; diff --git a/src/data/shared.ts b/src/data/shared.ts index d82995e..67c5ddf 100644 --- a/src/data/shared.ts +++ b/src/data/shared.ts @@ -1,13 +1,16 @@ -import { ImageAnchorFactory } from '../page/basics/image-anchor/image-anchor'; - +import cvIcon from '../../static/icons/cv.svg'; import githubIcon from '../../static/icons/github.svg'; import openIcon from '../../static/icons/open.svg'; -import cvIcon from '../../static/icons/cv.svg'; import packageIcon from '../../static/icons/package.svg'; +import pythonIcon from '../../static/icons/python.svg'; import youtubeIcon from '../../static/icons/youtube.svg'; +import { ImageAnchorFactory } from '../page/basics/image-anchor/image-anchor'; export const GitHub = ImageAnchorFactory(githubIcon, 'Open on GitHub'); export const NPM = ImageAnchorFactory(packageIcon, 'Open on npm'); +export const PyPi = ImageAnchorFactory(pythonIcon, 'Open on PyPi'); export const Open = ImageAnchorFactory(openIcon, 'Open in new tab'); -export const Thesis = ImageAnchorFactory(cvIcon, 'Download thesis'); +export const Thesis = ImageAnchorFactory(cvIcon, 'Download thesis', { + shouldDownload: true, +}); export const Youtube = ImageAnchorFactory(youtubeIcon, 'Open on YouTube'); diff --git a/src/helper/add-support-for-tab-navigation.ts b/src/helper/add-support-for-tab-navigation.ts new file mode 100644 index 0000000..3ed924f --- /dev/null +++ b/src/helper/add-support-for-tab-navigation.ts @@ -0,0 +1,7 @@ +export const addSupportForTabNavigation = () => + document.addEventListener('keydown', (e) => { + if (e.key === ' ') { + (document.activeElement as HTMLElement)?.click(); + e.preventDefault(); + } + }); diff --git a/src/helper/random.ts b/src/helper/random.ts index 236463d..58888f8 100644 --- a/src/helper/random.ts +++ b/src/helper/random.ts @@ -3,7 +3,9 @@ export class Random { public get next(): number { // result is in [0, 1) - return ((2 ** 31 - 1) & (this.seed = Math.imul(48271, this.seed))) / 2 ** 31; + + this.seed = Math.imul(48271, this.seed); + return ((2 ** 31 - 1) & this.seed) / 2 ** 31; } public choose(list: Array): T { diff --git a/src/helper/remove-unnecessary-outlines.ts b/src/helper/remove-unnecessary-outlines.ts new file mode 100644 index 0000000..1ec6b12 --- /dev/null +++ b/src/helper/remove-unnecessary-outlines.ts @@ -0,0 +1,4 @@ +export const removeUnnecessaryOutlines = () => + document.addEventListener('click', () => + (document.activeElement as HTMLElement).blur?.() + ); diff --git a/src/helper/scroll-to-fragment.ts b/src/helper/scroll-to-fragment.ts new file mode 100644 index 0000000..98f5432 --- /dev/null +++ b/src/helper/scroll-to-fragment.ts @@ -0,0 +1,6 @@ +export const scrollToFragment = () => { + // it might be necessary when the page takes too long to load + if (location.hash) { + document.getElementById(location.hash.slice(1))?.scrollIntoView(); + } +}; diff --git a/src/index.ts b/src/index.ts index 79f9adc..15e2602 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,3 @@ -import '../static/no-change/og-image.jpg'; -import '../static/no-change/robots.txt'; import '../static/no-change/404.html'; import '../static/no-change/favicons/android-chrome-192x192.png'; import '../static/no-change/favicons/android-chrome-512x512.png'; @@ -8,32 +6,15 @@ import '../static/no-change/favicons/favicon-16x16.png'; import '../static/no-change/favicons/favicon-32x32.png'; import '../static/no-change/favicons/favicon.ico'; import '../static/no-change/favicons/site.webmanifest'; +import '../static/no-change/og-image.jpg'; +import '../static/no-change/robots.txt'; +import { create as createPortfolio } from './data/portfolio'; +import { addSupportForTabNavigation } from './helper/add-support-for-tab-navigation'; +import { removeUnnecessaryOutlines } from './helper/remove-unnecessary-outlines'; +import { scrollToFragment } from './helper/scroll-to-fragment'; import './styles.scss'; -import { create } from './data/portfolio'; - -const addSupportForTabNavigation = () => - document.addEventListener('keydown', (e) => { - if (e.key === ' ') { - (document.activeElement as HTMLElement)?.click(); - e.preventDefault(); - } - }); - -const removeUnnecessaryOutlines = () => - document.addEventListener('click', () => - (document.activeElement as HTMLElement).blur?.() - ); - -// it might be necessary when the page takes too long to load -const scrollToFragment = () => { - if (location.hash) { - document.getElementById(location.hash.slice(1))?.scrollIntoView(); - } -}; addSupportForTabNavigation(); removeUnnecessaryOutlines(); - -create(); - +createPortfolio().forEach((e) => e.attachToDOM(document.body)); scrollToFragment(); diff --git a/src/page/basics/image-anchor/image-anchor.scss b/src/page/basics/image-anchor/image-anchor.scss index 3f5ba0d..bad4ea2 100644 --- a/src/page/basics/image-anchor/image-anchor.scss +++ b/src/page/basics/image-anchor/image-anchor.scss @@ -20,5 +20,6 @@ font-size: 0.9rem; font-style: italic; padding: 0 8px 8px 8px; + text-align: center; } } diff --git a/src/page/basics/image-anchor/image-anchor.ts b/src/page/basics/image-anchor/image-anchor.ts index 343e828..47870da 100644 --- a/src/page/basics/image-anchor/image-anchor.ts +++ b/src/page/basics/image-anchor/image-anchor.ts @@ -1,15 +1,11 @@ -import { createElement } from '../../../helper/create-element'; import { url } from '../../../types/url'; -import { PageElement } from '../../page-element'; import { generate } from './image-anchor.html'; -export const ImageAnchorFactory = ( - svg: string, - title: string, - { shouldDownload = false }: { shouldDownload?: boolean } = {} -) => - class ImageAnchor extends PageElement { - public constructor(href: url) { - super(createElement(generate({ href, svg, title, shouldDownload }))); - } - }; +export const ImageAnchorFactory = + ( + svg: string, + title: string, + { shouldDownload = false }: { shouldDownload?: boolean } = {} + ) => + (href: url) => + generate({ href, svg, title, shouldDownload }); diff --git a/src/page/basics/preview/preview.ts b/src/page/basics/preview/preview.ts index a846dd0..db7999c 100644 --- a/src/page/basics/preview/preview.ts +++ b/src/page/basics/preview/preview.ts @@ -17,7 +17,7 @@ export class Preview extends PageElement { this.query('.start-button').addEventListener('click', this.loadContent.bind(this)); } - public setParent(parent: PageElement) { + protected setParent(parent: PageElement) { new IntersectionObserver((e) => { if (!e[0].isIntersecting) { this.unloadContent(); diff --git a/src/page/body/body.ts b/src/page/body/body.ts deleted file mode 100644 index 0612bee..0000000 --- a/src/page/body/body.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PageElement } from '../page-element'; - -export class Body extends PageElement { - constructor(...children: Array) { - super(document.body, children); - children.forEach((c) => this.attachElement(c)); - this.setParent(); - } -} diff --git a/src/page/content/content.html.ts b/src/page/content/content.html.ts deleted file mode 100644 index d295767..0000000 --- a/src/page/content/content.html.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { html } from '../../types/html'; -import './content.scss'; - -export const generate = (): html => ` -
-`; diff --git a/src/page/content/content.scss b/src/page/content/content.scss deleted file mode 100644 index 4ea1c81..0000000 --- a/src/page/content/content.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use '../../style/mixins' as *; - -.content { - text-align: left; -} diff --git a/src/page/content/content.ts b/src/page/content/content.ts deleted file mode 100644 index 523519c..0000000 --- a/src/page/content/content.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createElement } from '../../helper/create-element'; - -import { generate } from './content.html'; -import { PageElement } from '../page-element'; - -export class PageContent extends PageElement { - public constructor(content: Array) { - super(createElement(generate())); - content.map((t) => { - const p = createElement(`

${t}

`); - this.htmlRoot.appendChild(p); - }); - } -} diff --git a/src/page/header/header.html.ts b/src/page/header/header.html.ts index 0237ff6..c485811 100644 --- a/src/page/header/header.html.ts +++ b/src/page/header/header.html.ts @@ -1,10 +1,17 @@ import { html } from '../../types/html'; import './header.scss'; -export const generate = (name: string): html => ` +export const generate = ({ + name, + about, +}: { + name: string; + about: Array; +}): html => `

${name}

+ ${about.map((t) => `

${t}

`).join('\n')}
`; diff --git a/src/page/header/header.ts b/src/page/header/header.ts index ed3854a..1e52dc0 100644 --- a/src/page/header/header.ts +++ b/src/page/header/header.ts @@ -1,16 +1,22 @@ import { createElement } from '../../helper/create-element'; import { Image } from '../basics/image/image'; -import { PageContent } from '../content/content'; import { PageElement } from '../page-element'; import { PageThemeSwitcher } from '../theme-switcher/theme-switcher'; import { generate } from './header.html'; export class PageHeader extends PageElement { - public constructor(header: { name: string; photo: Image; about: Array }) { - super(createElement(generate(header.name))); + public constructor({ + name, + photo, + about, + }: { + name: string; + photo: Image; + about: Array; + }) { + super(createElement(generate({ name, about }))); - this.attachElementByReplacing('.picture', header.photo); - this.attachElement(new PageContent(header.about)); + this.attachElementByReplacing('.picture', photo); this.attachElement(new PageThemeSwitcher()); } } diff --git a/src/page/image-viewer/image-viewer.ts b/src/page/image-viewer/image-viewer.ts index 5ed305d..e925244 100644 --- a/src/page/image-viewer/image-viewer.ts +++ b/src/page/image-viewer/image-viewer.ts @@ -1,6 +1,6 @@ +import { createElement } from '../../helper/create-element'; import { PageElement } from '../page-element'; import { generate } from './image-viewer.html'; -import { createElement } from '../../helper/create-element'; export class PageImageViewer extends PageElement { public constructor() { @@ -9,7 +9,7 @@ export class PageImageViewer extends PageElement { document.body.addEventListener('click', (event: MouseEvent) => { if ( event.target instanceof HTMLImageElement && - !event.target.attributes['image-viewer-ignore'] + !(event.target.attributes['image-viewer-ignore'] as boolean | undefined) ) { this.showImage(event.target); } diff --git a/src/page/page-element.ts b/src/page/page-element.ts index 0dc303b..ce30cb9 100644 --- a/src/page/page-element.ts +++ b/src/page/page-element.ts @@ -4,6 +4,11 @@ export abstract class PageElement { protected children: Array = [] ) {} + public attachToDOM(target: HTMLElement) { + target.appendChild(this.htmlRoot); + this.setParent(null); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars protected setParent(parent?: PageElement | null): void { this.children.forEach((c) => c.setParent(this)); diff --git a/src/page/timeline/timeline-element/timeline-element-parameters.ts b/src/page/timeline/timeline-element/timeline-element-parameters.ts new file mode 100644 index 0000000..44f4cb6 --- /dev/null +++ b/src/page/timeline/timeline-element/timeline-element-parameters.ts @@ -0,0 +1,13 @@ +import { html } from '../../../types/html'; +import { Image } from '../../basics/image/image'; +import { Preview } from '../../basics/preview/preview'; +import { Video } from '../../basics/video/video'; + +export interface TimelineElementParameters { + date: string; + figure: Image | Video | Preview; + title: string; + description: string; + more: Array; + links: Array; +} diff --git a/src/page/timeline/timeline-element/timeline-element.html.ts b/src/page/timeline/timeline-element/timeline-element.html.ts index 1c36441..dc8ea08 100644 --- a/src/page/timeline/timeline-element/timeline-element.html.ts +++ b/src/page/timeline/timeline-element/timeline-element.html.ts @@ -1,11 +1,11 @@ import info from '../../../../static/icons/info.svg'; import { titleToFragment } from '../../../helper/title-to-fragment'; import { html } from '../../../types/html'; -import { TimelineElementParameters } from './timeline-element'; +import { TimelineElementParameters } from './timeline-element-parameters'; import './timeline-element.scss'; export const generate = ( - { date, title, description, more }: TimelineElementParameters, + { date, title, description, more, links }: TimelineElementParameters, showMore: string ): html => `
@@ -22,7 +22,14 @@ export const generate = (

${description}

- ${more ? '
' : ''} + ${ + more + ? ` +
+ ${more.map((t) => `

${t}

`).join('\n')} +
` + : '' + }
${ @@ -32,6 +39,7 @@ export const generate = (

${showMore}

` } + ${links.join('')} diff --git a/src/page/timeline/timeline-element/timeline-element.scss b/src/page/timeline/timeline-element/timeline-element.scss index 0599f2c..ac45906 100644 --- a/src/page/timeline/timeline-element/timeline-element.scss +++ b/src/page/timeline/timeline-element/timeline-element.scss @@ -85,7 +85,6 @@ } .card { - text-align: center; box-shadow: var(--shadow); border-radius: var(--border-radius); z-index: 1; @@ -108,27 +107,31 @@ margin-top: var(--small-margin); } - h2 > a { - @include sub-title-font(); - text-decoration: none; - position: relative; + h2 { + text-align: center; - &:before { - content: '#'; - position: absolute; - left: -0.5ch; - top: 0; - opacity: 0; - transform: translateX(-100%); - transition: opacity var(--transition-time); - } + > a { + @include sub-title-font(); + text-decoration: none; + position: relative; - &:hover:before { - opacity: 0.5; + &:before { + content: '#'; + position: absolute; + left: -0.5ch; + top: 0; + opacity: 0; + transform: translateX(-100%); + transition: opacity var(--transition-time); + } + + &:hover:before { + opacity: 0.5; + } } } - & > p { + .description { text-align: center; } @@ -138,7 +141,7 @@ height: 0; transition: height var(--transition-time); - .content p { + > p { margin-top: var(--line-height); } } diff --git a/src/page/timeline/timeline-element/timeline-element.ts b/src/page/timeline/timeline-element/timeline-element.ts index 78555ba..7e49723 100644 --- a/src/page/timeline/timeline-element/timeline-element.ts +++ b/src/page/timeline/timeline-element/timeline-element.ts @@ -1,20 +1,8 @@ import { createElement } from '../../../helper/create-element'; -import { Image } from '../../basics/image/image'; -import { Preview } from '../../basics/preview/preview'; -import { Video } from '../../basics/video/video'; -import { PageContent } from '../../content/content'; import { PageElement } from '../../page-element'; +import { TimelineElementParameters } from './timeline-element-parameters'; import { generate } from './timeline-element.html'; -export interface TimelineElementParameters { - date: string; - figure: Image | Video | Preview; - title: string; - description: string; - more: Array; - links: Array; -} - export class PageTimelineElement extends PageElement { private isOpen = false; private more: HTMLElement; @@ -25,17 +13,12 @@ export class PageTimelineElement extends PageElement { private readonly showLess: string ) { super(createElement(generate(timelineElement, showMore))); - const content = new PageContent(timelineElement.more); - this.children = [content]; this.isOpen = false; this.more = this.query('.more'); - this.more.appendChild(content.htmlRoot); addEventListener('resize', this.handleResize.bind(this)); this.query('.info-button').addEventListener('click', this.toggleOpen.bind(this)); this.attachElementByReplacing('.figure', timelineElement.figure); - timelineElement.links.forEach((l) => this.attachElementAsChildOf('.buttons', l)); - this.isOpen = false; } diff --git a/src/page/timeline/timeline.ts b/src/page/timeline/timeline.ts index 8a7e035..88f5e37 100644 --- a/src/page/timeline/timeline.ts +++ b/src/page/timeline/timeline.ts @@ -1,9 +1,7 @@ import { createElement } from '../../helper/create-element'; import { PageElement } from '../page-element'; -import { - PageTimelineElement, - TimelineElementParameters, -} from './timeline-element/timeline-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 {