15 October 2024

How to create a screenshot with a Blazor app

If like me you have an application and you want to get feedback from your customers, then this article may interest you. When I logged into my Office 365 online account, I saw that sometimes Microsoft opened a small tab in the bottom right-hand corner of the screen, allowing us to give our opinion and possibly add a screenshot to show a problem for example:
Avis sur office.com

Problème et solution

Since the rendering of our web application is client-side, it’s obvious that we’ll be looking at what javascript offers. It was immediately canvas.toDataURL() that got my full attention. Now the problem is that my entire app would have to be in a canvas. 😣. Luckily, Niklas von Hertzen has developed a library that saves me! http://html2canvas.hertzen.com/. Its library is really great, by default you tell it an element of your DOM that you want to capture and it returns a Canvas!

In my case I want the full screen of my Blazor application. Well super easy because our application is in a <div> with the identifier app :


From there, the rest will be very simple and I have several options available to me:

  • Paste the returned canvas into an existing Canvas. This way the user will see what they are sending me
  • Fetch the data string from the Canvas to store in the message
  • .

  • Eventually upload this capture to a .PNG file.

 

Paste the canvas

function put2Canvas(canvasDestination) {
html2canvas(document.querySelector("#app")).then(canvas => {

var canvasID = document.getElementById(canvasDestination);
//get the destination context
var ctx = canvasID.getContext('2d');
//reduce the image
ctx.scale(0.5, 0.5);
ctx.width = window.innerWidth / 3;
ctx.height = window.innerHeight / 3;
ctx.drawImage(canvas, 0, 0);
});
}

Note that here I could pass directly html2canvas a scale configuration to get a “custom” canvas:

//...
html2canvas(document.querySelector("#app"), {
scale: 0.5
} ).then(canvas => {
//...

On the C# side, nothing fancy, I have a div on the HTML view and a lavascript call via the interop, passing the id of my DIV :

private async Task putToCanvas()
{
await js.InvokeVoidAsync("put2Canvas", "myCanvas");
}

My problem with the javascript response time

🤔

There is a very small delay between the call and the response of the javascript function that caused me problems. Thus for the function allowing me to recover on the C# side the DATA string of my image the code arrived directly to the string 38 without waiting for the return of the function :

await

So I used Promise to have it handle my function asynchronously and so the C# code had to wait for the resolve to continue

new promise

Find my sources on this Github repository : https://github.com/tossnet/Blazor-Screenshot

Leave a Reply