Jalil
Jalil

Reputation: 13

OpenSeaDragon doesnt display a slide

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

Answers (1)

Joachim Berdal Haga
Joachim Berdal Haga

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

Related Questions