JavaScript Documentation

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

Getting Started

Shader Carousel, a powerful, responsive, and extremely customizable, versatile slider/carousel 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 slider/carousel 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 carousel mesh.

Please note that the mettrix are units so visual aproximation is needed, since the carousel 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 carousel is used.

Include the carousel CSS file and JavaScript in the header:

<head>

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

</head>

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

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

	function fwdscSetupCarousel(){
		
		new FWDSC({
                
			// Main settings.  
			instance: 'fwdsc0',
			parentId: 'myDiv',
			carouselDataId: 'carouselData',
			type: 'carousel',
			initializeWhenVisible: 'no',
			maxWidth: 1920,
			maxHeight: 800,
			stopScrollingForPx: 0,
			autoScale: 'yes',
			antialias: 'yes',
			stats: 'no',
			gui: 'yes',
			showPreloader: 'yes',
			preloaderColor: '#FFFFFF',
			backgroundColor: '#000000',
			infinite: 'yes',
			radius: 5.5,
			radiusY: 0, 
			horizontalGap: 0,
			verticalGap: 0,
			planeWidth: 4,
			planeHeight: 2.4,
			planeWidthRatio: '0%',
			planeHeightRatio: '0%',
			useIntro: 'yes',
			useCaption: 'yes',
			captionPosition: 'sticky',
			useBlackAndWhite: 'yes',
			opacityStrength: 0.8,
			limitOpacity: 'no',
			rgbShiftStrength: 0,
			snap: 'yes',
			arcRadiusOffset: 2,
			scrollSpeedStrength: 0.6,
			scrollScaleStrength: 0,
			curveDistortionStrength: 1.5,
			liquidDistortionStrength: 0,
			rippleStrength: 1,
			reflectionSize: 0.6,
			reflectionOpacity: 1,
			reflectionBlurStrength: 0.2,
			cameraPositionX: 0,
			cameraPositionY: 0,
			x: 0,
			y: 0.25,
			z: -6.11,
			rotationX: 0,
			rotationZ: 0,

			// Post processing.
			uwaveFrequency: 0.1,
			waveAmplitude: 0.02,
			glitch: 'no',
			buldge: 'no',
			buldgeDirection: 'in',
			buldgeFixed: 'yes',
			buldgeStrength: 0.3,
			rippleDistortion: 'no',
			rippleDistortionStrength: 0.2,
			rippleDistortionSize: 0.5,
			grid: 'no',
			gridAddRGBDistortion: 'yes',
			gridSize: 400,
			gridMouseRadiusFactor: 0.2,
			gridMouseStrengthFactor: 0.48,
			gridMouseRelaxation: 0.9,
			afterImage: 'no',
			afterImageDumping: 0.75,

		});
		
	}
</script>

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

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

To add multiple carousels just redo the steps explained above and make sure to change the instance to fwdsc1, fwdsc2, fwdsc3, etc... depending on how many carousels are added, also change the parentId to a different ID and if you want add a different gallery by also change the carouselDataId to point to a different gallery.

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


A gallery 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 gallery data markup, This unique ID has to be added as the value of the carouselDataId option in the carousel settings like this carouselDataId: 'carouselData'.

<!-- Carousel gallery. -->
<div id="carouselData" style="display: none;">

	<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="fwdsc caption-title">Shader Carousel</p>
			<p class="fwdsc caption-desc">Yes there are animals hidden in the <a href="https://webdesign-flash.ro" target="_blank">Mona Lisa</a>, but you don't have to look sideways all the way.</p>
		</div>
	</div> 

	<div data-src="media/videos/2.mp4" data-width="950" data-height="540" data-url="https://fwdapps.net" data-target="_blank">
		<div data-caption="">
			<p class="fwdsc caption-title">Customizable Size</p>
			<p class="fwdsc caption-desc">Discover the hidden secrets within <a href="https://webdesign-flash.ro" target="_blank">Da Vinci’s Art</a>, look closer, and a new story unfolds before your eyes.</p>
		</div>
	</div> 
	
	<!-- Add as many gallery items as you need ... -->

</div>
	

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

Gallery 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.

Gallery 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="fwdsc caption-title">Shader Carousel</p>
		<p class="fwdsc caption-desc">Yes there are animals hidden in the <a href="https://webdesign-flash.ro" target="_blank">Mona Lisa</a>, but you don't have to look sideways all the way.</p>
	</div>
</div> 

Modify code

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


Settings

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

Example

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

	function fwdscSetupCarousel(){
		new FWDSC({ 

			// Main settings.  
			instance: 'fwdsc0',
			displayType: 'responsive',
			parentId: 'myDiv',
			carouselDataId: 'carouselData',
			proxyCorss: '',
			initializeWhenVisible: 'yes',
			etc...
			
		})
	}
</script>

instance

Type: (String) - default: unset

The carousel instance name, this is used to call the API. In the examples files the instance name is set to fwdsc0, if you are using multiple carousels instances just change the instance to fwdsc1, fwdsc2, fwdsc3, etc...

displayType

Type: (String) - default: responsive

Carousel display type.

  • responsive - displays the carousel in responsive type based on the maxWidth and maxHeight settings.
  • afterparent - displays the carousel based on the parent width and height.

parentId

Type: (String) - default: unset

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

carouselDataId

Type: (String) - default: unset

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

proxyCorss

Type: (String) - default: ''

Used for Shoutcast and Icecast if SSL is used, I created this video tutorial for a different carousel but the same applies to SC.

