niklasvh / html2canvas

Screenshots with JavaScript
https://html2canvas.hertzen.com/
MIT License
30.62k stars 4.81k forks source link

Complex SVG not rendered #2350

Open alitaker opened 4 years ago

alitaker commented 4 years ago

Using v1.0.0-rc.7, there is a problem when running on complex SVG charts.

https://jsfiddle.net/marcoesplores/ko2u3t19/19/

Specifications:

juliendesprez commented 4 years ago

I got the exact same issue with a sap UI5 VizFrame Chart

Azbesciak commented 4 years ago

Same for me - leaflet paths. EDIT: I noticed that the problem might be somewhere else, at least in leaflet example real image image

screenshot image

I tried to copy/add styles from the original document and adequate elements to copies but did not help. Any suggestions? In the rc6 it works fine. I noticed that at rc6 style for these SVGs were the same as in original, whereas in rc7 it is much more complex: rc6:

transform: translate3d(-134px, -95px, 0px)

rc7:

transform: matrix(1, 0, 0, 1, -134, -95);
-webkit-writing-mode: horizontal-tb;
-webkit-user-modify: read-only;
-webkit-user-drag: auto;
-webkit-text-stroke: 0px rgba(0, 0, 0, 0.87);
-webkit-text-security: none;
-webkit-text-orientation: vertical-right;
-webkit-text-fill-color: rgba(0, 0, 0, 0.87);
-webkit-text-emphasis: none rgba(0, 0, 0, 0.87);
-webkit-text-emphasis-position: over right;
-webkit-text-decorations-in-effect: none;
-webkit-text-combine: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-rtl-ordering: logical;
-webkit-print-color-adjust: economy;
-webkit-mask: none 0% 0% / auto repeat border-box border-box;
-webkit-mask-composite: source-over;
-webkit-mask-box-image-width: initial;
-webkit-mask-box-image-source: none;
-webkit-mask-box-image-slice: initial;
-webkit-mask-box-image-repeat: initial;
-webkit-mask-box-image-outset: initial;
-webkit-locale: "en";
-webkit-line-break: auto;
-webkit-hyphenate-character: auto;
-webkit-highlight: none;
-webkit-font-smoothing: auto;
-webkit-box-pack: start;
-webkit-box-orient: horizontal;
-webkit-box-ordinal-group: 1;
-webkit-box-flex: 0;
-webkit-box-direction: normal;
-webkit-box-decoration-break: slice;
-webkit-box-align: stretch;
border-spacing: 0px;
-webkit-border-image: none;
-webkit-app-region: none;
zoom: 1;
z-index: 200;
y: 0px;
x: 0px;
writing-mode: horizontal-tb;
word-spacing: 0px;
word-break: normal;
will-change: auto;
width: 1603px;
widows: 2;
white-space: normal;
visibility: visible;
vertical-align: baseline;
vector-effect: none;
user-select: auto;
unicode-bidi: normal;
transition: all 0s ease 0s;
transform-style: flat;
transform-origin: 0px 0px;
touch-action: auto;
top: 0px;
text-underline-position: auto;
text-transform: none;
text-size-adjust: auto;
text-shadow: none;
text-rendering: auto;
text-overflow: clip;
text-indent: 0px;
text-decoration: none solid rgba(0, 0, 0, 0.87);
text-decoration-skip-ink: auto;
text-anchor: start;
text-align-last: auto;
text-align: start;
table-layout: auto;
tab-size: 8;
stroke-width: 1px;
stroke-opacity: 1;
stroke-miterlimit: 4;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-dashoffset: 0px;
stroke-dasharray: none;
stroke: none;
stop-opacity: 1;
stop-color: rgb(0, 0, 0);
speak: normal;
shape-rendering: auto;
shape-outside: none;
shape-margin: 0px;
shape-image-threshold: 0;
scroll-padding-inline: auto;
scroll-padding-block: auto;
scroll-margin-inline: 0px;
scroll-margin-block: 0px;
scroll-behavior: auto;
ry: auto;
rx: auto;
ruby-position: over;
gap: normal;
right: -1603px;
resize: none;
r: 0px;
position: absolute;
pointer-events: none;
perspective-origin: 801.5px 568px;
perspective: none;
paint-order: normal;
padding: 0px;
padding-inline-start: 0px;
padding-inline-end: 0px;
padding-block-start: 0px;
padding-block-end: 0px;
overscroll-behavior-inline: auto;
overscroll-behavior-block: auto;
overflow: hidden;
overflow-wrap: normal;
overflow-anchor: auto;
outline: rgba(0, 0, 0, 0.87) none 0px;
outline-offset: 0px;
orphans: 2;
order: 0;
opacity: 1;
offset: none 0px auto 0deg;
object-position: 50% 50%;
object-fit: fill;
mix-blend-mode: normal;
min-width: 0px;
min-inline-size: 0px;
min-height: 0px;
min-block-size: 0px;
max-width: none;
max-inline-size: none;
max-height: none;
max-block-size: none;
mask-type: luminance;
marker: none;
margin: 0px;
margin-inline-start: 0px;
margin-inline-end: 0px;
margin-block-start: 0px;
margin-block-end: 0px;
list-style: outside none disc;
font: 400 12px / 18px "Helvetica Neue", Arial, Helvetica, sans-serif;
line-break: auto;
lighting-color: rgb(255, 255, 255);
letter-spacing: normal;
left: 0px;
place-self: auto;
place-items: normal;
place-content: normal;
isolation: auto;
inline-size: 1603px;
image-rendering: auto;
image-orientation: from-image;
hyphens: manual;
height: 1136px;
grid-template-rows: none;
grid-template-columns: none;
grid-template-areas: none;
grid-area: auto / auto / auto / auto;
grid-auto-rows: auto;
grid-auto-flow: row;
grid-auto-columns: auto;
font-optical-sizing: auto;
font-kerning: auto;
flood-opacity: 1;
flood-color: rgb(0, 0, 0);
float: none;
flex-flow: row nowrap;
flex: 0 1 auto;
filter: none;
fill-rule: nonzero;
fill-opacity: 1;
fill: rgb(0, 0, 0);
empty-cells: show;
dominant-baseline: auto;
display: block;
direction: ltr;
d: none;
cy: 0px;
cx: 0px;
cursor: grab;
columns: auto auto;
column-span: none;
column-rule: 0px none rgba(0, 0, 0, 0.87);
color-rendering: auto;
color-interpolation-filters: linearrgb;
color-interpolation: srgb;
color: rgba(0, 0, 0, 0.87);
clip-rule: nonzero;
clip-path: none;
clip: auto;
clear: none;
caret-color: rgba(0, 0, 0, 0.87);
caption-side: top;
buffered-rendering: auto;
break-inside: auto;
break-before: auto;
break-after: auto;
box-sizing: border-box;
box-shadow: none;
bottom: -1136px;
border: 0px none rgba(0, 0, 0, 0.87);
border-radius: 0px;
border-inline-start: 0px none rgba(0, 0, 0, 0.87);
border-inline-end: 0px none rgba(0, 0, 0, 0.87);
border-collapse: separate;
border-block-start: 0px none rgba(0, 0, 0, 0.87);
border-block-end: 0px none rgba(0, 0, 0, 0.87);
block-size: 1136px;
baseline-shift: 0px;
background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);
background-blend-mode: normal;
backface-visibility: visible;
backdrop-filter: none;
appearance: none;
animation: 0s ease 0s 1 normal none running none;
alignment-baseline: auto;

I solved this issue with adding additional div between the svg and the parent element, removing style from copied svg and coping the original one to the div:

const original = document.body.querySelectorAll("svg.leaflet-zoom-animated");
const copy = e.body.querySelectorAll("svg.leaflet-zoom-animated");
copy.forEach((copyEle, i) => {
     const attribute = original.item(i).getAttribute("style");
     const parentElement = copyEle.parentElement;
     parentElement.removeChild(copyEle);
     const temp = document.createElement("div");
     temp.appendChild(copyEle);
     parentElement.appendChild(temp);
     temp.setAttribute("style", attribute);
     copyEle.removeAttribute("style");
})