fix(pdf): flatten color-mix() values before html2canvas render
html2canvas can't parse CSS color-mix() function. Before rendering, walk the DOM tree and inline computed styles (with color-mix resolved by the browser) as inline styles. Restore originals after save.
This commit is contained in:
1 parent
7170b8a5fa
commit
7df7734eeb
2 files changed
+68
-2
No files matched your search
+34
-1
@@ -1034,6 +1034,35 @@
|
||||
photoReady = Promise.resolve(null);
|
||||
}
|
||||
|
||||
function flattenColors(el) {
|
||||
var s = getComputedStyle(el);
|
||||
var props = ['color','background-color','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','background'];
|
||||
var originals = {};
|
||||
props.forEach(function(p) {
|
||||
var v = s.getPropertyValue(p);
|
||||
if (v && v.indexOf('color-mix') !== -1) {
|
||||
originals[p] = el.style.getPropertyValue(p);
|
||||
el.style.setProperty(p, v);
|
||||
}
|
||||
});
|
||||
var children = el.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
flattenColors(children[i]);
|
||||
}
|
||||
return originals;
|
||||
}
|
||||
|
||||
function restoreColors(el, originals) {
|
||||
Object.keys(originals).forEach(function(p) {
|
||||
if (originals[p]) el.style.setProperty(p, originals[p]);
|
||||
else el.style.removeProperty(p);
|
||||
});
|
||||
var children = el.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
restoreColors(children[i], originals);
|
||||
}
|
||||
}
|
||||
|
||||
photoReady.then(function (dataUrl) {
|
||||
console.log('[PDF] step 1: photo ready, dataUrl:', dataUrl ? 'yes (' + dataUrl.length + ' chars)' : 'null');
|
||||
if (dataUrl && photo) photo.setAttribute('src', dataUrl);
|
||||
@@ -1046,6 +1075,8 @@
|
||||
})
|
||||
.then(function () {
|
||||
console.log('[PDF] step 4: html2pdf loaded, type:', typeof html2pdf);
|
||||
console.log('[PDF] step 4: flattening color-mix() values...');
|
||||
var snapshot = flattenColors(doc);
|
||||
console.log('[PDF] step 4: starting generation...');
|
||||
return html2pdf().from(doc).set({
|
||||
margin: 10,
|
||||
@@ -1053,7 +1084,9 @@
|
||||
image: { type: 'jpeg', quality: 0.95 },
|
||||
html2canvas: { scale: 2, useCORS: true, backgroundColor: '#fff' },
|
||||
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
|
||||
}).save();
|
||||
}).save().then(function() {
|
||||
restoreColors(doc, snapshot);
|
||||
});
|
||||
})
|
||||
.then(function (result) {
|
||||
console.log('[PDF] step 5: generation COMPLETE, result:', result);
|
||||
|
||||
+34
-1
@@ -903,6 +903,35 @@
|
||||
photoReady = Promise.resolve(null);
|
||||
}
|
||||
|
||||
function flattenColors(el) {
|
||||
var s = getComputedStyle(el);
|
||||
var props = ['color','background-color','border-color','border-top-color','border-bottom-color','border-left-color','border-right-color','box-shadow','background'];
|
||||
var originals = {};
|
||||
props.forEach(function(p) {
|
||||
var v = s.getPropertyValue(p);
|
||||
if (v && v.indexOf('color-mix') !== -1) {
|
||||
originals[p] = el.style.getPropertyValue(p);
|
||||
el.style.setProperty(p, v);
|
||||
}
|
||||
});
|
||||
var children = el.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
flattenColors(children[i]);
|
||||
}
|
||||
return originals;
|
||||
}
|
||||
|
||||
function restoreColors(el, originals) {
|
||||
Object.keys(originals).forEach(function(p) {
|
||||
if (originals[p]) el.style.setProperty(p, originals[p]);
|
||||
else el.style.removeProperty(p);
|
||||
});
|
||||
var children = el.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
restoreColors(children[i], originals);
|
||||
}
|
||||
}
|
||||
|
||||
photoReady.then(function (dataUrl) {
|
||||
console.log('[PDF] step 1: photo ready, dataUrl:', dataUrl ? 'yes (' + dataUrl.length + ' chars)' : 'null');
|
||||
if (dataUrl && photo) photo.setAttribute('src', dataUrl);
|
||||
@@ -915,6 +944,8 @@
|
||||
})
|
||||
.then(function () {
|
||||
console.log('[PDF] step 4: html2pdf loaded, type:', typeof html2pdf);
|
||||
console.log('[PDF] step 4: flattening color-mix() values...');
|
||||
var snapshot = flattenColors(doc);
|
||||
console.log('[PDF] step 4: starting generation...');
|
||||
return html2pdf().from(doc).set({
|
||||
margin: 10,
|
||||
@@ -922,7 +953,9 @@
|
||||
image: { type: 'jpeg', quality: 0.95 },
|
||||
html2canvas: { scale: 2, useCORS: true, backgroundColor: '#fff' },
|
||||
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' }
|
||||
}).save();
|
||||
}).save().then(function() {
|
||||
restoreColors(doc, snapshot);
|
||||
});
|
||||
})
|
||||
.then(function (result) {
|
||||
console.log('[PDF] step 5: generation COMPLETE, result:', result);
|
||||
|
||||
Reference in new issue
Block a user