diff --git a/src/data/portfolio.ts b/src/data/portfolio.ts index 8168b57..540aaa1 100644 --- a/src/data/portfolio.ts +++ b/src/data/portfolio.ts @@ -1,6 +1,6 @@ import { PageBackground } from '../page/background/background'; -import { Image } from '../page/basics/image/image'; -import { PageFooter } from '../page/footer/footer'; +import { Image } from '../page/basics/image/image.html'; +import { Footer } from '../page/footer/footer.html'; import { PageHeader } from '../page/header/header'; import { PageImageViewer } from '../page/image-viewer/image-viewer'; import { Main } from '../page/main/main'; @@ -28,7 +28,11 @@ export const create = (): Array => [ new PageBackground(1, 1), new PageHeader({ name: `AndrĂ¡s Schmelczer`, - photo: new Image(meWebP, meJpeg, `a picture of me`, false), + photo: Image({ + imageWebP: meWebP, + imageJpeg: meJpeg, + alt: `a picture of me`, + }), about: [ ` I have always been fascinated by the engineering feats that surround us and pervade every aspect @@ -62,7 +66,7 @@ export const create = (): Array => [ ledsTimelineElement, ], }), - new PageFooter({ + Footer({ title: `Learn more`, curriculaVitae: [{ name: `Curriculum vitae`, url: cvEnglish }], email: `andras@schmelczer.dev`, diff --git a/src/data/projects/colors.ts b/src/data/projects/colors.ts index 365225a..b3f6adf 100644 --- a/src/data/projects/colors.ts +++ b/src/data/projects/colors.ts @@ -1,4 +1,4 @@ -import { Image } from '../../page/basics/image/image'; +import { Image } from '../../page/basics/image/image.html'; 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'; @@ -6,7 +6,12 @@ import colourWebP from '../media/color.jpg?format=webp'; export const colorsTimelineElement: TimelineElementParameters = { title: `Photo colour grader`, date: `2018 June`, - figure: new Image(colourWebP, colourJpeg, `a picture of the app`), + figure: Image({ + imageWebP: colourWebP, + imageJpeg: colourJpeg, + alt: `a picture of the app`, + container: true, + }), description: `An innovative (at least I thought so) colour grader web application.`, more: [ ` diff --git a/src/data/projects/my-notes.ts b/src/data/projects/my-notes.ts index 5da8b18..c242458 100644 --- a/src/data/projects/my-notes.ts +++ b/src/data/projects/my-notes.ts @@ -1,4 +1,4 @@ -import { Image } from '../../page/basics/image/image'; +import { Image } from '../../page/basics/image/image.html'; 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'; @@ -7,7 +7,12 @@ import { GitHub } from '../shared'; export const myNotesTimelineElement: TimelineElementParameters = { title: `My Notes`, date: `2019 November`, - figure: new Image(myNotesWebP, myNotesJpeg, `two screenshots of the application`), + figure: Image({ + imageWebP: myNotesWebP, + imageJpeg: myNotesJpeg, + alt: `two screenshots of the application`, + container: true, + }), description: `A minimalist note organiser and editor powered by Markwon.`, more: [ ` diff --git a/src/data/projects/nuclear-editor.ts b/src/data/projects/nuclear-editor.ts index 3a681a6..b3935ed 100644 --- a/src/data/projects/nuclear-editor.ts +++ b/src/data/projects/nuclear-editor.ts @@ -1,4 +1,4 @@ -import { Image } from '../../page/basics/image/image'; +import { Image } from '../../page/basics/image/image.html'; 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'; @@ -6,11 +6,12 @@ import processSimulatorInputWebP from '../media/process-simulator-input.jpg?form export const nuclearEditorTimelineElement: TimelineElementParameters = { title: `Graph editing application`, date: `2018 October - November`, - figure: new Image( - processSimulatorInputWebP, - processSimulatorInputJpeg, - `a picture of the simulator's UI` - ), + figure: Image({ + imageWebP: processSimulatorInputWebP, + imageJpeg: processSimulatorInputJpeg, + alt: `a picture of the simulator's UI`, + container: true, + }), description: ` An intuitive editor to create and edit input for the nuclear facility simulator. `, diff --git a/src/data/projects/nuclear.ts b/src/data/projects/nuclear.ts index ad18019..bad382c 100644 --- a/src/data/projects/nuclear.ts +++ b/src/data/projects/nuclear.ts @@ -1,4 +1,4 @@ -import { Image } from '../../page/basics/image/image'; +import { Image } from '../../page/basics/image/image.html'; 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'; @@ -6,11 +6,12 @@ import processSimulatorWebP from '../media/process-simulator.jpg?format=webp'; export const nuclearTimelineElement: TimelineElementParameters = { title: `Simulating the cooling system of a nuclear facility`, date: `2018 October - November`, - figure: new Image( - processSimulatorWebP, - processSimulatorJpeg, - `a screenshot of the simulator` - ), + figure: Image({ + imageWebP: processSimulatorWebP, + imageJpeg: processSimulatorJpeg, + alt: `a screenshot of the simulator`, + container: true, + }), description: ` The temperatures and flow velocities are dynamically calculated in a fluid-based cooling system based on a simple model. diff --git a/src/data/projects/photos.ts b/src/data/projects/photos.ts index bde8031..0d2dada 100644 --- a/src/data/projects/photos.ts +++ b/src/data/projects/photos.ts @@ -1,4 +1,4 @@ -import { Image } from '../../page/basics/image/image'; +import { Image } from '../../page/basics/image/image.html'; 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'; @@ -7,7 +7,12 @@ import { Open } from '../shared'; export const photosTimelineElement: TimelineElementParameters = { title: `Photos`, date: `2016 summer`, - figure: new Image(photosWebP, photosJpeg, `a picture of the website`), + figure: Image({ + imageWebP: photosWebP, + imageJpeg: photosJpeg, + alt: `a picture of the website`, + container: true, + }), description: `A simple webpage where you can view my photos.`, more: [ ` diff --git a/src/data/projects/towers.ts b/src/data/projects/towers.ts index 9e9ae84..083604b 100644 --- a/src/data/projects/towers.ts +++ b/src/data/projects/towers.ts @@ -1,4 +1,4 @@ -import { Image } from '../../page/basics/image/image'; +import { Image } from '../../page/basics/image/image.html'; 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'; @@ -7,7 +7,12 @@ import { GitHub, Open } from '../shared'; export const towersTimelineElement: TimelineElementParameters = { title: `Towers tracking app`, date: `2019 August - September`, - figure: new Image(towersWebP, towersJpeg, `a picture of the website`), + figure: Image({ + imageWebP: towersWebP, + imageJpeg: towersJpeg, + alt: `a picture of the website`, + container: true, + }), description: `An aesthetic representation of your previous and current goals/tasks.`, more: [ ` diff --git a/src/data/shared.ts b/src/data/shared.ts index 67c5ddf..8684a33 100644 --- a/src/data/shared.ts +++ b/src/data/shared.ts @@ -4,7 +4,7 @@ import openIcon from '../../static/icons/open.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'; +import { ImageAnchorFactory } from '../page/basics/image-anchor/image-anchor.html'; export const GitHub = ImageAnchorFactory(githubIcon, 'Open on GitHub'); export const NPM = ImageAnchorFactory(packageIcon, 'Open on npm'); diff --git a/src/page/basics/image-anchor/image-anchor.html.ts b/src/page/basics/image-anchor/image-anchor.html.ts index 0dbc327..4cf25f1 100644 --- a/src/page/basics/image-anchor/image-anchor.html.ts +++ b/src/page/basics/image-anchor/image-anchor.html.ts @@ -1,18 +1,14 @@ -import { html } from '../../../types/html'; import { url } from '../../../types/url'; import './image-anchor.scss'; -export const generate = ({ - href, - svg, - title, - shouldDownload, -}: { - href: url; - svg: url; - title: string; - shouldDownload: boolean; -}): html => ` +export const ImageAnchorFactory = + ( + svg: string, + title: string, + { shouldDownload = false }: { shouldDownload?: boolean } = {} + ) => + (href: url) => + ` - (href: url) => - generate({ href, svg, title, shouldDownload }); diff --git a/src/page/basics/image/image.html.ts b/src/page/basics/image/image.html.ts index da92916..813564b 100644 --- a/src/page/basics/image/image.html.ts +++ b/src/page/basics/image/image.html.ts @@ -3,18 +3,18 @@ import { html } from '../../../types/html'; import { ResponsiveImage } from '../../../types/responsive-image'; import './image.scss'; -export const generate = ({ - sizes, +export const Image = ({ imageWebP, imageJpeg, alt, - container, + container = false, + isIgnoredByImageViewer = false, }: { - sizes: string; imageWebP: ResponsiveImage; imageJpeg: ResponsiveImage; alt: string; - container: boolean; + container?: boolean; + isIgnoredByImageViewer?: boolean; }): html => ` ${ container @@ -23,33 +23,39 @@ export const generate = ({ }%">` : '' } - - - - ${alt} - + + + + ${alt} + ${container ? `` : ''} `; + +const IMAGE_SCREEN_RATIO = 0.8; +const getSizes = (image: ResponsiveImage): string => + image.images + .slice(0, -1) + .map((d) => `(max-width: ${d.width / IMAGE_SCREEN_RATIO}px) ${d.width}px,`) + .join('\n') + `\n${last(image.images)!.width}px`; diff --git a/src/page/basics/image/image.ts b/src/page/basics/image/image.ts deleted file mode 100644 index 2a02206..0000000 --- a/src/page/basics/image/image.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { createElement } from '../../../helper/create-element'; -import { last } from '../../../helper/last'; -import { ResponsiveImage } from '../../../types/responsive-image'; -import { PageElement } from '../../page-element'; -import { generate } from './image.html'; - -export class Image extends PageElement { - private static readonly imageScreenRatio = 0.8; - - public constructor( - imageWebP: ResponsiveImage, - imageJpeg: ResponsiveImage, - alt: string, - container = true - ) { - super( - createElement( - generate({ - imageWebP, - imageJpeg, - alt, - container, - sizes: Image.getSizes(imageWebP), - }) - ) - ); - } - - private static getSizes(image: ResponsiveImage): string { - return ( - image.images - .slice(0, -1) - .map((d) => `(max-width: ${d.width / Image.imageScreenRatio}px) ${d.width}px,`) - .join('\n') + `\n${last(image.images)!.width}px` - ); - } -} diff --git a/src/page/basics/preview/preview.html.ts b/src/page/basics/preview/preview.html.ts index 9519931..587dc0e 100644 --- a/src/page/basics/preview/preview.html.ts +++ b/src/page/basics/preview/preview.html.ts @@ -1,11 +1,27 @@ import loading from '../../../../static/icons/loading.svg'; import play from '../../../../static/icons/play-button.svg'; import { html } from '../../../types/html'; +import { ResponsiveImage } from '../../../types/responsive-image'; +import { Image } from '../../basics/image/image.html'; import './preview.scss'; -export const generate = ({ alt }: { alt: string }): html => ` +export const generate = ({ + alt, + posterWebP, + posterJpeg, +}: { + alt: string; + posterWebP: ResponsiveImage; + posterJpeg: ResponsiveImage; +}): html => `
- + ${Image({ + imageWebP: posterWebP, + imageJpeg: posterJpeg, + alt, + container: true, + isIgnoredByImageViewer: true, + })}
${loading}
diff --git a/src/page/basics/preview/preview.ts b/src/page/basics/preview/preview.ts index db7999c..458a390 100644 --- a/src/page/basics/preview/preview.ts +++ b/src/page/basics/preview/preview.ts @@ -1,7 +1,6 @@ import { createElement } from '../../../helper/create-element'; import { ResponsiveImage } from '../../../types/responsive-image'; import { PageElement } from '../../page-element'; -import { Image } from '../image/image'; import { generate } from './preview.html'; export class Preview extends PageElement { @@ -11,9 +10,8 @@ export class Preview extends PageElement { private readonly url: string, alt: string ) { - super(createElement(generate({ alt }))); + super(createElement(generate({ posterWebP, posterJpeg, alt }))); this.url += '?portfolioView'; - this.attachElementByReplacing('.poster', new Image(posterWebP, posterJpeg, alt)); this.query('.start-button').addEventListener('click', this.loadContent.bind(this)); } diff --git a/src/page/basics/video/video-parameters.ts b/src/page/basics/video/video-parameters.ts new file mode 100644 index 0000000..da59482 --- /dev/null +++ b/src/page/basics/video/video-parameters.ts @@ -0,0 +1,10 @@ +import { ResponsiveImage } from '../../../types/responsive-image'; +import { url } from '../../../types/url'; + +export interface VideoParameters { + mp4: url; + webm: url; + posterWebP: ResponsiveImage; + posterJpeg: ResponsiveImage; + invertButton?: boolean; +} diff --git a/src/page/basics/video/video.html.ts b/src/page/basics/video/video.html.ts index 8fe102b..4fbd37d 100644 --- a/src/page/basics/video/video.html.ts +++ b/src/page/basics/video/video.html.ts @@ -1,19 +1,26 @@ import loading from '../../../../static/icons/loading.svg'; import play from '../../../../static/icons/play-button.svg'; import { html } from '../../../types/html'; -import { VideoParameters } from './video'; +import { Image } from '../../basics/image/image.html'; +import { VideoParameters } from './video-parameters'; import './video.scss'; export const generate = ({ webm, mp4, + posterWebP, posterJpeg, invertButton, }: VideoParameters): html => `
- + ${Image({ + imageWebP: posterWebP, + imageJpeg: posterJpeg, + alt: `thumbnail for the video`, + isIgnoredByImageViewer: true, + })}
${loading}