UNPKG

@bplok20010/viewbox

Version:

a tool class for matrix transformation of views (rotate, scale, translate, skew, etc.)

403 lines (402 loc) 13.9 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import { Matrix2D } from "matrix2d.js"; var DEFAULT_WIDTH = 400; var DEFAULT_HEIGHT = 400; function isset(value) { return !(value == null); } function getDefaultTransform() { return { a: 1, b: 0, c: 0, d: 1, x: 0, y: 0, scaleX: 1, scaleY: 1, rotation: 0, flipX: false, flipY: false, skewX: 0, skewY: 0, }; } /** * ViewBox */ var ViewBox = /** @class */ (function () { function ViewBox(options) { if (options === void 0) { options = {}; } this._matrix = new Matrix2D(); this._transform = getDefaultTransform(); this.transformOrigin = { x: 0, y: 0 }; this.options = options; this.transformOrigin = options.transformOrigin || this.transformOrigin; if (options.transform) { this.setTransform(options.transform); } } Object.defineProperty(ViewBox.prototype, "matrix", { get: function () { return this._matrix; }, set: function (mtx) { this._matrix = mtx; }, enumerable: false, configurable: true }); Object.defineProperty(ViewBox.prototype, "transform", { get: function () { this._transform.x = this.x; this._transform.y = this.y; return this._transform; // return this.decompose(); }, set: function (value) { this._transform = __assign(__assign({}, this._transform), value); }, enumerable: false, configurable: true }); ViewBox.prototype.decompose = function () { return this.matrix.decompose(); }; Object.defineProperty(ViewBox.prototype, "cx", { get: function () { return this.transformOrigin.x; }, enumerable: false, configurable: true }); Object.defineProperty(ViewBox.prototype, "cy", { get: function () { return this.transformOrigin.y; }, enumerable: false, configurable: true }); ViewBox.prototype.setTransformOrigin = function (x, y) { this.transformOrigin = { x: x, y: y, }; }; ViewBox.prototype.getTransformOrigin = function () { return { x: this.cx, y: this.cy, }; }; Object.defineProperty(ViewBox.prototype, "x", { get: function () { return this.matrix.tx; }, set: function (value) { var delta = value - this.x; this.translate(delta, 0); }, enumerable: false, configurable: true }); Object.defineProperty(ViewBox.prototype, "y", { get: function () { return this.matrix.ty; }, set: function (value) { var delta = value - this.y; this.translate(0, delta); }, enumerable: false, configurable: true }); ViewBox.prototype.getPosition = function () { return { x: this.x, y: this.y, }; }; ViewBox.prototype.setPosition = function (x, y) { this.x = x; this.y = y; return this; }; ViewBox.prototype.getTransform = function () { var _a = this.matrix, a = _a.a, b = _a.b, c = _a.c, d = _a.d, tx = _a.tx, ty = _a.ty; return __assign(__assign({}, this.transform), { a: a, b: b, c: c, d: d, x: tx, y: ty }); }; ViewBox.prototype.setTransform = function (transform) { var _a = transform.a, a = _a === void 0 ? 1 : _a, _b = transform.b, b = _b === void 0 ? 0 : _b, _c = transform.c, c = _c === void 0 ? 0 : _c, _d = transform.d, d = _d === void 0 ? 1 : _d, _e = transform.x, x = _e === void 0 ? 0 : _e, _f = transform.y, y = _f === void 0 ? 0 : _f; var matrix = new Matrix2D(a, b, c, d, x, y); var decompose = matrix.decompose(); this.transform = __assign(__assign(__assign({}, getDefaultTransform()), { scaleX: decompose.scaleX, scaleY: decompose.scaleY, rotation: decompose.rotation, x: decompose.x, y: decompose.y }), transform); this.matrix = matrix; return this; }; ViewBox.prototype.getMatrixObject = function () { return this.matrix.clone(); }; ViewBox.prototype.getMatrix = function () { var _a = this.matrix, a = _a.a, b = _a.b, c = _a.c, d = _a.d, tx = _a.tx, ty = _a.ty; return [a, b, c, d, tx, ty]; }; /** * 视图坐标(相对viewBox)转本地坐标(viewBox内容实际坐标) * @examples * viewBox.translate(100, 100) * viewBox.globalToLocal(0, 0) // {x: -100, y: -100} */ ViewBox.prototype.globalToLocal = function (x, y) { return this.getMatrixObject().invert().transformPoint(x, y); }; /** * 本地坐标(viewBox内容实际坐标)转视图坐标(相对viewBox) * @examples * viewBox.translate(100, 100) * viewBox.localToGlobal(-100, -100) // {x: 0, y: 0} */ ViewBox.prototype.localToGlobal = function (x, y) { return this.matrix.transformPoint(x, y); }; /** * 对viewBox内容进行平移 * @param x 相对viewBox的(视图坐标)x偏移量 * @param y 同上 y偏移量 * @returns */ ViewBox.prototype.translate = function (x, y) { this.matrix.prepend(1, 0, 0, 1, x, y); return this; }; ViewBox.prototype.translateX = function (x) { return this.translate(x, 0); }; ViewBox.prototype.translateY = function (y) { return this.translate(0, y); }; ViewBox.prototype.scale = function (scaleX, scaleY, cx, cy) { var m0 = new Matrix2D(); m0.scale(scaleX, scaleY, cx !== null && cx !== void 0 ? cx : this.cx, cy !== null && cy !== void 0 ? cy : this.cy); this.matrix.prependMatrix(m0); this.transform.scaleX *= scaleX; this.transform.scaleY *= scaleY; return this; }; ViewBox.prototype.rotate = function (rotation, cx, cy) { var m0 = new Matrix2D(); m0.rotate(rotation, cx !== null && cx !== void 0 ? cx : this.cx, cy !== null && cy !== void 0 ? cy : this.cy); this.matrix.prependMatrix(m0); this.transform.rotation += rotation; return this; }; ViewBox.prototype.flipX = function (cx, cy) { cx = cx !== null && cx !== void 0 ? cx : this.cx; cy = cy !== null && cy !== void 0 ? cy : this.cy; var m0 = new Matrix2D(); m0.flipX(cx, cy); this.matrix.prependMatrix(m0); this.transform.flipX = !this.transform.flipX; return this; }; ViewBox.prototype.flipY = function (cx, cy) { cx = cx !== null && cx !== void 0 ? cx : this.cx; cy = cy !== null && cy !== void 0 ? cy : this.cy; var m0 = new Matrix2D(); m0.flipY(cx, cy); this.matrix.prependMatrix(m0); this.transform.flipX = !this.transform.flipX; return this; }; ViewBox.prototype.skewX = function (value, cx, cy) { var m0 = new Matrix2D(); m0.skewX(value, cx !== null && cx !== void 0 ? cx : this.cx, cy !== null && cy !== void 0 ? cy : this.cy); this.matrix.prependMatrix(m0); this.transform.skewX += value; return this; }; ViewBox.prototype.setSkewX = function (value, cx, cy) { var skewX = this.transform.skewX; var m0 = new Matrix2D(); m0.skewX(value - skewX, cx !== null && cx !== void 0 ? cx : this.cx, cy !== null && cy !== void 0 ? cy : this.cy); this.matrix.prependMatrix(m0); this.transform.skewX = value; return this; }; ViewBox.prototype.skewY = function (value, cx, cy) { var m0 = new Matrix2D(); m0.skewY(value, cx !== null && cx !== void 0 ? cx : this.cx, cy !== null && cy !== void 0 ? cy : this.cy); this.matrix.prependMatrix(m0); this.transform.skewY += value; return this; }; ViewBox.prototype.setSkewY = function (value, cx, cy) { var skewY = this.transform.skewY; var m0 = new Matrix2D(); m0.skewY(value - skewY, cx !== null && cx !== void 0 ? cx : this.cx, cy !== null && cy !== void 0 ? cy : this.cy); this.matrix.prependMatrix(m0); this.transform.skewY = value; return this; }; /** * 获取当前缩放值 * @returns */ ViewBox.prototype.getZoom = function () { return this.transform.scaleX; }; ViewBox.prototype.setZoom = function (value, cx, cy) { var scaleX = this.transform.scaleX; var scaleY = this.transform.scaleY; this.transform.scaleX = value; this.transform.scaleY = value; cx = cx !== null && cx !== void 0 ? cx : this.cx; cy = cy !== null && cy !== void 0 ? cy : this.cy; var m0 = new Matrix2D(); m0.scale(value / scaleX, value / scaleY, cx, cy); this.matrix.prependMatrix(m0); return this; }; ViewBox.prototype.setRotation = function (rotation, cx, cy) { var delta = rotation - this.transform.rotation; this.rotate(delta, cx, cy); return this; }; ViewBox.prototype.getObjectFitScale = function (objectFit, nodeSize, viewBoxSize) { var scaleX = 1, scaleY = 1; var width = nodeSize.width, height = nodeSize.height; var vWidth = viewBoxSize.width; var vHeight = viewBoxSize.height; switch (objectFit) { case "cover": scaleX = scaleY = Math.max(vWidth / width, vHeight / height); break; case "none": scaleX = scaleY = 1; break; case "scale-down": scaleX = scaleY = Math.min(1, Math.min(vWidth / width, vHeight / height)); break; case "fill": scaleX = vWidth / width; scaleY = vHeight / height; break; default: //case "contain": scaleX = scaleY = Math.min(vWidth / width, vHeight / height); break; } return { scaleX: scaleX, scaleY: scaleY, }; }; /** * 缩放以显示指定矩形区域(基于视图的区域)内容,并将区域中心移动到指定的坐标(transformOrigin) * @param rect */ ViewBox.prototype.zoomToRect = function (rect, options) { var _a; if (options === void 0) { options = {}; } if (!rect) { return this; } if (options.matrix) { var m = options.matrix; this.setTransform({ a: m[0], b: m[1], c: m[2], d: m[3], x: m[4], y: m[5], }); } var objectFit = options.objectFit || "contain"; var size = (options === null || options === void 0 ? void 0 : options.viewBoxSize) || (options === null || options === void 0 ? void 0 : options.size) || { width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, }; var padding = (_a = options.padding) !== null && _a !== void 0 ? _a : 0; var vWidth = size.width - padding * 2; var vHeight = size.height - padding * 2; var scaleX = 1, scaleY = 1; if (isset(options.scale)) { scaleX = scaleY = options.scale; } else { var r = this.getObjectFitScale(objectFit, rect, { width: vWidth, height: vHeight, }); scaleX = r.scaleX; scaleY = r.scaleY; } var cx = options.transformOrigin ? options.transformOrigin.x : this.cx; var cy = options.transformOrigin ? options.transformOrigin.y : this.cy; var rectCx = rect.x + rect.width / 2; var rectCy = rect.y + rect.height / 2; this.translate(cx - rectCx, cy - rectCy); this.scale(scaleX, scaleY, cx, cy); return this; }; /** * 缩放以居中显示指定矩形区域内容 * @returns */ ViewBox.prototype.zoomToFit = function (rect, options) { if (options === void 0) { options = {}; } var size = (options === null || options === void 0 ? void 0 : options.viewBoxSize) || (options === null || options === void 0 ? void 0 : options.size) || { width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT, }; return this.zoomToRect(rect, __assign(__assign({}, options), { transformOrigin: { x: size.width / 2, y: size.height / 2, } })); }; ViewBox.prototype.reset = function () { var m = new Matrix2D(); this.setTransform({ a: m.a, b: m.b, c: m.c, d: m.d, x: m.tx, y: m.ty, }); return this; }; ViewBox.prototype.toCSS = function () { var mtx = this.getMatrix(); return "matrix(".concat(mtx.join(","), ")"); }; /** * alias toCSS * @returns */ ViewBox.prototype.toString = function () { return this.toCSS(); }; ViewBox.prototype.clone = function () { var viewBox = new ViewBox({ transformOrigin: this.getTransformOrigin(), transform: this.getTransform(), }); return viewBox; }; return ViewBox; }()); export { ViewBox };