diff --git a/src/data/portfolio.ts b/src/data/portfolio.ts index 293306b..cf6aea3 100644 --- a/src/data/portfolio.ts +++ b/src/data/portfolio.ts @@ -25,6 +25,19 @@ import { towers } from './projects/towers'; import { CV, Email, GitHubLink, LinkedIn } from './shared'; const imageViewer = new ImageViewer(); +const contact = new PageElement( + 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 ', + }) +); + const main = new Main( new Header({ name: 'Andras Schmelczer', @@ -60,20 +73,11 @@ const main = new Main( leds, ].map((p) => new TimelineElement(p, 'Show details', 'Show less', imageViewer)), - 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 ', - }) + contact ); export const portfolio: Array = [ main, - new UpArrowButton(main, 'go up'), + new UpArrowButton(main, contact, 'go up'), imageViewer, ]; diff --git a/src/page/up-arrow-button/up-arrow-button.html.ts b/src/page/up-arrow-button/up-arrow-button.html.ts index 9566eaa..02cd5a8 100644 --- a/src/page/up-arrow-button/up-arrow-button.html.ts +++ b/src/page/up-arrow-button/up-arrow-button.html.ts @@ -3,7 +3,7 @@ import { html } from '../../types/html'; import './up-arrow-button.scss'; export const generate = (label: string): html => ` - `; diff --git a/src/page/up-arrow-button/up-arrow-button.scss b/src/page/up-arrow-button/up-arrow-button.scss index 2fe5ea1..5b075a1 100644 --- a/src/page/up-arrow-button/up-arrow-button.scss +++ b/src/page/up-arrow-button/up-arrow-button.scss @@ -5,8 +5,7 @@ cursor: pointer; box-shadow: var(--shadow); - transition: opacity var(--transition-time), visibility var(--transition-time), - transform var(--transition-time); + transition: opacity var(--transition-time), transform var(--transition-time-long); border-radius: var(--border-radius); @@ -19,6 +18,13 @@ transform: scale(1.1); } + &.down { + transform: rotate(180deg); + &:hover { + transform: scale(1.1) rotate(180deg); + } + } + svg { @include square(var(--large-icon-size)); } diff --git a/src/page/up-arrow-button/up-arrow-button.ts b/src/page/up-arrow-button/up-arrow-button.ts index 989a5b1..3d5fe57 100644 --- a/src/page/up-arrow-button/up-arrow-button.ts +++ b/src/page/up-arrow-button/up-arrow-button.ts @@ -6,7 +6,11 @@ export class UpArrowButton extends PageElement { private static readonly interval = 50; private timeToLive = 0; - public constructor(private scrollTarget: PageElement, label: string) { + public constructor( + private scrollTarget: PageElement, + private turningThreshold: PageElement, + label: string + ) { super(generate(label)); this.htmlRoot.addEventListener('click', this.scrollToTop.bind(this)); @@ -15,7 +19,6 @@ export class UpArrowButton extends PageElement { 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); } @@ -24,19 +27,31 @@ export class UpArrowButton extends PageElement { 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; + this.htmlRoot.addEventListener('mouseover', () => { + this.timeToLive = UpArrowButton.defaultTimeToLive; + this.htmlRoot.style.opacity = '1'; + }); + + new IntersectionObserver((e) => { + if (e[0].isIntersecting) { + this.htmlRoot.classList.remove('down'); + } else { + this.htmlRoot.classList.add('down'); } + }).observe(this.turningThreshold.htmlRoot); + + super.initialize(); + } + + private scrollToTop() { + this.scrollTarget.htmlRoot.scrollTo({ + top: this.htmlRoot.classList.contains('down') + ? this.scrollTarget.htmlRoot.scrollHeight + : 0, + left: 0, + behavior: 'smooth', }); } - - private scrollToTop(e: MouseEvent) { - if (this.timeToLive > 0) { - this.scrollTarget.htmlRoot.scrollTo({ top: 0, left: 0, behavior: 'smooth' }); - } else { - e.preventDefault(); - } - } } diff --git a/src/style/vars.scss b/src/style/vars.scss index 459fad8..8212bbf 100644 --- a/src/style/vars.scss +++ b/src/style/vars.scss @@ -2,7 +2,7 @@ :root { --transition-time: 200ms; - --transition-time-long: 300ms; + --transition-time-long: 350ms; --line-width: 4px; --line-height: 1.125rem; --accent-color: #b7455e;