Failed to execute 'drawImage' on 'CanvasRenderingContext2D

when i try to serialize the scene in json doing scene.toJSON(), the console send me this error:Failed to execute ‘drawImage’ on 'CanvasRenderingContext2D.

    function downloadJson(sceneJSON) {
        var dataStr = "data:text/json;charset=utf-8," + 
        encodeURIComponent(JSON.stringify(sceneJSON));
        var downloadAnchorNode = document.createElement('a');
        downloadAnchorNode.setAttribute("href",     dataStr);
        downloadAnchorNode.setAttribute("download", "world.json");
        document.body.appendChild(downloadAnchorNode);
        downloadAnchorNode.click();
        downloadAnchorNode.remove();
  }  
  const sceneJSON = scene.toJSON();
  downloadJson(sceneJSON)

this is how i call a function to download the scene in json

and this is the complete error:
Uncaught TypeError: Failed to execute ‘drawImage’ on ‘CanvasRenderingContext2D’: The provided value is not of type ‘(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)’

Are you applying data textures to materials in your scene? Or maybe using render targets as a data source for textures?

no, i apply texture to materials using map:texture

Can you please show what you are doing?

The downloadJson() function from your first post is not relevant for this issue. The actual problem is that your texture can’t be serialized for some reasons.

in my project i implemented to choose if you want to use a custom texture or not

if (customTexture.value) {

    var texture = loader.load(URL.createObjectURL(customTexture.files[0]), render);

    for(let i = 0; i < 32; i++) {

      document.querySelectorAll("#ui input[type=radio] + label")[i].style.backgroundImage = `url(${URL.createObjectURL(customTexture.files[0])})`

    }

  }else {

    var texture = loader.load('/Assets/flourish-cc-by-nc-sa.png', render);

  }

  texture.magFilter = THREE.NearestFilter;

  texture.minFilter = THREE.NearestFilter;

this is the code to check this

const material = new THREE.MeshPhongMaterial({

    map: texture,

  });

  material.needsUpdate = true

and this is the material

AFAICT, your code looks actually good. Any chances to share a live example that demonstrates the runtime error. I want to debug why your code fails at this line:

i put all in this gitHub repostory

1 Like

The error happens because you have THREE.Water in your scene. This object type internally uses a render target for rendering its reflections. Unfortunately, the engine is not able yet to handle render targets correctly in context of serialization/deserialization. And even when this is fixed, THREE.Water would need a custom toJSON() method.

As a workaround, you have to exclude THREE.Water from your scene when saving it to JSON.

okok thanks, you have been very helpful

1 Like