Skip to content

Commit

Permalink
hotFix: lazyloading
Browse files Browse the repository at this point in the history
  • Loading branch information
Amr Wagdy committed Mar 17, 2022
1 parent 341aed9 commit 041645a
Show file tree
Hide file tree
Showing 13 changed files with 146 additions and 127 deletions.
85 changes: 41 additions & 44 deletions src/ci360.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
isPropsChangeRequireReload,
getImageAspectRatio,
removeChildFromParent,
initLazyload,
} from './utils';

class CI360Viewer {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1347,7 +1357,6 @@ import {
innerBox: this.innerBox,
apiVersion,
ciParams,
lazyload,
lazySelector,
amount: this.amountX,
indexZeroBase,
Expand All @@ -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) {
Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
});
};
21 changes: 9 additions & 12 deletions src/utils/load-images/images-from-list/prepare-images-from-list.js
Original file line number Diff line number Diff line change
@@ -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);
});
};
38 changes: 38 additions & 0 deletions src/utils/load-images/lazyload/init-lazyload.js
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
34 changes: 10 additions & 24 deletions src/utils/load-images/load-image-as-promise.js
Original file line number Diff line number Diff line change
@@ -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);
}
};
});
};
13 changes: 0 additions & 13 deletions src/utils/load-images/load-image.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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);
}));
};
4 changes: 2 additions & 2 deletions src/utils/load-images/load-original-images.js
Original file line number Diff line number Diff line change
@@ -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);
}));
};
Loading

0 comments on commit 041645a

Please sign in to comment.