example28.php HOME Examples overview Download Ask a question / privacy policy / imprint

Responsive multimedia swipe gallery with 360 / 3D views, flat images, videos, AJAX and IFRAME content

AJAX-ZOOM extension to display 360 product views or 3D product views together with flat images in one viewer. Optionally add Videos from Youtube, Vimeo, and Dailymotion. You can also add other content to display within an iframe or invoked by AJAX request.

Loading, please wait...

About this example and the $.axZm360Gallery extension

It has been often asked how to manage 360/3D product spins and plain 2D images in one gallery. The vertical and horizontal galleries which are integrated into AJAX-ZOOM do not support it. However it is possible to make a custom HTML gallery with both - 360 and 2D images and control the player over API functions. In this example we have made a custom function jQuery.axZmSwitchImage() including some additional logic - when switching between regular 2D images and 360 object it is necessary (or more easy) to reload the player in the background. Thus the javascript function jQuery.axZmSwitchImage() handels the task. You will find the code in the source of this file. Edit, adjust the function as needed - it is commented. options of $.axZm360Gallery extension, which has been introduced in v. 4.2.1. All options of the extension are listed below.

What's new in $.axZm360Gallery compared to the old version:

  • HTML markup shrank to a couple of lines.
  • Easy to configure over options including the definition of the content.
  • Optionally include $.axZmThumbSlider plugin that manages the displaying and scrolling of the thumbnails gallery.
  • Almost the same code for responsive and none responsive layout. Basically, you only need to change the HTML markup and enable the embedResponsive option.
  • Additionally add videos from YouTube, Vimeo or Dailymotion.
  • Image thumbnails for all items in the gallery including that of the videos load instantly. You do not need to define them anywhere.
  • Added AJAX invoked content and content that display in an iframe.
  • Added subtle control for all features.

Despite all the possibilities, you can use the $.axZm360Gallery plugin only with plain images or only 360/3D product views. So, in case you don't have 360 photography images for a product, you can still use the same layout and scripts for displaying any media that is available.

One of the example objects loaded into the player on www.ajax-zoom.com is a multilevel (multirow) 3D object. However, as of definition, it makes no difference to a regular 360° product spin with just one row. The only difference between regular 360 spin and multirow is that AJAX-ZOOM expects to find the original images of each row in the subfolders of the target folder and not directly in the target folder as it would be for a single row 360 view. For example, the target path to a 3D view is /pic/zoomVR/nike. You would need to place images of each row into the subfolders of that target folder, e.g. /pic/zoomVR/nike/0, /pic/zoomVR/nike/15, /pic/zoomVR/nike/30, /pic/zoomVR/nike/45, /pic/zoomVR/nike/60, /pic/zoomVR/nike/75, /pic/zoomVR/nike/90. You do not need to define these subfolders anywhere. AJAX-ZOOM instantly detects them and proceeds all the images in them automatically. Also, the subfolders do not have to be named in a certain way. You just need to make sure that after sorting, the top row is at the first place and the last row at last.

