diff --git a/README.md b/README.md index 2fd45d4..447d55e 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,17 @@ window.CI360.init(); > > > ``` + +### addView + +###### Type: **Function** + +add new view by id to cloudimage 360 views. + +```javascript +window.CI360.addView(idOfView: string); +``` + ### update ###### Type: **Function** diff --git a/src/ci360.service.js b/src/ci360.service.js index d52d2a5..f9d31da 100644 --- a/src/ci360.service.js +++ b/src/ci360.service.js @@ -42,7 +42,7 @@ import { generateHotspotsConfigs, isMouseOnHotspot, hideHotspotsIcons, - isSrcPropsChanged, + isPropsChangeRequireReload, getImageAspectRatio, removeChildFromParent, } from './utils'; @@ -765,6 +765,7 @@ import { } const ctx = this.canvas.getContext("2d"); + ctx.scale(this.devicePixelRatio, this.devicePixelRatio); this.updateContainerAndCanvasSize(image); @@ -831,12 +832,9 @@ import { const ctx = this.canvas.getContext("2d"); - if (this.fullscreenView) { - this.canvas.width = window.innerWidth * this.devicePixelRatio; - this.canvas.style.width = window.innerWidth + 'px'; - this.canvas.height = window.innerHeight * this.devicePixelRatio; - this.canvas.style.height = window.innerHeight + 'px'; + this.updateContainerAndCanvasSize(image); + if (this.fullscreenView) { const { offsetX, offsetY, width, height } = contain(this.canvas.width, this.canvas.height, image.width, image.height); @@ -846,12 +844,6 @@ import { ctx.drawImage(image, offsetX, offsetY, width, height); } else { - this.canvas.width = this.container.offsetWidth * this.devicePixelRatio; - this.canvas.style.width = this.container.offsetWidth + 'px'; - - this.canvas.height = this.container.offsetHeight * this.devicePixelRatio; - this.canvas.style.height = this.container.offsetHeight + 'px'; - ctx.drawImage(image, 0, 0, this.canvas.width, this.canvas.height); } @@ -1012,23 +1004,33 @@ import { window.clearTimeout(this.loopTimeoutId); } - updatePlugin(forceUpdate) { - const container = this.container; + updateView(forceUpdate, viewers) { + let container = this.container; const imageProps = get360ViewProps(container); - const srcPropsChanged = isSrcPropsChanged(this, imageProps); + const srcPropsChanged = isPropsChangeRequireReload(this, imageProps); + const reInitView = srcPropsChanged || forceUpdate; + + if (reInitView) { + const oldElement = this.container; + const viewIndex = viewers.findIndex(view => view.id === this.container.id); + container = container.cloneNode(true); - const reloadPlugin = srcPropsChanged || forceUpdate; + container.className = container.className.replace(' initialized', ''); + container.innerHTML = ''; + + oldElement.parentNode.replaceChild(container, oldElement); + + return viewers.splice(viewIndex, 1, new CI360Viewer(container)); + } container.style.position = 'relative'; container.style.width = '100%'; container.style.cursor = 'default'; container.setAttribute('draggable', 'false'); - if (reloadPlugin) container.innerHTML = ''; - this.stop(); - this.init(container, !reloadPlugin, reloadPlugin); + this.init(container, true); } destroy() { @@ -1239,7 +1241,7 @@ import { document.addEventListener('keydown', this.keyDownGeneral.bind(this)); } - init(container, update = false, reload = false) { + init(container, update = false) { let { folder, apiVersion,filenameX, filenameY, imageListX, imageListY, indexZeroBase, amountX, amountY, draggable = true, swipeable = true, keys, keysReverse, bottomCircle, bottomCircleOffset, boxShadow, autoplay, autoplayBehavior, playOnce, speed, autoplayReverse, disableDrag = true, fullscreen, magnifier, ciToken, ciFilters, ciTransformation, lazyload, lazySelector, spinReverse, dragSpeed, stopAtEdges, controlReverse, hide360Logo, logoSrc, pointerZoom, ratio, imageInfo = 'black' @@ -1286,14 +1288,9 @@ import { this.pointerZoom = pointerZoom > 1 ? Math.min(pointerZoom, 3) : 0; this.keysReverse = keysReverse; this.info = imageInfo; + this.keys = keys; this.ratio = ratio && JSON.parse(ratio); - if (reload) { - new CI360Viewer(this.container); - - return; - } - if (update) { removeChildFromParent(this.innerBox, this.iconsContainer); removeChildFromParent(this.innerBox, this.boxShadowEl); @@ -1327,9 +1324,7 @@ import { this.boxShadowEl = createBoxShadow(this.boxShadow, this.innerBox); } - this.onAllImagesLoaded(); - - return; + return this.onAllImagesLoaded(); } this.innerBox = createInnerBox(this.container); @@ -1414,7 +1409,6 @@ import { if (this.lazyloadX || this.lazyloadY) return initLazyload(image, orientation); if (isFirstImageLoaded) { - this.updateContainerAndCanvasSize(image); this.onFirstImageLoaded(image); } diff --git a/src/constants/image-src-props.js b/src/constants/image-src-props.js deleted file mode 100644 index 3a968f1..0000000 --- a/src/constants/image-src-props.js +++ /dev/null @@ -1,12 +0,0 @@ -export const IMAGE_SRC_PROPS = [ - 'folder', - 'filenameX', - 'filenameY', - 'apiVersion', - 'imageListX', - 'imageListY', - 'indexZeroBase', - 'amountX', - 'amountY', - 'lazySelector', -] \ No newline at end of file diff --git a/src/constants/props-require-reload.js b/src/constants/props-require-reload.js new file mode 100644 index 0000000..ff992f3 --- /dev/null +++ b/src/constants/props-require-reload.js @@ -0,0 +1,15 @@ +export const PROPS_REQUIRE_RELOAD = [ + 'folder', //images source + 'filenameX', //images source + 'filenameY', //images source + 'apiVersion', //images source + 'imageListX', //images source + 'imageListY', //images source + 'indexZeroBase', //images source + 'lazySelector', //images source + 'keys', // events + 'stopAtEdges', // events + 'disableDrag', // events + 'controlReverse', // events + 'disableDrag', // events +] \ No newline at end of file diff --git a/src/index.js b/src/index.js index 92c979d..69aa4c6 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,18 @@ import 'core-js/features/array/includes'; import CI360Viewer from './ci360.service'; import { attr } from './ci360.utils'; +function setContainerId(container) { + const containerId = container.id; + + if (!containerId) { + const uniqueId = Math.floor(Math.random() * 10000); + const generatedContainerId = `cloudimage-360-view-${uniqueId}`; + + container.id = generatedContainerId; + } + + return container; +} function init() { const viewers = []; @@ -11,12 +23,14 @@ function init() { const hotspotsConfigs = window.CI360.hotspots|| {}; [].slice.call(view360Array).forEach(container => { - const hotspotInstanceName = attr(container, 'hotspot-instance') || - attr(container, 'data-hotspot-instance'); + const containerWithId = setContainerId(container); + + const hotspotInstanceName = attr(containerWithId, 'hotspot-instance') || + attr(containerWithId, 'data-hotspot-instance'); - const hotspotConfig = hotspotsConfigs[hotspotInstanceName] ? hotspotsConfigs[hotspotInstanceName] : null; + const hotspotConfig = hotspotsConfigs?.[hotspotInstanceName]; - viewers.push(new CI360Viewer(container, false, hotspotConfig)); + viewers.push(new CI360Viewer(containerWithId, false, hotspotConfig)); }) window.CI360._viewers = viewers; @@ -42,18 +56,29 @@ function getActiveIndexByID(id, oriantation) { return currentViewer && (currentViewer.activeImageX - 1); } +function addView(id) { + const view360Array = Array.from(document.querySelectorAll('.cloudimage-360:not(.initialized)')); + + if (view360Array.length && id) { + const newViewContainer = view360Array.filter(viewer => viewer.id === id)[0]; + + newViewContainer && window.CI360._viewers.push(new CI360Viewer(newViewContainer)); + } +} + function update(id = null, forceUpdate = false) { if (id) { - try{ + try { const view = window.CI360._viewers.filter(viewer => viewer.id === id)[0]; - - return view.updatePlugin(forceUpdate); + view.updateView(forceUpdate, window.CI360._viewers); } catch { - console.error(`Cloudimage-360: there is no view with such id '${id}'`) + console.warn(`Cloudimage-360: there is no view with such id '${id}', you may need to run window.addView('${id}') before run update'`); } + } else { + window.CI360._viewers + .forEach(viewer => { viewer.updateView(forceUpdate, window.CI360._viewers); }); } - return window.CI360._viewers.forEach(viewer => { viewer.updatePlugin(forceUpdate); }); } function isNoViewers() { @@ -65,6 +90,7 @@ window.CI360.init = init; window.CI360.destroy = destroy; window.CI360.getActiveIndexByID = getActiveIndexByID; window.CI360.update = update; +window.CI360.addView = addView; if (!window.CI360.notInitOnLoad) { init(); diff --git a/src/utils/image-src/is-src-props-changed.js b/src/utils/image-src/is-props-change-require-reload.js similarity index 52% rename from src/utils/image-src/is-src-props-changed.js rename to src/utils/image-src/is-props-change-require-reload.js index ae684e5..a7587f2 100644 --- a/src/utils/image-src/is-src-props-changed.js +++ b/src/utils/image-src/is-props-change-require-reload.js @@ -1,10 +1,10 @@ -import { IMAGE_SRC_PROPS } from "../../constants/image-src-props"; +import { PROPS_REQUIRE_RELOAD } from "../../constants/props-require-reload"; -export const isSrcPropsChanged = (currentProps, changedProps) => ( +export const isPropsChangeRequireReload = (currentProps, changedProps) => ( Object.keys(changedProps) .reduce((acc, current) => { const isPropChanged = currentProps[current] !== changedProps[current]; - const isSrcProp = IMAGE_SRC_PROPS.includes(current); + const isSrcProp = PROPS_REQUIRE_RELOAD.includes(current); if (isSrcProp && isPropChanged) { acc = true; diff --git a/src/utils/index.js b/src/utils/index.js index cbb40d1..1cb4dc5 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,4 +1,4 @@ -export { isSrcPropsChanged } from './image-src/is-src-props-changed'; +export { isPropsChangeRequireReload } from './image-src/is-props-change-require-reload'; export { generateImagesPath } from './image-src/generate-images-path'; export { preloadImages } from './load-images/preload-images';