Add "go up" arrow
This commit is contained in:
parent
2746f239d7
commit
d3927cc13c
7 changed files with 132 additions and 47 deletions
|
|
@ -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 — 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',
|
|
||||||
})
|
|
||||||
),
|
|
||||||
new ImageViewer(),
|
new ImageViewer(),
|
||||||
|
new UpArrowButton(main, 'go up'),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
9
src/page/up-arrow-button/up-arrow-button.html.ts
Normal file
9
src/page/up-arrow-button/up-arrow-button.html.ts
Normal 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>
|
||||||
|
`;
|
||||||
27
src/page/up-arrow-button/up-arrow-button.scss
Normal file
27
src/page/up-arrow-button/up-arrow-button.scss
Normal 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));
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/page/up-arrow-button/up-arrow-button.ts
Normal file
42
src/page/up-arrow-button/up-arrow-button.ts
Normal 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
3
static/icons/arrow.svg
Normal 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 |
|
|
@ -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 |
|
|
@ -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 |
Loading…
Add table
Add a link
Reference in a new issue