UNPKG

@aurigma/design-atoms

Version:

Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.

538 lines 25.2 kB
var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spread = (this && this.__spread) || function () { for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); return ar; }; // ReSharper disable once InconsistentNaming import { PointF, EqualsOfFloatNumbers, ConvertDegreeToRadian, RotatedRectangleF, Path, Transform, SizeF } from "@aurigma/design-atoms-model/Math"; import { NotImplementedException } from "@aurigma/design-atoms-model/Exception"; import { Margin } from "@aurigma/design-atoms-model/Math/Margin"; var Graphics = /** @class */ (function () { function Graphics() { } Graphics.drawCross = function (ctx, x, y, size, width, baselineColor) { var rect = new RotatedRectangleF(x, y, size, size).toRectangleF(); Graphics.drawLine(ctx, rect.left, rect.top, rect.right, rect.bottom, width, baselineColor); Graphics.drawLine(ctx, rect.left, rect.bottom, rect.right, rect.top, width, baselineColor); }; Graphics.drawLine = function (ctx, x, y, x1, y1, lineWidth, lineColor, opacity, dashWidth) { if (opacity === void 0) { opacity = 1; } if (dashWidth === void 0) { dashWidth = null; } if (Graphics.isFullTransparentColor(lineColor) || lineWidth <= 0 || opacity == null || opacity <= 0) return; ctx.save(); try { if (opacity) ctx.globalAlpha = ctx.globalAlpha * opacity; ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; if (dashWidth) ctx.setLineDash(dashWidth); ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x1, y1); ctx.stroke(); } finally { ctx.restore(); } }; Graphics.drawDashedLine = function (ctx, x0, y0, x1, y1, lineWidth, color, altColor, dashWidth, altDashWidth, opacity) { if (opacity === void 0) { opacity = 1; } if (lineWidth > 0 && dashWidth > 0 && altDashWidth > 0 && (opacity == null || opacity > 0)) { ctx.save(); if (opacity) ctx.globalAlpha = ctx.globalAlpha * opacity; ctx.lineWidth = lineWidth; if (x1 < x0) { var t = x0; x0 = x1; x1 = t; t = y0; y0 = y1; y1 = t; } var dx = x1 - x0; var dy = y1 - y0; var d = dashWidth + altDashWidth; var len = Math.sqrt(dx * dx + dy * dy); var dashCount = Math.floor(len / d); dx /= (len / d); dy /= (len / d); var dashX = dx * (dashWidth / d); var altDashX = dx * (altDashWidth / d); var dashY = dy * (dashWidth / d); var altDashY = dy * (altDashWidth / d); var x = x0; var y = y0; var i; if (!Graphics.isFullTransparentColor(color)) { ctx.strokeStyle = color; ctx.beginPath(); ctx.moveTo(x, y); for (i = 0; i < dashCount; i++) { x += dashX; y += dashY; ctx.lineTo(x, y); x += altDashX; y += altDashY; if (i + 1 < dashCount) { ctx.moveTo(x, y); } } if (x + dashX <= x1 && y + dashY <= y1) { ctx.moveTo(x, y); ctx.lineTo(x + dashX, y + dashY); } else { ctx.moveTo(x, y); ctx.lineTo(x1, y1); } ctx.closePath(); ctx.stroke(); } x = x0 + dashX; y = y0 + dashY; if (!Graphics.isFullTransparentColor(altColor)) { ctx.strokeStyle = altColor; ctx.beginPath(); ctx.moveTo(x, y); for (i = 0; i < dashCount; i++) { x += altDashX; y += altDashY; ctx.lineTo(x, y); x += dashX; y += dashY; if (i + 1 < dashCount) { ctx.moveTo(x, y); } } if (x < x1 && y < y1) { ctx.moveTo(x, y); ctx.lineTo(x1, y1); } ctx.closePath(); ctx.stroke(); } ctx.restore(); } }; Graphics.drawPolyline = function (ctx, points, lineWidth, lineColor, opacity) { if (!Graphics.isFullTransparentColor(lineColor) && lineWidth > 0 && (opacity == null || opacity > 0)) { if (points && points.length > 1) { ctx.save(); if (opacity) ctx.globalAlpha = ctx.globalAlpha * opacity; ctx.lineWidth = lineWidth; ctx.strokeStyle = lineColor; ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); for (var i = 1, imax = points.length; i < imax; ++i) { var p = points[i]; ctx.lineTo(p.x, p.y); } ctx.stroke(); ctx.restore(); } } }; Graphics.drawPath = function (ctx, path, center, transform, borderWidth, borderColor, opacity, dashWidth, altBorderColor) { if (dashWidth === void 0) { dashWidth = []; } if (altBorderColor === void 0) { altBorderColor = null; } Graphics.path(ctx, path, center, transform, null, borderWidth, borderColor, opacity, dashWidth, altBorderColor); }; Graphics.fillPath = function (ctx, path, center, transform, fillColor, opacity) { Graphics.path(ctx, path, center, transform, fillColor, 0, null, opacity, []); }; Graphics.drawStroke = function (ctx, path, center, transform, borderWidth, borderColor, altBorderColor, opacity, dash) { if (borderWidth <= 0) return; Graphics.path(ctx, path, center, transform, null, borderWidth, borderColor, opacity, dash); if (altBorderColor != null && dash != null && dash.length > 0) { var altDash = dash.slice(0); altDash.unshift(0); altDash.push(0); Graphics.path(ctx, path, center, transform, null, borderWidth, altBorderColor, opacity, altDash); } }; Graphics.path = function (ctx, path, center, transform, fillColor, borderWidth, borderColor, opacity, dashWidth, altBorderColor) { if (altBorderColor === void 0) { altBorderColor = null; } var stroke = borderColor != null && !Graphics.isFullTransparentColor(borderColor) && borderWidth > 0; var fill = fillColor != null && !Graphics.isFullTransparentColor(fillColor); if ((stroke || fill) && (opacity == null || opacity > 0)) { ctx.save(); if (opacity) ctx.globalAlpha = ctx.globalAlpha * opacity; var matrix = transform.toMatrix(); ctx.translate(center.x, center.y); ctx.transform(matrix.m00, matrix.m10, matrix.m01, matrix.m11, matrix.m02, matrix.m12); ctx.translate(-center.x, -center.y); if (path instanceof Path) path.draw(ctx); else if (typeof path.addToContext == "function") //TextWhizz.Path path.addToContext(ctx); if (fill) { ctx.fillStyle = fillColor; ctx.fill(); } if (stroke) { if (path instanceof Path && !EqualsOfFloatNumbers(transform.scaleX, transform.scaleY)) { ctx.restore(); ctx.save(); if (opacity) ctx.globalAlpha = opacity; var transformedPath = path.clone(); transformedPath.transform(transform, center); transformedPath.draw(ctx); } else { borderWidth /= transform.scaleX; if (dashWidth && dashWidth.length > 0) { for (var i = 0; i < dashWidth.length; i++) dashWidth[i] /= transform.scaleX; } } ctx.lineWidth = borderWidth; ctx.strokeStyle = borderColor; ctx.setLineDash(dashWidth); ctx.stroke(); if (dashWidth != null && dashWidth.length > 0 && altBorderColor) { var altDash = __spread([0], dashWidth, [0]); ctx.setLineDash(altDash); ctx.strokeStyle = altBorderColor; ctx.stroke(); } } ctx.restore(); } }; Graphics.clipPath = function (ctx, path) { path.draw(ctx); ctx.clip(); }; Graphics.drawImage = function (ctx, image, rotatedRectangle, scaleX, scaleY, disableSmoothing, maskColor, opacity, imageRect, increaseImageRect) { if (disableSmoothing === void 0) { disableSmoothing = false; } if (maskColor === void 0) { maskColor = null; } if (opacity === void 0) { opacity = 1; } if (imageRect === void 0) { imageRect = null; } if (increaseImageRect === void 0) { increaseImageRect = 0; } if (opacity == null || opacity > 0) { ctx.save(); if (opacity) ctx.globalAlpha = ctx.globalAlpha * opacity; ctx.translate(rotatedRectangle.centerX, rotatedRectangle.centerY); ctx.rotate(ConvertDegreeToRadian(rotatedRectangle.angle)); if (increaseImageRect) { var mx = increaseImageRect / scaleX; var my = increaseImageRect / scaleY; rotatedRectangle.width += mx * 2; rotatedRectangle.height += my * 2; } var imageWidth = void 0, imageHeight = void 0; if (imageRect != null) { imageWidth = imageRect.width; imageHeight = imageRect.height; } else { if (image.naturalWidth) imageWidth = image.naturalWidth; else if (image.width) imageWidth = image.width; else imageWidth = ctx.canvas.width; if (image.naturalHeight) imageHeight = image.naturalHeight; else if (image.height) imageHeight = image.height; else imageHeight = ctx.canvas.height; } var drawImageAsIs = scaleX != undefined && scaleX !== 0 && scaleY != undefined && scaleY !== 0 && Math.abs(imageWidth - rotatedRectangle.width * scaleX) < 1 && Math.abs(imageHeight - rotatedRectangle.height * scaleY) < 1; ; if (!disableSmoothing) { // depends on angle if parameter not specified disableSmoothing = (ctx.imageSmoothingEnabled || ctx.msImageSmoothingEnabled === true) && Math.abs(rotatedRectangle.angle) % 90 < 0.01 && drawImageAsIs; } if (disableSmoothing) { ctx.imageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false; } try { if (drawImageAsIs) { ctx.scale(1 / scaleX, 1 / scaleY); if (imageRect != null) ctx.drawImage(image, imageRect.left, imageRect.top, imageRect.width, imageRect.height, -rotatedRectangle.width * scaleX / 2, -rotatedRectangle.height * scaleY / 2, imageWidth, imageHeight); else ctx.drawImage(image, -rotatedRectangle.width * scaleX / 2, -rotatedRectangle.height * scaleY / 2, imageWidth, imageHeight); ctx.scale(scaleX, scaleY); } else if (imageRect != null) ctx.drawImage(image, imageRect.left, imageRect.top, imageRect.width, imageRect.height, -rotatedRectangle.width / 2, -rotatedRectangle.height / 2, rotatedRectangle.width, rotatedRectangle.height); else ctx.drawImage(image, -rotatedRectangle.width / 2, -rotatedRectangle.height / 2, rotatedRectangle.width, rotatedRectangle.height); if (maskColor && !Graphics.isFullTransparentColor(maskColor)) { ctx.fillStyle = maskColor; ctx.fillRect(-rotatedRectangle.width / 2, -rotatedRectangle.height / 2, rotatedRectangle.width, rotatedRectangle.height); } } catch (err) { } if (disableSmoothing) { ctx.imageSmoothingEnabled = true; ctx.msImageSmoothingEnabled = true; } ctx.restore(); } }; Graphics.drawRectangle = function (ctx, rotatedRectangle, borderWidth, borderColor, opacity) { Graphics.rectangle(ctx, rotatedRectangle, borderWidth, borderColor, null, opacity); }; Graphics.fillRectangle = function (ctx, rotatedRectangle, fillColor, opacity) { Graphics.rectangle(ctx, rotatedRectangle, 0, null, fillColor, opacity); }; Graphics.rectangle = function (ctx, rotatedRectangle, borderWidth, borderColor, fillColor, opacity, strokeDash) { if (fillColor === void 0) { fillColor = null; } if (opacity === void 0) { opacity = 1; } if (strokeDash === void 0) { strokeDash = null; } var stroke = borderColor && !Graphics.isFullTransparentColor(borderColor) && borderWidth > 0; var fill = fillColor && !Graphics.isFullTransparentColor(fillColor); if ((stroke || fill) && (opacity == null || opacity > 0)) { ctx.save(); if (opacity) ctx.globalAlpha = ctx.globalAlpha * opacity; ctx.translate(rotatedRectangle.centerX, rotatedRectangle.centerY); ctx.rotate(ConvertDegreeToRadian(rotatedRectangle.angle)); if (fill) { ctx.fillStyle = fillColor; ctx.fillRect(-rotatedRectangle.width / 2, -rotatedRectangle.height / 2, rotatedRectangle.width, rotatedRectangle.height); } if (stroke) { if (strokeDash != null) ctx.setLineDash(strokeDash); ctx.lineWidth = borderWidth; ctx.strokeStyle = borderColor; ctx.strokeRect(-rotatedRectangle.width / 2, -rotatedRectangle.height / 2, rotatedRectangle.width, rotatedRectangle.height); } ctx.restore(); } }; Graphics.measureText = function (ctx, text, point, font, fillColor, strokeColor, angle) { if (fillColor === void 0) { fillColor = null; } if (strokeColor === void 0) { strokeColor = null; } if (angle === void 0) { angle = 0; } var stroke = strokeColor && !Graphics.isFullTransparentColor(strokeColor); var fill = fillColor && !Graphics.isFullTransparentColor(fillColor); if (stroke == null && fill == null) return null; ctx.save(); try { ctx.font = font; ctx.translate(point.x, point.y); ctx.rotate(ConvertDegreeToRadian(angle)); if (fill) ctx.fillStyle = fillColor; if (stroke) ctx.strokeStyle = strokeColor; return ctx.measureText(text); } finally { ctx.restore(); } }; Graphics._drawTextBackground = function (ctx, left, right, top, bottom, background, border, borderWidth, margin, cornerRadius) { var width = right - left; var height = bottom - top; var radiuses = null; if (cornerRadius > 0) { var cornerSize = new SizeF(cornerRadius, cornerRadius); radiuses = [cornerSize, cornerSize, cornerSize, cornerSize]; } var rectPath = Path.roundedRectangle(left - margin.left, top - margin.top, width + margin.left + margin.right, height + margin.top + margin.bottom, radiuses); Graphics.path(ctx, rectPath, new PointF(), new Transform(), background, borderWidth, border, 1, []); }; Graphics.text = function (ctx, text, point, font, fillColor, strokeColor, angle, maxWidth, textAlign, textBaseline, background, border, borderWidth, backgroundMargin, backgroundCornerRadius) { if (fillColor === void 0) { fillColor = null; } if (strokeColor === void 0) { strokeColor = null; } if (angle === void 0) { angle = 0; } if (maxWidth === void 0) { maxWidth = null; } if (textAlign === void 0) { textAlign = "left"; } if (textBaseline === void 0) { textBaseline = "alphabetic"; } if (background === void 0) { background = null; } if (border === void 0) { border = null; } if (borderWidth === void 0) { borderWidth = 0; } if (backgroundMargin === void 0) { backgroundMargin = new Margin(0); } if (backgroundCornerRadius === void 0) { backgroundCornerRadius = 0; } if (background != null && (textBaseline != "bottom" && textBaseline != "middle")) throw new NotImplementedException("textBaseline = " + textBaseline + " is not supported yet"); var stroke = strokeColor && !Graphics.isFullTransparentColor(strokeColor); var fill = fillColor && !Graphics.isFullTransparentColor(fillColor); if (stroke || fill) { ctx.save(); ctx.font = font; ctx.translate(point.x, point.y); ctx.rotate(ConvertDegreeToRadian(angle)); ctx.textAlign = textAlign; ctx.textBaseline = textBaseline; if (fill) ctx.fillStyle = fillColor; if (stroke) ctx.strokeStyle = strokeColor; var maxWidthInChars = Math.floor(maxWidth / ctx.measureText("x").width); // x is average width char var lines = this._splitTextToLines(text, maxWidthInChars); if (lines.length > 1 && textBaseline != "bottom") throw new NotImplementedException("textBaseline = " + textBaseline + " is not supported yet"); var widestMetrics_1 = ctx.measureText(""); var actualBoundingBoxAscent_1 = 0; var actualBoundingBoxDescent_1 = 0; lines.forEach(function (a) { var metrics = ctx.measureText(a); actualBoundingBoxAscent_1 += metrics.actualBoundingBoxAscent; actualBoundingBoxDescent_1 += metrics.actualBoundingBoxDescent; if (metrics.width > widestMetrics_1.width) widestMetrics_1 = metrics; }); var fontSizeStr = font.match(/\d+(px|pt)/); var pxFontSize = 0; if (fontSizeStr.length > 0) { var val = Number.parseFloat(fontSizeStr[0].substring(0, fontSizeStr[0].length - 2)); if (fontSizeStr[1] == "px") pxFontSize = val; else pxFontSize = val * 1.33; } var fontSize = pxFontSize > 0 ? pxFontSize : widestMetrics_1.actualBoundingBoxAscent + widestMetrics_1.actualBoundingBoxDescent; var pxBetweenLines_1 = (fontSize) * 10 / 7; var height = fontSize + pxBetweenLines_1 * (lines.length - 1); var textYStart_1 = 0; switch (textBaseline) { //TODO: other cases case "bottom": actualBoundingBoxDescent_1 = -pxBetweenLines_1 / 40; actualBoundingBoxAscent_1 = height - widestMetrics_1.actualBoundingBoxDescent; textYStart_1 = -pxBetweenLines_1 * (lines.length - 1); break; default: break; } if (background || (border != null && borderWidth > 0)) { this._drawTextBackground(ctx, -widestMetrics_1.actualBoundingBoxLeft, widestMetrics_1.actualBoundingBoxRight, -actualBoundingBoxAscent_1, actualBoundingBoxDescent_1, background, border, borderWidth, backgroundMargin, backgroundCornerRadius); } lines.forEach(function (a, i) { if (fill) ctx.fillText(a, 0, textYStart_1 + i * (pxBetweenLines_1)); if (stroke) ctx.strokeText(a, 0, textYStart_1 + i * (pxBetweenLines_1)); }); ctx.restore(); } }; Graphics._splitTextToLines = function (text, maxWidth) { if (maxWidth === void 0) { maxWidth = null; } var lines = null; if (maxWidth) { var reg = new RegExp("(?![^\\n]{1," + maxWidth + "}$)([^\\n]{1," + maxWidth + "})\\s", 'g'); var cropedText = text.replace(reg, '$1\n'); // do linebreaks at nearest to Whitespace places lines = cropedText.split("\n"); for (var i = 0; i < lines.length; i++) { if (lines[i].length > maxWidth) { var newLine = lines[i].substring(maxWidth); lines[i] = lines[i].substring(0, maxWidth); lines.splice(i + 1, 0, newLine); } } } else lines = text.split("\n"); return lines; }; Graphics.isFullTransparentColor = function (color) { if (!color) return false; //test if color has A, R, G, B properties var a = color.A || color.a; if (a === 0) return true; if (typeof color === "string") { //parse string var rgba = /^\s*rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\,\s*(\d{1,}(\.\d{1,})?)\s*\)\s*;{0,1}\s*$/i; a = rgba.exec(color); if (a) { a = parseFloat(a[1]); if (a === 0) return true; else return false; } } return false; }; Graphics.clearCanvas = function (context, preserveTransform) { if (preserveTransform === void 0) { preserveTransform = false; } if (preserveTransform) { context.save(); context.setTransform(1, 0, 0, 1, 0, 0); } context.clearRect(0, 0, context.canvas.width, context.canvas.height); if (preserveTransform) { context.restore(); } }; Graphics.drawRoundedRectangle = function (ctx, rect, rounded) { ctx.roundedRectangle(rect.left, rect.top, rect.width, rect.height, rounded); }; return Graphics; }()); export { Graphics }; CanvasRenderingContext2D.prototype.roundedRectangle = function (x, y, width, height, rounded) { var halfRadians = (2 * Math.PI) / 2; var quarterRadians = (2 * Math.PI) / 4; this.beginPath(); // top left arc this.arc(rounded + x, rounded + y, rounded, -quarterRadians, halfRadians, true); // line from top left to bottom left this.lineTo(x, y + height - rounded); // bottom left arc this.arc(rounded + x, height - rounded + y, rounded, halfRadians, quarterRadians, true); // line from bottom left to bottom right this.lineTo(x + width - rounded, y + height); // bottom right arc this.arc(x + width - rounded, y + height - rounded, rounded, quarterRadians, 0, true); // line from bottom right to top right this.lineTo(x + width, y + rounded); // top right arc this.arc(x + width - rounded, y + rounded, rounded, 0, -quarterRadians, true); // line from top right to top left this.lineTo(x + rounded, y); this.stroke(); this.fill(); this.closePath(); }; //# sourceMappingURL=Graphics.js.map