DEV Community

Cover image for Flutter Web and Parallax
aseem wangoo
aseem wangoo

Posted on • Updated on

Flutter Web and Parallax

In case it helped :)
Pass Me A Coffee!!

We have a parallax webpage on the website (made with Flutter Web). This page comprises of 3 sections :

  • Image section
  • Section One (What you need to know section)
  • Section Two (Ways we are uniting against COVID)

The root of our page is comprised of a Stack widget..The children of this widget is basically, above three sections…

Article here: https://flatteredwithflutter.com/flutter-web-parallax/

Image Section…

This is basically an image, now as we scroll down, we need to enable the parallax effect….with the following steps:

  1. Set the image’s width and height equal to the screen’s width and height…

This ensures that the image covers entire screen…

Image.asset(
WebAssets.socialDistance.assetName,
fit: BoxFit.fitWidth,
width: _imageWidth,
height: _imgHeight,
)

2. Create a ListView widget and pass in the stack as one of the child.

Now, inside this listview, the first child is a SizedBox, the height of this SizedBox is equal to the screen’s height…

Note : This is an important step and done, as the root widget is a Stack…

ListView(
cacheExtent: 100.0,
addAutomaticKeepAlives: false,
controller: _scrollController,
children: <Widget>[
SizedBox(height: _imgHeight),
],
),

Properties of ListView :

addAutomaticKeepAlives : false

By default, this is set to true, meaning that the children would preserve their state, otherwise they are garbage collected...

We set this to false, meaning the children will be garbage collected depending on the cacheExtent property we set..

cacheExtent : 100.0

As per the documentation :

The cacheExtent describes how many pixels the cache area extends before the leading edge and after the trailing edge of the viewport.

controller : We need to track the scrolling portion of the user, hence introducing ScrollConrollers..

Using scrollcontrollers, we can determine the current scroll position or offset..

To do so, we need to wrap our Stack with another widget called NotificationListener.

NotificationListener<T extends Notification> class

As per the documentation, 

A widget that listens for Notifications bubbling up the tree.

Notifications will trigger the onNotification callback only if their runtimeType is a subtype of T.

Our stack is wrapped with a NotificationListener of type ScrollNotification.

NotificationListener<ScrollNotification>(
onNotification: _handleScrollNotification,
child: Stack(),
)

The callback for this listener is _handleScrollNotification which returns a boolean..

Inside this listener, we get the current scroll offset of the user..

bool _handleScrollNotification(ScrollNotification notification) {
    if (notification is ScrollUpdateNotification) {
      _currOffset = notification.metrics.pixels;
    }
 return false;
}

This offset (_currOffset), which is set from the listener, is used to move our first image section…..

(Prev. Image Section…..)

Image.asset(
WebAssets.socialDistance.assetName,
fit: BoxFit.fitWidth,
width: _imageWidth,
height: _imgHeight,
)

(New image section…)

Positioned(
top: -0.25 * _currOffset, // -ve as we want to scroll upwards
child: Image.asset(
WebAssets.socialDistance.assetName,
fit: BoxFit.fitWidth,
width: _imageWidth,
height: _imgHeight,
),
),

Notice, the _currOffset here is multiplied by a negative number…Basically this is, as we want to move the image upwards (like what is needed for parallax)…

Pss: The number itself depends on your parallax effect. (for me it was 0.25)

Don’t forget to dispose off your scroll controller…..


Section One & Section Two…

In the image section, we introduced a listview…

We simply add the sections one and two, as children of the listview..

ListView(
cacheExtent: 100.0,
addAutomaticKeepAlives: false,
controller: _scrollController,
children: <Widget>[
SizedBox(height: _imgHeight), // IMP STEP 1..
InfoRow(
sectionText: ParallaxConstants.whatUKnow,
),
InfoRow(
sectionText: ParallaxConstants.united,
),
],
),

In case it helped :)
Pass Me A Coffee!!

Hosted URL : https://fir-signin-4477d.firebaseapp.com/#/

Source code for Flutter Web App..

Top comments (0)