JS Cloudimage 360 View - A simple, interactive resource that can be used to provide a virtual tour of your product

Overview

Release Size Download Contributions welcome License Scaleflex team Cloudimage

cloudimage logo cloudimage logo

JS Cloudimage 360 View

DocsDemoCode SandboxVideo TutorialWhy

A simple, interactive resource that can be used to provide a virtual tour of your product.

The Lounge

Table of contents

Demo

To see the Cloudimage 360 view plugin in action, please check out the Demo page.

Step 1: Installation

Add script tag with CDN link to js-cloudimage-360-view lib after all content in body tag

">
<script src="https://scaleflex.cloudimg.io/v7/plugins/js-cloudimage-360-view/latest/js-cloudimage-360-view.min.js?func=proxy"></script>

Step 2: Initialize

After adding the js-cloudimage-360-view lib, simply initialize it with class name "cloudimage-360", server folder path, file name and amount of images:

">
<div
   class="cloudimage-360"
   id="gurkha-suv"
   data-folder="https://scaleflex.cloudimg.io/v7/demo/suv-orange-car-360/"
   data-filename-x="orange-{index}.jpg"
   data-amount-x="73"
>div>

edit in codesandbox

Methods

init

Type: Function

Initialization of js cloudimage 360 view plugin.

window.CI360.init();

NOTE: initialization of the plugin runs on the script load. In case you need to postpone the initialization of the plugin you can disable it with notInitOnLoad param

">
<script>window.CI360 = { notInitOnLoad: true }</script>
<script src="https://cdn.scaleflex.it/plugins/js-cloudimage-360-view/3.0./js-cloudimage-360-view.min.js"></script>
<script>window.CI360.init(); // initialize the plugin when you need</script>

add

Type: Function
window.CI360.add(idOftheView: string);

lazy init cloudimage-360 view by id.

arguments

idOftheView: string The id of the new view

edit in codesandbox

update

Type: Function
window.CI360.update(idOftheView, forceUpdate);

Update cloudimage 360 viewer instance.
For any update in source attributes after plugin initialization (e.g. data-folder, data-filename-x, data-amount-y), the plugin will re-init.

arguments

idOftheView: string The id of the new view

forceUpdate: bool Force the view to reinitialize.

">
<div
   class="cloudimage-360"
   id="gurkha-suv"
   data-folder="https://scaleflex.cloudimg.io/v7/demo/suv-orange-car-360/"
   data-filename-x="orange-{index}.jpg"
   data-amount-x="73"
>div>
window.CI360.update('gurkha-suv');
window.CI360.update(null, true);

edit in codesandbox

destroy

Type: Function

Destroying a cloudimage 360 viewer instance will reset the HTML to its original state.

window.CI360.destroy();
edit in codesandbox

getActiveIndexByID

Type: Function

Get the {index} of the image that is being viewed.

window.CI360.getActiveIndexByID(idOfInstance: string, oriantation: string);
arguments

idOfInstance: string The id of the instance

oriantation: string The oriantation of the active index

Customize elements

You can customize elements by adding the following classes:

Example CSS

