roerohan / react-vnc

A React Component to connect to a websockified VNC client using noVNC.
https://roerohan.github.io/react-vnc/
MIT License
88 stars 21 forks source link

Screenshot Feature #24

Closed candiedoperation closed 2 years ago

candiedoperation commented 2 years ago

@roerohan, Assigning an ID (taking it from the props) for the canvas helps capture a screen shot by using the canvas.toDataURL(type, encoderOptions); browser API

This would be a really useful feature.

roerohan commented 2 years ago

Hello @candiedoperation

The canvas element is inserted by the RFB object in the noVNC library itself, I do not create a canvas on my own. Here's what I do: https://github.com/roerohan/react-vnc/blob/932cb068d99803aa660579ca7e5497d7fb0e705d/src/lib/VncScreen.tsx#L252-L258

And then, the screen reference is passed to the RFB constructor: https://github.com/roerohan/react-vnc/blob/932cb068d99803aa660579ca7e5497d7fb0e705d/src/lib/VncScreen.tsx#L183

Now, there are 2 ways to resolve your issue:

  1. I could accept a canvasId prop, and set:
    _rfb._canvas.id = canvasId;
  2. You could use the rfb object that's exposed with the onConnect method:

    function App() {
    const vncRfb = useRef(null);
    const vncScreenRef = useRef<React.ElementRef<typeof VncScreen>>(null);
    
    useEffect(() => {
    // Assuming that `canvasId` is defined
    vncRfb.current?._canvas?.id = canvasId;
    }, [vncRfb.current]);
    
    return (
    <VncScreen
      url={vncUrl}
      scaleViewport
      debug
      ref={vncScreenRef}
      onConnect={(rfb) => {
        console.log('connected', rfb);
        vncRfb.current = rfb;
      }}
    />
    )
    }

I think you could use the second approach here, I'm not really in favor of adding a canvasId prop in the library - unless you can tell me if there are any issues with this approach, or if assigning it in the library is better in any way.

roerohan commented 2 years ago

In #26, I've exposed the rfb object. So, if you have a code snippet like:

function App() {
  const vncScreenRef = useRef<React.ElementRef<typeof VncScreen>>(null);

  return (
    <VncScreen
      url={vncUrl}
      scaleViewport
      debug
      ref={vncScreenRef}
    />
  )
}

You can access the rfb object using vncScreenRef.current?.rfb. If the rfb object isn't set, it's value is null.