Add "go up" arrow

This commit is contained in:
Andras Schmelczer 2022-09-26 17:01:02 +02:00
parent 2746f239d7
commit d3927cc13c
No known key found for this signature in database
GPG key ID: 0EA1BC97D0AB076E
7 changed files with 132 additions and 47 deletions

View file

@ -6,6 +6,7 @@ import { Link } from '../page/link/link.html';
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 { TimelineElement } from '../page/timeline-element/timeline-element'; import { TimelineElement } from '../page/timeline-element/timeline-element';
import { UpArrowButton } from '../page/up-arrow-button/up-arrow-button';
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';
@ -23,51 +24,54 @@ import { sdf2d } from './projects/sdf2d';
import { towers } from './projects/towers'; import { towers } from './projects/towers';
import { CV, Email, GitHubLink, LinkedIn } from './shared'; import { CV, Email, GitHubLink, LinkedIn } from './shared';
const main = new Main(
new Background(1, 1),
new Header({
name: 'András Schmelczer',
image: me,
imageAltText: 'a picture of me',
about: [
'With more than six years of professional software engineering experience and a degree in Computer Science, I can confidently undertake any challenge. My interests span diverse areas, allowing me to design complex — even multidisciplinary — systems with a clear understanding.',
"I'm passionate about architecting and building large-scale systems, especially in the context of AI/ML. However, in my free time, I also enjoy working with shaders, data visualisation, and sometimes even microcontrollers.",
`Discover some of my more exciting projects below. And if you'd like to reach out to me, you can find my contact details at ${Link(
'the bottom of the page',
'#contact'
)}.`,
],
}),
...[
greatAi,
declared,
sdf2d,
adAstra,
forex,
myNotes,
towers,
nuclear,
nuclearEditor,
citySimulation,
platformGame,
photos,
leds,
].map((p) => new TimelineElement(p, 'Show details', 'Show less')),
Contact({
title: 'Get in touch',
links: [
CV(cvEnglish),
Email('mailto:andras@schmelczer.dev'),
LinkedIn('https://www.linkedin.com/in/andras-schmelczer'),
GitHubLink('https://github.com/schmelczer'),
],
lastEditText: 'Last modified on',
})
);
export const portfolio: Array<PageElement> = [ export const portfolio: Array<PageElement> = [
new Main( main,
new Background(1, 1),
new Header({
name: 'András Schmelczer',
image: me,
imageAltText: 'a picture of me',
about: [
'With more than six years of professional software engineering experience and a degree in Computer Science, I can confidently undertake any challenge. My interests span diverse areas, allowing me to design complex &mdash; even multidisciplinary &mdash; systems with a clear understanding.',
"I'm passionate about architecting and building large-scale systems, especially in the context of AI/ML. However, in my free time, I also enjoy working with shaders, data visualisation, and sometimes even microcontrollers.",
`Discover some of my more exciting projects below. And if you'd like to reach out to me, you can find my contact details at ${Link(
'the bottom of the page',
'#contact'
)}.`,
],
}),
...[
greatAi,
declared,
sdf2d,
adAstra,
forex,
myNotes,
towers,
nuclear,
nuclearEditor,
citySimulation,
platformGame,
photos,
leds,
].map((p) => new TimelineElement(p, 'Show details', 'Show less')),
Contact({
title: 'Get in touch',
links: [
CV(cvEnglish),
Email('mailto:andras@schmelczer.dev'),
LinkedIn('https://www.linkedin.com/in/andras-schmelczer'),
GitHubLink('https://github.com/schmelczer'),
],
lastEditText: 'Last modified on',
})
),
new ImageViewer(), new ImageViewer(),
new UpArrowButton(main, 'go up'),
]; ];

View file

@ -0,0 +1,9 @@
import arrow from '../../../static/icons/arrow.svg';
import { html } from '../../types/html';
import './up-arrow-button.scss';
export const generate = (label: string): html => `
<button id="up-arrow-button" aria-label="${label}">
${arrow}
</button>
`;

View file

@ -0,0 +1,27 @@
@use '../../style/mixins' as *;
#up-arrow-button {
@include blurred-background();
cursor: pointer;
box-shadow: var(--shadow);
transition: opacity var(--transition-time), visibility var(--transition-time),
transform var(--transition-time);
border-radius: var(--border-radius);
background: none;
border: none;
position: fixed;
bottom: var(--small-margin);
right: var(--small-margin);
padding: 4px;
&:hover {
transform: scale(1.1);
}
svg {
@include square(var(--large-icon-size));
}
}

View file

@ -0,0 +1,42 @@
import { PageElement } from '../page-element';
import { generate } from './up-arrow-button.html';
export class UpArrowButton extends PageElement {
private static readonly defaultTimeToLive = 2000;
private static readonly interval = 50;
private timeToLive = 0;
public constructor(private scrollTarget: PageElement, label: string) {
super(generate(label));
this.htmlRoot.addEventListener('click', this.scrollToTop.bind(this));
setInterval(() => {
this.timeToLive = Math.max(0, this.timeToLive - UpArrowButton.interval);
if (this.timeToLive == 0) {
this.htmlRoot.style.opacity = '0';
this.htmlRoot.style.visibility = 'hidden';
}
}, UpArrowButton.interval);
}
protected initialize() {
this.scrollTarget.htmlRoot.addEventListener('scroll', () => {
this.timeToLive = UpArrowButton.defaultTimeToLive;
this.htmlRoot.style.opacity = '1';
this.htmlRoot.style.visibility = 'visible';
if (this.scrollTarget.htmlRoot.scrollTop == 0) {
this.timeToLive = 0;
}
});
}
private scrollToTop(e: MouseEvent) {
if (this.timeToLive > 0) {
this.scrollTarget.htmlRoot.scrollTo({ top: 0, left: 0, behavior: 'smooth' });
} else {
e.preventDefault();
}
}
}

3
static/icons/arrow.svg Normal file
View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">
<polyline points="8,9 12,5 12,19 12,5 16,9" />
</svg>

After

Width:  |  Height:  |  Size: 197 B

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" stroke-width="1.5" stroke="#ffffff" fill="none" stroke-linecap="round" stroke-linejoin="round"> <svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<line x1="18" y1="6" x2="6" y2="18" /> <line x1="18" y1="6" x2="6" y2="18" />
<line x1="6" y1="6" x2="18" y2="18" /> <line x1="6" y1="6" x2="18" y2="18" />

Before

Width:  |  Height:  |  Size: 322 B

After

Width:  |  Height:  |  Size: 305 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" stroke="#ffffff" fill="none" stroke-linecap="round" stroke-linejoin="round"> <svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 24 24" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
<rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="4" y="4" width="16" height="16" rx="2" />
<line x1="8" y1="11" x2="8" y2="16" /> <line x1="8" y1="11" x2="8" y2="16" />

Before

Width:  |  Height:  |  Size: 440 B

After

Width:  |  Height:  |  Size: 423 B

Before After
Before After