Last Updated:

Image Gallery with Cover Flow effect in JavaScript

A few years ago, while browsing the internet galleries with the "Cover Flow" effect, I came across a site where the "Cover Flow" effect was implemented very beautifully, in various versions and the ability to switch between them. The scripts were written in jQuery, while still minified, encrypted and paid.


I wanted to do the same thing, but in pure JavaScript. To be honest, I took from this site the very idea of the effect and a few pictures.

Since then, the Simple 3D Coverflow plugin has been significantly improved by its authors - the "Cover Flow" effect has become smoother, the gallery has adaptability for different resolutions, etc.


Nevertheless, in this article we will consider the gallery with the "Cover Flow" effect as it was at the time of writing the script a couple of years ago.

Gallery with Cover Flow effect in JavaScript
 

The Cover Flow effect is based on the CSS3 property, which allows you to transform an element into a three-dimensional coordinate system. If you have not encountered CSS transformation, I recommend that you familiarize yourself with a couple of articles: CSS3 transformations and CSS3 3D transformations.transform

I hope everyone understands everything. Well, now we will draw up a technical task so as not to forget or miss anything.

  • 1

    The gallery will have a fixed width to simplify the script and concentrate directly on implementing the Cover Flow effect when flipping through the gallery.
    If you are interested in creating an adaptive gallery, you can study the article Adaptive image gallery for a site using JavaScript.

  • 2

    To scroll through the gallery, we use the following control options:
    — navigation buttons "prev" and "next";
    – keyboard keys with arrows "←" and "→";
    – rotation of the mouse wheel;
    — click on the image to which you want to scroll the gallery.

  • 3

    Let's create several variants of the Cover Flow effect and switch between them without reloading the page.

  • 4

    It is possible to use several galleries on one page.

HTML-layout of the gallery with cover Flow effect.

 

I will not give the layout in full - I hope that you will be able to independently prescribe the necessary meta tags, connect the style sheet, fonts and js-script.

The HTML layout of the gallery is very simple and consists of three main blocks:

  1. the gallery itself;
  2. gallery navigation with "prev" and "next" buttons;
  3. Switch between Cover Flow effect options.

As a comment on the HTML layout of the gallery with the Cover Flow effect, I want to draw attention to the empty one located after each gallery image. With its help, gradient shading of the image is created.DIV

A style sheet for the gallery with the Cover Flow effect.

 

A builder for an adaptive gallery with a Cover Flow effect.

 

The first thing we will do is create an anonymous self-starting function, within which our code will be located.
It is necessary to make it a rule to limit the scope of the script in order to exclude conflicts with other JS scripts connected to the page.

When writing a JS script, we will use prototype inheritance. This will create multiple galleries on a single page.


To create gallery objects with the Cover Flow effect, we will use constructors, because they are well suited for creating many similar objects that have the same structure, with common property and method names. In JavaScript, this is called prototyping inheritance, and the object from which properties and methods are inherited is called a prototype.

In our case, this is an object created by the constructor. In other words, the mechanism of inheritance through prototypes is to inherit and reuse properties and methods created in the constructor, with the ability to extend the properties in the newly created object.

 

The constructor is a functional expression (Function Expression) with a set of settings that define the appearance of the Cover Flow gallery, its behavior and methods of control. You can change these settings during gallery initialization, replacing their values with custom values.


In addition, the constructor calls the function , which forms a kind of Cover Flow effect based on the received settings.
init

The constructor takes two arguments:

  1. id is the ID of the galleries that are currently initializing.
  2. setup is an associative array with user settings.

In order to be able to access the constructor from outside the anonymous function, let's write the constructor function as a property of the object .Window

Now let's look at the designer's complete JS code, supplemented with comments:

As you can see from the above code, the constructor contains the default settings - this is the object . These settings can be reassigned when the constructor is called, and their new values will be passed in the . This will be discussed later.


In addition, the designer defines the main DOM elements and collections of DOM elements on which the frame of the gallery with the Cover Flow effect depends.
defaultssetup

We will call the constructor function from the HTML page, for which at the end of the HTML layout, before the closing tag, we will write the following JS code:</BODY>

As a result, we will get an instance of the adaptive gallery, supplemented with new properties and from which the methods responsible for the formation of the frame and navigation of the gallery, as well as its operation, will be inherited.

Since all methods are inherited from their prototype, their recording will look like this:

Let's shorten this entry by creating a variable that will reference the prototype , to do this, let's add the following JS code to the end of our anonymous function:Coverflow

;(function() {
'use strict';


// constructor function
var Coverflow = function(id, setup) {
// default settings and basic DOM elements
// galleries defining its framework
...


// building a gallery based on the received settings
this.init(this.setup.type);
};


// write a constructor to the 'window.Coverflow' property to provide
// access it from outside the anonymous function
window.coverflow = coverflow;
// to shorten the record, create a variable that will refer to
// to 'Coverflow' prototype
var fn = coverflow.prototype;
})();

The function entry will now look like this:

Remember, this is very important.

All functions that we will create in the future should be placed at the end of an anonymous self-starting function. In the future, we will not focus on this.

Initialize a gallery with a Cover Flow effect.

 

Initializing the gallery begins by calling a function from a constructor function. As an argument, the function receives the Cover Flow effect type and solves the following tasks:initCoverflowinit

  1. Sets the settings based on the type of Cover Flow effect.
  2. Combines Cover Flow effect settings with custom and default settings by writing the result to the Settings object.options
  3. Based on the number of elements in the gallery, calculates the center element and its coordinates along the X, Y, and Z axes.
  4. Creates a gallery wireframe and places elements in it depending on the type of Cover Flow effect you choose.
  5. Sets event handlers for gallery management.

JS function code :init

In the above JS code, there was a call to three new functions - , and . Let us consider in more detail the purpose and operation of these functions.extendcreatGallerygalleryControl

The function combines the contents of two objects, supplementing and overwriting the contents of the source object with the properties of the source object. This function is called twice. The first time you call, combine the Cover Flow effect settings with the custom settings, and then combine the result with the default settings.extend

Let's write the following JS code to the end of the anonymous self-starting function:

It is necessary to pay attention to such a point - when calling the function , the property , the value of which is taken from the user settings, is formed. When you switch the Cover Flow effect type, the value of this property will not change, because the user settings remain unchanged, so the value of the property is spelled explicitly using the resulting argument of the function .

extendoptions.typeoptions.typetypeinit

Functions and consider separately, because they are quite complex and in their work use a number of auxiliary functions.

creatGallerygalleryControl

Wireframe and place gallery elements with Cover Flow effect.

In this section, we'll look at a function that shapes the frame of the gallery and starts an animation for the placement of its elements depending on the type of Cover Flow effect you choose.
Consider the algorithm of the function:

creatGallerycreatGallery

  • 1

    The start time of the animation of the placement of gallery elements is fixed and a number of variables are registered:
    — zIndex, Z-index of the gallery element;
    — shiftLX, the x-axis offset of elements located to the left of the central (left branch of elements);
    — shiftRX, the X-axis offset of elements located to the right of the central (right branch of elements);
    is shiftZ, the displacement of elements along the z-axis;
    is the alignment, the content of the gallery element attribute.
    style

  • 2

    The animation function starts.

  • 3

    The entire gallery rotates on the x-axis at an angle equal to the type of Cover Flow effect.options.rotateXOut

  • 4

    Positions the center element of the gallery that has an index of . The coordinates of its middle coincide with the center of the gallery and are the starting point for positioning the rest of the gallery elements.options.currIndex

  • 5

    The nearest elements on the right and left sides of the central (current) are installed. These elements have a 2x increased shift on the X-axis () and 3 times on the Z-axis (), compared to other gallery elements. This is due to the fact that otherwise, the central (current) element will cover the neighboring elements.options.shiftXlongoptions.shiftZlong

  • 6

    The rest of the elements of the left and right branches of the gallery are positioned.

  • 7

    After the animation finishes, the Z coordinate of each element is saved to an array. You will need this coordinate to animate the change in the position of an element when you hover over it.

Now let's look at the JS code that implements this algorithm.

Let's create a function and register a number of variables in it:creatGallery

Now you need to run the animation feature, which will smoothly arrange the gallery elements according to the settings of the Cover Flow effect.

 

Remember, this is very important.

When creating an animation in JavaScript, use the . This feature allows you to synchronize animations with the browser's built-in page refresh mechanisms. The result will be a more efficient use of the graphics accelerator, re-processing of the same sections of the page will be excluded, there will be less CPU usage and, most importantly, the animation will be smoother, without jerks and twitches. 
 
setIntervalrequestAnimationFrame

