Open joshembling opened 2 years ago
Hiya! This issue has gone quiet. Spooky quiet. 👻 We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 20 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not-stale" to keep this issue open! As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.
Thanks for being a part of the Antv community! 💪💯
Hey @joshembling -- I've recently been experiencing the exact same issue. I thought it might be because I wasn't setting certain CSS properties on my child elements (width, height, position, etc.), but I've experimented a ton with those with no luck. Very strange that it's on mobile only (cannot reproduce simulating mobile screen size on my desktop either). Were you able to find any fixes or workarounds?
Hey @joshembling -- I've recently been experiencing the exact same issue. I thought it might be because I wasn't setting certain CSS properties on my child elements (width, height, position, etc.), but I've experimented a ton with those with no luck. Very strange that it's on mobile only (cannot reproduce simulating mobile screen size on my desktop either). Were you able to find any fixes or workarounds?
No I haven't found a fix, unfortunately. There doesn't seem to be much support for this package anymore either so I can't see it being fixed anytime soon.
It's the same this issue on domtoimage
https://github.com/tsayen/dom-to-image/issues/343
I had to call it twice to make it work on iPhones
So i was able to solve this using html2canvas this one
here's what I'm doing
let node = document.getElementById(`someid`);
html2canvas(node, {
useCORS: true, //useCORS if there's one or more images using external URL
}).then(function (canvas) {
const dataURL = canvas.toDataURL();
download(dataURL, 'image.png'); // download here using downloadJs
})
Hope this helps
I've done some trial-and-error testing on this today and noticed that rendering in Safari (16.2, 18614.3.7.1.5, in my case) seems to fail when there are any interactions with the canvas. I'm attempting to render a Chart.js 3.9.1 canvas element and noticed it's blank for the first render AND if any events were triggered immediately prior (hover, click, drag, etc).
I'm still not entirely sure why it works, but my solution was:
async function downloadChart() {
// 1. Disable all sources of interactivity
// TODO: Experiment with https://www.chartjs.org/docs/3.9.1/configuration/animations.html#disabling-animation
chart.options = {
...chart.options,
events: [], // Disable all event listeners
plugins: { ... }, // Disable plugins, e.g. { enabled: false }
};
chart.update('none'); // Update the chart with 'none' animation
...
// 2. Waits and renders
// Chart.js default animation duration is 400ms
await new Promise((resolve) => {
setTimeout(resolve, 500); // Wait for any existing animations/events to resolve
});
await toBlob(domToImgContainer); // First render, discard. Safari bug?
chart.update('none'); // Update the chart with 'none' animation. For some reason this helps prevent in-progress animations causing a failure.
await toBlob(domToImgContainer); // Second render, discard. Does this fill buffer 1 of 2?
await new Promise((resolve) => {
setTimeout(resolve, 500); // Wait for any new animations/events to resolve
});
const blob = await toBlob(domToImgContainer); // Final render, export
if (!blob) return;
...
// 3. Open or download the result
}
My best guess is that interactivity flushes the drawing buffer in Safari, or something similar. I read in another Github issue that preserveDrawingBuffer: true
solved their blank canvas issues:
...and after reading https://stackoverflow.com/a/27747016/8680333, I have a hunch that it could help, but haven't had time to test it. This might also explain why my solution above is working for me, since I'd be filling both buffers before Safari gets to flush (invalidate?) either of them.
Hope this helps someone! Curious to hear if anyone has success or finds out more information about this behaviour.
I've done some trial-and-error testing on this today and noticed that rendering in Safari (16.2, 18614.3.7.1.5, in my case) seems to fail when there are any interactions with the canvas. I'm attempting to render a Chart.js 3.9.1 canvas element and noticed it's blank for the first render AND if any events were triggered immediately prior (hover, click, drag, etc).
I'm still not entirely sure why it works, but my solution was:
async function downloadChart() { // 1. Disable all sources of interactivity // TODO: Experiment with https://www.chartjs.org/docs/3.9.1/configuration/animations.html#disabling-animation chart.options = { ...chart.options, events: [], // Disable all event listeners plugins: { ... }, // Disable plugins, e.g. { enabled: false } }; chart.update('none'); // Update the chart with 'none' animation ... // 2. Waits and renders // Chart.js default animation duration is 400ms await new Promise((resolve) => { setTimeout(resolve, 500); // Wait for any existing animations/events to resolve }); await toBlob(domToImgContainer); // First render, discard. Safari bug? chart.update('none'); // Update the chart with 'none' animation. For some reason this helps prevent in-progress animations causing a failure. await toBlob(domToImgContainer); // Second render, discard. Does this fill buffer 1 of 2? await new Promise((resolve) => { setTimeout(resolve, 500); // Wait for any new animations/events to resolve }); const blob = await toBlob(domToImgContainer); // Final render, export if (!blob) return; ... // 3. Open or download the result }
My best guess is that interactivity flushes the drawing buffer in Safari, or something similar. I read in another Github issue that
preserveDrawingBuffer: true
solved their blank canvas issues:
- Canvas element doesnt appear in the image #299
- html2canvas not work when the html contains a canvas element niklasvh/html2canvas#1311
...and after reading https://stackoverflow.com/a/27747016/8680333, I have a hunch that it could help, but haven't had time to test it. This might also explain why my solution above is working for me, since I'd be filling both buffers before Safari gets to flush (invalidate?) either of them.
Hope this helps someone! Curious to hear if anyone has success or finds out more information about this behaviour.
Thanks,it works
There is an issue I have surfaced on mobile devices - particularly using Safari where the first render of the image is completely broken, formatting issues, font issues etc.
On refresh these are resolved and the image is correct.
Here is my code: