html2canvas-pro 2.3.1 → 2.3.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 +34 -64
- package/dist/html2canvas-pro.cjs.map +1 -1
- package/dist/html2canvas-pro.esm.js +34 -64
- package/dist/html2canvas-pro.esm.js.map +1 -1
- package/dist/html2canvas-pro.js +34 -64
- package/dist/html2canvas-pro.js.map +1 -1
- package/dist/html2canvas-pro.min.js +2 -2
- package/dist/lib/render/canvas/canvas-renderer.js +1 -4
- package/dist/lib/render/canvas/content-renderer.js +5 -3
- package/dist/lib/render/canvas/font-utils.js +29 -0
- package/dist/lib/render/canvas/text-renderer.js +7 -6
- package/dist/types/render/canvas/canvas-renderer.d.ts +0 -1
- package/dist/types/render/canvas/content-renderer.d.ts +1 -2
- package/dist/types/render/canvas/font-utils.d.ts +19 -0
- package/dist/types/render/canvas/text-renderer.d.ts +0 -3
- package/package.json +1 -1
package/dist/html2canvas-pro.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* html2canvas-pro 2.3.
|
|
2
|
+
* html2canvas-pro 2.3.2 <https://yorickshan.github.io/html2canvas-pro/>
|
|
3
3
|
* Copyright (c) 2024-present yorickshan and html2canvas-pro contributors
|
|
4
4
|
* Released under MIT License
|
|
5
5
|
*/
|
|
@@ -8947,60 +8947,6 @@ const calculateBackgroundRepeatPath = (repeat, [x, y], [width, height], backgrou
|
|
|
8947
8947
|
}
|
|
8948
8948
|
};
|
|
8949
8949
|
//#endregion
|
|
8950
|
-
//#region src/core/util.ts
|
|
8951
|
-
const SMALL_IMAGE = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
8952
|
-
//#endregion
|
|
8953
|
-
//#region src/render/font-metrics.ts
|
|
8954
|
-
const SAMPLE_TEXT = "Hidden Text";
|
|
8955
|
-
var FontMetrics = class {
|
|
8956
|
-
constructor(document) {
|
|
8957
|
-
this._data = {};
|
|
8958
|
-
this._document = document;
|
|
8959
|
-
}
|
|
8960
|
-
parseMetrics(fontFamily, fontSize) {
|
|
8961
|
-
const container = this._document.createElement("div");
|
|
8962
|
-
const img = this._document.createElement("img");
|
|
8963
|
-
const span = this._document.createElement("span");
|
|
8964
|
-
const body = this._document.body;
|
|
8965
|
-
container.style.visibility = "hidden";
|
|
8966
|
-
container.style.fontFamily = fontFamily;
|
|
8967
|
-
container.style.fontSize = fontSize;
|
|
8968
|
-
container.style.margin = "0";
|
|
8969
|
-
container.style.padding = "0";
|
|
8970
|
-
container.style.whiteSpace = "nowrap";
|
|
8971
|
-
body.appendChild(container);
|
|
8972
|
-
img.src = SMALL_IMAGE;
|
|
8973
|
-
img.width = 1;
|
|
8974
|
-
img.height = 1;
|
|
8975
|
-
img.style.margin = "0";
|
|
8976
|
-
img.style.padding = "0";
|
|
8977
|
-
img.style.verticalAlign = "baseline";
|
|
8978
|
-
span.style.fontFamily = fontFamily;
|
|
8979
|
-
span.style.fontSize = fontSize;
|
|
8980
|
-
span.style.margin = "0";
|
|
8981
|
-
span.style.padding = "0";
|
|
8982
|
-
span.appendChild(this._document.createTextNode(SAMPLE_TEXT));
|
|
8983
|
-
container.appendChild(span);
|
|
8984
|
-
container.appendChild(img);
|
|
8985
|
-
const baseline = img.offsetTop - span.offsetTop + 2;
|
|
8986
|
-
container.removeChild(span);
|
|
8987
|
-
container.appendChild(this._document.createTextNode(SAMPLE_TEXT));
|
|
8988
|
-
container.style.lineHeight = "normal";
|
|
8989
|
-
img.style.verticalAlign = "super";
|
|
8990
|
-
const middle = img.offsetTop - container.offsetTop + 2;
|
|
8991
|
-
body.removeChild(container);
|
|
8992
|
-
return {
|
|
8993
|
-
baseline,
|
|
8994
|
-
middle
|
|
8995
|
-
};
|
|
8996
|
-
}
|
|
8997
|
-
getMetrics(fontFamily, fontSize) {
|
|
8998
|
-
const key = `${fontFamily} ${fontSize}`;
|
|
8999
|
-
if (typeof this._data[key] === "undefined") this._data[key] = this.parseMetrics(fontFamily, fontSize);
|
|
9000
|
-
return this._data[key];
|
|
9001
|
-
}
|
|
9002
|
-
};
|
|
9003
|
-
//#endregion
|
|
9004
8950
|
//#region src/render/canvas/text/text-decoration-renderer.ts
|
|
9005
8951
|
var TextDecorationRenderer = class {
|
|
9006
8952
|
constructor(ctx) {
|
|
@@ -9089,6 +9035,33 @@ var TextDecorationRenderer = class {
|
|
|
9089
9035
|
}
|
|
9090
9036
|
};
|
|
9091
9037
|
//#endregion
|
|
9038
|
+
//#region src/render/canvas/font-utils.ts
|
|
9039
|
+
/**
|
|
9040
|
+
* Font measurement utility
|
|
9041
|
+
*
|
|
9042
|
+
* Provides Canvas API-based baseline measurement that works correctly with
|
|
9043
|
+
* webfonts (which may not be loaded in the original document) and system fonts.
|
|
9044
|
+
*
|
|
9045
|
+
* Fallback chain:
|
|
9046
|
+
* 1. fontBoundingBoxAscent — font-level metric (Chrome 99+, FF 116+, Safari 17.4+)
|
|
9047
|
+
* 2. actualBoundingBoxAscent — glyph-level metric (widely supported)
|
|
9048
|
+
* 3. fallback value — coarse CSS fallback
|
|
9049
|
+
*/
|
|
9050
|
+
const SAMPLE_TEXT = "Mg";
|
|
9051
|
+
/**
|
|
9052
|
+
* Measure the baseline ascent for the currently set font.
|
|
9053
|
+
*
|
|
9054
|
+
* @param ctx - Canvas 2D rendering context with ctx.font already set
|
|
9055
|
+
* @param fallback - Fallback value when no metrics are available (e.g. fontSize.number)
|
|
9056
|
+
* @returns The distance from the text baseline to the top of the bounding box
|
|
9057
|
+
*/
|
|
9058
|
+
const measureBaseline = (ctx, fallback) => {
|
|
9059
|
+
const tm = ctx.measureText(SAMPLE_TEXT);
|
|
9060
|
+
const fmAscent = tm.fontBoundingBoxAscent;
|
|
9061
|
+
const ascent = fmAscent !== void 0 && !Number.isNaN(fmAscent) ? fmAscent : tm.actualBoundingBoxAscent;
|
|
9062
|
+
return ascent !== void 0 && !Number.isNaN(ascent) ? ascent : fallback;
|
|
9063
|
+
};
|
|
9064
|
+
//#endregion
|
|
9092
9065
|
//#region src/render/canvas/text-renderer.ts
|
|
9093
9066
|
const iOSBrokenFonts = ["-apple-system", "system-ui"];
|
|
9094
9067
|
/**
|
|
@@ -9141,7 +9114,6 @@ var TextRenderer = class {
|
|
|
9141
9114
|
constructor(deps) {
|
|
9142
9115
|
this.glyphWidthCache = null;
|
|
9143
9116
|
this.ctx = deps.ctx;
|
|
9144
|
-
this.fontMetrics = deps.fontMetrics;
|
|
9145
9117
|
this.options = deps.options;
|
|
9146
9118
|
this.decorationRenderer = new TextDecorationRenderer(deps.ctx);
|
|
9147
9119
|
}
|
|
@@ -9402,13 +9374,13 @@ var TextRenderer = class {
|
|
|
9402
9374
|
}
|
|
9403
9375
|
async renderTextNode(text, styles, containerBounds) {
|
|
9404
9376
|
this.glyphWidthCache = null;
|
|
9405
|
-
const [fontString
|
|
9377
|
+
const [fontString] = this.createFontStyle(styles);
|
|
9406
9378
|
this.ctx.font = fontString;
|
|
9407
9379
|
this.ctx.direction = styles.direction === 1 ? "rtl" : "ltr";
|
|
9408
9380
|
this.ctx.textAlign = "left";
|
|
9409
9381
|
this.ctx.textBaseline = "alphabetic";
|
|
9410
9382
|
const paintOrder = styles.paintOrder;
|
|
9411
|
-
const
|
|
9383
|
+
const baseline = measureBaseline(this.ctx, styles.fontSize.number);
|
|
9412
9384
|
if (styles.webkitLineClamp > 0 && (styles.display & 2) !== 0 && styles.overflowY === 1 && text.textBounds.length > 0) {
|
|
9413
9385
|
if (this.renderLineClampedText(text, styles, paintOrder, baseline, containerBounds)) return;
|
|
9414
9386
|
}
|
|
@@ -10304,7 +10276,7 @@ async function renderReplacedElements(ctx, context, options, iframeRendererFacto
|
|
|
10304
10276
|
/**
|
|
10305
10277
|
* Render form element content: checkbox, radio, text input.
|
|
10306
10278
|
*/
|
|
10307
|
-
function renderFormElements(ctx,
|
|
10279
|
+
function renderFormElements(ctx, textRenderer, pathFn, container, styles) {
|
|
10308
10280
|
if (container instanceof InputElementContainer) {
|
|
10309
10281
|
const size = Math.min(container.bounds.width, container.bounds.height);
|
|
10310
10282
|
if (container.type === "checkbox" && container.checked) {
|
|
@@ -10331,9 +10303,9 @@ function renderFormElements(ctx, fontMetrics, textRenderer, pathFn, container, s
|
|
|
10331
10303
|
}
|
|
10332
10304
|
}
|
|
10333
10305
|
if (isTextInputElement(container) && container.value.length) {
|
|
10334
|
-
const [font
|
|
10335
|
-
const { baseline } = fontMetrics.getMetrics(fontFamily, fontSize);
|
|
10306
|
+
const [font] = textRenderer.createFontStyle(styles);
|
|
10336
10307
|
ctx.font = font;
|
|
10308
|
+
const baseline = measureBaseline(ctx, getAbsoluteValue(styles.fontSize, 0));
|
|
10337
10309
|
ctx.fillStyle = container instanceof InputElementContainer && container.isPlaceholder ? asString(PLACEHOLDER_COLOR) : asString(styles.color);
|
|
10338
10310
|
ctx.textBaseline = "alphabetic";
|
|
10339
10311
|
ctx.textAlign = canvasTextAlign(container.styles.textAlign);
|
|
@@ -10431,7 +10403,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10431
10403
|
this.canvas.style.width = `${options.width}px`;
|
|
10432
10404
|
this.canvas.style.height = `${options.height}px`;
|
|
10433
10405
|
}
|
|
10434
|
-
this.fontMetrics = new FontMetrics(document);
|
|
10435
10406
|
this.ctx.scale(this.options.scale, this.options.scale);
|
|
10436
10407
|
this.ctx.translate(-options.x, -options.y);
|
|
10437
10408
|
this.ctx.textBaseline = "bottom";
|
|
@@ -10455,7 +10426,6 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10455
10426
|
this.effectsRenderer = new EffectsRenderer({ ctx: this.ctx }, { path: (paths) => this.path(paths) });
|
|
10456
10427
|
this.textRenderer = new TextRenderer({
|
|
10457
10428
|
ctx: this.ctx,
|
|
10458
|
-
fontMetrics: this.fontMetrics,
|
|
10459
10429
|
options: { scale: options.scale }
|
|
10460
10430
|
});
|
|
10461
10431
|
this.context.logger.debug(`Canvas renderer initialized (${options.width}x${options.height}) with scale ${options.scale}`);
|
|
@@ -10503,7 +10473,7 @@ var CanvasRenderer = class CanvasRenderer {
|
|
|
10503
10473
|
width: this.options.width,
|
|
10504
10474
|
height: this.options.height
|
|
10505
10475
|
}, (ctx, opts) => new CanvasRenderer(ctx, opts), container, curves, styles, (c, cv, img) => this.renderReplacedElement(c, cv, img));
|
|
10506
|
-
renderFormElements(this.ctx, this.
|
|
10476
|
+
renderFormElements(this.ctx, this.textRenderer, this.path.bind(this), container, styles);
|
|
10507
10477
|
await renderListMarker(this.ctx, this.context, this.textRenderer, paint, container, styles);
|
|
10508
10478
|
}
|
|
10509
10479
|
async renderStackContent(stack) {
|