8.1 C
New York
Wednesday, February 7, 2024

On-Scroll Revealing WebGL Photos | Codrops


Having objects seem on scroll is sort of customary these days. Nonetheless, there aren’t too many choices out there on the subject of HTML. Due to this fact, I made a decision so as to add a touch of pleasure with some WebGL results!

Beginning with a Aircraft

Let’s study a easy PlaneGeometry object with a ShaderMaterial. What potentialities does this mix supply?

Nicely, really loads of issues! You may take a look at the tutorial on unrolling pictures for an additional fascinating impact.

However this time I needed to discover pixelated results. So how do you obtain pixillation in shaders?

It’s really fairly easy. You simply must around the UVs to the closest pixel. And that’s it! You’ve got a pixelated impact. Let’s say we would like a ten “pixel” grid:

vec2 uv = ground(vUv * 10.0) / 10.0;

These are UVs, however by sampling the feel with them you’ll get this impact:

Simply to underline the impact a bit, I’ve additionally added borders to every pixel:

One other small caveat is that if the picture is just not a sq., you’ll get an equal quantity of rows and columns, therefore the pixels received’t be squares anymore, both. To work round that, as a substitute of multiplying UVs with a scalar worth, we are able to do this with vec2:

vec2 gridSize = vec2(
    20., 
    ground(20./ASPECT_RATIO)
);
vec2 uv = ground(vUv * gridSize) / gridSize;

This manner we may have sq. pixels (roughly), but in addition an integer quantity of them in rows and columns! On high of it I added a few extra easy results, like a background curtain and a altering quantity of pixillation. Right here is the great end result:

Doing issues on scroll

There may be plenty of methods to attach HTML and our new impact. The best one these days can be to make use of React Three Fiber.

R3F has an incredible library of useful modules because of the Poimandres group. The library title is Drei and it has a <View /> part there.

The thought of this part is to have the ability to insert components of your 3D scene proper into your DOM. Which, sure, is principally magic (the one indistinguishable from tremendous superior science 😅)

This instance is correct from the docs:

//react code
return (
    <fundamental ref={container}>
        <h1>Html content material right here</h1>
        <!-- right here we go, MESH in HTML, identical to that -->
        <View type={{ width: 200, peak: 200 }} className="canvas-view">
            <mesh geometry={foo} />
            <OrbitControls />
        </View>
        <Canvas eventSource={container}>
        <View.Port /> // that is the place our Views will likely be in 3D world
        </Canvas>
    </fundamental>
    )

As you possibly can see, we are able to simply put our Three.js objects proper into our HTML. And, as a bonus, we are able to use native HTML occasions to manage them. This can be a big step ahead by way of integration of those two worlds.

So for my demo I used to be ready to make use of the native IntersectionObserver API to run all of the animations in WebGL!

useGSAP

Lately, GSAP launched a pleasant hook for React, so I made a decision to make use of it as properly. Having the isIntersecting parameter from the native IntersectionObserver API, I simply did this:

import { useGSAP } from "@gsap/react";
import gsap from "gsap";
...
useGSAP(() => {
      gsap.to(materials, {
        uProgress: isIntersecting ? 1 : 0,
        period: 1.5,
      });
}, [isIntersecting]);

This manner the animation runs every time a picture pops into view.

It might be far more difficult in fact, however in my case I solely used the “uProgress” uniform, and did all of the magic inside shaders. To be taught extra about and GSAP/React integration head over to official docs.

Scroll sync between HTML and WebGL

The final annoying bit is a synchronisation situation between WebGL and HTML. As a result of these are nonetheless two completely different layers. All of the WebGL is being rendered in a fullscreen canvas on high of your web page. These two worlds must scroll collectively. And in case you determine to make use of native scroll which is, properly, pure, you’ll have a scenario when HTML scrolls natively, and WebGL scrolls when it will get the scroll occasion.

Whereas you may think these to be the identical factor, there will likely be a slight delay and jiggering between layers:

To beat this, it’s best to use a customized scroll resolution. Like Lenis or Locomotive scroll. In my case I used Lenis, as a world impact inside React Three Fiber:

import { addEffect } from "@react-three/fiber";
import Lenis from "@studio-freight/lenis";

const lenis = new Lenis();
addEffect((t) => lenis.raf(t));

So, now as soon as our <View /> is contained in the viewport, I’ll simply change my materials uniform uProgress from 0 to 1. And that’s it! I’ve a shader animation in HTML.

One other essential factor to notice right here, is that though declaratively we now have HTML and WebGL blended up on this great cocktail, they’re two separate worlds, and, for instance, traditional React Three Fiber hooks, won’t work with <View /> parts.

perform MyView(){
    const { scene } = useThree()
    >>R3F: Hooks can solely be used inside the Canvas part!
    return (
        <View type={{ width: 200, peak: 200 }} className="canvas-view">
            <mesh geometry={foo} />
            <OrbitControls />
        </View>
    )
}

Despite the fact that it’s being inserted into the Three.js scene through <View.port>, it’s probably not from the WebGL root. All of it seems so easy, however you could have to bear in mind, what is definitely happening behind the scenes to grasp these caveats.

However even taking these into consideration, you simply cant underestimate how easy this stuff have gotten with React. I don’t actually like utilizing React for animated scrollable landings, however, when integration is that simple, I should suppose thrice.

Ultimate Phrases

I hope you favored this integration instance! Share your methods of animating pictures, or examples that you just like! And help open supply builders, because of them we now have such wonderful infrastructures these days 🙂



Supply hyperlink

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles