Forever Grid WordPress documentation

JavaScript Documentation

Documentation for the JavaScript version, API and overall JavaScript implementation.

Getting Started

Forever Grid, a powerful, responsive, and extremely customizable, versatile grid with image (.jpg, .jpg, .png, .webp) and video (.mp4) support, seamlessly running on all major browsers and mobile devices, including iPhone, iPad, iOS, Android, MAC, and Windows, elevating your website's audio experience to a whole new level.

It is built using EcmaScript6 using the latest JavaScript and CSS standards. The spiral/grid is using Three.js and WebGL shaders running exclusively on the device's GPU, the caption is HTML.

Please note that it will not work locally, it has to run on an HTTP or HTTPS protocol.

It is crucial to optimize your images and videos, especially since they are used as textures. Larger image and video files demand more GPU power to display due to the increased number of pixels. To minimize performance impact, select images and videos that are visually close in size to the grid mesh.

Please note that the mettrix are units so visual aproximation is needed, since the grid runs in 3D space and various aspects like camera position or camera rotation, using pixels is not possible.


Installation

The demo presetes are all included in the build folder.

Choose one of the preset HTML files from the build folder and open it in a text editor as a refference.

In the download files inside the build folder you will find the src folder that contains the JavaScript code and content folder that contains the CSS file and other important files like the vector font, the content folder has to be uploaded on the server where the grid is used.

Include the grid CSS file and JavaScript in the header:

<head>

<!-- ... -->
<link rel="stylesheet" href="./content/global.css">
<script type="text/javascript" src="./src/FWDFG.js"></script>
<!-- ... -->	

</head>

The next step is to add the initialize code in the page header or footer after the inclusion of the grid JavaScript and CSS files.

<script type="text/javascript">
	if(document.readyState == 'complete'){
		setupFG();
	}else{
		document.addEventListener('DOMContentLoaded', ()=>{
			setupFG();
		});
	}

    function setupFG(){
		
		new FWDFG({
                
			// Main settings.  
            instance: 'fwdfg0',
            parentId: 'myDiv',
            gridDataId: 'gridData',
            displayType: 'afterParent',
            initializeWhenVisible: 'no',
            maxWidth: 1920,
            maxHeight: 900,
            stopScrollingForPx: 0,
            backgroundText: 'FOREVER GRID',
            paralax: 'yes',
            autoScale: 'yes',
            stats: 'no',
            gui: 'yes',
            showPreloader: 'yes',
            preloaderColor: '#000000',
            backgroundColor: 'rgba(255, 255, 255, 1)',
            infinite: 'yes',
            allowZoom: 'yes',
            itemImageShift: 'yes',
            itemShift: 'yes',
            zoomStartScale: 0.6,
            planeSize: 12,
            planeGap: 11,
            showMaskGradient: 'no',
            useCaption: 'yes',
            captionBackgroundColor: '#000000',
            blackAndWhiteFadeDistance: 6000,
            snap: 'yes',
            showMouseScrollIcon: 'yes',
            mouseScrollIconNormalColor: '#ffffff',
            mouseScrollIconHoverColor: '#cccccc',
            autoScrollHorizontal: 'no',
            autoScrollVertical: 'no',
            autoScrollSpeed: 9.5,
            hoverScale: 0.9,
            scrollSpeedStrength: 0.4,
            scrollDragDirection: 'both',
            tiltType: 'none',
            noiseAmplitude: 0,
            noiseFrequency: 0,
            noiseSpeed: 0.6,
            
            // Post processing.
            antialias: 'yes',

            uwaveFrequency: 0.1,
            waveAmplitude: 0.02,
            waveRgbShiftStrength: 0,
            mouseRippleStrength: 0,
            
            fluid: 'no',
            fluidPassMainText: 'FOREVER GRID',
            fluidPassSubText: 'Hold to start experience',

            glitch: 'no',
            
            buldgeType: 'fixed',
            buldgeRGBStrength: 0,
            buldgeStrength: 0,

            grid: 'no',
            gridAddRGBDistortion: 'yes',
            gridSize: 400,
            gridMouseRadiusFactor: 0.1,
            gridMouseStrengthFactor: 0.48,
            gridMouseRelaxation: 0.9,

            afterImage: 'no',
            afterImageDumping: 0.95,

            useNoise: 'no',
            noiseSize: 0.4,
            noiseFadeSize: 0.2,
            noiseBlurStrength: 0.3,
            noiseFadeColor: '#ffffff',

		});
		
	}
