⬅ Zurück zur Übersicht

Scrollblur

david am Sonntag, 17.06.2018 - 01:50:10
⬅ Zurück zur Übersicht

Als „Designfreak“ suche ich natürlich immer nach geeigneter Inspiration, und was bietet sich da besser an als ab und an auf den Webseiten der großen Agenturen vorbei zu schauen, und so lande ich auch ab und zu auf der Seite von Syzygy.
Beim Scrollen ist mir natürlich aufgefallen, dass das Header Bild auf der Startseite langsam verschwommen wird, je weiter man auf der Seite nach unten scrollt. Das will ich auch!

Ziemlich nice! Das ganze musste natürlich nachgebaut werden, und war für mich insbesondere interessant da ich davon ausgegangen bin, dass es keine CSS Property für „Blur – Image“ gibt (und habe mich da wohl getäuscht). Statt es also vorher zu StackOverflow’en habe ich mich für eine andere Methode entschieden und stelle hier kurz beide Möglichkeiten vor.
Vielleicht findet ja jemand den Effekt genauso eindrucksvoll wie ich und kann sich an meinem Code orientieren.

Möglichkeit 1: Fade

Der erste Ansatz war, einfach zwei Bilder übereinander zu lagern und eines von beiden beim scrollen proportional zur Scrollposition auszublenden.
Dazu benötigen wir das Bild in zwei Versionen: Einmal mit Blur Effekt, und einmal ohne. Dazu hab ich das Original – Bild in Fotoshop mit dem Gaus’schen Weichzeichner bearbeitet und 8px Blur gesetzt (mit den Werten muss je nach Bild ein bisschen experimentiert werden).

Da ich das ganze auch als Heroimage (volle breite, baby) aufbauen wollte (wie bei syzygy), habe ich ein Div mit 100% width und position:relative; definiert und als background-image das verschwommene Bild gesetzt.
In das div kommt ein weiteres div mit 100% width und 100% height, position:absolute und als background-image das „unverschwommene Bild“, so dass das unblurred Bild das blurred überlagert, bzw. das obere div mit dem unverschwommenen Bild das div mit dem verschwommenen verdeckt.
Sobald jetzt gescrollt wird, blenden wir das „innere“ Div (= unverschwommen) langsam aus, sodass das „äußere“ Div (= verschwommen) eingeblendet wird.
So weit, so einfach. Lediglich die Berechnung des Opacity – Wertes könnte zu ein paar Kopfschmerzen führen. Nach ein bisschen experimentieren bin ich zu folgender Lösung gekommen:
Wir wollen, sobald das Bild zu 100% aus dem Viewport gescrollt wurde, eine Opacity von 0 für das innere div, sodass das äußere div mit dem verschwommenen Bild sichtbar wird .  Wir brauchen also erstmal 1% der Höhe des Bildes um uns zu orientieren, was wir durch
[javascript] 100/$(‚#hero-image-inner‘).height()
[/javascript] berechnen können. Diesen Wert multiplizieren wir mit der Scrollposition in px (= entspricht der Anzahl an Pixel, die wir bereits runtergescrollt haben). Diesen Wert ziehen wir von 1 ab, da wir einen negativen Opacitywert haben wollen (Opacity 1 bedeutet sichtbar, Opacity 0 unsichtbar). Ich persönlich teile den Wert vorher noch durch 50, da ich bereits bei 50% einen Blur von 100% haben will. Andernfalls wäre das Bild erst „unverschwommen“ (= das innere div hat eine Opacity von 0), wenn der Nutzer so weit gescrollt hat, dass er das Bild nicht mehr sehen kann. Wäre natürlich doof.
Aber Code sagt ja bekanntlich mehr als 1000 Worte:
Javascript
[javascript] $(document).on(’scroll‘, function(){
$("#hero-image-inner").css("opacity", 1 – (100 / $(‚#hero-image-inner‘).height() * $(document).scrollTop()) / 50);
});
[/javascript] HTML
[html] <div class="hero-image-outer">
<div id="hero-image-inner"></div>
</div>
[/html]

Möglichkeit 2: CSS Filter

Die zweite Möglichkeit, welche mir selbst neu war, setzt den CSS Filter „blur“ abhängig davon, wie weit schon gescrollt wurde.
Wer damit noch nicht gearbeitet hat kann sich eine Einführung zu CSS – Filtern bei W3Schools holen.
Wir brauchen bei dieser Variante kein Photoshop bzw. kein Bildbearbeitungsprogramm, da der Effekt direkt im Browser generiert wird.
Die jQuery Funktion wird jetzt immer dann ausgelöst, sobald gescrollt wird und berechnet dabei den „Blurfilter“ neu.
Dabei wird die Variable percent anders berechnet als oben, da der Blur – Filter einen Wert von 0 – 100 und nicht von 0 – 1 erwartet.
var percent berechnet sich also aus der Gesamthöhe des Bildes in Pixel multipliziert mit der aktuellen Scrollposition. Scrollen wir beispielsweise 2px nach unten, wäre der Blur – Wert bei einer Bildgröße von 200×200 genau 400. Das wäre ein bisschen viel, da wir dann schon nach einem Pixel das gesamte Bild verschwommen hätten. Deswegen brauchen wir nur einen Bruchteil des Wertes, welchen wir dadurch berechnen, dass wir einen „Teilwert“ nutzen (in diesem Fall 20), welchen wir durch den berechneten Wert teilen. Wenn ihr eine schnellere oder langsamere Animation wollt, spielt einfach ein wenig mit dem Teiler 20 rum – höherer Wert führt zu einer schnelleren Animation, niedrigerer Wert entsprechend zu einer schnelleren.
HTML
[html] <img src="images/clearimage.png" id="heroimage">
[/html] Javascript
[javascript] $(document).on(’scroll‘, function(){
var percent =(20 / $(‚#heroimage‘).height() * $(document).scrollTop());
$("#heroimage").css("filter","blur(" + percent + "px)");
$("#heroimage").css("filter","filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='(" + percent + "‘)");
});
[/javascript] Hier gilt – ganz wichtig: Die Berechnung des Opacity / Blur – Wertes habe ich durch Trial&Error herausgefunden. Es mag sein, dass es sich hierbei nicht um die performanteste oder beste Lösung handelt. Wenn jemand eine „sauberere“ Lösung anbieten kann darf er oder sie mir das gerne in den Kommentaren mitteilen.

TL;DR

Kommentar schreiben

Kommentare