locked
How to know when img has completely loaded RRS feed

  • Question

  • User-1800146227 posted

    In my Blazor app component I change the src attribute of an img element. In the onLoad event handler I then use some Javascript to get the img naturalWidth and naturalHeight. 

    The problem is that when I check it in the onLoad event handler the dimensions are always zero. If I check the img dimensions after another app event has occurred, button press for example, then the img dimensions are correctly reported. I am calling StateHasChange() in my component after changing the src attribute.

    What can I do to be informed in my component that the img has completely loaded and the naturalWidth and naturalHeight attibutes are correct?

    Friday, September 4, 2020 5:35 PM

All replies

  • User-474980206 posted

    When the onload event of an <img> fires the image has a size unless, it’s depend on other markup or resize events. You could load into a JavaScript image, then at the load you will have the real size. Then just set the dom img script to the image arc. This is typical JavaScript pre cache trick.

    Saturday, September 5, 2020 12:22 AM
  • User-1800146227 posted

    I created the following jscript function that I call with the image url. I based this on the following article. https://docs.microsoft.com/en-us/aspnet/core/blazor/call-dotnet-from-javascript?view=aspnetcore-3.1

    JScript

    SetImageAsync: function (url) {
    var image = new Image();

    image.addEventListener("load", function () {
    DotNet.invokeMethodAsync('MyAssembly', 'ReturnImgSizeAsync')
    .then(data => {
    data.push(image.naturalWidth); data.push(image.naturalHeight);
    console.log(image.naturalWidth.toString());
    console.log(image.naturalHeight.toString());
    });

    });

    image.src = url;
    return url;
    }

    The problem is that in the C# callback, ReturnSizeAsync, I'm not seeing any changes to the int[] parameter. It just has the same values as what it was initialized with. From the article example I'm expecting two more values pushed onto the array.

    C#

    [JSInvokable]

    public static async Task<int[]> ReturnImgSizeAsync()
    {
        var r = await Task.FromResult(new int[] { 98, 99 });
        return r;
    }

    The jscript method is called like this

    js.InvokeAsync<string>("functions.SetImageAsync", ImageURL);

    Saturday, September 5, 2020 7:04 PM
  • User-474980206 posted

    Your JavaScript is modifying the return data from the blazor code. As this a a copy, not the original array, changes made in JavaScript have no changes on the blazor data. The is load data function should pass the size to the blazor method, not modify the response data. WASM has its own memory, it can not access js memory nor can js directly access WASM memory.

    note. WASM implements a sdk to pass data between WASM and JavaScript 

    https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API

    Sunday, September 6, 2020 3:51 PM
  • User-1800146227 posted

    I'm just using the example code from Microsoft as a template to start, assuming it should work. 

    I couldn't find any documentation for DotNet.InvokeMethodAsync, so I followed the JSRuntimeExtensions examples for calling InvokeAsync and tacked on the return values as a parameter to the callback. That seems to be working now.

    Monday, September 7, 2020 3:05 AM