initializeWhenVisible

Type: (String) - default: yes

This can be yes or no, lazy scrolling / loading, the posibility to initialize SC 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 SC will be initalized only when the user is scrolling to that section in which SC is added.

maxWidth

Type: (Number) - default: 1920

The carousel maximum width in px.

maxHeight

Type: (Number) - default: 800

The carousel maximum height in px.

minHeight

Type: (Number) - default: 620

The carousel minimum height in px, this is useful when the carousel is resized and autoscale is used.

autoScale

Type: (String) - default: yes

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

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.

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 this allows infinte scrolling.

radius

Type: (Number) - default: 5

The horizontal radius, this might vary based on the type.

radiusY

Type: (Number) - default: 0

The vertical radius for the spiral type.

horizontalGap

Type: (Number) - default: 0

Horizontal gap.

verticalGap

Type: (Number) - default: 0

Vertical gap, this dose not apply to the slider,filmStrip and filmStripDouble types.

planeWidth

Type: (Number) - default: 3.8

The mesh/plane item width.

planeHeight

Type: (Number) - default: 2.4

The mesh/plane item height.

planeWidthRatio

Type: (String) - default: 0%

The mesh/plane width in percentage, applies only to the slider type, if set to 0% this feature is ignored and planeWidth is used.

planeHeightRatio

Type: (String) - default: 0%

The mesh/plane height in percentage, applies only to the slider type, if set to 0% this feature is ignored and planeHeight is used.

useIntro

Type: (String) - default: yes

This can be yes or no, uses animated intro camera.

useCaption

Type: (String) - default: yes

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

captionPosition

Type: (String) - default: sticky

This can be sticky, bottom-center, bottom-left, bottom-right.

useBlackAndWhite

Type: (String) - default: yes

This can be yes or no, sets all meshes/items except the center/focus one to black and white.

opacityStrength

Type: (Number) - default: yes

This can be yes or no, sets all meshes/items except the center/focus opacity.

limitOpacity

Type: (String) - default: yes

This can be yes or no, limits opacity mehes/items for the spiral type.

rgbShiftStrength

Type: (Number) - default: 0

This enable RGB shift based on the scroll speed.

snap

Type: (Number) - default: yes

This can be yes or no, snaps the colsest mesh/item to the center.

rgbShiftStrength

Type: (Number) - default: 0

This enable RGB shift based on the scroll speed.

arcRadiusOffset

Type: (Number) - default: 2

The arc radius for the carouselCircular type.

scrollSpeedStrength

Type: (Number) - default: 0.6

The scroll/drag speed factor.

scrollScaleStrength

Type: (Number) - default: 0

The scroll/drag scale factor.

curveDistortionStrength

Type: (Number) - default: 1.5

The scroll/drag mehes/items curve distortion strength.

liquidDistortionStrength

Type: (Number) - default: 0

The scroll/drag mehes/items liquid/ripple distortion strength.

rippleStrength

Type: (Number) - default: 1

The mouse ripple strength.

rippleStrreflectionSize

Type: (Number) - default: 0.6

The reflection size, between 0 and 1.

reflectionOpacity

Type: (Number) - default: 1

The reflection opacity, between 0 and 1.

reflectionBlurStrength

Type: (Number) - default: 1

The reflection blur distortion strength, between 0 and 1.

cameraPositionX

Type: (Number) - default: 0

Camera position x.

cameraPositionY

Type: (Number) - default: 0

Camera position y.

x

Type: (Number) - default: 0

Mehes group position x.

y

Type: (Number) - default: 0

Mehes group position y.

z

Type: (Number) - default: 0

Mehes group position z.

rotationX

Type: (Number) - default: 0

Mehes group rotation x.

rotationZ

Type: (Number) - default: 0

Mehes group rotation z.

uwaveFrequency

Type: (Number) - default: 0.1

Wave frequency.

waveAmplitude

Type: (Number) - default: 0.02

Wave amplitude.

glitch

Type: (String) - default: no

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

buldge

Type: (String) - default: no

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

buldgeDirection

Type: (String) - default: in

This can be in, out or both, enable buldge post-processing effect.

buldgeFixed

Type: (String) - default: no

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

buldgeStrength

Type: (Number) - default: 0.3

The buldge post-processing strength.

Ripple distortion

Type: (String) - default: no

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

rippleDistortionStrength

Type: (Number) - default: 0.2

The ripple post-processing distortion strength.

rippleDistortionSize

Type: (Number) - default: 0.5

The ripple post-processing distortion size.

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.


Methods

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

JavaScript methods look like fwdsc0.methodName( /* arguments */ ), please note that fwdsc0 is the carousel instance name, if you are using multiple carousels don't forget to set the instance unique for each instance like this fwdsc1, fwdsc2, fwdsc3, etc... depending on how many carousels are added.

destory

.destory()

Destroy the instance and removes it from the DOM.


Events

Shader Carousel 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 fwdscAPI = setInterval(() =>{
if(window['fwdsc0']){
	console.log('SC API ready')
	clearInterval(fwdscAPI);

	// Register the LIKE event.
	fwdsc0.addEventListener(FWDSC.ERROR, onEerror);
}
}, 100);


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

FWDSC.ERROR

FWDSC.ERROR

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


Notes

I've dreamt of bringing this vision to life since I first started developing in the 2000s. For nearly 25 years, this idea has lived in my mind—waiting for the right moment, the right tools, and the right technology. And now, at last, it's possible!

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.