UNPKG

@alilc/lowcode-editor-core

Version:

Core Api for Ali lowCode engine

262 lines (257 loc) 7.29 kB
"use strict"; exports.__esModule = true; exports.resolvePosition = resolvePosition; exports.resolveRelativePosition = resolveRelativePosition; function resolveEdge(popup, target, arrow, bounds) { var sx = arrow.width > target.width ? (arrow.width - target.width) / 2 : 0; var sy = arrow.width > target.height ? (arrow.width - target.height) / 2 : 0; var top = Math.max(target.top - popup.height + arrow.width - sy, bounds.top); var right = Math.min(target.right + popup.width - arrow.width + sx, bounds.right); var bottom = Math.min(target.bottom + popup.height - arrow.width + sy, bounds.bottom); var left = Math.max(target.left - popup.width + arrow.width - sx, bounds.left); return { top: top, right: right, bottom: bottom, left: left }; } function resolveDirection(popup, target, edge, bounds, prefers) { if (prefers.forceDirection) { return prefers.dir; } var extendWidth = popup.width + popup.extraOffset; var extendHeight = popup.height + popup.extraOffset; var SY = popup.width * extendHeight; var SX = popup.height * extendWidth; var mw = Math.min(edge.right - edge.left, popup.width); var mh = Math.min(edge.bottom - edge.top, popup.height); var mat = { top: function top() { var s = mw * Math.min(target.top - bounds.top, extendHeight); return { s: s, enough: s >= SY }; }, bottom: function bottom() { var s = mw * Math.min(bounds.bottom - target.bottom, extendHeight); return { s: s, enough: s >= SY }; }, left: function left() { var s = mh * Math.min(target.left - bounds.left, extendWidth); return { s: s, enough: s >= SX }; }, right: function right() { var s = mh * Math.min(bounds.right - target.right, extendWidth); return { s: s, enough: s >= SX }; } }; var orders = ['top', 'right', 'bottom', 'left']; if (prefers.dir) { var i = orders.indexOf(prefers.dir); if (i > -1) { orders.splice(i, 1); orders.unshift(prefers.dir); } } var ms = 0; var prefer = orders[0]; for (var _i = 0, l = orders.length; _i < l; _i++) { var dir = orders[_i]; var _mat$dir = mat[dir](), s = _mat$dir.s, enough = _mat$dir.enough; if (enough) { return dir; } if (s > ms) { ms = s; prefer = dir; } } return prefer; } function resolvePrefer(prefer, targetRect, bounds) { if (!prefer) { if (targetRect.left - bounds.left < 10) { return { dir: 'right' }; } else if (targetRect.top - bounds.top < 10) { return { dir: 'bottom' }; } else if (bounds.bottom - targetRect.bottom < 10) { return { dir: 'top' }; } else if (bounds.right - targetRect.right < 10) { return { dir: 'left' }; } return {}; } var force = prefer[0] === '!'; if (force) { prefer = prefer.slice(1); } var _prefer$split = prefer.split(/\s+/), dir = _prefer$split[0], offset = _prefer$split[1]; var forceDirection = false; var forceOffset = false; if (dir === 'center') { dir = 'auto'; if (!offset) { offset = 'center'; } } if (force) { if (dir && dir !== 'auto') { forceDirection = true; } if (offset && offset !== 'auto') { forceOffset = true; } } return { dir: dir, offset: offset, forceDirection: forceDirection, forceOffset: forceOffset }; } function resolvePosition(popup, target, arrow, bounds, prefer) { popup = { extraOffset: arrow.height, top: popup.top, right: popup.right, left: popup.left, bottom: popup.bottom, height: popup.height, width: popup.width }; var prefers = resolvePrefer(prefer, target, bounds); var edge = resolveEdge(popup, target, arrow, bounds); // 选择方向 var dir = resolveDirection(popup, target, edge, bounds, prefers); var top; var left; var arrowTop; var arrowLeft; // 或得该方位上横向 或 纵向的 偏移 if (dir === 'top' || dir === 'bottom') { if (dir === 'top') { top = target.top - popup.extraOffset - popup.height; } else { top = target.bottom + popup.extraOffset; } // 解决横向偏移 var offset = arrow.width > target.width ? (arrow.width - target.width) / 2 : 0; var minLeft = target.left + arrow.width - offset - popup.width; var maxLeft = target.right - arrow.width + offset; var centerLeft = target.left - (popup.width - target.width) / 2; if (prefers.offset === 'left') { left = minLeft; } else if (prefers.offset === 'right') { left = maxLeft; } else { left = centerLeft; } if (!prefers.forceOffset) { left = Math.max(Math.min(edge.right - popup.width, left), minLeft); left = Math.min(Math.max(edge.left, left), maxLeft); } arrowLeft = Math.min(popup.width - arrow.width, Math.max(target.left - (arrow.width - target.width) / 2 - left, 0)); } else { if (dir === 'left') { left = target.left - popup.extraOffset - popup.width; } else { left = target.right + popup.extraOffset; } // 解决纵向偏移 var _offset = arrow.width > target.height ? (arrow.width - target.height) / 2 : 0; var minTop = target.top + arrow.width - _offset - popup.height; var maxTop = target.bottom - arrow.width + _offset; var centerTop = target.top - (popup.height - target.height) / 2; if (prefers.offset === 'top') { top = minTop; } else if (prefers.offset === 'bottom') { top = maxTop; } else { top = centerTop; } if (!prefers.forceOffset) { top = Math.max(Math.min(edge.bottom - popup.height, top), minTop); top = Math.min(Math.max(edge.top, top), maxTop); } arrowTop = Math.min(popup.height - arrow.height, Math.max(target.top - (arrow.width - target.height) / 2 - top, 0)); } return { dir: dir, left: left, top: top, arrowLeft: arrowLeft, arrowTop: arrowTop }; } var percentPresets = { right: 1, left: 0, top: 0, bottom: 1, center: 0.5 }; function isPercent(val) { return /^[\d.]+%$/.test(val); } function resolveRelativeValue(val, offset, total) { if (!val) { val = 0; } else if (isPercent(val)) { val = parseFloat(val) / 100 * total; } else if (percentPresets.hasOwnProperty(val)) { val = percentPresets[val] * total; } else { val = parseFloat(val); if (isNaN(val)) { val = 0; } } return val + offset + "px"; } function resolveRelativePosition(align, popup, bounds) { if (!align) { // return default position return { top: '38.2%', left: 'calc(50% - 110px)' }; } var _align$trim$split = align.trim().split(/\s+/), xAlign = _align$trim$split[0], yAlign = _align$trim$split[1]; if (xAlign === 'top' || xAlign === 'bottom' || yAlign === 'left' || yAlign === 'right') { var tmp = xAlign; xAlign = yAlign; yAlign = tmp; } if (xAlign === 'center' && !yAlign) { yAlign = 'center'; } return { left: resolveRelativeValue(xAlign, 0, bounds.right - bounds.left - popup.width), top: resolveRelativeValue(yAlign, 0, bounds.bottom - bounds.top - popup.height) }; }