Open getCryptoAddress opened 11 months ago
👋 @getCryptoAddress
Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. To help make it easier for us to investigate your issue, please follow the contributing guidelines.
We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.
Hi @getCryptoAddress, have you been able to move past this yet? I am using the html-to-image V1.11.11 and I experience the same issue as you. The image is only visible on the third download, and I don't know the cause of that.
Having the same issues here... I can reproduce this issue even on v1.11.0
Same here
This is an iOS issue unfortunately https://bugs.webkit.org/show_bug.cgi?id=219770
I partially resolved this adding a delay of 250ms after the creation of the svg and before drawing to the canvas. 250 is just a magic number that I know in most of times image has been loaded. For images of high size and if you haven’t loaded it into the dom probably it’s not enough
toCanvas()
Same here
Finally found a reliable solution: the modern-screenshot library (a fork of html-to-image). Completely fixed the problem for me!
H/t @qq15725
beware that this solution seems still clone image like everyone else (https://github.com/qq15725/modern-screenshot/blob/main/src/clone-image.ts), so probably it is fixed by implicitly being asynchronous and adding some delays, since it uses worker (I don't know if it's a good idea, since the major computation only concerns the dom which is not available in the worker side)
default drawImageInterval
is 100
https://github.com/qq15725/modern-screenshot/blob/0973c6c302e91b3d49921876f5c021b5ddda833a/src/create-context.ts#L53
He explained the difference here:
https://github.com/bubkoo/html-to-image/issues/361#issuecomment-1413526381
What do you think?
Delaying the final canvas rendering by a fixed timeout can be the solution for most of cases.
It’s valid in my opinion since there isn’t any way to know if safari will render the image.
What I don’t like it’s this magic number which doesn’t guarantee it works every time 😅, but probably it’s the best it can be done at the moment.
Anyway this solution seems delaying n seconds for each image present in the html structure, so if you have like 10 images, it will be delayed for 1000ms~ (10 * 100ms) 🤔 but I don’t have the full understand of the code so I may be wrong.
Another important thing: what’s the device we are using to render that image, and how much mb is it?
Assuming we are trying to render an image around 0-1mb, most of iOS and macOS device can render it with a timeout of 100. If the image gets bigger, we surely need to increment this timeout. But I think there are others factors like device speed (what if energy save mode is on?)
currently I think the most safest way of rendering an image without having issues is using puppeteer/playwright with chrome under the hood 🤷🏻♂️ doing this will also allows to export the same image for all sort of devices (e.g. safari still can’t handle box-shadow), but it may be expensive
10 image ref = 10 (canvasContext2d.drawImage('data:image/svg+xml,html-to-svg-data') and await 100ms)
I don't know how it works, but it works 😄
Can confirm that it's working beautifully! Thanks again @qq15725 :)
(For me, it's working on photos >5MB... will post an update if it stops working but for now I think we're good to go)
10 image ref = 10 (canvasContext2d.drawImage('data:image/svg+xml,html-to-svg-data') and await 100ms)
I don't know how it works, but it works 😄
Thanks, work for me too.
https://github.com/bubkoo/html-to-image/blob/master/src/index.ts#L58
if add
await new Promise((resolve) => setTimeout(resolve, 1));
Safari will render always
UPDATED
ok, I created PR https://github.com/bubkoo/html-to-image/pull/423
UPDATED I'm wrong. I reproduced bug again. Not 8 times from 10, but 3 times from 10. It is better, but not solution
Vue code example
<script lang="ts" setup>
// ....
// get svg from "html-to-image" for html
canvasSvgElement.value = decodeURIComponent(await toSvg(targetElement));
// wait vue render
await nextTick();
// get images into svg
const images = canvasImageWrapperElement.value?.querySelectorAll("img");
// wait all images
if (images) {
await Promise.all(
[...images].map((img) => {
return new Promise((resolve, reject) => {
if (img.complete) {
resolve(null);
} else {
img.onload = resolve;
img.onerror = reject;
}
});
})
);
console.log("images loaded"); // <--- it's true for safari
How I understand, safari needs time to render, not just load https://github.com/bubkoo/html-to-image/blob/master/src/embed-images.ts#L57 This is just a hypothesis, anyway the code above works in safari
Expected Behavior
Images always render
Current Behavior
Images are sometimes skipped via iOS
For example: The background appeared only for the 3rd time![ezgif com-optimize](https://github.com/bubkoo/html-to-image/assets/125769450/b44f7dd5-2078-45d9-b18f-ef347a216b3c)
Possible Solution
Steps To Reproduce
Error Message & Stack Trace
no errors
Additional Context
Code:
Your Environment