To do this, it is necessary to create the possibility of cross-browser use of the function . Let's add the following code inside the generated anonymous function:

requestAnimationFrame

Let's register the animation function inside the function. It is a named functional expression. This is done to work with recursion, i.e., to allow a function from within to call itself.

creatGalleryanimate

The first thing that the function does is to rotate the entire gallery along the x-axis by the angle specified in the settings.animate

 

Let's use the example of rotating the gallery along the x-axis to figure out how JavaScript animation works. The entire animation of the Cover Flow effect is built on this principle.

 

So, we have a number of variables:

 

timePassed
is equal to the difference between the current time and the start time of the animation. In other words, this variable contains the duration of the animation at the moment.
duration
contains the time allotted for the animation, i.e. the duration of the animation, depends on the gallery settings.
progress
Animation execution factor. During the operation of the function and the growth of the value of the variable , changes its value from 0 to 1.animatetimePassed
options.rotateXOut
the angle by which the gallery should rotate on the x-axis depends on the gallery settings.

The current rotation angle of the gallery is equal to options.rotateXOut * progress. As the animation time increases, the animation execution rate increases and, as a result, the result of the product options.rotateXOut * progress tends to a given angle of rotation .
Each time the function is called, the animation execution factor is compared to 1. If progress < 1, consider that the animation is not yet finished and recursively call the animation function.
timePassedprogressoptions.rotateXOutanimate

By the same principle, using the dependence of the animation execution factor on the animation time, other properties of the css transformation are calculated.

Now let's look at the positioning animation of gallery elements at its initial construction.

You can access the elements of the collection to apply css transformation to them by their indexes in the collection. Due to the fact that the css transformation of the elements of the left and right parts of the gallery is different, it is necessary to determine which indexes belong to the left branch of the gallery, and which to the right.
We know the index of the center element - . It is logical to assume that elements with an index less than , belong to the left side, and those with more - to the right. In this case, elements whose index is greater or less per unit of the index of the central element are subject to their own transformation.
elementsoptions.currIndexoptions.currIndex

Once again, because this is very important - in the gallery with the Cover Flow effect there are three groups of elements:

  •  the central element,
  • two elements next to the central one,
  • the remaining elements of the left and right parts of the gallery,

to which different values of the css3 transformation properties are applied.

To get indexes, use a loop from 0 to options.currIndex. Using the resulting indexes, you can divide the elements into groups and then apply your own css transformation to each group.

Positioning of the central element.

 

The central element is located in the center of the gallery, which in principle is clear from its name. Accordingly, its x0 and y0 coordinates coincide with the center of the gallery and are the starting point for the rest of the elements.

To position the center element, put the data for the 3D transformation into the variable and call the function, passing it as arguments the index of the center element and .
Set the shading of the element by calling the function . The first parameters of this function will be the index of the item whose shading is set, and the second parameter specifies the transparency () of the shading. Since the center element does not need shading, the second parameter will be equal to 0.

alignmentsetAlignmentalignmentsetbgopacity

We'll look at how the features work later.

setAlignmentsetbg

 

Preparation of data for positioning of elements adjacent to the central one.

 

install the nearest elements on the right and left sides of the central (current). These elements have increased shear on the x-axis () and on the z-axis (). The shift of these elements is counted from the center of the gallery.


Let me remind you that the shift increased along the X and Z axes is necessary so that the central element does not cover neighboring elements.

shiftXlongshiftZlong

 

Prepare the data for positioning the remaining elements.

 

For these elements, positioning begins with the coordinates obtained for the elements adjacent to the central one: , and shiftLXshiftRXshiftZ

 

Apply css transformation to gallery elements.

 

With each iteration of the loop, we get the indexes of the three elements (the central one and one of the left and right sides of the gallery) and their offset over the past time of the animation.
Now you need to use this data to form the property and then set the attribute value to the corresponding Cover Flow gallery element. For the center element, this is done immediately, when the current index matches . For the rest of the gallery elements, you need to write separate JS-code, and different for the left and right branches.
transformstyleoptions.currIndex

We've covered the individual parts of the JS code of the function, now let's put them together:creatGallery

Save the Z coordinate of gallery elements.

 

As you can see from the function code, at the end of the gallery formation animation, the function . This function stores the Z coordinates of all gallery elements in an array. You will need the data from this array when you create a hover animation on these elements.saveCoordinatesZarrayZ0