</script>

The last step adding the grid is to create a div with an unique ID that will act as the parent/holder for the grid and set the parentId option to point to the div id ex: parentId: 'myDiv', this div can be added anywhere in your page.

<!-- Grid holder. --> 
<div id="myDiv"></div>

To add multiple grids just redo the steps explained above and make sure to change the instance to fwdfg1, fwdfg2, fwdfg3, etc... depending on how many grids are added, also change the parentId to a different ID and if you want add a different grid by also change the gridDataId to point to a different grid.

Please read the settings section to understand the grid configuration options.


Setup grid

A grid is created by adding in the page inside the body a div with an unique ID and setting the display style to none, this will be used only as the grid data markup, This unique ID has to be added as the value of the gridDataId option in the grid settings like this gridDataId: 'gridData'.

<!-- Forever Grid. -->
<div data-src="media/images/1.jpg" data-width="640" data-height="400" data-url="https://fwdapps.net" data-target="_blank">
	<div data-caption="">
		<p class="fwdfg caption">Forever Grid </p>
	</div>
</div> 

<div data-src="media/images/2.jpg" data-width="640" data-height="800" data-url="https://fwdapps.net" data-target="_blank">
	<div data-caption="">
		<p class="fwdfg caption">Infinite Grid </p>
	</div>
</div>

<div data-src="media/images/3.jpg" data-width="640" data-height="427" data-url="https://fwdapps.net" data-target="_blank">
	<div data-caption="">
		<p class="fwdfg caption">Various Sizes </p>
	</div>
</div> 

<!-- Add as many grid items as you need ... -->

</div>

Adding grid items is done by adding inside the grid div one or more div's with data paremeters expplained below.

Grid item parameters

  • data-src - required media path (.jpg, .jpeg, .png, .webp) or video (.mp4)
  • data-width - video or image width in px.
  • data-height - video or image height in px.
  • data-url - The URL page to open when the mehs is clicked.
  • data-target - The URL page to open target, _self or _blank.

Grid item caption

An optional caption can be added, the CSS formating is added in the global.css file.

<div data-src="media/images/1.png" data-width="900" data-height="600" data-url="https://fwdapps.net" data-target="_blank">
	<div data-caption="">
		<p class="fwdfg caption">Cute Bunny</p>
	</div>
</div> 

Modify code

FG is using VITE to build the built final Javascript file.


Settings

Forever Grid has many options that allows to customize it's features. They are added directly in the grid constructor as it can be seen in the installation section.

Example

<script type="text/javascript">
	if(document.readyState == 'complete'){
		setupFG();
	}else{
		document.addEventListener('DOMContentLoaded', ()=>{
			setupFG();
		});
	}

    function setupFG(){
		new FWDFG({ 

			// Main settings.  
			instance: 'fwdfg0',
			displayType: 'responsive',
			parentId: 'myDiv',
			gridDataId: 'gridData',
			initializeWhenVisible: 'yes',
			etc...
			
		})
	}
</script>

instance

Type: (String) - default: fwdfg0

The grid instance name, this is used to call the API. In the examples files the instance name is set to fwdfg0, if you are using multiple grids instances just change the instance to fwdfg1, fwdfg2, fwdfg3, etc...

parentId

Type: (String) - default: unset

The grid holder/div ID, please make sure that this has an unique ID, it can be added anywhere in your page.

gridDataId

Type: (String) - default: unset

The grid data div ID, please read the grid section for more info.

displayType

Type: (String) - default: responsive

The grid display type can be either responsive, which will automatically resize the grid based on the maxWidth and maxHeight settings, or afterParent, which will resize the grid based on its parent element’s width and height.

initializeWhenVisible

Type: (String) - default: yes

