UNPKG

sprotty

Version:

A next-gen framework for graphical views

132 lines 6.18 kB
"use strict"; /******************************************************************************** * Copyright (c) 2019 TypeFox and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the Eclipse * Public License v. 2.0 are satisfied: GNU General Public License, version 2 * with the GNU Classpath Exception which is available at * https://www.gnu.org/software/classpath/license.html. * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DiamondAnchor = exports.RectangleAnchor = exports.EllipseAnchor = void 0; const anchor_1 = require("./anchor"); const geometry_1 = require("../../utils/geometry"); const inversify_1 = require("inversify"); const polyline_edge_router_1 = require("./polyline-edge-router"); const geometry_2 = require("sprotty-protocol/lib/utils/geometry"); let EllipseAnchor = class EllipseAnchor { get kind() { return polyline_edge_router_1.PolylineEdgeRouter.KIND + ':' + anchor_1.ELLIPTIC_ANCHOR_KIND; } getAnchor(connectable, refPoint, offset = 0) { const bounds = connectable.bounds; const c = geometry_2.Bounds.center(bounds); const dx = c.x - refPoint.x; const dy = c.y - refPoint.y; const distance = Math.sqrt(dx * dx + dy * dy); const normX = (dx / distance) || 0; const normY = (dy / distance) || 0; return { x: c.x - normX * (0.5 * bounds.width + offset), y: c.y - normY * (0.5 * bounds.height + offset) }; } }; exports.EllipseAnchor = EllipseAnchor; exports.EllipseAnchor = EllipseAnchor = __decorate([ (0, inversify_1.injectable)() ], EllipseAnchor); let RectangleAnchor = class RectangleAnchor { get kind() { return polyline_edge_router_1.PolylineEdgeRouter.KIND + ':' + anchor_1.RECTANGULAR_ANCHOR_KIND; } getAnchor(connectable, refPoint, offset = 0) { const bounds = connectable.bounds; const c = geometry_2.Bounds.center(bounds); const finder = new NearestPointFinder(c, refPoint); if (!(0, geometry_2.almostEquals)(c.y, refPoint.y)) { const xTop = this.getXIntersection(bounds.y, c, refPoint); if (xTop >= bounds.x && xTop <= bounds.x + bounds.width) finder.addCandidate(xTop, bounds.y - offset); const xBottom = this.getXIntersection(bounds.y + bounds.height, c, refPoint); if (xBottom >= bounds.x && xBottom <= bounds.x + bounds.width) finder.addCandidate(xBottom, bounds.y + bounds.height + offset); } if (!(0, geometry_2.almostEquals)(c.x, refPoint.x)) { const yLeft = this.getYIntersection(bounds.x, c, refPoint); if (yLeft >= bounds.y && yLeft <= bounds.y + bounds.height) finder.addCandidate(bounds.x - offset, yLeft); const yRight = this.getYIntersection(bounds.x + bounds.width, c, refPoint); if (yRight >= bounds.y && yRight <= bounds.y + bounds.height) finder.addCandidate(bounds.x + bounds.width + offset, yRight); } return finder.best; } getXIntersection(yIntersection, centerPoint, point) { const t = (yIntersection - centerPoint.y) / (point.y - centerPoint.y); return (point.x - centerPoint.x) * t + centerPoint.x; } getYIntersection(xIntersection, centerPoint, point) { const t = (xIntersection - centerPoint.x) / (point.x - centerPoint.x); return (point.y - centerPoint.y) * t + centerPoint.y; } }; exports.RectangleAnchor = RectangleAnchor; exports.RectangleAnchor = RectangleAnchor = __decorate([ (0, inversify_1.injectable)() ], RectangleAnchor); class NearestPointFinder { constructor(centerPoint, refPoint) { this.centerPoint = centerPoint; this.refPoint = refPoint; this.currentDist = -1; } addCandidate(x, y) { const dx = this.refPoint.x - x; const dy = this.refPoint.y - y; const dist = dx * dx + dy * dy; if (this.currentDist < 0 || dist < this.currentDist) { this.currentBest = { x: x, y: y }; this.currentDist = dist; } } get best() { if (this.currentBest === undefined) return this.centerPoint; else return this.currentBest; } } let DiamondAnchor = class DiamondAnchor { get kind() { return polyline_edge_router_1.PolylineEdgeRouter.KIND + ':' + anchor_1.DIAMOND_ANCHOR_KIND; } getAnchor(connectable, refPoint, offset) { const bounds = connectable.bounds; const referenceLine = new geometry_1.PointToPointLine(geometry_2.Bounds.center(bounds), refPoint); const closestDiamondSide = new geometry_1.Diamond(bounds).closestSideLine(refPoint); const anchorPoint = (0, geometry_1.intersection)(closestDiamondSide, referenceLine); return geometry_2.Point.shiftTowards(anchorPoint, refPoint, offset); } }; exports.DiamondAnchor = DiamondAnchor; exports.DiamondAnchor = DiamondAnchor = __decorate([ (0, inversify_1.injectable)() ], DiamondAnchor); //# sourceMappingURL=polyline-anchors.js.map