Please note: some default settings from /axZm/zoomConfig.inc.php are overridden in /axZm/zoomConfigCustom.inc.php after elseif ($_GET['example'] == 'spinAnd2D') { So if changes in /axZm/zoomConfig.inc.php have no effect look for the same options /axZm/zoomConfigCustom.inc.php;

Last but not least: there is no PHP needed to run it in your actual application so you can use it, e.g. with Phalanger in ASP.NET environment.

JavaScript & CSS files in head

<!--  Include jQuery core into head section if not already exists -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

<!--  AJAX-ZOOM JavaScript -->
<script type="text/javascript" src="../axZm/jquery.axZm.js"></script>
<link type="text/css" href="../axZm/axZm.css" rel="stylesheet" />

<!-- JavaScript for 360/3D gallery -->
<script type="text/javascript" src="../axZm/extensions/jquery.axZm.360Gallery.js"></script>
<link rel="stylesheet" type="text/css" href="../axZm/extensions/jquery.axZm.360Gallery.css" />

<!-- Include axZm.thumbSlider -->
<link rel="stylesheet" type="text/css" href="../axZm/extensions/axZmThumbSlider/skins/default/jquery.axZm.thumbSlider.css" />
<script type="text/javascript" src="../axZm/extensions/axZmThumbSlider/lib/jquery.mousewheel.min.js"></script>
<script type="text/javascript" src="../axZm/extensions/axZmThumbSlider/lib/jquery.axZm.thumbSlider.js"></script>

CSS in Head

#playerWrap {
	padding-right: 120px; /* width of the gallery */
	height: 600px;
	max-height: calc(100vh - 50px);
	position: relative;

#spinGalleryContainer {
	position: absolute;
	z-index: 11;
	width: 120px;
	height: 100%;
	right: 0px;
	top: 0px;

#axZmPlayerContainer {
	position: relative;
	height: 100%;

#spinGallery {
	position: absolute;
	right: 0;
	width: 110px;
	height: 100%;
	overflow: hidden;

/* hide gallery for small screens */
@media (max-width: 768px) {
	#spinGalleryContainer {
		display: none;
	#playerWrap {
		padding-right: 0;
		height: 400px;

HTML markup in body

All containers can be responsive! If the container where AJAX-ZOOM will be loaded into is responsive, then set "embedResponsive" option below to true.

<div id="playerWrap">
	<!-- Container where AJAX-ZOOM will be loaded into -->
	<div id="axZmPlayerContainer">
		<!-- This div will be removed after anything is loaded into "content" div -->
		<h4>Loading, please wait...</h4>

	<div id="spinGalleryContainer">
		<!-- Thumb slider -->
		<div id="spinGallery">
			<!-- Temp message that will be removed after the slider initialization -->
			<div id="spinGallery_temp" class="spinGallery_temp">
				Gallery will be loaded...


$.axZm360Gallery - documentation (options)

axZmPath 'auto' Path to /axZm directory, e.g. /test/axZm/
gallery3dDir '' Path to the folder where in subfolders are images for several 360s/3D So if under this path there are any other subfolders, then the first image will be loaded into the gallery. Do not use "gallery3dDir" and "galleryData" at the same time.
first3dDir '' Path under gallery3dDir to the folder with 360 or 3D which will be loaded first
example3dDir 17 Configuration set value which is passed to ajax-zoom, e.g. 17 or "spinIpad" some default settings from /axZm/zoomConfig.inc.php are overridden in /axZm/zoomConfigCustom.inc.php after elseif ($_GET['example'] == 17){
galleryData '' While "gallery3dDir" option simply loads many 360s or 3D from a given folder, with "galleryData" option you can precisely define which 360s or 3D have to beloaded. Additionally you can also define regular 2D images and videos located at some straming platform like youtube, iframed content or load content over ajax, e.g.

galleryData: [
	['imageZoom', '/pic/zoom/animals/animals_014.jpg'],
	['imageZoom', '/pic/zoom/boutique/boutique_015.jpg'],
	['imageZoom', '/pic/zoom/boutique/boutique_013.jpg'],
	['image360', '/pic/zoom3d/Nike_Running'],
	['image360', '/pic/zoom3d/Teva'],
	['image360', '/pic/zoom3d/nike'],
	['imageZoom', '/pic/zoom/boutique/boutique_014.jpg'],
	['imageZoom', '/pic/zoom/boutique/boutique_015.jpg'],
	['youtube', 'q57I1n4s5Hg'],
	['vimeo', '78673338'],
	['dailymotion', 'x144odn']
As you can see in the code example above, galleryData is of type array, containing other arrays for each element. The first array value is data type, the second is link. Possible data types are:
  • 'imageZoom' - path to the image without http:// and without domain
  • 'image360' - path to the folder containing 360 or 3D images without http:// and without domain
  • 'youtube' - video ID
  • 'vimeo' - video ID
  • 'dailymotion' - video ID
  • 'ajax' - path to the file which should be loaded over AJAX request
  • 'iframe' - path to the file which should be set as src of the iframe
If data type is of type 'ajax', the third value can be a function which will be executed when ajax content is loaded (callback).

"image360" is data type for both, 360 and 3D images. The only difference between regular 360 spin and 3D multirow is that original images are placed in subfolders of the target folder. E.g. the target folder is "/pic/zoomVR/nike"; Now if it is 3D multirow and not one row 360, then images of each row are placed in subfolders of the target path, e.g. /pic/zoomVR/nike/0, /pic/zoomVR/nike/15, /pic/zoomVR/nike/30, /pic/zoomVR/nike/45, /pic/zoomVR/nike/60, /pic/zoomVR/nike/75, /pic/zoomVR/nike/90; It is not important how these subfolders are named and you also do not need to define these subfolder names anywhere. AJAX-ZOOM will instantly detect them and procede all the images in them.

Every image must have an unique filename!!! This is also the case if images are prepared for completly different 360s or 3D; If all your sourceimages happen to have the same filenames (e.g. spin001.jpg, spin002.jpg, [...], spin036.jpg), you could then prefix each image of a spin e.g. with the product ID or something else logical to ensure this uniqueness, e.g.
firstToLoad null What should be loaded at first if "galleryData" option is used - null (first item in "galleryData"), name of 360, text, video or "imageZoom" for regular images.
prevNextAllData {} Object containing some settings to enable previous / next button to switch not only between images, but also images and 360/3d; at time videos and external content is not supported in fullscreen mode.

	enabled: false,
	next: {file: '[buttonSet]/zoombutton_slide_vert_next', ext: 'png', w: 20, h: 100},
	prev: {file: '[buttonSet]/zoombutton_slide_vert_prev', ext: 'png', w: 20, h: 100},
	posNext: {right: 0, top: '50%', marginTop: -50, position: 'absolute', zIndex: 5},
	posPrev: {left: 0, top: '50%', marginTop: -50, position: 'absolute', zIndex: 5}
galleryHotspots {} AJAX-ZOOM supports "hotspots" which can be optionally loaded for 3D/360 or 2D (plain images). Hotspots can be configured manually in example33.php which produces a separate JS file with all possible settings. If you have already done this you can define which of these JS hotspot files will be loaded together with your content, e.g.

galleryData: [
	['animals_014.jpg', '../pic/hotspotJS/animals_014.js'],
	['bike360', '../pic/hotspotJS/bike.js']
the first property would be for an individual image, the second is for a 360 (only the folder name). Since hotspots can be defined for a gallery (set of many images) in one JS file and all the 2D images are loaded in this plugin as gallery too, you can also define one path to this JS file with the property name "2D", e.g.

galleryData: [
	['2D', '../pic/hotspotJS/animals.js'],
	['bike360', '../pic/hotspotJS/bike.js']
exampleData 'spinAnd2D' Configuration set value which is passed to ajax-zoom when using "galleryData"; some default settings from /axZm/zoomConfig.inc.php are overridden in /axZm/zoomConfigCustom.inc.php after elseif ($_GET['example'] == 'spinAnd2D') {... additionally to $_GET['example'], image360 is passed over query string as a paramter when 360 or 3D are loaded, so it is available in the config file as $_GET['image360'] and the configuration set can be differed from plain images.
zoomSwitchAnm 'SwipeHorz' When clicked on the thumbs the image inside AJAX-ZOOM will be switched with one of the following effects, possible values: "Center", "Top", "Right", "Bottom", "Left", "StretchVert", "StretchHorz", "SwipeHorz", "SwipeVert", "Vert", "Horz"
zoomSwitchSpeed 300 Speed of switching between images in the gallery.
azOptions {} Not all but some of the AJAX-ZOOM options which are normally set in zoomConfig.inc.php and zoomConfigCustom.inc.php can be set directly as js var in onBeforeStart AJAX-ZOOM callback. The property of the object is the name of the option and value its correstponding value.
divID 'axZmPlayerContainer' The ID of the element (placeholder) where AJAX-ZOOM has to be inserted into
embedResponsive false If "divID" is responsive, set this to true
spinGalleryContainerID 'spinGalleryContainer' Parent container of "spinGalleryID"
spinGalleryID 'spinGallery' Container where thumbs gallery will be loaded into
spinGallery_tempID 'spinGallery_temp' Temp container which some text which will be removed just before gallery appears.
spinGalleryLoadCallback 'onSpinPreloadEnd' Possible values: "onSpinPreloadEnd" or "onLoad"; "onLoad" would make sense if you configure $zoom['config']['spinNoInit'] to be enabled, so the user needs to click somewhere to load all other images of 360/3D;
backgroundColor '#FFFFFF' Background color of the player, possible values: #hex color or "auto". If "auto" AJAX-ZOOM will try to determin the background color. Use "auto" only if you have e.g. black and white on different 360s.
checkReverse true Set true to check spinReverse / spinReverseZ settings upon the below options - "toReverseArr" and "toReverseArrZ"
toReverseArr [] Array with folder names where spinReverse option should be applied
toReverseArrZ [] Array with folder names where spinReverseZ option should be applied
toBounceArr [] Array with folder names where spinBounce option should be set to "bounce".
fullScreenApi false Try to open AJAX-ZOOM at browsers fullscreen mode if available (requestFullScreen)
thumbsAtFullscreen false Show 360 thumb gallery at fullscreen mode, possible values: "bottom", "top", "left", "right" or false; Please note that if you have different content e.g. 360/3D, regular images or video, this option will not work (not implementet yet). It only works for the same content types - if you have only 360/3D or only 2D;
axZmThumbSlider true Use $.axZmThumbSlider extension for the thumbs, set false to disable. Requires:
axZmThumbSliderParam {} Options passed to $.axZmThumbSlider For more information see /axZm/extensions/axZmThumbSlider/, e.g.

axZmThumbSliderParam: {
	btn: false,
	orientation: 'vertical',
	scrollbar: true,
	scrollbarMargin: 5
axZmCallBacks {} Object with AJAX-ZOOM callbacks, https://www.ajax-zoom.com/index.php?cid=docs#onBeforeStart, e.g

axZmCallBacks: {
	onLoad: function(){
		console.log('onLoad fired');
	onSpinPreloadEnd: function(){
		console.log('spin preloaded');
axZmPar '' Additional parameter which can be passed to AJAX-ZOOM
thumbWidth 120 Width of the thumbnail image
thumbHeight 120 Height of the thumbnail image
thumbRetina true true will double the resolution of the thumbnails images but keep "thumbWidth" and "thumbHeight" on screen
thumbsCache true Cache thumbnails
thumbQual 90 jpg quality of the thumbnail image
thumbMode false possible values: "contain", "cover" or false
thumbBackColor '#FFFFFF' Background color of the thumb if "thumbMode" is set to "contain"
thumbPadding null Quickly overwrite the css padding of the thumbs
thumbMarginRight null Quickly overwride the css margin to the right of the thumbs
thumbMarginBottom null Quickly overwride the css margin to the bottom of the thumbs
thumbCss {} Quickly overwride any other CSS
thumbPreloadingImg 'ajax-loader-map-white.gif' Image located in /axZm/icons directory which will appear before the thumbs are loaded
thumbDescr true Show thumb description, if true and thumbDescrObj is not defined, then for 360/3D number of frames will be shown.
thumbDescrObj {} Object containing descriptions of the thumbs, e.g.

thumbDescrObj: {
	boutique_014.jpg: 'Image 1',
	q57I1n4s5Hg: 'Video 1',
	Uvex_Occhiali '360 object 1'
thumbImgObj {} Alternativly to dynamically generated thumbs you can define a list of thumbs. "thumbWidth" and "thumbHeight" options still determin the css of the thumbs. E.g.

thumbImgObj: {
	boutique_014.jpg: '/images/thumb_dbVSGr3.jpg',
	q57I1n4s5Hg: '/images/thumb_mBOG8CL.jpg',
	Uvex_Occhiali '/images/thumb_LWgFmgn.jpg'
thumbIcon true Show 360, 3D or some other icon for the thumbs
thumbIconFile {..} Filenames for icons located in /axZm/icons directory, default:

thumbIconFile: {
	'360': '360_2.png',
	'3D': '3d_2.png',
	'2D': '',
	'youtube': 'youtube_icon.png',
	'vimeo': 'vimeo_icon_1.png',
	'dailymotion': 'video_icon.png'
videoThumb {..} Paths for video thumbs. Depending on the video streaming platform images will be retieved instantly, default:

videoThumb: {
	youtube: {
		url: 'https://i1.ytimg.com/vi/',
		img: 'mqdefault'
	vimeo: {
		url: 'https://vimeo.com/api/v2/video/',
		img: 'thumbnail_medium'
	dailymotion: {
		url: 'https://api.dailymotion.com/video/',
		img: 'thumbnail_480_url'
Notes: dailymotion acceppts only https, does not work on IE8, IE9 if not in https mode
videoUrl {..} Url for the videos, default:

videoUrl: {
	youtube: 'https://www.youtube-nocookie.com/embed/',
	vimeo: 'https://player.vimeo.com/video/',
	dailymotion: 'https://www.dailymotion.com/embed/video/'
videoSettings {..} Parameters which are passed to the video players, defaults:

videoSettings: {
	youtube: {
		autoplay: 0,
		controls: 1,
		loop: 0,
		rel: 0,
		showinfo: 0,
		theme: 'light',
		html5: 1
	vimeo: {
		autoplay: 0,
		byline: 0,
		portrait: 0
	dailymotion: {
		autoplay: 0,
		logo: 0,
		quality: 720,
		related: 0
for more information see:
$.axZm360Gallery documentation last updated: 2015-06-11

1 examples that use the $.axZm360Gallery extension

  • example15
  • example15_gallery_clean
  • example24
  • example29
  • example29_clean
  • example29_fullscreen
  • example29_responsive_easy
2 you will find the respective configuration set in /axZm/zoomConfigCustom.inc.php after
elseif ($_GET['example'] == [someValue])
There you can change existing options or copy from /axZm/zoomConfig.inc.php other options to change their values.

Comments (1)

korosh 2013-03-04 08:22:38
korosh It's really good way to show products to my customer. thank you

Leave a Comment

Looking for a place to add a personal image? Visit www.gravatar.com to get Your own gravatar, a globally-recognized avatar. After you're all setup, your personal image will be attached every time you comment.
Load other examples in slider