Fixed Headers, On-Page Links, and Overlapping Content, Oh My!

Let's take a basic on-page link:

<a href="#section-two">Section Two</a>

When clicked, the browser will scroll itself to the element with that ID: <section id="section-two"></section>. A browser feature as old as browsers themselves, just about.

But as soon as position: fixed; came into play, it became a bit of an issue. The browser will still jump to bring the newly targeted element into view, but that element may be obscured by a fixed position element, which is pretty bad UX.

I called this "headbutting the browswer window" nearly 10 years ago, and went over some possible solutions. Nicolas Gallager documented five different techniques. I'm even using a fixed position header here in v17 of CSS-Tricks, and I don't particularly love any of those techniques. I sort of punted on it and added top padding to all my <h3> elements, which is big enough for the header to fit there.

There is a new way though! Finally!

Šime Vidas documented this in Web Platform News. There are a bunch of CSS properties that go together as part of CSS scroll snapping, but it turns out that scroll-padding and scroll-margin can be used outside of a scroll snapping container.

body {
  scroll-padding-top: 70px; /* height of sticky header */
}

This only works in Chromium browsers:

See the Pen
Scroll Padding on Fixed Postion Headers
by Chris Coyier (@chriscoyier)
on CodePen.

This is such a useful thing we should hoot and holler for WebKit and Firefox to do it.

The post Fixed Headers, On-Page Links, and Overlapping Content, Oh My! appeared first on CSS-Tricks.

How to Create Smooth WebGL Transitions on Scroll using Phenomenon

This tutorial is going to demonstrate how to create a smooth WebGL transition on scroll using Phenomenon (based on three.js).

Attention: This tutorial assumes you already have some understanding of how three.js works.
If you are not familiar, I highly recommend checking out the official documentation and examples .

Let’s get started

Interactive elements on websites can enhance the user experience a lot. In the demo, a mix of WebGL and regular UI elements will transition based on the scroll position.

The following libraries are used for this demo:

  • Three.js: Provides the structure for everything in the WebGL environment.
  • THREE.Phenomenon: Makes it easy to create an instanced mesh that can be transitioned smoothly.
  • updateOnScroll: Observes scroll position changes based on percentage values.

About Phenomenon

Phenomenon is a small wrapper around three.js built for high-performance WebGL experiences. It started out as a no-dependency library that I created to learn more about WebGL and was later made compatible with the powerful features of three.js.

With Phenomenon it’s possible to transition thousands of objects in 3D space in a smooth way. This is done by combining all the separate objects as one. The objects will share the same logic but can move or scale or look different based on unique attributes. To make the experience as smooth as possible it’s important to make it run almost entirely on the GPU. This technique will be explained further below.

Animate an instance

To create the animated instances in the demo there are a few steps we need to go through.

Provide base properties

Define what Geometry to multiply:

const geometry = new THREE.IcosahedronGeometry(1, 0);

Define how many of objects we want to combine:

const multiplier = 200;

Define what Material it should have:

const material = new THREE.MeshPhongMaterial({
  color: '#448aff',
  emissive: '#448aff',
  specular: '#efefef',
  shininess: 20,
  flatShading: true,
});

Here we only define the behavior for a single instance. To add to this experience you can add more objects, add lights and shadow or even post processing. Have a look at the Three.js documentation for more information.

Build the transition

The transition of the instance is a little more complex as we will write a vertex shader that will later be combined with our base properties. For this example, we’ll start by moving the objects from point A to point B.

We can define these points through attributes which are stored directly on the GPU (for every object) and can be accessed from our program. In Phenomenon these attributes are defined with a name so we can use it in our shader and a data function which can provide a unique value for every object.

The code below will define a start- and end position between -10 and 10 for every instance randomly.

function r(v) {
  return -v + Math.random() * v * 2;
}

const attributes = [
  {
    name: 'aPositionStart',
    data: () => [r(10), r(10), r(10)},
    size: 3,
  },
  {
    name: 'aPositionEnd',
    data: () => [r(10), r(10), r(10)]
    size: 3,
  },
];

After all of the objects have a unique start and end position we’ll need a progress value to transition between them. This variable is a uniform that is updated at any time from our main script (for example based on scroll or time).

const uniforms = {
  progress: {
    value: 0,
  },
};

Once this is in place the only thing left for us is writing the vertex shader, which isn’t our familiar Javascript syntax, but instead GLSL. We’ll keep it simple for the example to explain the concept, but if you’re interested you can check out the more complex source.

In the vertex shader a `gl_Position` should be set that will define where every point in our 3d space is located. Based on these positions we can also move, rotate, ease or scale every object separately.

Below we define our two position attributes, the progress uniform, and the required main function. In this case, we mix the positions together with the progress which will let the instances move around.

attribute vec3 aPositionStart;
attribute vec3 aPositionEnd;
uniform float progress;

void main(){
  gl_Position = position + mix(aPositionStart, aPositionEnd, progress);
}

The position value is defined in the core of three.js and is based on the selected geometry.

Transition on scroll

When we put all the above code together and give each instance a slight offset (so they move after each other) we can start updating our progress based on the scroll position.

With the updateOnScroll library we can easily observe the scroll position based on percentage values. In the example below a value of 0 to 1 is returned between 0% and 50% of the total scroll height. By setting the progress uniform to that value our interaction will be connected to the transition in WebGL!

const phenomenon = new THREE.Phenomenon({ ... });

updateOnScroll(0, 0.5, progress => {
 phenomenon.uniforms.progress.value = progress;
});

In the demo every instance (and the UI elements in between) have their own scroll handler (based on a single listener).

Next steps

With all of the above combined our experience is off to a great start, but there’s a lot more we can do:

  • Add color, lights and custom material
  • Add more types user interaction
  • Transition with easing
  • Transition scale or rotation
  • Transition based on noise

Have a look at the WebGL Wonderland collection for multiple experiments showcasing the possibilities!

WebGLWonderland

Conclusion

Learning about WebGL has been an interesting journey for me and I hope this tutorial has inspired you!

Feel free to ask questions or share experiments that you’ve created, thank you for reading! 🙂

How to Create Smooth WebGL Transitions on Scroll using Phenomenon was written by Colin van Eenige and published on Codrops.

Blogasm

Blogasm is a minimal, elegant, clean and responsive free WordPress blog theme with a pleasing design and minimalist color combination to emphasize your blog posts. Create your awesome blog for personal, fashion, lifestyle, food, travel, photography, portfolio, technology or any other types of blog sites. Built-in One-click demo importer option helps to get started quickly.

The post Blogasm appeared first on WeLoveWP.

D7 CREATIVE

A simple straightforward Creative Agency website with hidden surprises and interactive gems. It offers a little of everything this Agency is capable of.

The post D7 CREATIVE appeared first on WeLoveWP.