The function is very simple, I will not consider its work separately, comments in the code will be enough.saveCoordinatesZ

fn.saveCoordinatesZ = function() {
// get the value of the 'style' attribute of each element from the collection
// gallery items, i.e. the current location of each item
varstyles = this.getStylesElements();


for (var i = 0, j = this.elements.length; i < j; i++) {
// value of the 'style' attribute of the i-th element
var style = styles[i];
// store the z0 value of each gallery element in an array
this.arrayZ0[i] = style.z0;
}
};

In its work, the function calls the function , and it in turn . These functions are also very simple and there is no need to consider every line of code. Let's make do with the comments embedded in the code:

saveCoordinatesZgetStylesElementsgetStylesElement

Assign built-in styles to gallery elements with a Cover Flow effect.

Consider the three important functions mentioned in the above JS code that, having received the current values of shifts and rotation angles, write the transformation CSS code directly inside the element tag using the attribute . These functions are used not only when building, but also when flipping through the gallery, creating a Cover Flow effect.style

Before you can write CSS code to an attribute, you must create this code. The . Taking the calculated data as an argument, it returns the finished CSS code, collected from the existing template.stylegetAlignment

Next, the resulting CSS code must be written to the attribute of a specific gallery element. We use for this purpose the function . The arguments to this function are the CSS and the index of the element to which you want to apply it.stylesetAlignment

As you can see in the screenshot at the beginning of the article, the gallery elements have shading. Moreover, the elements of the left branch have the right part shaded, and the elements of the right branch have the left part. This effect is created by applying a linear gradient to a container located above the gallery element.
To implement shading, let's create a function . The arguments for this function will be: the index of the current element and transparency.
<DIV>setbg

As you can see from the above code, the direction of the gradient depends not only on the index of the element, but also on the type of Cover Flow effect.

Switch Cover Flow effect options.

 

After considering the animation of forming the frame of the gallery when the page loads, it is logical to understand how the gallery changes its appearance when you switch the type of Cover Flow effect.
If, when the page loads, we pass the appearance of the Cover Flow effect by calling the constructor function, then in the future we can change the type of effect using the control unit created by us. Let me remind you of its HTML code:
Coverflow

Visually, the Cover Flow animation switching unit looks like this:

 

Cover Flow

Interactive items are list items. Clicking on these elements will cause you to switch the type of Cover Flow effect.<LI>

 
Remember, this is very important.

Both from the point of view of semantics and from the point of view of SEO – the tag should be used only to form links leading to other pages of the site or other Internet resource. To control the elements of the current page (show/hide, change style, move, load, etc.), the tags , , , . They should be the interactive elements of the page. 
 
<a><span><button><div><li>

To simplify and shorten the JS code, we will not hang event handlers on each element, but will use delegation and use the function to hang one handler on their parent element. When an event occurs on an unnumbered list, the handler will call the .
The registration of the handler occurs in the function , which we will consider when we deal with the implementation of the functionality of scrolling through the gallery.

<LI>addEventListener<UL>click<UL>switchGalleryTypegalleryControl

Remember, this is very important.
When you use the method, you lose the call context - , which refers to the current object. Using the built-in JavaScript method, you can directly pass the call context to the event handler function. addEventListenerthisbind

I will not analyze in detail how delegation based on the pop-up of events works. You can read about it here.

The algorithm of the function:switchGalleryType

  • 1

    When the event is triggered (a click was made on the switching unit) and using delegation, we determine that the click occurred on the element, and not on the empty area of its parent element. Get the attribute value of the element that was clicked on, the attribute value contains the Cover Flow effect type.<LI>data-type<LI>

  • 2

    Go through the collection of radio buttons and remove the class . Assign a class to the element that was clicked.activeactive

  • 3

    Call the function , passing as a parameter the type of the selected animation of the Cover Flow effect.init

Full JS code of the function with comments:switchGalleryType

Gallery flipping control with Cover Flow effect.

In the terms of reference, we identified four ways to control the scrolling of the gallery. Let me remind you of them:
— navigation buttons "prev" and "next";
– keyboard keys with arrows "←" and "→";
– rotation of the mouse wheel;
— click on the image to which you want to scroll the gallery.

All gallery management is implemented in the . In this function, event handlers are registered, and when these events occur, the direction of movement is determined and the gallery scrolls. In addition, an event handler for switching the Cover Flow effect animation type is registered here.galleryControl

 

