Claim the FREE Multi Step Form - Learn How

Grid to Fullscreen Animation

Creating Grid-to-Fullscreen Animations with Three.js in Webflow

Learn how to integrate a mind-bending Three.js animation in your Webflow project.


In a future tutorial, I’ll go into more detail about the custom CSS and Javascript - specifically, how you can further integrate and customize with Webflow’s native interactions. Make sure the CSS settings for each element match that found in the demo project.

1.0 Create Layout in Webflow

  • “Main” - This will be your top-level wrapper. In the element settings menu, make sure you change the tag from the default ‘div’ to ‘main’.
  • “app” - This is where the Three.js canvas will render after publishing the project.
  • “grid” - The grid will hold your grid items. If we expand the “grid” div, you will see three grid items. Each grid item contains the following:
  • 2 embedded thumbnail images (small and large)

In order to bypass CrossOrigin issues, it is imperative that your image embed code includes the attribute crossorigin="anonymous" as well as a “?” after the image URL.

  • The grid items caption
  • “fullview” - This holds the content for each item’s fullscreen state (title, link), as well as the button trigger to transition back to thumbnail.

2.0 Add custom CSS

<style>
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-y: overlay;
}
#app {
pointer-events: none;
}
.fullview {
pointer-events: none;
 -webkit-overflow-scrolling: touch;
}
.fullview__item--current {
pointer-events: auto;
}
.fullview__item-title {
 opacity: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.link {
 opacity: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.fullview__close {
pointer-events: none;
opacity: 0;
 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.fullview__item--current ~ .fullview__close {
pointer-events: auto;
}
.fullview__close:focus {
outline: none;
}
.grid__item-img {
max-width: 100%;
display: block;
cursor: pointer;
}
.grid__item-img--large {
pointer-events: none;
position: fixed;
opacity: 0;
}
</style>
  1. Add custom Javascript scripts and code
< script src = "https://assets.website-files.com/5ce62dab952a22dd060278e3/5ce62dbe5375ca4e2e927f78_three-bundle.txt" > < /script>
< script src = "https://assets.website-files.com/5ce62dab952a22dd060278e3/5ce62e295375ca5dfd927fc8_demo-core.txt" > < /script>
< script src = "https://assets.website-files.com/5ce62dab952a22dd060278e3/5ce62e29952a223c080279af_demo.txt" > < /script> < script >

let currentIndex;
const itemsWrapper = document.getElementById("itemsWrapper");
const thumbs = [...itemsWrapper.querySelectorAll("img.grid__item-img:not(.grid__item-img--large)")];
const fullviewItems = [...document.querySelectorAll(".fullview__item")];
const backToGridCtrl = document.querySelector(".fullview__close");
const transitionEffectDuration = 1.2;
const transitionEffect = createDemoEffect({
activation: {
type: "mouse"
},
timing: {
duration: transitionEffectDuration
},
transformation: {
type: "simplex",
props: {
seed: "8000",
frequencyX: 0.2,
frequencyY: 0.2,
amplitudeX: 0.3,
amplitudeY: 0.3
}
},
onToFullscreenStart: ({
index
}) => {
currentIndex = index;
thumbs[currentIndex].style.opacity = 0;
transitionEffect.uniforms.uSeed.value = index * 10;
toggleFullview();
},
onToGridFinish: ({
index,
lastIndex
}) => {
thumbs[lastIndex].style.opacity = 1;
fullviewItems[currentIndex].classList.remove("fullview__item--current");
},
seed: 800,
easings: {
toFullscreen: Power1.easeOut,
toGrid: Power1.easeInOut
}
});
transitionEffect.init();
const toggleFullview = () => {
if (transitionEffect.isFullscreen) {
TweenLite.to(fullviewItems[currentIndex].querySelector(".fullview__item-title"), 0.2, {
ease: Quad.easeOut,
opacity: 0,
x: "5%"
});
TweenLite.to(fullviewItems[currentIndex].querySelector(".link"), 0.2, {
ease: Quad.easeOut,
opacity: 0,
x: "5%"
});
TweenLite.to(backToGridCtrl, 0.2, {
ease: Quad.easeOut,
opacity: 0,
scale: 0
});
transitionEffect.toGrid();
} else {
fullviewItems[currentIndex].classList.add("fullview__item--current");
TweenLite.to(fullviewItems[currentIndex].querySelector(".fullview__item-title"), 1, {
ease: Expo.easeOut,
startAt: {
x: "5%"
},
opacity: 1,
x: "0%",
delay: transitionEffectDuration * 0.6
});
TweenLite.to(fullviewItems[currentIndex].querySelector(".link"), 1, {
ease: Expo.easeOut,
startAt: {
x: "5%"
},
opacity: 1,
x: "0%",
delay: transitionEffectDuration * 0.9
});
TweenLite.to(backToGridCtrl, 1, {
ease: Expo.easeOut,
startAt: {
scale: 0
},
opacity: 1,
scale: 1,
delay: transitionEffectDuration * 0.6
});
}
};
backToGridCtrl.addEventListener("click", () => {
if (transitionEffect.isAnimating) {
return;
}
toggleFullview();
});
imagesLoaded(document.querySelectorAll(".grid__item-img"), instance => {
document.body.classList.remove("loading");
let images = [];
for (var i = 0, imageSet = {}; i < instance.elements.length; i++) {
let image = {
element: instance.elements[i],
image: instance.images[i].isLoaded ? instance.images[i].img : null
};
if (i % 2 === 0) {
imageSet = {};
imageSet.small = image;
}
if (i % 2 === 1) {
imageSet.large = image;
images.push(imageSet);
}
}
transitionEffect.createTextures(images);
}); < /script>


  1. Publish



This guide has been developed by CJhersh.

https://www.cjhersh.com
https://webflow.com/cjhersh



Original Author: Daniel Velasquez

More Technical Details: Here  


This product is not yet available. Join us on twitter for updates.

What’s a Rich Text element?

The rich text element allows you to create and format headings, paragraphs, blockquotes, images, and video all in one place instead of having to add and format them individually. Just double-click and easily create content.

Static and dynamic content editing

A rich text element can be used with static or dynamic content. For static content, just drop it into any page and begin editing. For dynamic content, add a rich text field to any collection and then connect a rich text element to that field in the settings panel. Voila!

How to customize formatting for each rich text

Headings, paragraphs, blockquotes, figures, images, and figure captions can all be styled after a class is added to the rich text element using the "When inside of" nested selector system.

This product is not yet available. Join us on twitter for updates.