This can be yes or no, lazy scrolling / loading, the posibility to initialize FG on scroll when the product is visible in the page, this way for example if the product is in a section of a page that is not visible it will not be initialized, instead FG will be initalized only when the user is scrolling to that section in which FG is added.

maxWidth

Type: (Number) - default: 1920

The grid maximum width in px.

maxHeight

Type: (Number) - default: 800

The grid maximum height in px.

stopScrollingForPx

Type: (Number) - default: 620

Adds artificial scrolling (in pixels) to keep the grid visible in the viewport for a longer duration.

backgroundText

Type: (String) - default: FOREVER GRID

This background text displayed under the grid.

paralax

Type: (String) - default: no

This can be yes or no ads parallax vertical scrolling.

autoScale

Type: (String) - default: yes

This can be yes or no and applies if the displayType is reponsive. If set to yes this grid height will always be proportional to the grid width, if set to no the height will be fixed based on the maxHeight property.

stats

Type: (String) - default: yes

This can be yes or no, show the stats, FSP/memory usage.

gui

Type: (String) - default: yes

This can be yes or no, show the GUI live settings.

showPreloader

Type: (String) - default: yes

This can be yes or no, show the preloader.

preloaderColor

Type: (String) - default: #FFFFFF

The preloader color in HEX or RGB.

backgroundColor

Type: (String) - default: #000000

The main background color in HEX or RGB.

infinite

Type: (String) - default: yes

This can be yes or no, based on the type enable ifninte scroll.

allowZoom

Type: (String) - default: yes

This can be yes or no, enable mouse wheel or gesture zoom.

itemImageShift

Type: (String) - default: yes

This can be yes or no, enables item image shift when the grid is dragged.

itemShift

Type: (String) - default: yes

This can be yes or no, enables item shift when the grid is dragged.

zoomStartScale

Type: (Number) - default: 0.6

The default scale start scale in uints.

planeSize

Type: (Number) - default: 12

The default items size in uints.

planeGap

Type: (Number) - default: 11

The gap between items in uints.

showMaskGradient

Type: (Number) - default: 0.1

The item min scale in uints.

useCaption

Type: (String) - default: yes

This can be yes or no, set this to no if you don't want to use a caption.

captionBackgroundColor

Type: (Number) - default: #000000

The item caption faded background color.

blackAndWhiteFadeDistance

Type: (Number) - default: 1

This represents the distance from the center of the grid in a radial manner, where the images fade into black and white.

snap

Type: (String) - default: yes

This can be yes or no, snaps the grid to the closest mesh from the center.

showMouseScrollIcon

Type: (String) - default: yes

This can be yes or no, show the scroll icon.

mouseScrollIconNormalColor

Type: (String) - default: #FFFFFF

The scroll icon normal color.

mouseScrollIconHoverColor

Type: (String) - default: #cccccc

The scroll icon selected color.

autoScrollHorizontal

Type: (String) - default: yes

This can be yes or no, enable horizontal autoscroll.

autoScrollVertical

Type: (String) - default: yes

This can be yes or no, enable vertical autoscroll.

autoScrollSpeed

Type: (Number) - default: 9.5

Autoscroll speed.

hoverScale

Type: (Number) - default: 0.9

The item hover scale.

scrollSpeedStrength

Type: (Number) - default: 1

The scroll/drag speed strength factor.

scrollDragDirection

Type: (String) - default: both

This can be both, horizontal or vertical, grid drag contrain.

tiltType

Type: (String) - default: none

This can be top, right, bottom, left or none, enable 3D roation/tilt for the entire grid.

autoScrollVertical

Type: (Number) - default: 0

The item mesh curve distortion based on the drag speed.

autoScrollSpeed

Type: (Number) - default: 0.6

The default items opacity.

hoverScale

Type: (Number) - default: 0.6

The scroll/drag speed factor.

noiseAmplitude

Type: (Number) - default: 0

The item item noise amplitude.

noiseFrequency

Type: (Number) - default: 0

The item item noise frequency.

noiseSpeed

Type: (Number) - default: 0.6

The item item noise speed.

