@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
JavaScript
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