I'm building e-shop and I'm trying to implement Photoswipe plugin to gallery. Everything works perfect, when I'm fetching data from vendure.io cms, because imgs have widht and height. Problem comes, when I fetch imgs from API, because I fetch only image url, but not the width and weight of the image.
Have someone any tips/tricks/quick replacement? || Has anyone encountered something similar?
Everytime when I click on img and try to open lightbox with fetched img from external API, it throws error:
Unhandled Runtime Error
TypeError: can't access property "x", p2 is undefined
.next\static\chunks\src_photoswipe_ts.js (510:0) @ _equalizePoints
508 |
509 | _equalizePoints = function(p1, p2) {
> 510 | p1.x = p2.x;
511 | p1.y = p2.y;
512 | if(p2.id) {
513 | p1.id = p2.id;
function ProductGallery(props: ProductGalleryProps) {
const { layout, images } = props;
if (!images) {
return <BlockLoader />;
} else {
const direction = useDirection();
const [state, setState] = useState({ currentIndex: 0, transition: false });
const imagesRefs = useRef<Array<HTMLImageElement | null>>([]);
const slickFeaturedRef = useRef<Slick>(null);
const createGalleryRef = useRef<Promise<CreateGalleryFn> | null>(null);
const galleryRef = useRef<PhotoSwipe<PhotoSwipeUIDefault.Options> | null>(
null
);
const getIndexDependOnDirRef = useRef<((index: number) => number) | null>(
null
);
const unmountedRef = useRef(false);
const getIndexDependOnDir = useCallback(
(index: number) => {
// we need to invert index id direction === 'rtl' due to react-slick bug
if (direction === "rtl") {
return images.length - 1 - index;
}
return index;
},
[direction, images]
);
const openPhotoswipe = (index: number) => {
if (!createGalleryRef.current) {
return;
}
const items = imagesRefs.current.map((tag, index) => {
if (!tag) {
throw Error("Image ref is null");
}
const width = images[index].width;
const height = images[index].height;
return {
src: images[index].source,
msrc: images[index].source,
w: width,
h: height,
};
});
if (direction === "rtl") {
items.reverse();
}
// noinspection JSUnusedGlobalSymbols
const options: PhotoSwipe.Options = {
getThumbBoundsFn: (index) => {
// IMPORTANT: Inside this function, we can use variables and functions only through ref.
if (!getIndexDependOnDirRef.current) {
return { x: 0, y: 0, w: 0 };
}
const dirDependentIndex = getIndexDependOnDirRef.current(index);
const tag = imagesRefs.current[dirDependentIndex];
if (!tag) {
return { x: 0, y: 0, w: 0 };
}
const width = tag.naturalWidth;
const height = tag.naturalHeight;
const rect = tag.getBoundingClientRect();
const ration = Math.min(rect.width / width, rect.height / height);
const fitWidth = width * ration;
const fitHeight = height * ration;
return {
x: rect.left + (rect.width - fitWidth) / 2 + window.pageXOffset,
y: rect.top + (rect.height - fitHeight) / 2 + window.pageYOffset,
w: fitWidth,
};
},
index: getIndexDependOnDir(index),
bgOpacity: 0.9,
history: false,
};
createGalleryRef.current.then((createGallery) => {
// IMPORTANT: Inside this function, we can use variables and functions only through ref.
if (unmountedRef.current) {
return;
}
galleryRef.current = createGallery(items as any, options);
galleryRef.current.listen("beforeChange", () => {
if (galleryRef.current && slickFeaturedRef.current) {
slickFeaturedRef.current.slickGoTo(
galleryRef.current.getCurrentIndex(),
true
);
}
});
galleryRef.current.listen("destroy", () => {
galleryRef.current = null;
});
galleryRef.current.init();
});
};
Used technologies: Next.js. Vendure.io, Typescript, GraphQL