antialias

Type: (String) - default: yes

This can be yes or no It uses an anti-aliasing algorithm to enhance visual quality at a small performance cost.

uwaveFrequency

Type: (Number) - default: 0.1

Wave frequency.

waveAmplitude

Type: (Number) - default: 0.02

Wave amplitude.

rgbShiftStrength

Type: (Number) - default: 0

Wave RGB color shift.

mouseRippleStrength

Type: (Number) - default: 0.6

Ripple mouse strength.

fluid

Type: (String) - default: no

This can be yes or no Ads fulid post-processing effect.

fluidPassMainText

Type: (String) - default: LINEAR GRID

Fluid post-porcessing main text.

fluidPassSubText

Type: (String) - default: Hold to start experience

Fluid post-porcessing sub text.

glitch

Type: (String) - default: no

This can be yes or no, enable glitch post-processing effect.

buldgeType

Type: (String) - default: fixed

This can be fixed, pointerMove or pointerDown, the buldge post-processing effect type.

buldgeRGBStrength

Type: (Number) - default: 10

The buldge post-processing RGB strength.

buldgeStrength

Type: (Number) - default: 1.3

The buldge post-processing strength.

grid

Type: (String) - default: no

This can be yes or no, enable grid post-porcessing effect.

gridAddRGBDistortion

Type: (String) - default: no

This can be yes or no, enable grid post-porcessing RGB shigt effect.

gridSize

Type: (Number) - default: 400

The grid post-processing grid size.

gridMouseRadiusFactor

Type: (Number) - default: 0.2

The grid post-processing grid radius size.

gridMouseStrengthFactor

Type: (Number) - default: 0.48

The grid post-processing grid strength factor.

gridMouseRelaxation

Type: (Number) - default: 0.9

The grid post-processing grid relaxation factor.

afterImage

Type: (String) - default: no

This can be yes or no, enable after-image post-porcessing effect.

afterImageDumping

Type: (Number) - default: 0.75

The after-image post-processing strength factor.

useNoise

Type: (String) - default: no

This can be yes or no, enable useNoise post-processing effect.

noiseSize

Type: (Number) - default: 0.4

The useNoise post-porcessing efect size.

noiseFadeSize

Type: (Number) - default: 0.2

The useNoise post-porcessing efect fade size.

noiseBlurStrength

Type: (Number) - default: 0.3

The useNoise post-porcessing efect blur fade size.


Methods

Methods are functions that can be called via the API to execute certain actions.

JavaScript methods look like fwdfg0.methodName( /* arguments */ ), please note that fwdfg0 is the grid instance name, if you are using multiple grids don't forget to set the instance unique for each instance like this fwdfg1, fwdfg2, fwdfg3, etc... depending on how many grids are added.

destory

.destory()

Destroy the instance and removes it from the DOM.


Events

Forever Grid has many events, they are added via the addEventListener method add accessed via the instance name.

The events must be registered when the API is ready.

// API.
let fwdfgAPI = setInterval(() =>{
if(window['fwdfg0']){
	console.log('FG API ready')
	clearInterval(fwdfgAPI);

	// Register the LIKE event.
	fwdfg0.addEventListener(FWDFG.ERROR, onEerror);
}
}, 100);


// Listen for the LIKE event.
function onEerror(e){
	console.log(e)
}

FWDFG.ITEM_UPDATE

FWDFG.ITEM_UPDATE

Dispatched when the grid item postions are changing.

FWDFG.ERROR

FWDFG.ERROR

Dispatched when an error occurs with the grid like not finding the media.


Notes

From my very first “Hello, world!” script in the early 2000s, I’ve been driven by one goal: to turn static pixels into living, breathing experiences. Over two decades of relentless tinkering—mastering Three.js for real-time 3D, crafting custom GLSL shaders, and fine-tuning GPU optimizations—has culminated in Forever Grid. Today, it seamlessly transforms your images and videos into interactive, high-performance canvases on any device.

For me this is more than a job, it is my passion, I love to create innovative tools that my clients can benefit from. @Tibi - FWD.

For support and customizations please write to me directly at this email.