Skip to content

Alt om WordPress, webutvikling — og mer til

🔄 Objektanimasjon ved rulling: trinn-for-trinn-guide

🔄 Objektanimasjon ved rulling: trinn-for-trinn-guide

Du lander på et nettsted, scroller siden, og logoen i hjørnet roterer jevnt og reagerer på hver bevegelse av scrollehjulet. Det ser levende og teknologisk kyndig ut, og gir det lille ekstra som folk legger merke til.

Å lage denne rotasjonen er enklere enn det ser ut. Du trenger ikke tunge biblioteker eller megabyte med animasjonsrammeverk. Alt du trenger er én div, noen få linjer CSS, og bokstavelig talt én blokk med JavaScript.

Nedenfor følger en trinnvis gjennomgang: fra klargjøring av bildet til tilpasning for mobilskjermer. Koden er testet, fungerer og har ingen avhengigheter.

💡 Rask oversikt:

  • Klargjør et SVG- eller PNG-objekt og sett det inn i HTML-en
  • Fiksér posisjonen med position: fixed og sett avstander med viewport-enheter
  • Legg til en JavaScript scroll-handler som roterer objektet ved hjelp av transform: rotate()
  • Juster rotasjonshastigheten ved å dele window.scrollY på en koeffisient
  • For mobil, legg til en media query med ny posisjonering og overgangstid

1. Klargjøring av objektet

Objektet kan være hva som helst: et ikon, en logo, en vektorform, et pilsymbol. Jeg anbefaler SVG, det mister ikke skarphet under transformasjoner og veier nesten ingenting. Hvis gjennomsiktighet er kritisk og du ikke har en vektor, vil PNG fungere.

Plasser bildet inni en container-div og legg det i body, helst nær toppen. En separat div forenkler administrasjon: senere kan du legge til naboelementer eller bytte ut bildet uten å røre posisjoneringslogikken.

1<div id="scrollContainer">
2 <img src="img/scrollObject.svg" alt="scrollObject" id="scrollObject">
3</div>

Du kan ha flere objekter, bare gi hvert enkelt en unik id og dupliser JS-logikken med binding til sitt respektive element. Men la oss først bygge én fungerende instans.

2. Posisjonering med CSS

Hvor skal objektet plasseres? Det avhenger av målet:

  • Nederste høyre hjørne, et miniatyrikon som ikke forstyrrer innholdet. Klassisk for blogger og porteføljer.
  • Øverste venstre hjørne, indikator for scrolleposisjon (fremdriftshjul).
  • Midten av nederste kant, stort dekorativt element som trekker oppmerksomhet til bunnteksten.

La oss se på scenarioet med nederste høyre hjørne, det er universelt og dekker ikke navigasjonen. I CSS skriver du:

1#scrollObject {
2 position: fixed;
3 right: 3vw;
4 bottom: 3vh;
5 top: auto;
6 width: 7vh;
7 height: auto;
8 transition: 0.1s ease-out;
9}

Nøkkelen er position: fixed. Dette fikserer elementet i forhold til nettleservinduet, ikke dokumentet. Ved scrolling beveger innholdet seg, men objektet forblir på plass. Enhetene vw og vh (prosentandeler av viewport-bredde og -høyde) justerer automatisk avstander for enhver skjerm, fra smarttelefon til 4K-skjerm.

Egenskapen transition: 0.1s ease-out jevner ut rykk ved endring av posisjon. For rotasjon er rollen sekundær, men ved endring av størrelse eller media query-endringer ser overgangen renere ut.

3. Rotasjonsanimasjon med JavaScript

CSS kan gjøre enkle @keyframes, men vår oppgave er å knytte rotasjonsvinkelen til scrolleposisjon. Det er her JavaScript kommer inn. Minimal arbeidskode:

1const scrollObject = document.getElementById("scrollObject");
2
3window.addEventListener("scroll", () => {
4 scrollObject.style.transform = `rotate(${window.scrollY}deg)`;
5});