.cloudimage-360-icons-container {
	top: 5px;
  	right: 5px;
}
.cloudimage-360-fullscreen-modal {
	top: 0;
  	bottom: 0;
}
.cloudimage-360-magnifier-icon {
	background: url(https://scaleflex.cloudimg.io/v7/filerobot/js-cloudimage-360-view/loupe.svg) 50% 50% / cover no-repeat;
}
.cloudimage-360-close-fullscreen-icon {
	background: url(https://scaleflex.cloudimg.io/v7/filerobot/js-cloudimage-360-view/cross.svg) 50% 50% / cover no-repeat;
}
.cloudimage-360-view-360-circle {
  	margin: auto;
}
.cloudimage-360-loader {
	margin: auto;
}
.cloudimage-360-view-360-icon {
	background: url(https://scaleflex.cloudimg.io/v7/filerobot/js-cloudimage-360-view/360_view.svg) 50% 50% / cover no-repeat;
}
.cloudimage-360-box-shadow {
	top: 0;
  	left: 0;
}
.cloudimage-360-img-magnifier-glass {
	border: 3px solid #000;
  	border-radius: 50%;
}

Config

class

Type: String | Value: "cloudimage-360" | required

The selector for js-cloudimage-360-view lib.

data-folder (or folder)

Type: String(url) | required

Your images folder on server.

data-api-version (or api-version)

Type: String |Default: 'v7' | optional

Allow to use a specific version of API.

  • set a specific version of API
data-api-version="v7"
  • disable API version
data-api-version="null"

data-filename-x (or filename-x)

Type: String | Default: image-{index}.jpg | optional

The filename pattern for your 360 image. Must include {index}, which the library will replace with a number between 1 and data-amount-x.

data-filename-y (or filename-y)

Type: String | Default: image-y-{index}.jpg | optional

The same for data-amount-x but for images set in Y-axis.

data-amount-x (or amount-x)

Type: Number | Default: 36 | optional

Amount of images to load in X-axis for 360 view .

data-amount-y (or amount-y)

Type: Number | Default: 0 | optional

Amount of images to load in Y-axis for 360 view.

data-keys (or keys)

Type: Bool | Default: false | optional

Support for 360 spin by pressing arrow keys on keyboard.

data-keys-reverse (or keys-reverse)

Type: Bool | Default: false | optional

invert arrow keys on keyboard.

data-autoplay (or autoplay)

Type: Bool | Default: false | optional

Autoplay 360 spin view on load.

data-play-once (or autoplay)

Type: Bool | Default: false | optional

stops the autoplay after one complete cycle.

data-autoplay-behavior (or autoplay-behavior)

Type: String | Default: spin-x | optional

Changing autoplay behavior

Available behaviors (spin-x, spin-y, spin-xy, spin-yx)

data-fullscreen (or fullscreen)

Type: Bool | Default: false | optional

Open 360 spin view in full screen modal.

data-magnifier (or magnifier)

Type: Number | Default: none | optional

Magnifier to zoom image.

data-ratio (or ratio)

Type: Number (width / height) or JSON object | Default: none | optional

ratio: string

Setting the height relative to the container width according to the provided ratio

">
<div
   class="cloudimage-360"
   id="gurkha-suv"
   data-folder="https://scaleflex.cloudimg.io/v7/demo/suv-orange-car-360/"
   data-filename-x="orange-{index}.jpg"
   data-amount-x="73"
   data-ratio="2"
>div>

edit in codesandbox

ratio: JSON

Setting the height relative to the container width at any window size.

In the following example, the height should be 1.3 the container width at window size less than or equal to 567px and 2.22 at window size less than or equal to 768px.

">
<div
   class="cloudimage-360"
   id="gurkha-suv"
   data-folder="https://scaleflex.cloudimg.io/v7/demo/suv-orange-car-360/"
   data-filename-x="orange-{index}.jpg"
   data-amount-x="73"
   data-ratio='{
      "576": "1.3",
      "768": "2.22",
      "992": "2.23",
      "1200": "3",
      "2400": "3.2"
   }'
>div>

edit in codesandbox

data-autoplay-reverse (or autoplay-reverse)

Type: Bool | Default: false | optional

Autoplay 360 spin view on load.

data-disable-drag (or disable-drag)

Type: bool | Default: false | optional

disable mouse drag.

data-speed (or speed)

Type: Number | Default: 150 | optional

Speed of changing frames for autoplay in milliseconds.

data-drag-speed (or drag-speed)

Type: Number | Default: 150 | optional

Speed Factor of changing frames on drag event.

data-spin-reverse (or spin-reverse)

Type: Bool | Default: false | optional

Spin direction, by default it uses counterclockwise (image indexes from 1 to data-amount-x).

data-box-shadow (or box-shadow)

Type: String (e.g. data-box-shadow="inset 0 0 100px #222") | Default: none | optional

Apply box shadow for container.

data-bottom-circle (or bottom-circle)

Type: Bool | Default: false | optional

Display 360 view line at the bottom of container.

data-hide-360-logo (or hide-360-logo)

Type: Bool | Default: false | optional

Hide 360 view icon.

data-control-reverse (or control-reverse)

Type: Bool | Default: false | optional

Spin direction using controls, by default it uses counterclockwise (image indexes from 1 to data-amount-x).

data-stop-at-edges (or stop-at-edges)

Type: Bool | Default: false | optional

Blocks repeating images after reaching last image (or first image in opposite direction)

data-bottom-circle-offset (or bottom-circle-offset)

Type: Number | Default: 5 | optional

Bottom offset for 360 view line.

data-index-zero-base (or index-zero-base)

Type: Number | optional

Left zero padding on filename. For example: index-zero-base="4" => image index will be "0004"

data-image-list-x (or data-image-list-x)

Type: Array | optional

Option to add list of images in x-oriantation instead of folder , filename-x & amount-x.

example:

data-image-list-y (or data-image-list-y)

Type: Array | optional

Option to add list of images in y-oriantation instead of folder , filename-y & amount-y.

example:

data-pointer-zoom (or pointer-zoom)

Type: Number | Default: none | optional

Option to scale images on click on it to provided value.

example:

data-pointer-zoom="3"

data-lazyload (or lazyload)

Type: Bool | Default: false | optional

Only 360 view images close to the client's viewport will be loaded, hence accelerating the page loading time. If set to true, an additional script must be included, see Lazy loading

data-lazyload-selector (or lazyload-selector)

Type: String | Default: lazyload | optional

Helper class to apply lazy-loading depending on library you choose, see Lazy loading

Controls

You can add controls by adding elements with the following classes: cloudimage-360-left, cloudimage-360-right, cloudimage-360-top, **cloudimage-360-bottom

Example CSS

.cloudimage-360 .cloudimage-360-left, .cloudimage-360 .cloudimage-360-right {
	padding: 8px;
	background: rgba(255, 255, 255, 0.5);
	border: none;
	border-radius: 4px;
}
.cloudimage-360 .cloudimage-360-left:focus, .cloudimage-360 .cloudimage-360-right:focus {
	outline: none;
}
.cloudimage-360 .cloudimage-360-left {
	display: none;
	position: absolute;
	z-index: 100;
	top: calc(50% - 15px);
	left: 20px;
}
.cloudimage-360 .cloudimage-360-right {
	display: none;
	position: absolute;
	z-index: 100;
	top: calc(50% - 15px);
	right: 20px;
}
.cloudimage-360 .cloudimage-360-left:before, .cloudimage-360 .cloudimage-360-right:before {
	content: '';
	display: block;
	width: 30px;
	height: 30px;
	background: 50% 50% / cover no-repeat;
}
.cloudimage-360 .cloudimage-360-left:before {
	background-image: url('https://cdn.scaleflex.it/plugins/js-cloudimage-360-view/assets/img/arrow-left.svg');
}
.cloudimage-360 .cloudimage-360-right:before {
	background-image: url('https://cdn.scaleflex.it/plugins/js-cloudimage-360-view/assets/img/arrow-right.svg');
}
.cloudimage-360 .cloudimage-360-left.not-active, .cloudimage-360 .cloudimage-360-right.not-active {
	opacity: 0.4;
	cursor: default;
}

Example HTML

">
<div
	class="cloudimage-360"
	data-folder="https://scaleflex.cloudimg.io/v7/demo/360-car/"
	data-filename-x="{index}.jpeg"
>
	<button class="cloudimage-360-left">button>
	<button class="cloudimage-360-right">button>
	<button class="cloudimage-360-top">button>
	<button class="cloudimage-360-bottom">button>
div>

edit in codesandbox

Spin in X and Y axes

Allow the view to spin in both X, Y axes

Requirements

We need to provide the file-name of the y-axis images using data-filename-y

Also as we did for the x-axis if we are intializing the view using data-folder and data-filename-y so we need to provide data-amount-y which indicates the number of images on the y-axis. example:

">
<div
   class="cloudimage-360"
   data-folder="https://scaleflex.cloudimg.io/v7/demo/360-nike/"
   data-filename-x="nike-{index}.jpg"
   data-filename-y="nike-y-{index}.jpg"
   data-amount-x="35"
   data-amount-y="36"
>
</div>

edit in codesandbox

Note: We can initilize the view in x, y axes without providing add data-folder, data-amount-y, data-amount-y.
Just we need to provide the data-amount-y

Hotspots or Markers

Display information about the product on specific areas. Once a hotspot is created it can be used on more than one image.

Requirements

First, we need to set data-hotspots attribute to the view we want to add hotspots or markers on it, to prevent the plugin to init the view without hotspots config. Also we need to set an id attribute, we will need it to link the view with the hotspots config.

Create hotspots configuration

The hotspots config should be an array of objects, each object in the array indicates a single hotspot config. For each item in the array, we need to set the positions (X-coord and Y-coord) of the hotspot at every image index we need to show the hotspot on it.
hint: To know the current image index we will need to set data-info="white || black" attribute.

example:

const HOTSPOTS_CONFIG = [
 {
  positions: [
   { imageIndex: 0, xCoord: 527, yCoord: 319 },
   { imageIndex: 1, xCoord: 524 },
   { imageIndex: 2, xCoord: 520 },
   { imageIndex: 3, xCoord: 498 },
   { imageIndex: 4, xCoord: 470 },
   { imageIndex: 5, xCoord: 441 },
  ]
 }
]

In the previous example, we have only set the Ycoord a single time at the image index 0. So if the coord didn't change there's no need to reset it, it will already take the previous value.

Now we need to set the hotspot variant, we have three types of hotspots (link, popup, and custom), as it will be explained below.

Variant

Link

we need to provide the URL of the link and the link title.

example:

const HOTSPOTS_CONFIG = [
 {
  positions,
  variant: {
  title: 'New Gurkha Technical Specifications',
  url: 'https://www.forcegurkha.co.in/specifications/',
  newTab: true
  }
 }
]

Popup

Only the property inserted will displayed.

Property Type Default Description
images Array [] To display a carousel of images we need an array of objects, each object should include the src and the alt of each image
title String null Display title underneath the images
description String null Display description underneath the title
moreDetailsUrl String null Display a button underneath the description to navigate to a provided URL
moreDetailsTitle String null Set the title of the more details button

example:

const HOTSPOTS_CONFIG = [
 {
  positions,
  variant: {
   images: [
    { src: 'https://scaleflex.cloudimg.io/v7/demo/360-assets/AIR_SNORKEL_FINAL_JPG.png?vh=88bccb', alt: 'air snorkel' }
   ], // optional
   title: 'Air Intake Snorkel', // optional
   description: 'The snorkel gives the Gurkha an unmatched water-wading ability and ensures ample supply of fresh air for combustion.', // optional
   moreDetailsUrl: 'https://forcegurkha.co.in', // optional
   moreDetailsTitle: 'Read more' // optional
  }
 }
]

Custom

Display any element in the DOM in a popup and link it with the hotspot.
We will need to set the variant property value to the id of the element.

example:

const HOTSPOTS_CONFIG = [
 {
  positions,
  variant: 'gurkha-suv'
 }
]

PopupProps

Options to customize the hotspot popup.

Properties

Property Type Defaullt Description
popupSelector String null Set className to the popup wrapper
open Boolean false Open the popup
arrow Boolean true Dipslay an arrow that points toward the hotspot element
offset Array [0, 0] Set a distance between the hotspot element and the popup
placement String Auto - we can adjust the position of the hotspot popup relative to the hotspot element. (top - bottom - left - right)

example:

const HOTSPOTS_CONFIG = [
 {
  positions,
  variant,
  popupProps: {
   popupSelector: 'air-intake-popup', // optional
   offset: [20, 5], // optional
   arrow: false, // optional
   placement: 'bottom' // optional
  },
  indicatorSelector: 'first-hotspot-icon' // optional
 }
]

Responsive hotspots

Now we need to make our hotspots responsive to have an accurate positioning in different screens. we have to set initialDimensions property to every hotspot config. which indicates the dimension of the cloudimage-360 view.
hint: data-info can be used to get view size.

example:

const HOTSPOTS_CONFIG = [
 {
   positions,
   variant,
   popupProps,
   indicatorSelector,
   initialDimensions: [ 1170, 662 ]
 }
]

Add Hotspots

we need this function to link the created config with the 360-view.

window.CI360.addHotspots(idOftheView, hotspotsConfig);

example:

window.CI360.addHotspots("gurkha-suv", HOTSPOTS_CONFIG);

edit in codesandbox

data-responsive (or responsive)

Type: String (Cloudimage token) | Default: none | required for cloudimage responsive plugin

Enables cloudimage responsive plugin for 360 view.

Cloudimage Responsive Integration

See how it works (article on Medium)

Requirements

To use the Cloudimage Responsive plugin, you will need a Cloudimage token to deliver your images over CDN. Don't worry, it only takes seconds to get one by registering here. Once your token is created, you can configure it as described below. This token allows you to use 25GB of image cache and 25GB of worldwide CDN traffic per month for free.

data-responsive (or responsive)

Type: String (Cloudimage token) | Default: none | required for cloudimage responsive plugin

Enables cloudimage responsive plugin for 360 view.

data-transformation (or transformation)

Type: String | Default: none | optional

Applies Cloudimage resize operations to your image, e.g. width, height, crop, face crop, rotate, prevent enlargement... Multiple transformation operations can be applied to your image, separated by "&" (Ampersand). example:

data-transformation="w=400&h=200&func=fit"

Full documentation here.

data-filters (or filters)

Type: String | Default: none | optional

Applies Cloudimage filters to your image, e.g. brightness, contrast, greyscale, blur, Sharpen... Multiple filters can be applied, separated by "," (comma). example:

data-filters="bright:15,contrast:30"

Full documentation here.

Lazy Loading

Lazy loading is not included into js-cloudimage-360-view by default. There are well thought libraries to achieve that. If you enable lazy loading in the configuration, you need to add an additional library like lazysizes, yall.js (Yet Another Lazy Loader), lozad.js to handle it.

Implementation example with lazysizes

Implementation example with yall.js

Implementation example with lozad.js

Best practices

Browser support

Tested in all modern browsers and IE 11, 10, 9.

Filerobot UI Familiy

Contributing!

All contributions are super welcome!

License

JS Cloudimage 360 View is provided under the MIT License

Comments
  • When using data-image-list: crashes because of requestResizedImages() function

    When using data-image-list: crashes because of requestResizedImages() function

    when supplying a image list, when requestResizedImages() is called, the images do not have the right source!

    my guess is that a function sets the image-src to the format '[base-url-of-website]/images-[idx].jpg', which should not be done!

    bug 
    opened by MarkoMZ 10
  • responsitivity

    responsitivity

    Hi Amr, sorry to post it as an issue - - unfortunately i have no idea of how to use github correctly - and how to get in touch with you directly. First of all : thanks a lot for your work and that wonderful script for the 360 Productviewer. It is absolutely wonderful - also your ongoing changes - even, if i do not understand half of it.

    MY issue as a USER of this is the multi device options. Any idea how to make it always fit perfectly in mobile / tablet / screen size? I mostly drop into scrollbars or in tiny images and large white areas :(

    It would be great, to talk to you - or to get feedback. You can also write a mail to me, if you want to just take the info at flow-motion dot eu

    thanks again for the script you already did. Take care

    help wanted 
    opened by flow-motion 6
  • drag-speed ?

    drag-speed ?

    Would it be possible to get an attribute to control the drag speed? Our client find it to be a bit slow :)

    Also "data-autoplay" / "autoplay" doesn't work because it's not cast as a bool, so it's always true :)

    Cheers

    enhancement 
    opened by HeuHax 6
  • X spin plus Y ?

    X spin plus Y ?

    I've got a slew of images naming convention of 'filename-01-01.jpeg' so I'm running into trouble displaying them as they have a column and a row number, not just one as required for this app. Short from renaming every file and forgetting the Y axis rotation, is there a way to use my files with two numbers instead of one ?

    enhancement 
    opened by jesfx 5
  • disable zoom

    disable zoom

    Is there a way to disable zoom and icon change (onclick)? I now set these values to disable zoom, but the icon keeps changing.

    pointer-zoom-factor={0} pinch-zoom-factor={0} max-scale={100}

    bug 
    opened by R-154 4
  • Add a normal zoom effect

    Add a normal zoom effect

    Hello. I've downloaded the library and im trying to edit the unminified file to add a standard-zoom function.

    Actually, i've managed to edit the update function with a doubled size with this command: t.drawImage(e, '-'+(r/2) , '-'+(a/2) , this.canvas.width * 2, this.canvas.height * 2)

    My problem is that i need to add an eventlistener onclick, so i can activate my custom zoom function when you just click on the main image. How can i add that? I've seen the whole code but im not too expert in JS and i don't understand how can i add my custom listener to the library.

    Thank you in advance.

    enhancement 
    opened by Kryuko 4
  • How to use function getActiveIndexByID()?

    How to use function getActiveIndexByID()?

    Hi, the getActiveIndexByID (https://github.com/scaleflex/js-cloudimage-360-view#getactiveindexbyid) function is not working for me. It always return 'undefined'. window.CI360._viewers array is empty.

    Are there any examples? To which event bind it? Are there any hotspots planned in the future?

    Thank you!

    opened by nicktoot 3
  • How to open the 360-view inside a modal

    How to open the 360-view inside a modal

    Hello,

    I'm trying to open the 360-view inside a modal, but the modal loads empty, showing only the 360º view icon. On mouse drag, the image appears.

    Is there a way to load the first image automatically, just like loading the 360-view directly on the page?

    Thanks,

    bug 
    opened by Mobiliar3D 3
  • Chrome warning for non passive event-listener

    Chrome warning for non passive event-listener

    Hi @dzmitry-stramavus, thanks for the great work! I've noticed this warning on the console and I think it is caused by this event listener.

    In addition this kind of optimization should be necessary only on touchstart and touchmove but not in touchend. It could also be useful to apply a passive listener only if supported. Something like:

    applyPassive() {
    	if (this._supportsPassive !== undefined) {
    		return this._supportsPassive ? { passive: true } : false
    	}
    
    	// feature detect
    	let isSupported = false
    	try {
    		document.addEventListener('test', null, {
    			get passive() {
    				isSupported = true
    			},
    		})
    	} catch (e) {
    		// do nothing
    	}
    
    	this._supportsPassive = isSupported
    	return this.applyPassive()
    }
    

    https://github.com/scaleflex/js-cloudimage-360-view/blob/8db632aeb8f2ba394852afa21623940785feada5/src/ci360.service.js#L756

    If you think this could be done I would be happy to prepare a PR

    enhancement 
    opened by matteobad 3
  • How to customize preloaders

    How to customize preloaders

    Good day! Thanks for a cool and very useful plugin!

    Is there an easy way to customize the preloader? There are actually two of them. The stripe at the top and the percents counter in the middle. I need to turn off the upper stripe/progress bar thing or move it to the bottom and change its color. Is that possible?

    feature request 
    opened by ivangretsky 3
  • Server responded with a status of 429

    Server responded with a status of 429

    I tried to setup a 360 degree view with this plugin and have the following

    • 40 images around 40kb each
    • All images hosted on a S3 bucket

    But some of the images are not pulled in with the 429 Too Many Requests response. I have similar behavior when the images are hosted on another of my web servers. Is there a good way to handle this by a) Adding small delay between image requests b) Raise requests for missing images again ?

    I understand the response is coming from S3 for requesting too many images too soon, I am looking for a decent way of handling cases like this.

    Any suggestions / help on this matter would be greatly appreciated.

    help wanted question 
    opened by saisanthoshdav 3
  • Mouse `click` is good on web/desktop, but for mobile please implement `tap`, `pinch` for zoom etc.

    Mouse `click` is good on web/desktop, but for mobile please implement `tap`, `pinch` for zoom etc.

    Have you tried to rotate from the mobile phone? The experience sucks, because a single tap = zoom whereas the expectation is for double tap to zoom Also the pinch and zoom doesen't work at all

    The vertical scroll (tap) doesn't work either even though only horizontal 360 are allowed

    bug 
    opened by dotnetwise 1
  • Button control for play is missing

    Button control for play is missing

    Please implement one, so after the user clicked on the image, they can click on play to resume the play otherwise they can only play if they reload the page

    enhancement 
    opened by dotnetwise 1
  • Add an option to prevent `original images` to be downloaded again when first click on zoom

    Add an option to prevent `original images` to be downloaded again when first click on zoom

    Currently it downloads all the images and then when you press click/tap to zoom it downloads the same items once again

    Should be an option to specify the file format at multiple resolutions

    {
     720: "image-720px-{index}.jpg", 
    1080: "image-1080px-{index}.jpg", 
    1920: "image-4k-{index}.jpg"
    }
    

    Also another parameter to control wether the original images (max resolution that is) are loaded from the first time and hence should not be loaded later again

    enhancement 
    opened by dotnetwise 1
  • Calling update() on a not-initialized lazyloaded viewer causes to add a duplicate 360 icon

    Calling update() on a not-initialized lazyloaded viewer causes to add a duplicate 360 icon

    <div
        class="cloudimage-360"
        id="tw-360-1"
        data-folder="https://localhost:44396/files/"
        data-image-list-x="[...]"
        data-lazyload
        data-lazyload-selector="lazyload"></div>
    

    If a viewer with data-lazyload (or lazyload) set is not yet loaded and it's updated instead by calling window.CI360.update("tw-360-1"), this causes to add a 360 icon to it, which then gets added again after it loads causing a duplicate icon, and the second one does not get deleted.

    I believe this is caused by https://github.com/scaleflex/js-cloudimage-360-view/blob/65f08fdb07f841b38821a430436ea0c113977f8e/src/ci360.service.js#L1072 which in turn creates the icon here https://github.com/scaleflex/js-cloudimage-360-view/blob/65f08fdb07f841b38821a430436ea0c113977f8e/src/ci360.service.js#L1333-L1344

    This could be easily solved by checking isReady() before updating: https://github.com/scaleflex/js-cloudimage-360-view/blob/65f08fdb07f841b38821a430436ea0c113977f8e/src/ci360.service.js#L85-L92

    opened by Xriuk 0
Releases(v3.0.4)
Owner
Scaleflex
Digital Asset Management & Media Optimization made easy
Scaleflex
A Virtual Interactive Keyboard which replicates every key you press and a Text-Area in which everything is written and can be copied to the clipboard with a click of a button.

A Virtual Interactive Keyboard which replicates every key you press and a Text-Area in which everything is written and can be copied to the clipboard with a click of a button.

Devang Joshi 1 Mar 1, 2021
... a contemporary perspective on how to integrate B2C Commerce and the Salesforce Customer 360 Platform to power frictionless customer experiences in the B2C domain.

Salesforce B2C Commerce / Customer 360 Platform Integration Introduction Salesforce B2C Commerce / CRM Sync is an enablement solution designed by Sale

Salesforce CommerceCloud 45 Dec 9, 2022
An opensource 360° media viewer written in JavaScript using Electron and Marzipano

open360viewer open360viewer is an opensource 360° media viewer. It is based on electron and marzipano. It currently supports opening equirectangular 3

null 4 Oct 9, 2022
Welcome to Space Traveler's HUB, this web app allows the user to take a fictional tour across the space.

Welcome to Space Traveler's HUB, this web app allows the user to take a fictional tour across the space. The user can choose a rocket from our catalog interface, and reserve it. Also, the user can see recent special missions and join them. Finally, the user will be able to keep track of all your rockets and mission they are subscribed to. Build with React, Redux, React-router, and Railwindcss.

Mihreteab Misganaw 3 Jan 27, 2022
jQuery plugin to add 360 rotatable bubble style tooltips

Sorry, this project is no longer maintained. grumble.js Add a bubble to any element; configure its rotation on a 360 degree axis and define its distan

James Cryer 777 Nov 9, 2022
This repo holds my work on Angular tutorial Tour of Heroes.

TourOfHeroes This project was generated with Angular CLI version 14.2.3. Development server Run ng serve for a dev server. Navigate to http://localhos

Veronica Goranova 2 Sep 21, 2022
Food Delivery APP is a website designed to provide interactive user experience and increase user engagement when ordering food delivery.

Food-Delivery-APP Features Food Delivery APP is a website built with HTML/Tailwind CSS/JavaScript, React and enhanced with 3D design using Spline to p

Qian Xiang 3 Oct 6, 2022
MLPleaseHelp is a simple ML resource search engine.

README MLPleaseHelp is a simple ML resource search engine. How To Use You can use this search engine right now at https://jgreenemi.github.io/MLPlease

Joseph Greene 5 Jan 20, 2021
PxLoader is a simple JavasScript library for creating preloaders and resource downloaders for HTML5 apps.

PxLoader is a Javascript library that helps you download images, sound files or anything else you need before you take a specific action on your site

Pixel Lab 1.1k Dec 30, 2022
A plugin for Strapi CMS that adds a preview button and live view button to the content manager edit view.

Strapi Preview Button A plugin for Strapi CMS that adds a preview button and live view button to the content manager edit view. Get Started Features I

Matt Milburn 53 Dec 30, 2022
StarkNet support extension for VSCode. Visualize StarkNet contracts: view storage variables, external and view functions, and events.

StarkNet Explorer extension This VSCode extension quickly shows relevant aspects of StarkNet contracts: Storage variables of the current contract, and

Crytic 6 Nov 4, 2022
This tool allows you to draw up plans for facilities from Foxhole's new Inferno update. It takes power and resource needs into account to help you efficiently design your facilities.

Foxhole Facility Planner This tool allows you to draw up plans for facilities from Foxhole's new Inferno update. It takes power and resource needs int

Brandon Ray 23 Dec 23, 2022
This is a project that is used to execute python codes in the web page. You can install and use it in django projects, You can do any operations that can be performed in python shell with this package.

Django execute code This is a project that is used to execute python codes in the web page. You can install and use it in django projects, You can do

Shinu 5 Nov 12, 2022
Simple jQuery plugin that will allow users to zoom in your images, perfect for product images and galleries.

Image Zoom (jQuery) Plugin Simple jQuery plugin that will allow users to zoom in your images, perfect for product images and galleries that is less th

Mario Duarte 8 Aug 3, 2022
A simple, lightweight, clean and small library for creating guided product tours for your web app.

Tourguide.js Simple, lightweight library for creating guided tours for your web, apps and more. A tour guide is a person who provides assistance, info

Docsie.io 277 Dec 12, 2022
A new Node.js resource built using Gatsby.js with React.js, TypeScript, and Remark.

Nodejs.dev Nodejs.dev site built using Gatsby.js with React.js, TypeScript, SCSS, and Remark. You can find the latest Figma design protype here. ?? Ge

Node.js 2.2k Jan 5, 2023
Utility for collecting resource-based policies from an AWS account

AWS resource-based policy collector This library aims to collect resource-based policies from an AWS account. NOTE: This library does not cover all AW

Will Dady 22 Dec 5, 2022
Cache Solidjs resources by key (derived from the resource source)

Solid Cached Resource (Experimental) Create a solid resource attached to a cached state by a unique key. Heavily inspired by react-query, but for soli

Yonatan 27 Dec 31, 2022