Destroying and reinstancing patch after deleting canvas dom


This is more of an embedding issue i’m currently having with cables.
Currently its done with React but i can replicate the same issue with the default exported files structure.

The simplified flow of what i’m trying to do is :

  1. Load cables patch with new CABLES.Patch({....}) with ‘#glcanvas1’ canvas dom element (works fine)
  2. Delete glcanvas1 dom element
  3. Add new canvas dom (#glcanvas2) element dynamically,
  4. Reload cables patch into #glcanvas2 with new CABLES.Patch({....})

After step 4, The new #glcanvas2 patch loads but 1 imagecompose texture dont show and i’m getting errors like so

WebGL: INVALID_OPERATION: bindTexture: object does not belong to this context
index.html:1 [.WebGL-0x7fc69e890400]RENDER WARNING: there is no texture bound to the unit 0

I googled and it seems like its something related to the sharing of contexts / textures (?)

Wondering how do i completely ‘destroy’ or delete the last instance patch instance.

I’m on chrome 81 / FF 75

You can see the test page and try clicking the buttons in the top right once in order from 1st to last to see that the ‘plus sign’ texture doesnt show in the 2nd instance of the patch with the above mentioned errors appearing in console :

You can see the patch here but i dont think its anything to do with it. (Click start on the sidebar)

Many thanks

thanks for reporting.
i have a suspicion. i will change this in the core and then lets test this after the next update.

Thanks for the status update.

for now I solved it in a bit of a dirty way by redeclaring the exported patch again on page mount.

Any news on this? I have successfully embedded a patch within a react application nicely but am unable to stop/destroy the patch when the user navigates away to another page.

For reference, my code so far:

  const [loaded, setLoaded] = useState(false);
  const patch = useRef<any | null>();
  const canvas = useRef<HTMLCanvasElement | null>(null);

  const patchPath = `/patches/${block.patchId}/`;

  useEffect(() => {
    let timeout: number;
    const check = () => {
      if (window && window.CABLES) {
      } else {
        timeout = setTimeout(check, 100);
    return () => {
      if (timeout) clearTimeout(timeout);
  }, []);

  useEffect(() => {
    if (loaded && window.CABLES) {
      patch.current = new window.CABLES.Patch({
        patch: window.CABLES.exportedPatch,
        prefixAssetPath: patchPath,
        doRequestAnimation: true,
        clearCanvasColor: false,
        clearCanvasDepth: false,
        glCanvas: canvas.current,
        glCanvasResizeToWindow: false,

      return () => {
        patch.current = null;
        window.CABLES = null;
  }, [loaded, canvas, patchPath]);