diff --git a/src/ci360.service.js b/src/ci360.service.js index 2f41553..55a2886 100644 --- a/src/ci360.service.js +++ b/src/ci360.service.js @@ -45,6 +45,7 @@ import { isPropsChangeRequireReload, getImageAspectRatio, removeChildFromParent, + initLazyload, } from './utils'; class CI360Viewer { @@ -80,6 +81,15 @@ import { this.init(container); } + isReady() { + const loadedXImages = this.imagesX.filter(image => image); + const loadedYImages = this.imagesY.filter(image => image); + + const totalAmount = this.amountX + this.amountY; + + return loadedXImages.length + loadedYImages.length === totalAmount; + } + mouseDown(event) { if (!this.imagesLoaded) return; @@ -734,15 +744,17 @@ import { } requestResizedImages() { + if (!this.isReady()) return; + const responsive = this.ciParams.ciToken; const firstImage = this.imagesX[0]; this.update(); + if (!responsive || this.container.offsetWidth < firstImage.width * 1.5) return; this.speedFactor = getSpeedFactor(this.dragSpeed, this.amountX, this.container.offsetWidth); const srcX = generateImagesPath(this.srcXConfig); - if (!responsive || this.container.offsetWidth < firstImage.width * 1.5) return; preloadImages( this.srcXConfig, @@ -1278,8 +1290,6 @@ import { this.disableDrag = disableDrag; this.fullscreen = fullscreen; this.magnifier = !this.isMobile && magnifier > 1 ? Math.min(magnifier, 5) : 0; - this.lazyloadX = lazyload; - this.lazyloadY = lazyload; this.lazySelector = lazySelector; this.spinReverse = spinReverse; this.controlReverse = controlReverse; @@ -1347,7 +1357,6 @@ import { innerBox: this.innerBox, apiVersion, ciParams, - lazyload, lazySelector, amount: this.amountX, indexZeroBase, @@ -1363,27 +1372,6 @@ import { } const srcX = generateImagesPath(this.srcXConfig); - const srcY = generateImagesPath(this.srcYConfig); - - const initLazyload = (image, orientation) => { - const lazyloadXConfig = {...this.srcXConfig, lazyload: false}; - const lazyloadYConfig = {...this.srcYConfig, lazyload: false}; - - if (orientation === ORIENTATIONS.Y) { - this.lazyloadY = false; - - preloadImages(lazyloadXConfig, srcX, ( - onImageLoad.bind(this, ORIENTATIONS.X) - )); - } else { - this.lazyloadX = false; - this.lazyloadInitImageX = image; - - preloadImages(lazyloadYConfig, srcY, ( - onImageLoad.bind(this, ORIENTATIONS.Y) - )); - } - } const onImageLoad = (orientation, image, index) => { if (orientation !== ORIENTATIONS.Y) { @@ -1396,39 +1384,48 @@ import { const loadedYImages = this.imagesY.filter(image => image); const totalAmount = this.amountX + this.amountY; - const totalLoadedImages = this.imagesX.length + this.imagesY.length; - const isFirstImageLoaded = index === 0 && orientation !== ORIENTATIONS.Y; - - const isAllImagesLoaded = ( - loadedXImages.length + loadedYImages.length === this.amountX + this.amountY - ); + const totalLoadedImages = loadedXImages.length + loadedYImages.length; + const isFirstImageLoaded = !index && orientation !== ORIENTATIONS.Y; const percentage = Math.round(totalLoadedImages / totalAmount * 100); this.updatePercentageInLoader(percentage); - if (this.lazyloadX || this.lazyloadY) return initLazyload(image, orientation); - if (isFirstImageLoaded) { this.onFirstImageLoaded(image); } - if (isAllImagesLoaded) { + if (this.isReady()) { this.onAllImagesLoaded(); - if (lazyload) { - this.innerBox.removeChild(this.lazyloadInitImageX); - } } } - preloadImages(this.srcXConfig, srcX, ( - onImageLoad.bind(this, ORIENTATIONS.X) - )); - - if (this.allowSpinY) { - preloadImages(this.srcYConfig, srcY, ( - onImageLoad.bind(this, ORIENTATIONS.Y) + const loadImages = () => { + preloadImages(this.srcXConfig, srcX, ( + onImageLoad.bind(this, ORIENTATIONS.X) )); + + if (this.allowSpinY) { + const srcY = generateImagesPath(this.srcYConfig); + + preloadImages( + this.srcYConfig, + srcY, + onImageLoad.bind(this, ORIENTATIONS.Y) + ); + } + } + + if (lazyload) { + const onFirstImageLoad = (image) => { + this.innerBox.removeChild(image); + + loadImages(); + } + + initLazyload(srcX, this.srcXConfig, onFirstImageLoad); + } else { + loadImages(); } this.attachEvents(draggable, swipeable, keys); diff --git a/src/utils/index.js b/src/utils/index.js index 1cb4dc5..7d1f605 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -3,6 +3,7 @@ export { isPropsChangeRequireReload } from './image-src/is-props-change-require- export { generateImagesPath } from './image-src/generate-images-path'; export { preloadImages } from './load-images/preload-images'; export { preloadOriginalImages } from './load-images/preload-original-images'; +export { initLazyload } from './load-images/lazyload/init-lazyload' export { contain } from './responsive/contain'; export { getImageAspectRatio } from './responsive/get-image-aspect-ratio'; diff --git a/src/utils/load-images/images-from-folder/prepare-images-from-folder.js b/src/utils/load-images/images-from-folder/prepare-images-from-folder.js index 1dee831..2131a13 100644 --- a/src/utils/load-images/images-from-folder/prepare-images-from-folder.js +++ b/src/utils/load-images/images-from-folder/prepare-images-from-folder.js @@ -1,25 +1,21 @@ import { AND_SYMBOL_REGEX, ORGINAL_SIZE_REGEX } from '../../../constants/regex'; import { pad } from '../pad'; -export const prepareImagesFromFolder = (imagesSrc, srcConfig) => { +export const prepareImagesFromFolder = (imagesSrc, srcConfig, loadOriginalImages) => { const { amount, indexZeroBase } = srcConfig || {}; - const resultSrc = []; - const originalSrc = []; - - [...new Array(amount)].forEach((_item, index) => { + return [...new Array(amount)].map((_item, index) => { const nextZeroFilledIndex = pad(index + 1, indexZeroBase); - const imageResultSrc = imagesSrc.replace('{index}', nextZeroFilledIndex); - const imageOriginalSrc = imageResultSrc - .replace(ORGINAL_SIZE_REGEX, '') - .replace(AND_SYMBOL_REGEX, '?'); + const imageSrc = imagesSrc.replace('{index}', nextZeroFilledIndex); - resultSrc.push(imageResultSrc); - originalSrc.push(imageOriginalSrc); - }); + if (loadOriginalImages) { + const imageOriginalSrc = imageSrc + .replace(ORGINAL_SIZE_REGEX, '') + .replace(AND_SYMBOL_REGEX, '?'); - return { - resultSrc, - originalSrc, - }; + return imageOriginalSrc; + } + + return imageSrc; + }); }; diff --git a/src/utils/load-images/images-from-list/prepare-images-from-list.js b/src/utils/load-images/images-from-list/prepare-images-from-list.js index f0417cd..d122baa 100644 --- a/src/utils/load-images/images-from-list/prepare-images-from-list.js +++ b/src/utils/load-images/images-from-list/prepare-images-from-list.js @@ -1,22 +1,19 @@ import { generateImagesPath } from '../../image-src/generate-images-path'; -export const prepareImagesFromList = (images, srcConfig) => { +export const prepareImagesFromList = (images, srcConfig, loadOriginalImages ) => { const { folder } = srcConfig; - const resultSrc = []; - const originalSrc = []; - images.forEach((src) => { + return images.map((src) => { const nextSrcConfig = { ...srcConfig }; nextSrcConfig.folder = /(http(s?)):\/\//gi.test(src) ? '' : folder; nextSrcConfig.filename = src; - const lastIndex = resultSrc.lastIndexOf('//'); - resultSrc.push(generateImagesPath(nextSrcConfig)); - originalSrc.push(resultSrc.slice(lastIndex)); - }); + if (loadOriginalImages) { + const lastIndex = resultSrc.lastIndexOf('//'); + + return resultSrc.slice(lastIndex); + } - return { - resultSrc, - originalSrc, - }; + return generateImagesPath(nextSrcConfig); + }); }; diff --git a/src/utils/load-images/lazyload/init-lazyload.js b/src/utils/load-images/lazyload/init-lazyload.js new file mode 100644 index 0000000..ad9a0c5 --- /dev/null +++ b/src/utils/load-images/lazyload/init-lazyload.js @@ -0,0 +1,38 @@ +import { prepareFirstImageFromFolder } from "./prepare-first-image/prepare-first-image-from-folder"; +import { prepareFirstImageFromList } from "./prepare-first-image/prepare-first-image-from-list"; + +export const initLazyload = (imagesSrc, srcConfig, cb) => { + const { imageList, lazySelector, innerBox } = srcConfig || {}; + let firstImageSrc; + + if (imageList) { + try { + const images = JSON.parse(imageList); + + firstImageSrc = prepareFirstImageFromList(images, srcConfig); + } catch (error) { + console.error(`Wrong format in image-list attribute: ${error.message}`); + } + } else { + firstImageSrc = prepareFirstImageFromFolder(imagesSrc, srcConfig); + } + + const image = new Image(); + + image.setAttribute('data-src', firstImageSrc); + image.style.position = 'absolute'; + image.style.top = 0; + image.style.left = 0; + image.style.width = '100%'; + image.style.maxWidth = '100%'; + image.style.maxHeight = '100%'; + + + if (lazySelector) image.className = lazySelector; + + innerBox.appendChild(image); + + if (cb) { + image.onload = () => cb(image); + } +} \ No newline at end of file diff --git a/src/utils/load-images/lazyload/prepare-first-image/prepare-first-image-from-folder.js b/src/utils/load-images/lazyload/prepare-first-image/prepare-first-image-from-folder.js new file mode 100644 index 0000000..b3456d8 --- /dev/null +++ b/src/utils/load-images/lazyload/prepare-first-image/prepare-first-image-from-folder.js @@ -0,0 +1,8 @@ +import { pad } from "../../pad"; + +export const prepareFirstImageFromFolder = (imagesSrcs, srcConfig) => { + const {indexZeroBase } = srcConfig || {}; + const nextZeroFilledIndex = pad(1, indexZeroBase); + + return imagesSrcs.replace('{index}', nextZeroFilledIndex); +} \ No newline at end of file diff --git a/src/utils/load-images/lazyload/prepare-first-image/prepare-first-image-from-list.js b/src/utils/load-images/lazyload/prepare-first-image/prepare-first-image-from-list.js new file mode 100644 index 0000000..7755215 --- /dev/null +++ b/src/utils/load-images/lazyload/prepare-first-image/prepare-first-image-from-list.js @@ -0,0 +1,13 @@ +import { generateImagesPath } from "../../../image-src/generate-images-path"; + +export const prepareFirstImageFromList = (images, srcConfig) => { + const { folder } = srcConfig; + + const firstImageSrc = images[0]; + + const nextSrcConfig = { ...srcConfig }; + nextSrcConfig.folder = /(http(s?)):\/\//gi.test(firstImageSrc) ? '' : folder; + nextSrcConfig.filename = firstImageSrc; + + return generateImagesPath(nextSrcConfig); +} \ No newline at end of file diff --git a/src/utils/load-images/load-image-as-promise.js b/src/utils/load-images/load-image-as-promise.js index 457122f..87e24e4 100644 --- a/src/utils/load-images/load-image-as-promise.js +++ b/src/utils/load-images/load-image-as-promise.js @@ -1,37 +1,23 @@ -import { ORIENTATIONS } from '../../constants/orientations'; - -export const loadImageAsPromise = async (src, index, srcConfig, onImageLoadCallback = () => {}) => { - const { - lazyload, lazySelector, fullscreenView, innerBox, orientation, - } = srcConfig || {}; +export const loadImageAsPromise = async (src, index, cb) => { const image = new Image(); - if (lazyload && !fullscreenView) { - image.setAttribute('data-src', src); - image.className = image.className.length ? `${image.className} ${lazySelector}` : lazySelector; - - if (index === 0 && orientation !== ORIENTATIONS.Y) { - image.style.position = 'absolute'; - image.style.top = '0'; - image.style.left = '0'; - - innerBox.appendChild(image); - } - - image.onload = () => onImageLoadCallback(image, index); - } else { - image.src = src; - } + image.src = src; return new Promise((reslove) => { image.onload = () => { - onImageLoadCallback(image, index); reslove(image); + + if (cb) { + cb(image, index); + } }; image.onerror = () => { - onImageLoadCallback(image, index); reslove(image); + + if (cb) { + cb(image, index); + } }; }); }; diff --git a/src/utils/load-images/load-image.js b/src/utils/load-images/load-image.js deleted file mode 100644 index 8c63e08..0000000 --- a/src/utils/load-images/load-image.js +++ /dev/null @@ -1,13 +0,0 @@ -export const loadImage = (src, index, srcConfig) => { - const { lazyload, lazySelector, fullscreenView } = srcConfig || {}; - const image = new Image(); - - if (lazyload && !fullscreenView) { - image.setAttribute('data-src', src); - image.className = image.className.length ? `${image.className} ${lazySelector}` : lazySelector; - } else { - image.src = src; - } - - return image; -}; diff --git a/src/utils/load-images/load-images-relative-to-container-size.js b/src/utils/load-images/load-images-relative-to-container-size.js index 64dcabf..1d5eec9 100644 --- a/src/utils/load-images/load-images-relative-to-container-size.js +++ b/src/utils/load-images/load-images-relative-to-container-size.js @@ -1,7 +1,7 @@ import { loadImageAsPromise } from './load-image-as-promise'; -export const loadImagesRelativeToContainerSize = async (imagesSrcs, srcConfig, onImageLoadCallback) => { +export const loadImagesRelativeToContainerSize = async (imagesSrcs, cb) => { await Promise.all(imagesSrcs.map(async (src, index) => { - await loadImageAsPromise(src, index, srcConfig, onImageLoadCallback); + await loadImageAsPromise(src, index, cb); })); }; diff --git a/src/utils/load-images/load-original-images.js b/src/utils/load-images/load-original-images.js index 664b4e7..f728008 100644 --- a/src/utils/load-images/load-original-images.js +++ b/src/utils/load-images/load-original-images.js @@ -1,7 +1,7 @@ import { loadImageAsPromise } from './load-image-as-promise'; -export const loadOriginalImages = async (imagesSrcs, onImageLoadCallback) => { +export const loadOriginalImages = async (imagesSrcs, cb) => { await Promise.all(imagesSrcs.map(async (src, index) => { - await loadImageAsPromise(src, index, null, onImageLoadCallback); + await loadImageAsPromise(src, index, cb); })); }; diff --git a/src/utils/load-images/preload-images.js b/src/utils/load-images/preload-images.js index 58bc8ae..0aa78f9 100644 --- a/src/utils/load-images/preload-images.js +++ b/src/utils/load-images/preload-images.js @@ -3,23 +3,21 @@ import { loadImagesRelativeToContainerSize } from './load-images-relative-to-con import { prepareImagesFromFolder } from './images-from-folder/prepare-images-from-folder'; import { prepareImagesFromList } from './images-from-list/prepare-images-from-list'; -export const preloadImages = (srcConfig, imagesSrc, onImageLoadCallback) => { +export const preloadImages = (srcConfig, imagesSrc, cb) => { const { imageList } = srcConfig || {}; - let imagesSets = {}; + let imagesSrcs = []; if (imageList) { try { const images = JSON.parse(imageList); - imagesSets = prepareImagesFromList(images, srcConfig); + imagesSrcs = prepareImagesFromList(images, srcConfig); } catch (error) { console.error(`Wrong format in image-list attribute: ${error.message}`); } } else { - imagesSets = prepareImagesFromFolder(imagesSrc, srcConfig); + imagesSrcs = prepareImagesFromFolder(imagesSrc, srcConfig); } - const { resultSrc } = imagesSets || {}; - - loadImagesRelativeToContainerSize(resultSrc, srcConfig, onImageLoadCallback); + loadImagesRelativeToContainerSize(imagesSrcs, cb); }; diff --git a/src/utils/load-images/preload-original-images.js b/src/utils/load-images/preload-original-images.js index 046658c..f8c1d88 100644 --- a/src/utils/load-images/preload-original-images.js +++ b/src/utils/load-images/preload-original-images.js @@ -3,23 +3,21 @@ import { prepareImagesFromFolder } from './images-from-folder/prepare-images-fro import { prepareImagesFromList } from './images-from-list/prepare-images-from-list'; import { loadOriginalImages } from './load-original-images'; -export const preloadOriginalImages = (srcConfig, imagesSrc, onImageLoadCallback) => { +export const preloadOriginalImages = (srcConfig, imagesSrc, cb) => { const { imageList } = srcConfig || {}; - let imagesSets = {}; + let imagesSrcs = []; if (imageList) { try { const images = JSON.parse(imageList); - imagesSets = prepareImagesFromList(images, srcConfig); + imagesSrcs = prepareImagesFromList(images, srcConfig, true); } catch (error) { console.error(`Wrong format in image-list attribute: ${error.message}`); } } else { - imagesSets = prepareImagesFromFolder(imagesSrc, srcConfig); + imagesSrcs = prepareImagesFromFolder(imagesSrc, srcConfig, true); } - const { originalSrc } = imagesSets || {}; - - loadOriginalImages(originalSrc, onImageLoadCallback); + loadOriginalImages(imagesSrcs, cb); };