@aurigma/design-atoms
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
146 lines • 6.96 kB
JavaScript
import { GroupItemHandler } from "../ItemHandlers";
import { PointF, Matrix, RectangleF } from "@aurigma/design-atoms-model/Math";
import Environment from "@aurigma/design-atoms-model/Utils/Environment";
import { CoordinatesConvertUtils } from "../Utils/CoordinatesConvertUtils";
import { CoordinateSystem } from "../Viewer/CoordinateSystem";
export class HitTestManager {
constructor(_canvas) {
this._canvas = _canvas;
}
/** @inheritDoc */
getItemHandlersByHitTest(point, coordinateSystem = CoordinateSystem.page) {
let items = [];
const workspacePoint = this._convertToWorkspace(point, coordinateSystem);
const isSelectableItemHandler = (itemHandler) => {
return itemHandler.visible
&& !itemHandler.isLocked()
&& this._productHandler.isInteractive(itemHandler.item)
&& !itemHandler.getPermissions().noShow
&& !itemHandler.isEmpty();
};
for (let i = this._canvas.layers.length - 1; i >= 0; i--) {
const layer = this._canvas.layers.getItem(i);
if (!this._productHandler.isInteractive(layer.container))
continue;
if (layer.visible && !layer.locked) {
for (let j = layer.itemHandlers.length - 1; j >= 0; j--) {
const vo = layer.itemHandlers.getItem(j);
if (isSelectableItemHandler(vo)) {
let ht = vo.hitTest(workspacePoint);
if (ht.body) {
items.push(vo);
if (vo instanceof GroupItemHandler && vo.item.groupItemPermissions.allowSelectNestedItems)
items.push(...vo.getNestedItemHandlers(false, true).filter(gItemHandler => gItemHandler.hitTest(workspacePoint).body === true && isSelectableItemHandler(gItemHandler)));
}
}
}
}
}
return items;
}
/** @inheritDoc */
findItemByHitTest(point, coordinateSystem = CoordinateSystem.page) {
const workspacePoint = CoordinatesConvertUtils.pageToWorkspacePoint(point, this._canvas.viewer);
const itemHandlers = this.getItemHandlersByHitTest(workspacePoint, CoordinateSystem.workspace);
const selectedHandler = itemHandlers.find(itemHandler => this._canvas.isItemHandlerSelected(itemHandler));
if (selectedHandler != null)
return selectedHandler.item;
return itemHandlers[0] != null ? itemHandlers[0].item : null;
}
getFirstHandlerByHitTest(workspacePoint) {
return this.getItemHandlersByHitTest(workspacePoint, CoordinateSystem.workspace)[0];
}
hitTestSelection(rect, workspacePoint, onlyWidthResizeEnabled = false, tolerance = null) {
let transformedPoint = this._convertToProductCoord(workspacePoint);
let result = {};
const m = new Matrix();
if (rect.angle !== 0) {
m.rotate(-rect.angle);
}
m.translate(-rect.centerX, -rect.centerY);
transformedPoint = m.transformPoint(transformedPoint, true);
const w = rect.width;
const h = rect.height;
const mul = this._canvas.mul;
// check body
const bodyHeight = tolerance != null ? Math.max(tolerance / mul, h) : h;
const bodyWidth = tolerance != null ? Math.max(tolerance / mul, w) : w;
result.body = new RectangleF(-bodyWidth / 2, -bodyHeight / 2, bodyWidth, bodyHeight).contains(transformedPoint);
// check resize
result.resize = false;
result.resizeIndex = 0;
const resizeGripSize = Environment.IsTouchDevice() ? 33 : this._canvas.resizeGripSize;
let r = resizeGripSize / mul, r2 = r / 2;
const resizeGrips = [
null,
new RectangleF(-w / 2 - r2, -h / 2 - r2, r, r),
new RectangleF(w / 2 - r2, -h / 2 - r2, r, r),
new RectangleF(w / 2 - r2, h / 2 - r2, r, r),
new RectangleF(-w / 2 - r2, h / 2 - r2, r, r),
new RectangleF(-w / 2 - r2, 0 - r2, r, r),
new RectangleF(0 - r2, -h / 2 - r2, r, r),
new RectangleF(w / 2 - r2, 0 - r2, r, r),
new RectangleF(0 - r2, h / 2 - r2, r, r)
];
const widthResizeGripsIndexes = new Array(5, 7);
for (let i = 1, imax = resizeGrips.length; i < imax; i++) {
if (resizeGrips[i].contains(transformedPoint) &&
!(onlyWidthResizeEnabled && !(widthResizeGripsIndexes.indexOf(i) !== -1))) {
result.resize = true;
result.resizeIndex = i;
break;
}
}
// check rotate
result.rotate = false;
const rotationCenter = HitTestManager.getDeltaFromSelectionCenterToRotateCenter(this._canvas.rotationGripSize, Math.abs(h), Math.abs(w), this._canvas.viewer.contentAngle, mul);
r = (this._canvas.rotationGripSize / 2) / mul;
const tx = transformedPoint.x - rotationCenter.x;
const ty = transformedPoint.y - rotationCenter.y;
if (tx * tx + ty * ty < r * r) {
result.rotate = true;
}
return result;
}
/** Get delta from selection center to rotate center. Without angle!*/
static getDeltaFromSelectionCenterToRotateCenter(rotationGripSize, selectionHeight, selectionWidth, contentAngle, mul = 1) {
let cx = 0;
let cy = 0;
;
const r = (rotationGripSize / 2) / mul;
if (contentAngle == 0) {
cx = 0;
cy = selectionHeight / 2 + (rotationGripSize) / mul + r;
}
else if (contentAngle == 90) {
cx = selectionWidth / 2 + (rotationGripSize) / mul + r;
cy = 0;
}
else if (contentAngle == 180) {
cx = 0;
cy = -(selectionHeight / 2 + (rotationGripSize) / mul + r);
}
else if (contentAngle == 270) {
cx = -(selectionWidth / 2 + (rotationGripSize) / mul + r);
cy = 0;
}
return new PointF(cx, cy);
}
get _productHandler() {
return this._canvas.viewer.productHandler;
}
_convertToProductCoord(point) {
return CoordinatesConvertUtils.workspaceToProduct(point, this._canvas.offset);
}
_convertToWorkspace(point, coordinateSystem) {
switch (coordinateSystem) {
case CoordinateSystem.page:
return CoordinatesConvertUtils.pageToWorkspacePoint(point, this._canvas.viewer);
case CoordinateSystem.workspace:
return point;
default:
throw new Error(`Unexpected coordinateSystem ${coordinateSystem}`);
}
}
}
//# sourceMappingURL=HitTestManager.js.map