Det som skjer her: window.scrollY returnerer antall piksler siden har scrollet vertikalt. Dette tallet settes inn i CSS-funksjonen rotate(), én piksel scrolling tilsvarer én grads rotasjon.

Hvis objektet roterer for raskt, del verdien på en koeffisient:

1const speedFactor = window.scrollY / 2;
2const scrollObject = document.getElementById("scrollObject");
3
4window.addEventListener("scroll", () => {
5 scrollObject.style.transform = `rotate(${speedFactor}deg)`;
6});

Velg en divisor som passer sidelengden din. En verdi på /2 halverer rotasjonen, /4 gjør den jevn og knapt merkbar. For lange landingssider, bruk /6 eller /8 slik at objektet ikke gjør ti hele rotasjoner halvveis ned på siden.

Ytelsesmerknad

scroll-hendelsen utløses dusinvis av ganger per sekund. På et enkelt nettsted med én transform er dette umerkelig, men hvis du har flere animerte objekter eller tung DOM, pakk logikken inn i requestAnimationFrame:

1const scrollObject = document.getElementById("scrollObject");
2let ticking = false;
3
4window.addEventListener("scroll", () => {
5 if (!ticking) {
6 requestAnimationFrame(() => {
7 scrollObject.style.transform = `rotate(${window.scrollY}deg)`;
8 ticking = false;
9 });
10 ticking = true;
11 }
12});

requestAnimationFrame grupperer kall i nettleserens synkroniseringsrammer (vanligvis 60 fps) og kjører ikke stilomberegning ved hver scroll-hendelse, noe som sparer CPU og batteri på mobil.

Legg også til will-change: transform i CSS-regelen for #scrollObject. Dette forteller nettleseren om å allokere et GPU-komposittlag på forhånd, og rotasjonen vil bli maskinvareakselerert:

1#scrollObject {
2 /* ... other properties ... */
3 will-change: transform;
4}

4. Mobiltilpasning

På skjermer mindre enn 600 piksler kan nederste høyre hjørne komme i konflikt med burgermenyer eller «til toppen»-knapper. En fornuftig løsning er å flytte objektet til nederst i midten slik at det ikke dekker interaktive elementer:

1@media only screen and (max-width: 600px) {
2 #scrollObject {
3 transition: 0.2s ease-out;
4 margin-left: -4vh;
5 width: 8vh;
6 height: auto;
7 top: 10px;
8 left: 50%;
9 }
10}

Objektet flyttes til toppen av skjermen, sentrert ved hjelp av left: 50% med negativ margin-left, en klassisk teknikk for horisontal sentrering. Bredden økes litt (8vh i stedet for 7vh) for å kompensere for kortere visningsavstand.

Legg merke til transition: 0.2s ease-out i media queryen. Når du bytter fra desktop til mobil (eller under endring av vindusstørrelse), «hopper» ikke objektet umiddelbart, men sklir jevnt til den nye posisjonen over 0,2 sekunder.

Rulleikon på mobilskjerm

Hvis du jobber i Vue eller React, trekk ut scroll-objektet til en egen komponent. Du kan feste den til roten App.vue eller i layout slik at animasjonen er til stede på alle sider samtidig, uten kodeduplisering.

Animasjonsresultat for rulleobjekt etter tilpasning

Moderne alternativ: CSS scroll-drevne animasjoner

I 2024-2025 fikk Chromium-nettlesere (Chrome, Edge, Opera) innebygd støtte for animation-timeline: scroll(), scroll-koblede animasjoner uten en eneste linje JavaScript. Det ser slik ut:

1@keyframes rotate {
2 to { transform: rotate(360deg); }
3}
4
5#scrollObject {
6 animation: rotate linear;
7 animation-timeline: scroll();
8}

