Most features done

This commit is contained in:
Schmelczer András 2019-12-23 11:31:53 +01:00
parent cdaa423b8a
commit c8679b77bf
43 changed files with 803 additions and 648 deletions

View file

@ -0,0 +1,13 @@
import { Header } from "../../model/portfolio";
import { html } from "../../model/misc";
export const generate = (
{ name, picture, about }: Header,
aPictureOf: string
): html => `
<section id="about">
<header>
<img alt="${aPictureOf} ${name}" src="${picture}"/>
<h1>${name}</h1>
</header>
</section>`;

View file

@ -4,21 +4,17 @@
#about {
header {
@include center-children();
margin-top: $normal-margin;
h1,
img {
font: $title-font;
}
h1 {
text-align: center;
@include title-font();
}
img {
@include square(4ch);
border-radius: 100%;
margin-right: 1.5ex;
cursor: pointer;
}
}

View file

@ -1,20 +1,16 @@
import { PageContent } from "../content/content";
import { Header } from "../../model/portfolio";
import "./about.scss";
import { PageElement } from "../../framework/page-element";
import { createElement } from "../../framework/element-factory";
import { generate } from "./about.html";
import "./about.scss";
export class PageHeader extends PageElement {
public constructor({ name, picture, about }: Header, aPictureOf: string) {
const root = createElement(`
<section id="about">
<header>
<img alt="${aPictureOf} ${name}" src="${picture}"/>
<h1>${name}</h1>
</header>
</section>
`);
const content = new PageContent(about);
public constructor(header: Header, aPictureOf: string) {
const root = createElement(generate(header, aPictureOf));
const content = new PageContent(header.about);
root.appendChild(content.getElement());
super([content]);
this.setElement(root);

View file

@ -2,7 +2,12 @@
.content {
margin-top: $small-margin;
* {
margin-top: 1ch;
margin-top: $line-height;
}
p {
text-align: left;
}
}

View file

@ -0,0 +1,9 @@
import { Footer } from "../../model/portfolio";
import { html } from "../../model/misc";
export const generate = ({ email, cv }: Footer, cvName: string): html => `
<footer>
<a id="email" href="mailto:${email}">${email}</a>
<a id="cv" href="mailto:${cv}">${cvName}</a>
</footer>
`;

View file

@ -3,5 +3,4 @@
footer {
@include card();
@include center-children();
margin-top: $normal-margin;
}

View file

@ -1,18 +1,13 @@
import { Footer } from "../../model/portfolio";
import "./footer.scss";
import { PageElement } from "../../framework/page-element";
import { createElement } from "../../framework/element-factory";
import "./footer.scss";
import { generate } from "./footer.html";
export class PageFooter extends PageElement {
constructor({ email, cv }: Footer, cvName: string) {
constructor(footer: Footer, cvName: string) {
super();
this.setElement(
createElement(`
<footer>
<a id="email" href="mailto:${email}">${email}</a>
<a id="email" href="mailto:${cv}">${cvName}</a>
</footer>
`)
);
this.setElement(createElement(generate(footer, cvName)));
}
}

View file

@ -0,0 +1,9 @@
import { html } from "../../model/misc";
import cancel from "../../static/icons/cancel.svg";
export const generate = (): html => `
<section class="photo-viewer">
<img id="photo" alt="currently opened photo"/>
<img id="cancel" src="${cancel}" alt="cancel"/>
</section>
`;

View file

@ -0,0 +1,30 @@
@import "../../style/vars";
@import "../../style/mixins";
.photo-viewer {
@include center-children();
display: none;
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
margin: 0;
z-index: 2;
background-color: rgba(0, 0, 0, 0.75);
#photo {
max-width: 90vw;
max-height: 80vh;
}
#cancel {
@include square($icon-size);
position: absolute;
padding: $normal-margin;
right: 0;
top: 0;
cursor: pointer;
}
}

View file

@ -1,28 +1,24 @@
import "./image-viewer.scss";
import cancel from "../../static/icons/cancel.svg";
import { html } from "../../model/misc";
import { createElement } from "../../framework/element-factory";
import { PageElement } from "../../framework/page-element";
import { hide, show } from "../../framework/helpers";
import "./image-viewer.scss";
import { generate } from "./image-viewer.html";
import { mixColorsToRGB } from "../../framework/helper";
export class PageImageViewer extends PageElement {
private static template: html = `
<section class="photo-viewer">
<img id="photo" alt="currently opened photo"/>
<img id="cancel" src="${cancel}" alt="cancel"/>
</section>
`;
public constructor() {
super();
const root = createElement(PageImageViewer.template);
(root.querySelector("#cancel") as HTMLElement).onclick = () => hide(root);
const root = createElement(generate());
(root.querySelector("#cancel") as HTMLElement).onclick = () =>
PageImageViewer.hide(root);
this.setElement(root);
}
public onAfterLoad(parent: HTMLElement) {
super.onAfterLoad(parent);
document.body.addEventListener("keydown", this.handleKeydown.bind(this));
const images = Array.prototype.slice.call(parent.querySelectorAll("img"));
images
.filter(
@ -38,6 +34,22 @@ export class PageImageViewer extends PageElement {
"#photo"
) as HTMLImageElement).src = (event.target as HTMLImageElement).src;
show(this.getElement());
PageImageViewer.show(this.getElement());
}
private handleKeydown(event: KeyboardEvent) {
if (event.key === "Escape") {
PageImageViewer.hide(this.getElement());
}
}
private static show(e: HTMLElement) {
e.style.display = "flex";
console.log("#" + mixColorsToRGB("00000", "ffd6d6", 0.75));
document.body.parentElement.style.backgroundColor =
"#" + mixColorsToRGB("00000", "ffd6d6", 0.75);
}
private static hide(e: HTMLElement) {
e.style.display = "none";
}
}

View file

@ -0,0 +1,37 @@
import { TimelineElement } from "../../../model/portfolio";
import { html } from "../../../model/misc";
export const generate = (
{ date, title, picture, description, more, link }: TimelineElement,
showMore: string,
showLess: string
): html => `
<section class="timeline-element">
<div class="line">
<p class="date-wide-screen">${date}</p>
</div>
<div class="card">
<h2>${title}</h2>
<p class="date-narrow-screen">${date}</p>
<img src="${picture}" alt="${picture}"/>
<p class="description">${description}</p>
${
more
? `
<div id="more"></div>
<div class="buttons">
<a id="show-more">${showMore}</a>
<a id="show-less">${showLess}</a>
</div>
`
: ""
}
${
link
? `
<a href="${link}" target="_blank">${link}</a>`
: ""
}
</div>
</section>
`;

View file

@ -6,7 +6,7 @@
.date-narrow-screen,
.date-wide-screen {
font: $text-font;
@include insignificant-font();
}
.line {
@ -31,7 +31,8 @@
.date-wide-screen {
position: relative;
top: calc(33% + #{$icon-size} + 1ch);
top: calc(33% + #{$icon-size} + 2ch);
transform: rotate(30deg);
margin: 0 $normal-margin 0 calc(#{$line-width} + 1ex);
width: 100px;
}
@ -43,9 +44,14 @@
.card {
@include card();
overflow: hidden;
& > *:not(:first-child) {
margin-top: $line-height;
}
h2 {
font: $sub-title-font;
@include sub-title-font();
}
.date-narrow-screen {
@ -57,23 +63,40 @@
color: $light-text-color;
}
img {
cursor: pointer;
}
.description {
font-style: italic;
}
#more {
overflow: hidden;
height: 0;
transition: height $transition-time;
margin-top: 0;
transition: height $slow-transition-time;
}
.buttons {
position: relative;
margin-top: $small-margin;
* {
position: absolute;
left: 50%;
transform: translateX(-50%);
transition: opacity $transition-time;
transition: opacity $slow-transition-time;
}
#show-more {
opacity: 1;
}
#show-less {
opacity: 0;
visibility: hidden;
position: absolute;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
}
}
}

View file

@ -3,49 +3,21 @@ import { PageContent } from "../../content/content";
import "./timeline-element.scss";
import { PageElement } from "../../../framework/page-element";
import { createElement } from "../../../framework/element-factory";
import { generate } from "./timeline-element.html";
export class PageTimelineElement extends PageElement {
private isOpen;
private more: HTMLElement;
public constructor(
{ date, title, picture, description, more, link }: TimelineElement,
timelineElement: TimelineElement,
showMore: string,
showLess: string
) {
const root = createElement(`
<section class="timeline-element">
<div class="line">
<p class="date-wide-screen">${date}</p>
</div>
<div class="card">
<h2>${title}</h2>
<p class="date-narrow-screen">${date}</p>
<img src="${picture}" alt="${picture}"/>
<p class="description">${description}</p>
${
more
? `
<div id="more"></div>
<div class="buttons">
<a id="show-more">${showMore}</a>
<a id="show-less">${showLess}</a>
</div>
`
: ""
}
${
link
? `
<a href="${link}" target="_blank">${link}</a>`
: ""
}
</div>
</section>
`);
const root = createElement(generate(timelineElement, showMore, showLess));
if (more) {
const content = new PageContent(more);
if (timelineElement.more) {
const content = new PageContent(timelineElement.more);
super([content]);
this.isOpen = false;
this.more = root.querySelector("#more");
@ -67,17 +39,27 @@ export class PageTimelineElement extends PageElement {
) as HTMLElement;
if (this.isOpen) {
this.more.style.height = "0";
showMore.style.opacity = "1";
showLess.style.opacity = "0";
PageTimelineElement.show(showMore);
PageTimelineElement.hide(showLess);
} else {
this.openMoreToFullHeight();
showMore.style.opacity = "0";
showLess.style.opacity = "1";
PageTimelineElement.hide(showMore);
PageTimelineElement.show(showLess);
}
this.isOpen = !this.isOpen;
}
private static hide(element: HTMLElement) {
element.style.opacity = "0";
setTimeout(() => (element.style.visibility = "hidden"), 350);
}
private static show(element: HTMLElement) {
element.style.visibility = "visible";
element.style.opacity = "1";
}
private openMoreToFullHeight() {
this.more.style.height = `${this.more.scrollHeight.toString()}px`;
}

View file

@ -0,0 +1,5 @@
import { html } from "../../model/misc";
export const generate = (): html => `
<main id="timeline"></main>
`;

View file

@ -1,5 +1 @@
@import "../../style/vars";
#timeline {
margin-top: $normal-margin;
}

View file

@ -3,6 +3,7 @@ import "./timeline.scss";
import { PageElement } from "../../framework/page-element";
import { createElement } from "../../framework/element-factory";
import { PageTimelineElement } from "./timeline-element/timeline-element";
import { generate } from "./timeline.html";
export class PageTimeline extends PageElement {
public constructor(
@ -10,7 +11,7 @@ export class PageTimeline extends PageElement {
showMore: string,
showLess: string
) {
const root = createElement(`<main id="timeline"></main>`);
const root = createElement(generate());
const elements = timeline.map(
e => new PageTimelineElement(e, showMore, showLess)
);