Reputation: 13
I don’t understand what the problem is, OpenSeaDragon doesn’t display the slide that I take from the API to the screen.
Here is a full code
import '../../../App.css'
import { useParams } from "react-router-dom";
import { useState, useEffect,useRef } from "react";
import OpenSeadragon from "openseadragon";
function CaseImage(){
const { id } = useParams();
const viewerRef = useRef(null);
const [imageSize, setImageSize] = useState(null)
useEffect(()=>{
fetch(`http://localhost/api/case/slide/GetDimensions?file_id=${id}`)
.then((response) => response.json())
.then((result) =>setImageSize(result.data))
},[id])
useEffect(() => {
if (imageSize && viewerRef.current) {
const viewer = OpenSeadragon({
id: 'openseadragon-viewer',
prefixUrl: '',
constrainDuringPan: true,
tileSources: {
getTileUrl: function (level, x, y) {
return "http://localhost/api/case/slide/GetTile/" + id + "/" +
level + "/" + x + "_" + y;
},
zoomPerScroll: 2,
overlap: 10,
height: imageSize.height,
width: imageSize.width,
tileSize: 256,
minLevel: 8,
},
zoomInButton: 'zoom-in',
zoomOutButton: 'zoom-out',
homeButton: 'home',
fullPageButton: 'full-page',
nextButton: 'next',
previousButton: 'previous',
});
viewerRef.current = viewer;
}
return () => {
if (viewerRef.current) {
viewerRef.current.destroy();
}
};
}, [imageSize, id]);
return(
<>
<div id="openseadragon-viewer" style={{ height: "700px", width: '100%' }}></div>
<div id="openseadragon-buttons" className="Panel">
<button id="zoom-in">Zoom In</button>
<button id="zoom-out">Zoom Out</button>
<button id="home">Home</button>
<button id="full-page">Full Page</button>
</div>
</>
)
}
export default CaseImage
I tried to give a straight direct like this
http://localhost/api/case/slide/GetTile/397a03fc-6ebe-4278-ae86-7be34a5b9034/8/0_0
instead of this http://localhost/api/case/slide/GetTile/" + id + "/" + level + "/" + x + "_" + y
but it didnt help
Upvotes: 1
Views: 343
Reputation: 2911
I believe the problem is that your CaseImage
component is probably mounted twice. This can happen for various reasons, e.g. if React StrictMode is on. So the viewer is constructed and then immediately destructed at the end of the first mount.
If you set viewerRef.current
to null
after destruction, the viewer will be reconstructed on the second call, and this might be enough.
However, a better approach (which avoids the double construction) would be to create the viewer as a response to the <div>
going into or out of the DOM. One way to achieve this is (approximately)
const setRef = useCallback((element: HTMLDivElement | null) => {
if (viewerRef.current) {
... <destruct old>
viewerRef.current = null; // not strictly necessary
}
if (element) {
... <create viewer on element>
viewerRef.current = viewer;
}
}, []);
...
return <div ref={setRef} {...etc}></div>
Upvotes: 0