From 448ae8a49b727af3baa1fcd21d7b2e479906ff1d Mon Sep 17 00:00:00 2001 From: michivonah Date: Thu, 20 Mar 2025 21:49:02 +0100 Subject: [PATCH] implement animations on scroll --- layouts/partials/about.html | 4 +- layouts/partials/contact.html | 4 +- layouts/partials/projects.html | 6 +- static/main.js | 38 +++++++----- static/style.css | 102 +++++++++++++++++++++++++++++---- 5 files changed, 121 insertions(+), 33 deletions(-) diff --git a/layouts/partials/about.html b/layouts/partials/about.html index 638d54b..56db49d 100644 --- a/layouts/partials/about.html +++ b/layouts/partials/about.html @@ -1,11 +1,11 @@
{{ with .Site.GetPage "about" }} -
+
{{ with .Params.image }} {{ $.Params.title }} {{ end }}
-
+

{{ .Title }}

{{ .Content }}
diff --git a/layouts/partials/contact.html b/layouts/partials/contact.html index 3a4c1e3..f0ff1f3 100644 --- a/layouts/partials/contact.html +++ b/layouts/partials/contact.html @@ -1,8 +1,8 @@
-
+

{{ T "contact-me" }}

-
+
{{ range .Site.Data.socialmedia }} {{ end }} diff --git a/layouts/partials/projects.html b/layouts/partials/projects.html index 4988101..b397713 100644 --- a/layouts/partials/projects.html +++ b/layouts/partials/projects.html @@ -1,6 +1,6 @@
-

{{ T "projects" }}

-
+

{{ T "projects" }}

+
{{ range .Site.Data.tags }}
@@ -11,7 +11,7 @@
-
+
\ No newline at end of file diff --git a/static/main.js b/static/main.js index 6521cdf..034edb3 100644 --- a/static/main.js +++ b/static/main.js @@ -70,20 +70,27 @@ function updateNavStyle(){ // intersection observer for animations // credits: https://coolcssanimation.com/how-to-trigger-a-css-animation-on-scroll/ -const observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - const actionObject = entry.target.querySelector('.contact-title'); - - if (entry.isIntersecting) { - actionObject.classList.add('typewriter-animation'); - return; - } - - actionObject.classList.remove('typewriter-animation'); - }); -}); - -observer.observe(document.querySelector('.contact-title-wrapper')); +function animationOnScroll(triggerSelector, animationClass, targetElement){ + const trigger = document.querySelector(triggerSelector); + const target = ((targetElement) ? document.querySelector(targetElement) : trigger); + + if(trigger){ + const observer = new IntersectionObserver(entries => { + entries.forEach(entry => { + if (entry.isIntersecting) { + target.classList.add(animationClass); + } + else{ + target.classList.remove(animationClass); + } + }); + }, { rootMargin: '0px 0px 5% 0px', threshold: 0.1 }); + + return observer.observe(trigger); + } +} + +animationOnScroll('.contact-title-wrapper', 'typewriter-animation', '.contact-title'); // calculate age function calculateAge(selector){ @@ -145,8 +152,9 @@ async function getProjectCard(data){ }); const container = document.createElement("div"); - container.classList = "project-card"; + container.classList = "project-card fade-up"; container.classList.add(category); + //container.style.animation = "fade-up var(--baseDuration) linear"; //container.style.backgroundImage = `url(${image})`; const cardFirst = document.createElement("div"); diff --git a/static/style.css b/static/style.css index dd61742..f5d6f45 100644 --- a/static/style.css +++ b/static/style.css @@ -22,6 +22,9 @@ body{ --baseTransition: all var(--baseDuration); --baseDuration: 250ms; --navSmallHeight: 66px; + --animationOffset: 100px; + --animationScale: 0.75; + --animationCoverValue: 40%; } /* CONTENT */ @@ -434,17 +437,6 @@ nav.small .nav-links a:last-child:focus{ box-shadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.705); overflow: hidden; position: relative; - animation: fadeIn 400ms linear; -} - -@keyframes fadeIn{ - 0%{ - opacity: 0; - } - - 100%{ - opacity: 1; - } } .card-first img{ @@ -755,4 +747,92 @@ nav.small .nav-links a:last-child:focus{ transition: var(--baseTransition); border: 1px solid var(--primary); outline: none; +} + +/* GENERAL ANIMATIONS */ +/* only css on scroll animations: https://www.youtube.com/watch?v=0TnO1GzKWPc */ +@media (prefers-reduced-motion: no-preference){ + .fade-up{ + animation: fade-up linear; + animation-timeline: view(); + animation-composition: add; + animation-range: entry 0 cover var(--animationCoverValue); + } + + .fade-down{ + animation: fade-down var(--baseDuration) linear; + animation-timeline: view(); + animation-composition: add; + animation-range: entry 0 cover var(--animationCoverValue); + } + + .fade-left{ + animation: fade-left var(--baseDuration) linear; + animation-timeline: view(); + animation-composition: add; + animation-range: entry 0 cover var(--animationCoverValue); + } + + .fade-right{ + animation: fade-right var(--baseDuration) linear; + animation-timeline: view(); + animation-composition: add; + animation-range: entry 0 cover var(--animationCoverValue); + } +} + +@keyframes fade-up{ + 0%{ + opacity: 0; + translate: 0px var(--animationOffset); + scale: var(--animationScale); + } + + 100%{ + opacity: 1; + translate: 0px 0px; + scale: 1; + } +} + +@keyframes fade-down{ + 0%{ + opacity: 0; + translate: 0px calc(var(--animationOffset) * -1); + scale: var(--animationScale); + } + + 100%{ + opacity: 1; + translate: 0px 0px; + scale: 1; + } +} + +@keyframes fade-left{ + 0%{ + opacity: 0; + translate: calc(var(--animationOffset) * -1) 0px; + scale: var(--animationScale); + } + + 100%{ + opacity: 1; + translate: 0px 0px; + scale: 1; + } +} + +@keyframes fade-right{ + 0%{ + opacity: 0; + translate: var(--animationOffset) 0px; + scale: var(--animationScale); + } + + 100%{ + opacity: 1; + translate: 0px 0px; + scale: 1; + } } \ No newline at end of file