html2canvas-pro 2.4.0 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html2canvas-pro.cjs +49 -13
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +49 -13
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +49 -13
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +4 -4
- package/dist/lib/dom/replaced-elements/svg-element-container.js +40 -2
- package/dist/lib/render/canvas/background-renderer.js +20 -9
- package/dist/types/dom/replaced-elements/svg-element-container.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,8 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SVGElementContainer = void 0;
|
|
3
|
+
exports.SVGElementContainer = exports.serializeWithoutBoxOffsets = void 0;
|
|
4
4
|
const element_container_1 = require("../element-container");
|
|
5
5
|
const bounds_1 = require("../../css/layout/bounds");
|
|
6
|
+
const BOX_OFFSET_PROPERTIES = [
|
|
7
|
+
'position',
|
|
8
|
+
'inset',
|
|
9
|
+
'top',
|
|
10
|
+
'right',
|
|
11
|
+
'bottom',
|
|
12
|
+
'left',
|
|
13
|
+
'inset-inline',
|
|
14
|
+
'inset-inline-start',
|
|
15
|
+
'inset-inline-end',
|
|
16
|
+
'inset-block',
|
|
17
|
+
'inset-block-start',
|
|
18
|
+
'inset-block-end',
|
|
19
|
+
'margin',
|
|
20
|
+
'margin-top',
|
|
21
|
+
'margin-right',
|
|
22
|
+
'margin-bottom',
|
|
23
|
+
'margin-left',
|
|
24
|
+
'margin-inline',
|
|
25
|
+
'margin-inline-start',
|
|
26
|
+
'margin-inline-end',
|
|
27
|
+
'margin-block',
|
|
28
|
+
'margin-block-start',
|
|
29
|
+
'margin-block-end'
|
|
30
|
+
];
|
|
31
|
+
const serializeWithoutBoxOffsets = (serializer, img) => {
|
|
32
|
+
const style = img.getAttribute('style');
|
|
33
|
+
BOX_OFFSET_PROPERTIES.forEach((property) => img.style.removeProperty(property));
|
|
34
|
+
const serialized = serializer.serializeToString(img);
|
|
35
|
+
if (style === null) {
|
|
36
|
+
img.removeAttribute('style');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
img.setAttribute('style', style);
|
|
40
|
+
}
|
|
41
|
+
return serialized;
|
|
42
|
+
};
|
|
43
|
+
exports.serializeWithoutBoxOffsets = serializeWithoutBoxOffsets;
|
|
6
44
|
class SVGElementContainer extends element_container_1.ElementContainer {
|
|
7
45
|
constructor(context, img) {
|
|
8
46
|
super(context, img);
|
|
@@ -10,7 +48,7 @@ class SVGElementContainer extends element_container_1.ElementContainer {
|
|
|
10
48
|
const bounds = (0, bounds_1.parseBounds)(context, img);
|
|
11
49
|
img.setAttribute('width', `${bounds.width}px`);
|
|
12
50
|
img.setAttribute('height', `${bounds.height}px`);
|
|
13
|
-
this.svg = `data:image/svg+xml,${encodeURIComponent(
|
|
51
|
+
this.svg = `data:image/svg+xml,${encodeURIComponent((0, exports.serializeWithoutBoxOffsets)(s, img))}`;
|
|
14
52
|
this.intrinsicWidth = img.width.baseVal.value;
|
|
15
53
|
this.intrinsicHeight = img.height.baseVal.value;
|
|
16
54
|
this.context.cache.addImage(this.svg);
|
|
@@ -226,22 +226,27 @@ class BackgroundRenderer {
|
|
|
226
226
|
if (rx > 0 && ry > 0) {
|
|
227
227
|
// Cache key for radial gradient: position + radii + colour stops
|
|
228
228
|
const cacheKey = `rg|${Math.round(x)}x${Math.round(y)}|${Math.round(rx)}x${Math.round(ry)}|${JSON.stringify(backgroundImage.stops)}`;
|
|
229
|
+
// The ellipse is rasterised as a circle of radius rx that is scaled vertically by
|
|
230
|
+
// ry / rx, so the offscreen canvas must be the ellipse's full bounding box
|
|
231
|
+
// (2rx × 2ry). Sizing it as a max(rx, ry) square stretched the gradient past the
|
|
232
|
+
// canvas edge whenever ry > rx, clipping the ellipse before its last stop and
|
|
233
|
+
// leaving a hard horizontal seam on tall elements.
|
|
234
|
+
const stops = (0, gradient_1.processColorStops)(backgroundImage.stops, rx * 2);
|
|
235
|
+
const lastStop = stops[stops.length - 1];
|
|
229
236
|
let pattern = this.patternCache.get(cacheKey);
|
|
230
237
|
if (!pattern) {
|
|
231
238
|
const ownerDocument = this.canvas.ownerDocument ?? document;
|
|
232
|
-
const size = Math.ceil(Math.max(rx, ry) * 2);
|
|
233
239
|
const offscreen = ownerDocument.createElement('canvas');
|
|
234
|
-
offscreen.width =
|
|
235
|
-
offscreen.height =
|
|
240
|
+
offscreen.width = Math.ceil(rx * 2);
|
|
241
|
+
offscreen.height = Math.ceil(ry * 2);
|
|
236
242
|
const offCtx = offscreen.getContext('2d');
|
|
237
243
|
if (offCtx) {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
(0, gradient_1.processColorStops)(backgroundImage.stops, offRadius * 2).forEach((s) => gradient.addColorStop(s.stop, (0, color_utilities_1.asString)(s.color)));
|
|
244
|
+
const gradient = offCtx.createRadialGradient(rx, rx, 0, rx, rx, rx);
|
|
245
|
+
stops.forEach((s) => gradient.addColorStop(s.stop, (0, color_utilities_1.asString)(s.color)));
|
|
241
246
|
offCtx.fillStyle = gradient;
|
|
242
247
|
if (rx !== ry)
|
|
243
248
|
offCtx.scale(1, ry / rx);
|
|
244
|
-
offCtx.fillRect(0, 0,
|
|
249
|
+
offCtx.fillRect(0, 0, rx * 2, rx * 2);
|
|
245
250
|
pattern = this.ctx.createPattern(offscreen, 'no-repeat');
|
|
246
251
|
this.patternCache.set(cacheKey, pattern);
|
|
247
252
|
}
|
|
@@ -250,9 +255,15 @@ class BackgroundRenderer {
|
|
|
250
255
|
this.path(path);
|
|
251
256
|
this.ctx.save();
|
|
252
257
|
this.ctx.clip();
|
|
253
|
-
|
|
258
|
+
// Outside the ending shape a radial gradient continues with its last colour
|
|
259
|
+
// stop, so paint that first and lay the ellipse pattern on top.
|
|
260
|
+
if (lastStop) {
|
|
261
|
+
this.ctx.fillStyle = (0, color_utilities_1.asString)(lastStop.color);
|
|
262
|
+
this.ctx.fill();
|
|
263
|
+
}
|
|
264
|
+
this.ctx.translate(left + x - rx, top + y - ry);
|
|
254
265
|
this.ctx.fillStyle = pattern;
|
|
255
|
-
this.ctx.fillRect(0, 0,
|
|
266
|
+
this.ctx.fillRect(0, 0, rx * 2, ry * 2);
|
|
256
267
|
this.ctx.restore();
|
|
257
268
|
}
|
|
258
269
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ElementContainer } from '../element-container';
|
|
2
2
|
import { Context } from '../../core/context';
|
|
3
|
+
export declare const serializeWithoutBoxOffsets: (serializer: XMLSerializer, img: SVGSVGElement) => string;
|
|
3
4
|
export declare class SVGElementContainer extends ElementContainer {
|
|
4
5
|
svg: string;
|
|
5
6
|
intrinsicWidth: number;
|