UNPKG

html2canvas-pro

Version:

Screenshots with JavaScript. Next generation!

185 lines 6.82 kB
"use strict"; /** * Border Renderer * * Handles rendering of element borders including: * - Solid borders * - Double borders * - Dashed borders * - Dotted borders */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BorderRenderer = void 0; const color_utilities_1 = require("../../css/types/color-utilities"); const border_1 = require("../border"); const bezier_curve_1 = require("../bezier-curve"); const vector_1 = require("../vector"); /** * Border Renderer * * Specialized renderer for element borders. * Extracted from CanvasRenderer to improve code organization and maintainability. */ class BorderRenderer { constructor(deps, pathCallbacks) { this.ctx = deps.ctx; this.pathCallbacks = pathCallbacks; } /** * Render a solid border * * @param color - Border color * @param side - Border side (0=top, 1=right, 2=bottom, 3=left) * @param curvePoints - Border curve points */ async renderSolidBorder(color, side, curvePoints) { this.pathCallbacks.path((0, border_1.parsePathForBorder)(curvePoints, side)); this.ctx.fillStyle = (0, color_utilities_1.asString)(color); this.ctx.fill(); } /** * Render a double border * Falls back to solid border if width is too small * * @param color - Border color * @param width - Border width * @param side - Border side (0=top, 1=right, 2=bottom, 3=left) * @param curvePoints - Border curve points */ async renderDoubleBorder(color, width, side, curvePoints) { if (width < 3) { await this.renderSolidBorder(color, side, curvePoints); return; } const outerPaths = (0, border_1.parsePathForBorderDoubleOuter)(curvePoints, side); this.pathCallbacks.path(outerPaths); this.ctx.fillStyle = (0, color_utilities_1.asString)(color); this.ctx.fill(); const innerPaths = (0, border_1.parsePathForBorderDoubleInner)(curvePoints, side); this.pathCallbacks.path(innerPaths); this.ctx.fill(); } /** * Render a dashed or dotted border * * @param color - Border color * @param width - Border width * @param side - Border side (0=top, 1=right, 2=bottom, 3=left) * @param curvePoints - Border curve points * @param style - Border style (DASHED or DOTTED) */ async renderDashedDottedBorder(color, width, side, curvePoints, style) { this.ctx.save(); const strokePaths = (0, border_1.parsePathForBorderStroke)(curvePoints, side); const boxPaths = (0, border_1.parsePathForBorder)(curvePoints, side); if (style === 2 /* BORDER_STYLE.DASHED */) { this.pathCallbacks.path(boxPaths); this.ctx.clip(); } // Extract start and end coordinates let startX, startY, endX, endY; if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) { startX = boxPaths[0].start.x; startY = boxPaths[0].start.y; } else { startX = boxPaths[0].x; startY = boxPaths[0].y; } if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) { endX = boxPaths[1].end.x; endY = boxPaths[1].end.y; } else { endX = boxPaths[1].x; endY = boxPaths[1].y; } // Calculate border length let length; if (side === 0 || side === 2) { length = Math.abs(startX - endX); } else { length = Math.abs(startY - endY); } this.ctx.beginPath(); if (style === 3 /* BORDER_STYLE.DOTTED */) { this.pathCallbacks.formatPath(strokePaths); } else { this.pathCallbacks.formatPath(boxPaths.slice(0, 2)); } // Calculate dash and space lengths let dashLength = width < 3 ? width * 3 : width * 2; let spaceLength = width < 3 ? width * 2 : width; if (style === 3 /* BORDER_STYLE.DOTTED */) { dashLength = width; spaceLength = width; } // Adjust dash pattern for border length let useLineDash = true; if (length <= dashLength * 2) { useLineDash = false; } else if (length <= dashLength * 2 + spaceLength) { const multiplier = length / (2 * dashLength + spaceLength); dashLength *= multiplier; spaceLength *= multiplier; } else { const numberOfDashes = Math.floor((length + spaceLength) / (dashLength + spaceLength)); const minSpace = (length - numberOfDashes * dashLength) / (numberOfDashes - 1); const maxSpace = (length - (numberOfDashes + 1) * dashLength) / numberOfDashes; spaceLength = maxSpace <= 0 || Math.abs(spaceLength - minSpace) < Math.abs(spaceLength - maxSpace) ? minSpace : maxSpace; } // Apply line dash pattern if (useLineDash) { if (style === 3 /* BORDER_STYLE.DOTTED */) { this.ctx.setLineDash([0, dashLength + spaceLength]); } else { this.ctx.setLineDash([dashLength, spaceLength]); } } // Set line style and stroke if (style === 3 /* BORDER_STYLE.DOTTED */) { this.ctx.lineCap = 'round'; this.ctx.lineWidth = width; } else { this.ctx.lineWidth = width * 2 + 1.1; } this.ctx.strokeStyle = (0, color_utilities_1.asString)(color); this.ctx.stroke(); this.ctx.setLineDash([]); // Fill dashed round edge gaps if (style === 2 /* BORDER_STYLE.DASHED */) { if ((0, bezier_curve_1.isBezierCurve)(boxPaths[0])) { const path1 = boxPaths[3]; const path2 = boxPaths[0]; this.ctx.beginPath(); this.pathCallbacks.formatPath([ new vector_1.Vector(path1.end.x, path1.end.y), new vector_1.Vector(path2.start.x, path2.start.y) ]); this.ctx.stroke(); } if ((0, bezier_curve_1.isBezierCurve)(boxPaths[1])) { const path1 = boxPaths[1]; const path2 = boxPaths[2]; this.ctx.beginPath(); this.pathCallbacks.formatPath([ new vector_1.Vector(path1.end.x, path1.end.y), new vector_1.Vector(path2.start.x, path2.start.y) ]); this.ctx.stroke(); } } this.ctx.restore(); } } exports.BorderRenderer = BorderRenderer; //# sourceMappingURL=border-renderer.js.map