Fordel: null JavaScript, ulempe: kun i Chromium foreløpig (Firefox og Safari implementerer). For progressiv forbedring kan du kombinere: gi CSS-versjonen til moderne nettlesere og behold JS-handleren som en fallback for resten. Detaljer på MDN.

⁉️🤔 Ofte stilte spørsmål

Kan jeg animere ikke bare rotasjon, men også skala eller opasitet?

Ja. transform støtter flere funksjoner samtidig. For å få et objekt til å rotere og krympe ved scrolling: scrollObject.style.transform = \rotate(${window.scrollY}deg) scale(${1 - window.scrollY / 5000})`;. Opasitet håndteres separat fra transformved hjelp avopacity. Kombiner opptil fem eller seks parametere, men test, flere transformasjoner på svake enheter kan forårsake mikrohakking. Én eller to parametere pluss will-change: transform` er et trygt tak for 60 fps.

**Hva er best: SVG eller PNG for animasjon?**

SVG, uten tvil. Det skalerer uten å miste skarphet ved enhver rotasjon og skjermoppløsning, veier mindre, og nettleseren gjengir det som vektor (ingen pikseltrapp på kanter etter rotate). Bruk PNG bare hvis du allerede har ferdig rastergrafikk og ikke har tid til å lage det på nytt. Unngå JPEG for roterende objekter, komprimeringsartefakter blir mer merkbare etter rotasjon.

**Hvordan får jeg animasjonen til å starte først når objektet er i det synlige området?**

Bruk IntersectionObserver. I stedet for å binde til global scroll, overvåker du om objektet har kommet inn i viewporten og aktiverer først da rotasjon. Dette sparer ressurser når elementet er utenfor skjermen. Grunnmal: opprett en observer med threshold: 0, i callbacken legg til/fjern en .active-klasse, og bind JS scroll-handleren til tilstedeværelsen av denne klassen.

**Hvorfor hakker animasjonen på nettstedet mitt?**

Tre typiske årsaker. For det første: ingen will-change: transform, nettleseren gir ikke elementet til GPU-kompositt og beregner layout på nytt for hvert bilde. For det andre: egenskaper som forårsaker reflow (som width, height, margin eller padding) brukes på elementet i den samme scroll-handleren. Erstatt dem med transform: scale() og transform: translate(). For det tredje: scroll-callbacken kjøres uten requestAnimationFrame og skaper ekstra repaints mellom bilder. Pakk logikken inn i rAF-mønsteret (eksempel i «Ytelsesmerknad»-seksjonen).

**Er JavaScript nødvendig? Det finnes rene CSS-løsninger.**

CSS @keyframes er knyttet til tid, ikke scrolleposisjon. Ja, animation-timeline: scroll() endrer spillet, men nettleserstøtten er fortsatt ufullstendig (se seksjon 4). Per midten av 2026 er JavaScript-løsningen med scrollY + transform fortsatt den mest pålitelige måten på tvers av nettlesere for å knytte rotasjon til scrolling. Hele koden får plass på 5 linjer, har ingen avhengigheter og fungerer fra Internet Explorer 10 til ferske Chrome.

Bør du legge til scroll-animasjon på nettstedet ditt?

Å rotere et objekt ved scrolling er ikke bare et «kult triks». Det er en mikrointeraksjon som gir den besøkende taktil tilbakemelding: «Jeg beveger siden og noe skjer». Riktig konfigurert irriterer eller distraherer den ikke, men gir personlighet til nettstedet.

Hvis nettstedet er minimalistisk, begrens deg til ett lite objekt i hjørnet og en koeffisient på /4 eller /6. For landingssider og porteføljer kan du leke mer dristig: et stort sentralt element med /2, kombinert rotasjons- og skalaanimasjon, bildebytte når en viss scrollY nås.

Hovedregel: scroll-animasjon skal komplementere innhold, ikke konkurrere med det om oppmerksomhet. Ett objekt, jevn bevegelse, ingen påtrengenhet, og nettstedet ditt vil bli husket.