@leafer-in/resize
Version:
221 lines (215 loc) • 7.77 kB
JavaScript
import { PathCommandMap, MatrixHelper, Direction9, Leaf, Text, Path, Line, Polygon, Group, Box, Plugin } from '@leafer-ui/draw';
const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = PathCommandMap;
const PathScaler = {
scale(data, scaleX, scaleY) {
if (!data)
return;
let command;
let i = 0, len = data.length;
while (i < len) {
command = data[i];
switch (command) {
case M:
case L:
scalePoints(data, scaleX, scaleY, i, 1);
i += 3;
break;
case C:
scalePoints(data, scaleX, scaleY, i, 3);
i += 7;
break;
case Q:
scalePoints(data, scaleX, scaleY, i, 2);
i += 5;
break;
case Z:
i += 1;
break;
case N:
scalePoints(data, scaleX, scaleY, i, 2);
i += 5;
break;
case D:
scalePoints(data, scaleX, scaleY, i, 2);
i += 9;
break;
case X:
scalePoints(data, scaleX, scaleY, i, 2);
i += 6;
break;
case G:
scalePoints(data, scaleX, scaleY, i, 2);
i += 9;
break;
case F:
scalePoints(data, scaleX, scaleY, i, 2);
i += 5;
break;
case O:
data[i] = G;
data.splice(i + 4, 0, data[i + 3], 0);
scalePoints(data, scaleX, scaleY, i, 2);
i += 7 + 2;
len += 2;
break;
case P:
data[i] = F;
data.splice(i + 4, 0, data[i + 3]);
scalePoints(data, scaleX, scaleY, i, 2);
i += 4 + 1;
len += 1;
break;
case U:
scalePoints(data, scaleX, scaleY, i, 2);
i += 6;
break;
}
}
},
scalePoints(data, scaleX, scaleY, start, pointCount) {
for (let i = pointCount ? start + 1 : 0, end = pointCount ? i + pointCount * 2 : data.length; i < end; i += 2) {
data[i] *= scaleX;
data[i + 1] *= scaleY;
}
}
};
const { scalePoints } = PathScaler;
const matrix = MatrixHelper.get();
const { topLeft, top, topRight, right, bottom, left } = Direction9;
function scaleResize(leaf, scaleX, scaleY) {
if (leaf.pathInputed) {
scaleResizePath(leaf, scaleX, scaleY);
}
else {
if (scaleX !== 1)
leaf.width *= scaleX;
if (scaleY !== 1)
leaf.height *= scaleY;
}
}
function scaleResizeFontSize(leaf, scaleX, scaleY, direction) {
let fontScale = scaleX;
if (direction !== undefined) {
const layout = leaf.__layout;
let { width, height } = layout.boxBounds;
width *= scaleY - scaleX;
height *= scaleX - scaleY;
switch (direction) {
case top:
case bottom:
fontScale = scaleY;
layout.affectScaleOrRotation ? leaf.moveInner(-width / 2, 0) : leaf.x -= width / 2;
break;
case left:
case right:
layout.affectScaleOrRotation ? leaf.moveInner(0, -height / 2) : leaf.y -= height / 2;
break;
case topLeft:
case topRight:
layout.affectScaleOrRotation ? leaf.moveInner(0, -height) : leaf.y -= height;
break;
}
}
leaf.fontSize *= fontScale;
const data = leaf.__, { padding } = data;
if (padding)
leaf.padding = padding instanceof Array ? padding.map(item => item * fontScale) : padding * fontScale;
if (!data.__autoWidth)
leaf.width *= fontScale;
if (!data.__autoHeight)
leaf.height *= fontScale;
}
function scaleResizePath(leaf, scaleX, scaleY) {
PathScaler.scale(leaf.__.path, scaleX, scaleY);
leaf.path = leaf.__.path;
}
function scaleResizePoints(leaf, scaleX, scaleY) {
const { points } = leaf;
typeof points[0] === 'object' ? points.forEach(p => { p.x *= scaleX, p.y *= scaleY; }) : PathScaler.scalePoints(points, scaleX, scaleY);
leaf.points = points;
}
function scaleResizeGroup(group, scaleX, scaleY) {
const { children } = group;
for (let i = 0; i < children.length; i++) {
matrix.a = scaleX;
matrix.d = scaleY;
children[i].transform(matrix, true);
}
}
const leaf = Leaf.prototype;
leaf.scaleResize = function (scaleX, scaleY = scaleX, noResize) {
const data = this;
if (noResize || (data.editConfig && data.editConfig.editSize === 'scale')) {
data.scaleX *= scaleX;
data.scaleY *= scaleY;
}
else {
if (scaleX < 0)
data.scaleX *= -1, scaleX = -scaleX;
if (scaleY < 0)
data.scaleY *= -1, scaleY = -scaleY;
this.__scaleResize(scaleX, scaleY);
}
};
leaf.__scaleResize = function (scaleX, scaleY) {
scaleResize(this, scaleX, scaleY);
};
leaf.resizeWidth = function (width) {
const scale = width / this.getBounds('box', 'local').width || 1;
this.scaleOf(this.__layout.boxBounds, scale, this.__.lockRatio ? scale : 1, true);
};
leaf.resizeHeight = function (height) {
const scale = height / this.getBounds('box', 'local').height || 1;
this.scaleOf(this.__layout.boxBounds, this.__.lockRatio ? scale : 1, scale, true);
};
Text.prototype.__scaleResize = function (scaleX, scaleY) {
const { app, editConfig } = this, editor = app && app.editor, dragPoint = editor && editor.dragPoint;
const { __autoWidth, __autoHeight, textAlign, verticalAlign } = this.__, { boxBounds } = this.__layout;
if (__autoWidth && textAlign !== 'left' && scaleX !== 1)
this.x += boxBounds.x;
if (__autoHeight && verticalAlign !== 'top' && scaleY !== 1)
this.y += boxBounds.y;
if (this.__.resizeFontSize || (editConfig && editConfig.editSize === 'font-size') || (dragPoint && editor.mergedConfig.editSize === 'font-size')) {
scaleResizeFontSize(this, scaleX, scaleY, dragPoint && dragPoint.direction);
}
else {
scaleResize(this, scaleX, scaleY);
}
};
Path.prototype.__scaleResize = function (scaleX, scaleY) {
scaleResizePath(this, scaleX, scaleY);
};
Line.prototype.__scaleResize = function (scaleX, scaleY) {
if (this.pathInputed) {
scaleResizePath(this, scaleX, scaleY);
}
else if (this.points) {
scaleResizePoints(this, scaleX, scaleY);
}
else {
this.width *= scaleX;
}
};
Polygon.prototype.__scaleResize = function (scaleX, scaleY) {
if (this.pathInputed) {
scaleResizePath(this, scaleX, scaleY);
}
else if (this.points) {
scaleResizePoints(this, scaleX, scaleY);
}
else {
scaleResize(this, scaleX, scaleY);
}
};
Group.prototype.__scaleResize = function (scaleX, scaleY) {
scaleResizeGroup(this, scaleX, scaleY);
};
Box.prototype.__scaleResize = function (scaleX, scaleY) {
const { resizeChildren, __autoSize } = this.__;
if (!(__autoSize && resizeChildren))
scaleResize(this, scaleX, scaleY);
if (resizeChildren)
scaleResizeGroup(this, scaleX, scaleY);
};
Plugin.add('resize');
export { PathScaler, scaleResize, scaleResizeFontSize, scaleResizeGroup, scaleResizePath, scaleResizePoints };