Gallery with Cover Flow effect. Control of "prev" and "next" buttons.

 

Let's recall the HTML code of the gallery navigation block with the "prev" and "next" buttons:

Again, we'll use delegation and use the function to hang the handler on the parent item container. The attribute of these elements contains information about the direction in which the gallery is flipped.addEventListener<SPAN>[data-show]

Let's write the following JS code to the function :galleryControl

As you can see, no loop is used here, because there are no child elements that can be clicked on.while<SPAN>

Gallery with Cover Flow effect. Keyboard control.

The event handler is set on an object that is a window that contains the DOM document. A "keyboard" event that will occur when a key is pressed will be monitored.
We are only interested in pressing the "←" and "→" arrow keys, which have code 37 and 39 respectively. Pressing other keys will exit the event handler.
windowkeydown

The direction in which the gallery is flipped depends on the key code pressed.

Gallery with Cover Flow effect. Mouse wheel control.

The event handler is set to an object, which means that the gallery will only scroll through if the mouse pointer is over it. The direction of scrolling through the gallery depends on the direction of rotation of the mouse wheel.coverflow

Scroll to the element on which the click was made.

 

Previous methods of flipping through the gallery, when the event occurs, shift it to the left or right by one element. Now we're going to look at scrolling through the gallery to the item that was clicked on. It does not matter at what distance this element is from the current one.

In this case, I decided to move away from delegating the event to registering a handler on each item. For a number of reasons related to the simplification of HTML layout, in this case it will be difficult to identify the selected element and determine its position (index) in the gallery. Of course, you can change the layout, for example, by presenting a gallery as an unmarked list, where the gallery items will be list items. You can add attributes to them that will contain information about the index of the element, etc. However, I decided to register event handlers on each element of the gallery.<LI>

So, we have a collection of gallery items, which we'll sort through using the method, assign each item its own event handler and get the index of each item.elementsforEachclick

Let's animate the selection of an item. Let the element, when hovered, smoothly move out of the general row of the gallery, and if you remove the cursor, just as smoothly falls into place. To do this, assign two more event handlers to each element - for events and :mouseentermouseleave

The functions , and , that are called when the event handlers are triggered, we'll look at a little later, but for now, the full JS code of the function:shifGalleryhoverShiftscrollgalleryControl

Scroll through the gallery with cover Flow effect.

 

The Cover Flow effect when scrolling through the gallery is created in the . The algorithm of this function and its JS code largely coincide with the algorithm and code of the function, so I will publish individual sections of the code without explanation in order to avoid unnecessary repetition.shifGallerycreatGallery

The function has two input parameters:
1. dir is the direction of the gallery;
2. duration — duration of the animation when shifted by one element.
In addition, the function uses values from the .
shifGalleryoptions

Consider the algorithm of the function:shifGallery

  • 1

    The index of the current item and the direction of movement are checked. If the current item is the first or last item, and the direction of movement is specified outside the gallery, the function stops working.

  • 2

    Prevents the gallery from scrolling until the current animation is finished.

  • 3

    The start time of the animation is fixed and a number of variables are registered:
    — zIndex, Z-index of the gallery element;
    is offsetX, the current offset of the element along the x-axis;
    is offsetZ, the current offset of the element along the z axis;
    is angleY, the current angle of rotation of the element along the y-axis;
    is alignment, the current value of the gallery element attribute.
    style

  • 4

    We get the attribute value of each element, that is, the current location of each element.style

  • 5

    The animation function starts.

  • 6

    The XZ, and y-axis rotation angle in the current iteration are calculated, as are the Z-index of each element.

  • 7

    Based on the current coordinates and the angle of rotation obtained, the content (value) of the attribute for each gallery element at the current time of the animation is formed.style

  • 8

    At the end of the animation:
    — the index of the new current element is calculated;
    is stored in an array of the Z coordinate of each element;
    - The ban on scrolling through the gallery is lifted.

Now let's start writing JS-code that implements the considered algorithm.
Let's start by:

  1. let's create a function shifGallery;
  2. we will register a number of variables in it and check the input data;
  3. Get the attribute value of each gallery element.style
  4. register the animation function inside the function and make its call;shifGalleryanimate
  5. specify the behavior of the function after the end of the time allotted for the shift animation.

 

 

Each time the function is called, all gallery elements are iterated through and each element is set to 3D transformation values that depend on the current value of the animation execution factor - .animateprogress

Before we look at the enumeration of elements and the algorithms by which transformation properties change, let's once again understand in great detail how the tween of the element is carried out. We will analyze on the example of the formation of an offset at the X coordinate. Here's the formula that implements the motion tween at this coordinate:

Now in detail about the components of this formula:

offsetX
The current X-coordinate value of the element at the current animation.
style.x0
The X-coordinate value of the element before the animation begins, that is, before clicking on the "prev"/"next" navigation buttons, or on the keyboard keys with arrows "←"/"→", or rotating the mouse wheel. The values of all coordinates of each element were obtained before the animation began.
dir
The direction of the animation. Can be set to 1 if the gallery is scrolling in the "prev" direction and -1 if it is in the "next" direction.
this.options.shiftX
This value indicates the distance between gallery elements along the X-axis and depends on the type of Cover Flow effect. Values are set in the function when the settings object is generated. Accordingly, when the gallery is shifted by one step, all elements are shifted along the x-axis by a value to the right or left.
As a reminder, for items adjacent to the current one, this value is twice as large and is stored in the .
initoptionsoptions.shiftXoptions.shiftXlong
progress
The current animation coefficient, which takes a value from 0 (when the animation starts) to 1 (at the end of the animation) and is directly dependent on the time since the animation began. When it becomes equal to 1, the result of the product
this.options.shiftX * progress will become equal to this.options.shiftX, that is,
by the end of the animation time, the element will shift along the x-axis by a distance equal to the distance between the two elements, which is laid down in the gallery settings with the Cover Flow effect.
progress

The same principle applies to the animation of the remaining coordinates and the angle of rotation.

When you iterate through the gallery's collection of items, all items are divided into three groups. Let's determine the conditions under which this division will occur:

— elements of the right branch of the gallery;
is the current item.
— elements adjacent to the current one.

 

Different values of the 3D transformation properties are applied to these groups of elements.

You may have a question why you need to divide the elements of the Cover Flow gallery into groups and what are the differences in 3D transformation for elements of different groups.

  1. The elements of the right side of the gallery are deployed along the y-axis at an angle with the opposite sign, in contrast to the elements of the left part. In addition, the shading imposed on them, in the form of a linear gradient, has a different direction.
  2. The current element does not have a y-axis rotation angle or a linear gradient, they appear during animation and depend on the direction of scrolling through the gallery.
    The X-axis offset of the current element will be twice as large as that of the rest of the gallery.
  3. Depending on the direction of the leaf, the element to the right or left of the current one should take its place, while its y-axis rotation angle and shading transparency should gradually decrease to 0.
    The x-axis offset of this element will be twice as large as that of the rest of the gallery.

now let's look at how the conditions that divide the elements of the Cover Flow gallery into groups are implemented:

Elements of the right branch of the gallery.

 

The current item.

 

Items adjacent to the current one.

 

Now let's display the full JS-code of the function, which provides shifting (flipping) of the gallery by one element:shifGallery

Animate the behavior of the Cover Flow gallery element when hovering.

 

Now let's look at the behavior of the element to which we want to scroll through the gallery with the Cover Flow effect when the cursor is hovered over it. It was written above that when you hover the cursor, the element will smoothly move out of the general series of gallery elements and also smoothly stand in place if the cursor is removed.
The animation of this effect will be the responsibility of the . This function is called when an event or . Handlers for these events have been registered in the .
hoverShiftmouseentermouseleavegalleryControl

The function takes three arguments:


— the gallery element on which the event handler was triggered;
is the index of the item;
is the event to which the handler fired.
hoverShift

The article has repeatedly considered JS-animation, so it is enough to describe the algorithm of the function, detailed comments in the function code.hoverShift

Scroll the gallery with the Cover Flow effect to the selected item.

 

The gallery's scroll to the selected element is a cycle of gallery shifts by one element, i.e. a sequence of function calls, where the number of calls depends on how many elements need to "scroll" through the gallery.
Responsible for this is a function that is called when an event handler registered in the .

shifGalleryscrollclickgalleryControl

The function is very simple, so there will be enough comments inside the function:scroll

 

This completes the creation of the Gallery with the Cover Flow effect. You can see a sample gallery and download html-layout and full JS-code, you can follow the links indicated at the beginning of the page.