croact-moveable
Version:
A React Compat Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Pinchable, Groupable, Snappable.
1,161 lines (1,136 loc) • 600 kB
JavaScript
/*
Copyright (c) 2019 Daybrush
name: croact-moveable
license: MIT
author: Daybrush
repository: https://github.com/daybrush/moveable/blob/master/packages/croact-moveable
version: 0.9.0
*/
'use strict';
var getAgent = require('@egjs/agent');
var frameworkUtils = require('framework-utils');
var utils = require('@daybrush/utils');
var matrix = require('@scena/matrix');
var cssToMat = require('css-to-mat');
var ChildrenDiffer = require('@egjs/children-differ');
var DragScroll = require('@scena/dragscroll');
var overlapArea = require('overlap-area');
var React = require('croact');
var Gesto = require('gesto');
var croactCssStyled = require('croact-css-styled');
var EventEmitter = require('@scena/event-emitter');
var listDiffer = require('@egjs/list-differ');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return n;
}
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
/*
Copyright (c) 2019 Daybrush
name: react-moveable
license: MIT
author: Daybrush
repository: https://github.com/daybrush/moveable/blob/master/packages/react-moveable
version: 0.56.0
*/
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(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);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(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;
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
function makeAble(name, able) {
return __assign({ events: [], props: [], name: name }, able);
}
var DIRECTIONS4 = ["n", "w", "s", "e"];
var DIRECTIONS = ["n", "w", "s", "e", "nw", "ne", "sw", "se"];
function getSVGCursor(scale, degree) {
return "data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"".concat(32 * scale, "px\" height=\"").concat(32 * scale, "px\" viewBox=\"0 0 32 32\" ><path d=\"M 16,5 L 12,10 L 14.5,10 L 14.5,22 L 12,22 L 16,27 L 20,22 L 17.5,22 L 17.5,10 L 20, 10 L 16,5 Z\" stroke-linejoin=\"round\" stroke-width=\"1.2\" fill=\"black\" stroke=\"white\" style=\"transform:rotate(").concat(degree, "deg);transform-origin: 16px 16px\"></path></svg>");
}
function getCursorCSS(degree) {
var x1 = getSVGCursor(1, degree);
// const x2 = getSVGCursor(2, degree);
var degree45 = (Math.round(degree / 45) * 45) % 180;
var defaultCursor = "ns-resize";
if (degree45 === 135) {
defaultCursor = "nwse-resize";
}
else if (degree45 === 45) {
defaultCursor = "nesw-resize";
}
else if (degree45 === 90) {
defaultCursor = "ew-resize";
}
// tslint:disable-next-line: max-line-length
return "cursor:".concat(defaultCursor, ";cursor: url('").concat(x1, "') 16 16, ").concat(defaultCursor, ";");
}
var agent = getAgent();
var IS_WEBKIT = agent.browser.webkit;
var IS_WEBKIT605 = IS_WEBKIT && (function () {
var navi = typeof window === "undefined" ? { userAgent: "" } : window.navigator;
var res = /applewebkit\/([^\s]+)/g.exec(navi.userAgent.toLowerCase());
return res ? parseFloat(res[1]) < 605 : false;
})();
var browserName = agent.browser.name;
var browserVersion = parseInt(agent.browser.version, 10);
var IS_CHROME = browserName === "chrome";
var IS_CHROMIUM = agent.browser.chromium;
var chromiumVersion = parseInt(agent.browser.chromiumVersion, 10) || 0;
var IS_CHROMIUM109 = (IS_CHROME && browserVersion >= 109)
|| (IS_CHROMIUM && chromiumVersion >= 109);
var IS_FIREFOX = browserName === "firefox";
var IS_SAFARI_ABOVE15 = parseInt(agent.browser.webkitVersion, 10) >= 612
|| browserVersion >= 15;
var PREFIX = "moveable-";
var directionCSS = DIRECTIONS.map(function (dir) {
var top = "";
var left = "";
var originX = "center";
var originY = "center";
var offset = "calc(var(--moveable-control-padding, 20) * -1px)";
if (dir.indexOf("n") > -1) {
top = "top: ".concat(offset, ";");
originY = "bottom";
}
if (dir.indexOf("s") > -1) {
top = "top: 0px;";
originY = "top";
}
if (dir.indexOf("w") > -1) {
left = "left: ".concat(offset, ";");
originX = "right";
}
if (dir.indexOf("e") > -1) {
left = "left: 0px;";
originX = "left";
}
return ".around-control[data-direction*=\"".concat(dir, "\"] {\n ").concat(left).concat(top, "\n transform-origin: ").concat(originX, " ").concat(originY, ";\n }");
}).join("\n");
var MOVEABLE_CSS = "\n{\nposition: absolute;\nwidth: 1px;\nheight: 1px;\nleft: 0;\ntop: 0;\nz-index: 3000;\n--moveable-color: #4af;\n--zoom: 1;\n--zoompx: 1px;\n--moveable-line-padding: 0;\n--moveable-control-padding: 0;\nwill-change: transform;\noutline: 1px solid transparent;\n}\n.control-box {\nz-index: 0;\n}\n.line, .control {\nposition: absolute;\nleft: 0;\ntop: 0;\nwill-change: transform;\n}\n.control {\nwidth: 14px;\nheight: 14px;\nborder-radius: 50%;\nborder: 2px solid #fff;\nbox-sizing: border-box;\nbackground: #4af;\nbackground: var(--moveable-color);\nmargin-top: -7px;\nmargin-left: -7px;\nborder: 2px solid #fff;\nz-index: 10;\n}\n.around-control {\nposition: absolute;\nwill-change: transform;\nwidth: calc(var(--moveable-control-padding, 20) * 1px);\nheight: calc(var(--moveable-control-padding, 20) * 1px);\nleft: calc(var(--moveable-control-padding, 20) * -0.5px);\ntop: calc(var(--moveable-control-padding, 20) * -0.5px);\nbox-sizing: border-box;\nbackground: transparent;\nz-index: 8;\ncursor: alias;\ntransform-origin: center center;\n}\n".concat(directionCSS, "\n.padding {\nposition: absolute;\ntop: 0px;\nleft: 0px;\nwidth: 100px;\nheight: 100px;\ntransform-origin: 0 0;\n}\n.line {\nwidth: 1px;\nheight: 1px;\nbackground: #4af;\nbackground: var(--moveable-color);\ntransform-origin: 0px 50%;\n}\n.line.edge {\nz-index: 1;\nbackground: transparent;\n}\n.line.dashed {\nbox-sizing: border-box;\nbackground: transparent;\n}\n.line.dashed.horizontal {\nborder-top: 1px dashed #4af;\nborder-top-color: #4af;\nborder-top-color: var(--moveable-color);\n}\n.line.dashed.vertical {\nborder-left: 1px dashed #4af;\nborder-left-color: #4af;\nborder-left-color: var(--moveable-color);\n}\n.line.vertical {\ntransform: translateX(-50%);\n}\n.line.horizontal {\ntransform: translateY(-50%);\n}\n.line.vertical.bold {\nwidth: 2px;\n}\n.line.horizontal.bold {\nheight: 2px;\n}\n\n.control.origin {\nborder-color: #f55;\nbackground: #fff;\nwidth: 12px;\nheight: 12px;\nmargin-top: -6px;\nmargin-left: -6px;\npointer-events: none;\n}\n").concat([0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165].map(function (degree) { return "\n.direction[data-rotation=\"".concat(degree, "\"], :global .view-control-rotation").concat(degree, " {\n").concat(getCursorCSS(degree), "\n}\n"); }).join("\n"), "\n\n.line.direction:before {\ncontent: \"\";\nposition: absolute;\nwidth: 100%;\nheight: calc(var(--moveable-line-padding, 0) * 1px);\nbottom: 0;\nleft: 0;\n}\n.group {\nz-index: -1;\n}\n.area {\nposition: absolute;\n}\n.area-pieces {\nposition: absolute;\ntop: 0;\nleft: 0;\ndisplay: none;\n}\n.area.avoid, .area.pass {\npointer-events: none;\n}\n.area.avoid+.area-pieces {\ndisplay: block;\n}\n.area-piece {\nposition: absolute;\n}\n\n").concat(IS_WEBKIT605 ? ":global svg *:before {\ncontent:\"\";\ntransform-origin: inherit;\n}" : "", "\n");
var NEARBY_POS = [
[0, 1, 2],
[1, 0, 3],
[2, 0, 3],
[3, 1, 2],
];
var FLOAT_POINT_NUM = 0.0001;
var TINY_NUM = 0.0000001;
var MIN_SCALE = 0.000000001;
var MAX_NUM = Math.pow(10, 10);
var MIN_NUM = -MAX_NUM;
var DIRECTION_REGION_TO_DIRECTION = {
n: [0, -1],
e: [1, 0],
s: [0, 1],
w: [-1, 0],
nw: [-1, -1],
ne: [1, -1],
sw: [-1, 1],
se: [1, 1],
};
var DIRECTION_INDEXES = {
n: [0, 1],
e: [1, 3],
s: [3, 2],
w: [2, 0],
nw: [0],
ne: [1],
sw: [2],
se: [3],
};
var DIRECTION_ROTATIONS = {
n: 0,
s: 180,
w: 270,
e: 90,
nw: 315,
ne: 45,
sw: 225,
se: 135,
};
var MOVEABLE_METHODS = [
"isMoveableElement",
"updateRect",
"updateTarget",
"destroy",
"dragStart",
"isInside",
"hitTest",
"setState",
"getRect",
"request",
"isDragging",
"getManager",
"forceUpdate",
"waitToChangeTarget",
"updateSelectors",
"getTargets",
"stopDrag",
"getControlBoxElement",
"getMoveables",
"getDragElement",
];
function setCustomDrag(e, state, delta, isPinch, isConvert, ableName) {
var _a, _b;
if (ableName === void 0) { ableName = "draggable"; }
var result = (_b = (_a = state.gestos[ableName]) === null || _a === void 0 ? void 0 : _a.move(delta, e.inputEvent)) !== null && _b !== void 0 ? _b : {};
var datas = result.originalDatas || result.datas;
var ableDatas = datas[ableName] || (datas[ableName] = {});
return __assign(__assign({}, (isConvert ? convertDragDist(state, result) : result)), { isPinch: !!isPinch, parentEvent: true, datas: ableDatas, originalDatas: e.originalDatas });
}
var CustomGesto = /*#__PURE__*/ (function () {
function CustomGesto(ableName) {
var _a;
if (ableName === void 0) { ableName = "draggable"; }
this.ableName = ableName;
this.prevX = 0;
this.prevY = 0;
this.startX = 0;
this.startY = 0;
this.isDrag = false;
this.isFlag = false;
this.datas = {
draggable: {},
};
this.datas = (_a = {},
_a[ableName] = {},
_a);
}
CustomGesto.prototype.dragStart = function (client, e) {
this.isDrag = false;
this.isFlag = false;
var originalDatas = e.originalDatas;
this.datas = originalDatas;
if (!originalDatas[this.ableName]) {
originalDatas[this.ableName] = {};
}
return __assign(__assign({}, this.move(client, e.inputEvent)), { type: "dragstart" });
};
CustomGesto.prototype.drag = function (client, inputEvent) {
return this.move([
client[0] - this.prevX,
client[1] - this.prevY,
], inputEvent);
};
CustomGesto.prototype.move = function (delta, inputEvent) {
var clientX;
var clientY;
var isFirstDrag = false;
if (!this.isFlag) {
this.prevX = delta[0];
this.prevY = delta[1];
this.startX = delta[0];
this.startY = delta[1];
clientX = delta[0];
clientY = delta[1];
this.isFlag = true;
}
else {
var isPrevDrag = this.isDrag;
clientX = this.prevX + delta[0];
clientY = this.prevY + delta[1];
if (delta[0] || delta[1]) {
this.isDrag = true;
}
if (!isPrevDrag && this.isDrag) {
isFirstDrag = true;
}
}
this.prevX = clientX;
this.prevY = clientY;
return {
type: "drag",
clientX: clientX,
clientY: clientY,
inputEvent: inputEvent,
isFirstDrag: isFirstDrag,
isDrag: this.isDrag,
distX: clientX - this.startX,
distY: clientY - this.startY,
deltaX: delta[0],
deltaY: delta[1],
datas: this.datas[this.ableName],
originalDatas: this.datas,
parentEvent: true,
parentGesto: this,
};
};
return CustomGesto;
}());
function calculateElementPosition(matrix, origin, width, height) {
var is3d = matrix.length === 16;
var n = is3d ? 4 : 3;
var poses = calculatePoses(matrix, width, height, n);
var _a = __read(poses, 4), _b = __read(_a[0], 2), x1 = _b[0], y1 = _b[1], _c = __read(_a[1], 2), x2 = _c[0], y2 = _c[1], _d = __read(_a[2], 2), x3 = _d[0], y3 = _d[1], _e = __read(_a[3], 2), x4 = _e[0], y4 = _e[1];
var _f = __read(calculatePosition(matrix, origin, n), 2), originX = _f[0], originY = _f[1];
var left = Math.min(x1, x2, x3, x4);
var top = Math.min(y1, y2, y3, y4);
var right = Math.max(x1, x2, x3, x4);
var bottom = Math.max(y1, y2, y3, y4);
x1 = (x1 - left) || 0;
x2 = (x2 - left) || 0;
x3 = (x3 - left) || 0;
x4 = (x4 - left) || 0;
y1 = (y1 - top) || 0;
y2 = (y2 - top) || 0;
y3 = (y3 - top) || 0;
y4 = (y4 - top) || 0;
originX = (originX - left) || 0;
originY = (originY - top) || 0;
var sx = matrix[0];
var sy = matrix[n + 1];
var direction = sign(sx * sy);
return {
left: left,
top: top,
right: right,
bottom: bottom,
origin: [originX, originY],
pos1: [x1, y1],
pos2: [x2, y2],
pos3: [x3, y3],
pos4: [x4, y4],
direction: direction,
};
}
function calculatePointerDist(moveable, e) {
var clientX = e.clientX, clientY = e.clientY, datas = e.datas;
var _a = moveable.state, moveableClientRect = _a.moveableClientRect, rootMatrix = _a.rootMatrix, is3d = _a.is3d, pos1 = _a.pos1;
var left = moveableClientRect.left, top = moveableClientRect.top;
var n = is3d ? 4 : 3;
var _b = __read(matrix.minus(calculateInversePosition(rootMatrix, [clientX - left, clientY - top], n), pos1), 2), posX = _b[0], posY = _b[1];
var _c = __read(getDragDist({ datas: datas, distX: posX, distY: posY }), 2), distX = _c[0], distY = _c[1];
return [distX, distY];
}
function setDragStart(moveable, _a) {
var datas = _a.datas;
var _b = moveable.state, allMatrix = _b.allMatrix, beforeMatrix = _b.beforeMatrix, is3d = _b.is3d, left = _b.left, top = _b.top, origin = _b.origin, offsetMatrix = _b.offsetMatrix, targetMatrix = _b.targetMatrix, transformOrigin = _b.transformOrigin;
var n = is3d ? 4 : 3;
datas.is3d = is3d;
datas.matrix = allMatrix;
datas.targetMatrix = targetMatrix;
datas.beforeMatrix = beforeMatrix;
datas.offsetMatrix = offsetMatrix;
datas.transformOrigin = transformOrigin;
datas.inverseMatrix = matrix.invert(allMatrix, n);
datas.inverseBeforeMatrix = matrix.invert(beforeMatrix, n);
datas.absoluteOrigin = matrix.convertPositionMatrix(matrix.plus([left, top], origin), n);
datas.startDragBeforeDist = matrix.calculate(datas.inverseBeforeMatrix, datas.absoluteOrigin, n);
datas.startDragDist = matrix.calculate(datas.inverseMatrix, datas.absoluteOrigin, n);
}
function getTransformDirection(e) {
return calculateElementPosition(e.datas.beforeTransform, [50, 50], 100, 100).direction;
}
function resolveTransformEvent(moveable, event, functionName) {
var datas = event.datas, originalDatas = event.originalDatas.beforeRenderable;
var index = datas.transformIndex;
var nextTransforms = originalDatas.nextTransforms;
var length = nextTransforms.length;
var nextTransformAppendedIndexes = originalDatas.nextTransformAppendedIndexes;
var nextIndex = -1;
if (index === -1) {
// translate => rotate => scale
if (functionName === "translate") {
nextIndex = 0;
}
else if (functionName === "rotate") {
nextIndex = utils.findIndex(nextTransforms, function (text) { return text.match(/scale\(/g); });
}
if (nextIndex === -1) {
nextIndex = nextTransforms.length;
}
datas.transformIndex = nextIndex;
}
else if (utils.find(nextTransformAppendedIndexes, function (info) { return info.index === index && info.functionName === functionName; })) {
nextIndex = index;
}
else {
nextIndex = index + nextTransformAppendedIndexes.filter(function (info) { return info.index < index; }).length;
}
var result = convertTransformInfo(nextTransforms, moveable.state, nextIndex);
var targetFunction = result.targetFunction;
var matFunctionName = functionName === "rotate" ? "rotateZ" : functionName;
datas.beforeFunctionTexts = result.beforeFunctionTexts;
datas.afterFunctionTexts = result.afterFunctionTexts;
datas.beforeTransform = result.beforeFunctionMatrix;
datas.beforeTransform2 = result.beforeFunctionMatrix2;
datas.targetTansform = result.targetFunctionMatrix;
datas.afterTransform = result.afterFunctionMatrix;
datas.afterTransform2 = result.afterFunctionMatrix2;
datas.targetAllTransform = result.allFunctionMatrix;
if (targetFunction.functionName === matFunctionName) {
datas.afterFunctionTexts.splice(0, 1);
datas.isAppendTransform = false;
}
else if (length > nextIndex) {
datas.isAppendTransform = true;
originalDatas.nextTransformAppendedIndexes = __spreadArray(__spreadArray([], __read(nextTransformAppendedIndexes), false), [{
functionName: functionName,
index: nextIndex,
isAppend: true,
}], false);
}
}
function convertTransformFormat(datas, value, dist) {
return "".concat(datas.beforeFunctionTexts.join(" "), " ").concat(datas.isAppendTransform ? dist : value, " ").concat(datas.afterFunctionTexts.join(" "));
}
function getTransformDist(_a) {
var datas = _a.datas, distX = _a.distX, distY = _a.distY;
var _b = __read(getBeforeDragDist({ datas: datas, distX: distX, distY: distY }), 2), bx = _b[0], by = _b[1];
// B * [tx, ty] * A = [bx, by] * targetMatrix;
// [tx, ty] = B-1 * [bx, by] * targetMatrix * A-1 * [0, 0];
var res = getTransfromMatrix(datas, matrix.fromTranslation([bx, by], 4));
return matrix.calculate(res, matrix.convertPositionMatrix([0, 0, 0], 4), 4);
}
function getTransfromMatrix(datas, targetMatrix, isAfter) {
var beforeTransform = datas.beforeTransform, afterTransform = datas.afterTransform, beforeTransform2 = datas.beforeTransform2, afterTransform2 = datas.afterTransform2, targetAllTransform = datas.targetAllTransform;
// B * afterTargetMatrix * A = (targetMatrix * targetAllTransform)
// afterTargetMatrix = B-1 * targetMatrix * targetAllTransform * A-1
// nextTargetMatrix = (targetMatrix * targetAllTransform)
var nextTargetMatrix = isAfter
? matrix.multiply(targetAllTransform, targetMatrix, 4)
: matrix.multiply(targetMatrix, targetAllTransform, 4);
// res1 = B-1 * nextTargetMatrix
var res1 = matrix.multiply(matrix.invert(isAfter ? beforeTransform2 : beforeTransform, 4), nextTargetMatrix, 4);
// res3 = res2 * A-1
var afterTargetMatrix = matrix.multiply(res1, matrix.invert(isAfter ? afterTransform2 : afterTransform, 4), 4);
return afterTargetMatrix;
}
function getBeforeDragDist(_a) {
var datas = _a.datas, distX = _a.distX, distY = _a.distY;
// TT = BT
var inverseBeforeMatrix = datas.inverseBeforeMatrix, is3d = datas.is3d, startDragBeforeDist = datas.startDragBeforeDist, absoluteOrigin = datas.absoluteOrigin;
var n = is3d ? 4 : 3;
// ABS_ORIGIN * [distX, distY] = BM * (ORIGIN + [tx, ty])
// BM -1 * ABS_ORIGIN * [distX, distY] - ORIGIN = [tx, ty]
return matrix.minus(matrix.calculate(inverseBeforeMatrix, matrix.plus(absoluteOrigin, [distX, distY]), n), startDragBeforeDist);
}
function getDragDist(_a, isBefore) {
var datas = _a.datas, distX = _a.distX, distY = _a.distY;
var inverseBeforeMatrix = datas.inverseBeforeMatrix, inverseMatrix = datas.inverseMatrix, is3d = datas.is3d, startDragBeforeDist = datas.startDragBeforeDist, startDragDist = datas.startDragDist, absoluteOrigin = datas.absoluteOrigin;
var n = is3d ? 4 : 3;
return matrix.minus(matrix.calculate(isBefore ? inverseBeforeMatrix : inverseMatrix, matrix.plus(absoluteOrigin, [distX, distY]), n), isBefore ? startDragBeforeDist : startDragDist);
}
function getInverseDragDist(_a, isBefore) {
var datas = _a.datas, distX = _a.distX, distY = _a.distY;
var beforeMatrix = datas.beforeMatrix, matrix$1 = datas.matrix, is3d = datas.is3d, startDragBeforeDist = datas.startDragBeforeDist, startDragDist = datas.startDragDist, absoluteOrigin = datas.absoluteOrigin;
var n = is3d ? 4 : 3;
return matrix.minus(matrix.calculate(isBefore ? beforeMatrix : matrix$1, matrix.plus(isBefore ? startDragBeforeDist : startDragDist, [distX, distY]), n), absoluteOrigin);
}
function calculateTransformOrigin(transformOrigin, width, height, prevWidth, prevHeight, prevOrigin) {
if (prevWidth === void 0) { prevWidth = width; }
if (prevHeight === void 0) { prevHeight = height; }
if (prevOrigin === void 0) { prevOrigin = [0, 0]; }
if (!transformOrigin) {
return prevOrigin;
}
return transformOrigin.map(function (pos, i) {
var _a = utils.splitUnit(pos), value = _a.value, unit = _a.unit;
var prevSize = (i ? prevHeight : prevWidth);
var size = (i ? height : width);
if (pos === "%" || isNaN(value)) {
// no value but %
var measureRatio = prevSize ? prevOrigin[i] / prevSize : 0;
return size * measureRatio;
}
else if (unit !== "%") {
return value;
}
return size * value / 100;
});
}
function getPosIndexesByDirection(direction) {
var indexes = [];
if (direction[1] >= 0) {
if (direction[0] >= 0) {
indexes.push(3);
}
if (direction[0] <= 0) {
indexes.push(2);
}
}
if (direction[1] <= 0) {
if (direction[0] >= 0) {
indexes.push(1);
}
if (direction[0] <= 0) {
indexes.push(0);
}
}
return indexes;
}
function getPosesByDirection(poses, direction) {
/*
[-1, -1](pos1) [0, -1](pos1,pos2) [1, -1](pos2)
[-1, 0](pos1, pos3) [1, 0](pos2, pos4)
[-1, 1](pos3) [0, 1](pos3, pos4) [1, 1](pos4)
*/
return getPosIndexesByDirection(direction).map(function (index) { return poses[index]; });
}
function getPosBySingleDirection(poses, direction) {
var ratio = (direction + 1) / 2;
return [
utils.dot(poses[0][0], poses[1][0], ratio, 1 - ratio),
utils.dot(poses[0][1], poses[1][1], ratio, 1 - ratio),
];
}
function getPosByDirection(poses, direction) {
var top = getPosBySingleDirection([poses[0], poses[1]], direction[0]);
var bottom = getPosBySingleDirection([poses[2], poses[3]], direction[0]);
return getPosBySingleDirection([top, bottom], direction[1]);
}
function getDist(startPos, matrix, width, height, n, fixedDirection) {
var poses = calculatePoses(matrix, width, height, n);
var fixedPos = getPosByDirection(poses, fixedDirection);
var distX = startPos[0] - fixedPos[0];
var distY = startPos[1] - fixedPos[1];
return [distX, distY];
}
function getNextMatrix(offsetMatrix, targetMatrix, origin, n) {
return matrix.multiply(offsetMatrix, getAbsoluteMatrix(targetMatrix, n, origin), n);
}
function getNextTransformMatrix(state, datas, transform, isAllTransform) {
var transformOrigin = state.transformOrigin, offsetMatrix = state.offsetMatrix, is3d = state.is3d;
var n = is3d ? 4 : 3;
var targetTransform;
if (utils.isString(transform)) {
var beforeTransform = datas.beforeTransform, afterTransform = datas.afterTransform;
if (isAllTransform) {
targetTransform = matrix.convertDimension(cssToMat.parseMat(transform), 4, n);
}
else {
targetTransform = matrix.convertDimension(matrix.multiply(matrix.multiply(beforeTransform, cssToMat.parseMat([transform]), 4), afterTransform, 4), 4, n);
}
}
else {
targetTransform = transform;
}
return getNextMatrix(offsetMatrix, targetTransform, transformOrigin, n);
}
function scaleMatrix(state, scale) {
var transformOrigin = state.transformOrigin, offsetMatrix = state.offsetMatrix, is3d = state.is3d, targetMatrix = state.targetMatrix, targetAllTransform = state.targetAllTransform;
var n = is3d ? 4 : 3;
return getNextMatrix(offsetMatrix, matrix.multiply(targetAllTransform || targetMatrix, matrix.createScaleMatrix(scale, n), n), transformOrigin, n);
}
function fillTransformStartEvent(moveable, e) {
var originalDatas = getBeforeRenderableDatas(e);
return {
setTransform: function (transform, index) {
if (index === void 0) { index = -1; }
originalDatas.startTransforms = utils.isArray(transform) ? transform : utils.splitSpace(transform);
setTransformIndex(moveable, e, index);
},
setTransformIndex: function (index) {
setTransformIndex(moveable, e, index);
},
};
}
function setDefaultTransformIndex(moveable, e, property) {
var originalDatas = getBeforeRenderableDatas(e);
var startTransforms = originalDatas.startTransforms;
setTransformIndex(moveable, e, utils.findIndex(startTransforms, function (func) { return func.indexOf("".concat(property, "(")) === 0; }));
}
function setTransformIndex(moveable, e, index) {
var originalDatas = getBeforeRenderableDatas(e);
var datas = e.datas;
datas.transformIndex = index;
if (index === -1) {
return;
}
var transform = originalDatas.startTransforms[index];
if (!transform) {
return;
}
var state = moveable.state;
var info = cssToMat.parse([transform], {
"x%": function (v) { return v / 100 * state.offsetWidth; },
"y%": function (v) { return v / 100 * state.offsetHeight; },
});
datas.startValue = info[0].functionValue;
}
function fillOriginalTransform(e, transform) {
var originalDatas = getBeforeRenderableDatas(e);
originalDatas.nextTransforms = utils.splitSpace(transform);
// originalDatas.nextTargetMatrix = parseMat(transform);
}
function getBeforeRenderableDatas(e) {
return e.originalDatas.beforeRenderable;
}
function getNextTransforms(e) {
var originalDatas = e.originalDatas.beforeRenderable;
return originalDatas.nextTransforms;
}
function getNextTransformText(e) {
return (getNextTransforms(e) || []).join(" ");
}
function getNextStyle(e) {
return getBeforeRenderableDatas(e).nextStyle;
}
function fillTransformEvent(moveable, nextTransform, delta, isPinch, e) {
fillOriginalTransform(e, nextTransform);
var drag = Draggable.drag(moveable, setCustomDrag(e, moveable.state, delta, isPinch, false));
var afterTransform = drag ? drag.transform : nextTransform;
return __assign(__assign({ transform: nextTransform, drag: drag }, fillCSSObject({
transform: afterTransform,
}, e)), { afterTransform: afterTransform });
}
function getTranslateFixedPosition(moveable, transform, fixedDirection, fixedOffset, datas, isAllTransform) {
var nextMatrix = getNextTransformMatrix(moveable.state, datas, transform, isAllTransform);
var nextFixedPosition = getDirectionOffset(moveable, fixedDirection, fixedOffset, nextMatrix);
return nextFixedPosition;
}
function getTranslateDist(moveable, transform, fixedDirection, fixedPosition, fixedOffset, datas, isAllTransform) {
var nextFixedPosition = getTranslateFixedPosition(moveable, transform, fixedDirection, fixedOffset, datas, isAllTransform);
var state = moveable.state;
var left = state.left, top = state.top;
var groupable = moveable.props.groupable;
var groupLeft = groupable ? left : 0;
var groupTop = groupable ? top : 0;
var dist = matrix.minus(fixedPosition, nextFixedPosition);
return matrix.minus(dist, [groupLeft, groupTop]);
}
function getScaleDist(moveable, transform, fixedDirection, fixedPosition, fixedOffset, datas, isAllTransform) {
var dist = getTranslateDist(moveable, transform, fixedDirection, fixedPosition, fixedOffset, datas, isAllTransform);
return dist;
}
function getDirectionByPos(pos, width, height) {
return [
width ? -1 + pos[0] / (width / 2) : 0,
height ? -1 + pos[1] / (height / 2) : 0,
];
}
function getDirectionOffset(moveable, fixedDirection, fixedOffset, nextMatrix) {
if (nextMatrix === void 0) { nextMatrix = moveable.state.allMatrix; }
var _a = moveable.state, width = _a.width, height = _a.height, is3d = _a.is3d;
var n = is3d ? 4 : 3;
var fixedOffsetPosition = [
width / 2 * (1 + fixedDirection[0]) + fixedOffset[0],
height / 2 * (1 + fixedDirection[1]) + fixedOffset[1],
];
return calculatePosition(nextMatrix, fixedOffsetPosition, n);
}
function getRotateDist(moveable, rotateDist, datas) {
var fixedDirection = datas.fixedDirection;
var fixedPosition = datas.fixedPosition;
var fixedOffset = datas.fixedOffset;
return getTranslateDist(moveable, "rotate(".concat(rotateDist, "deg)"), fixedDirection, fixedPosition, fixedOffset, datas);
}
function getResizeDist(moveable, width, height, fixedPosition, transformOrigin, datas) {
var groupable = moveable.props.groupable;
var state = moveable.state;
var prevOrigin = state.transformOrigin, offsetMatrix = state.offsetMatrix, is3d = state.is3d, prevWidth = state.width, prevHeight = state.height, left = state.left, top = state.top;
var fixedDirection = datas.fixedDirection;
var targetMatrix = datas.nextTargetMatrix || state.targetMatrix;
var n = is3d ? 4 : 3;
var nextOrigin = calculateTransformOrigin(transformOrigin, width, height, prevWidth, prevHeight, prevOrigin);
var groupLeft = groupable ? left : 0;
var groupTop = groupable ? top : 0;
var nextMatrix = getNextMatrix(offsetMatrix, targetMatrix, nextOrigin, n);
var dist = getDist(fixedPosition, nextMatrix, width, height, n, fixedDirection);
return matrix.minus(dist, [groupLeft, groupTop]);
}
function getAbsolutePosition(moveable, direction) {
return getPosByDirection(getAbsolutePosesByState(moveable.state), direction);
}
function getGestoData(moveable, ableName) {
var targetGesto = moveable.targetGesto;
var controlGesto = moveable.controlGesto;
var data;
if (targetGesto === null || targetGesto === void 0 ? void 0 : targetGesto.isFlag()) {
data = targetGesto.getEventData()[ableName];
}
if (!data && (controlGesto === null || controlGesto === void 0 ? void 0 : controlGesto.isFlag())) {
data = controlGesto.getEventData()[ableName];
}
return data || {};
}
function getShadowRoot(parentElement) {
if (parentElement && parentElement.getRootNode) {
var rootNode = parentElement.getRootNode();
if (rootNode.nodeType === 11) {
return rootNode;
}
}
return;
}
function getIndividualTransforms(getStyle) {
var scale = getStyle("scale");
var rotate = getStyle("rotate");
var translate = getStyle("translate");
var individualTransforms = [];
if (translate && translate !== "0px" && translate !== "none") {
individualTransforms.push("translate(".concat(translate.split(/\s+/).join(","), ")"));
}
if (rotate && rotate !== "1" && rotate !== "none") {
individualTransforms.push("rotate(".concat(rotate, ")"));
}
if (scale && scale !== "1" && scale !== "none") {
individualTransforms.push("scale(".concat(scale.split(/\s+/).join(","), ")"));
}
return individualTransforms;
}
function getMatrixStackInfo(target, container, checkContainer) {
var el = target;
var matrixes = [];
var documentElement = utils.getDocumentElement(target) || utils.getDocumentBody(target);
var requestEnd = !checkContainer && target === container || target === documentElement;
var isEnd = requestEnd;
var is3d = false;
var n = 3;
var transformOrigin;
var targetTransformOrigin;
var targetMatrix;
var hasFixed = false;
var offsetContainer = getOffsetInfo(container, container, true).offsetParent;
var zoom = 1;
while (el && !isEnd) {
isEnd = requestEnd;
var getStyle = getCachedStyle(el);
var position = getStyle("position");
var transform = getElementTransform(el);
var isFixed = position === "fixed";
var individualTransforms = getIndividualTransforms(getStyle);
var matrix$1 = matrix.convertCSStoMatrix(getTransformMatrix(transform));
var offsetParent = void 0;
var isOffsetEnd = false;
var isStatic = false;
var parentClientLeft = 0;
var parentClientTop = 0;
var fixedClientLeft = 0;
var fixedClientTop = 0;
var fixedInfo = {
hasTransform: false,
fixedContainer: null,
};
if (isFixed) {
hasFixed = true;
fixedInfo = getPositionFixedInfo(el);
offsetContainer = fixedInfo.fixedContainer;
}
// convert 3 to 4
var length_1 = matrix$1.length;
if (!is3d && (length_1 === 16 || individualTransforms.length)) {
is3d = true;
n = 4;
convert3DMatrixes(matrixes);
if (targetMatrix) {
targetMatrix = matrix.convertDimension(targetMatrix, 3, 4);
}
}
if (is3d && length_1 === 9) {
matrix$1 = matrix.convertDimension(matrix$1, 3, 4);
}
var _a = getOffsetPosInfo(el, target), tagName = _a.tagName, hasOffset = _a.hasOffset, isSVG = _a.isSVG, origin_1 = _a.origin, targetOrigin = _a.targetOrigin, offsetPos = _a.offset;
var _b = __read(offsetPos, 2), offsetLeft = _b[0], offsetTop = _b[1];
// no target with svg
if (tagName === "svg" && !el.ownerSVGElement && targetMatrix) {
// scale matrix for svg's SVGElements.
matrixes.push({
type: "target",
target: el,
matrix: getSVGMatrix(el, n),
});
matrixes.push({
type: "offset",
target: el,
matrix: matrix.createIdentityMatrix(n),
});
}
var targetZoom = parseFloat(getStyle("zoom")) || 1;
if (isFixed) {
offsetParent = fixedInfo.fixedContainer;
isOffsetEnd = true;
}
else {
var offsetInfo = getOffsetInfo(el, container, false, true, getStyle);
var offsetZoom = offsetInfo.offsetZoom;
offsetParent = offsetInfo.offsetParent;
isOffsetEnd = offsetInfo.isEnd;
isStatic = offsetInfo.isStatic;
zoom *= offsetZoom;
if ((offsetInfo.isCustomElement || offsetZoom !== 1) && isStatic) {
offsetLeft -= offsetParent.offsetLeft;
offsetTop -= offsetParent.offsetTop;
}
else if (IS_FIREFOX || IS_CHROMIUM109) {
var parentSlotElement = offsetInfo.parentSlotElement;
if (parentSlotElement) {
var customOffsetParent = offsetParent;
var customOffsetLeft = 0;
var customOffsetTop = 0;
while (customOffsetParent) {
if (!getShadowRoot(customOffsetParent)) {
break;
}
customOffsetLeft += customOffsetParent.offsetLeft;
customOffsetTop += customOffsetParent.offsetTop;
customOffsetParent = customOffsetParent.offsetParent;
}
offsetLeft -= customOffsetLeft;
offsetTop -= customOffsetTop;
}
}
}
if (IS_WEBKIT && !IS_SAFARI_ABOVE15
&& hasOffset && !isSVG && isStatic
&& (position === "relative" || position === "static")) {
offsetLeft -= offsetParent.offsetLeft;
offsetTop -= offsetParent.offsetTop;
requestEnd = requestEnd || isOffsetEnd;
}
if (isFixed) {
if (hasOffset && fixedInfo.hasTransform) {
// border
fixedClientLeft = offsetParent.clientLeft;
fixedClientTop = offsetParent.clientTop;
}
}
else {
if (hasOffset && offsetContainer !== offsetParent) {
// border
parentClientLeft = offsetParent.clientLeft;
parentClientTop = offsetParent.clientTop;
}
if (hasOffset && offsetParent === documentElement) {
var margin = getBodyOffset(el, false);
offsetLeft += margin[0];
offsetTop += margin[1];
}
}
matrixes.push({
type: "target",
target: el,
matrix: getAbsoluteMatrix(matrix$1, n, origin_1),
});
if (individualTransforms.length) {
matrixes.push({
type: "offset",
target: el,
matrix: matrix.createIdentityMatrix(n),
});
matrixes.push({
type: "target",
target: el,
matrix: getAbsoluteMatrix(cssToMat.parseMat(individualTransforms), n, origin_1),
});
}
if (hasOffset) {
var isElementTarget = el === target;
var scrollLeft = isElementTarget ? 0 : el.scrollLeft;
var scrollTop = isElementTarget ? 0 : el.scrollTop;
matrixes.push({
type: "offset",
target: el,
matrix: matrix.createOriginMatrix([
offsetLeft - scrollLeft + parentClientLeft - fixedClientLeft,
offsetTop - scrollTop + parentClientTop - fixedClientTop,
], n),
});
}
else {
// svg
matrixes.push({
type: "offset",
target: el,
origin: origin_1,
});
}
// transform으로 계산되지 않는 zoom을 위한 (0, 0) 을 기준 matrix 추가.
if (targetZoom !== 1) {
matrixes.push({
type: "zoom",
target: el,
matrix: getAbsoluteMatrix(matrix.createScaleMatrix([targetZoom, targetZoom], n), n, [0, 0]),
});
}
if (!targetMatrix) {
targetMatrix = matrix$1;
}
if (!transformOrigin) {
transformOrigin = origin_1;
}
if (!targetTransformOrigin) {
targetTransformOrigin = targetOrigin;
}
if (isEnd || isFixed) {
break;
}
else {
el = offsetParent;
requestEnd = isOffsetEnd;
}
if (!checkContainer || el === documentElement) {
isEnd = requestEnd;
}
}
if (!targetMatrix) {
targetMatrix = matrix.createIdentityMatrix(n);
}
if (!transformOrigin) {
transformOrigin = [0, 0];
}
if (!targetTransformOrigin) {
targetTransformOrigin = [0, 0];
}
return {
zoom: zoom,
offsetContainer: offsetContainer,
matrixes: matrixes,
targetMatrix: targetMatrix,
transformOrigin: transformOrigin,
targetOrigin: targetTransformOrigin,
is3d: is3d,
hasFixed: hasFixed,
};
}
var cacheStyleMap = null;
var clientRectStyleMap = null;
var matrixContainerInfos = null;
function setStoreCache(useCache) {
if (useCache) {
if (window.Map) {
cacheStyleMap = new Map();
clientRectStyleMap = new Map();
}
matrixContainerInfos = [];
}
else {
cacheStyleMap = null;
matrixContainerInfos = null;
clientRectStyleMap = null;
}
}
function getCachedClientRect(el) {
var clientRect = clientRectStyleMap === null || clientRectStyleMap === void 0 ? void 0 : clientRectStyleMap.get(el);
if (clientRect) {
return clientRect;
}
var nextClientRect = getClientRect(el, true);
if (clientRectStyleMap) {
clientRectStyleMap.set(el, nextClientRect);
}
return nextClientRect;
}
function getCachedMatrixContainerInfo(target, container) {
if (matrixContainerInfos) {
var result_1 = utils.find(matrixContainerInfos, function (info) { return info[0][0] == target && info[0][1] == container; });
if (result_1) {
return result_1[1];
}
}
var result = getMatrixStackInfo(target, container, true);
if (matrixContainerInfos) {
matrixContainerInfos.push([[target, container], result]);
}
return result;
}
function getCachedStyle(element) {
var cache = cacheStyleMap === null || cacheStyleMap === void 0 ? void 0 : cacheStyleMap.get(element);
if (!cache) {
var nextStyle_1 = utils.getWindow(element).getComputedStyle(element);
if (!cacheStyleMap) {
return function (property) {
return nextStyle_1[property];
};
}
cache = {
style: nextStyle_1,
cached: {},
};
cacheStyleMap.set(element, cache);
}
var cached = cache.cached;
var style = cache.style;
return function (property) {
if (!(property in cached)) {
cached[property] = style[property];
}
return cached[property];
};
}
function fillChildEvents(moveable, name, e) {
var datas = e.originalDatas;
datas.groupable = datas.groupable || {};
var groupableDatas = datas.groupable;
groupableDatas.childDatas = groupableDatas.childDatas || [];
var childDatas = groupableDatas.childDatas;
return moveable.moveables.map(function (_, i) {
childDatas[i] = childDatas[i] || {};
childDatas[i][name] = childDatas[i][name] || {};
return __assign(__assign({}, e), { isRequestChild: true, datas: childDatas[i][name], originalDatas: childDatas[i] });
});
}
function triggerChildGesto(moveable, able, type, delta, e, isConvert, ableName) {
var isStart = !!type.match(/Start$/g);
var isEnd = !!type.match(/End$/g);
var isPinch = e.isPinch;
var datas = e.datas;
var events = fillChildEvents(moveable, able.name, e);
var moveables = moveable.moveables;
var childEvents = [];
var eventParams = events.map(function (ev, i) {
var childMoveable = moveables[i];
var state = childMoveable.state;
var gestos = state.gestos;
var childEvent = ev;
if (isStart) {
childEvent = new CustomGesto(ableName).dragStart(delta, ev);
childEvents.push(childEvent);
}
else {
if (!gestos[ableName]) {
gestos[ableName] = datas.childGestos[i];
}
if (!gestos[ableName]) {
return;
}
childEvent = setCustomDrag(ev, state, delta, isPinch, isConvert, ableName);
childEvents.push(childEvent);
}
var result = able[type](childMoveable, __assign(__assign({}, childEvent), { parentFlag: true }));
if (isEnd) {
gestos[ableName] = null;
}
return result;
});
if (isStart) {
datas.childGestos = moveables.map(function (child) { return child.state.gestos[ableName]; });
}
return {
eventParams: eventParams,
childEvents: childEvents,
};
}
function triggerChildAbles(moveable, able, type, e, eachEvent, callback) {
if (eachEvent === void 0) { eachEvent = function (_, ev) { return ev; }; }
var isEnd = !!type.match(/End$/g);
var events = fillChildEvents(moveable, able.name, e);
var moveables = moveable.moveables;
var childs = events.map(function (ev, i) {
var childMoveable = moveables[i];
var childEvent = ev;
childEvent = eachEvent(childMoveable, ev);
var result = able[type](childMoveable, __assign(__assign({}, childEvent), { parentFlag: true }));
result && callback && callback(childMoveable, ev, result, i);
if (isEnd) {
childMoveable.state.gestos = {};
}
return result;
});
return childs;
}
function startChildDist(moveable, child, parentDatas, childEvent) {
var fixedDirection = parentDatas.fixedDirection;
var fixedPosition = parentDatas.fixedPosition;
var startPositions = childEvent.datas.startPositions || getAbsolutePosesByState(child.state);
var pos = getPosByDirection(startPositions, fixedDirection);
var _a = __read(matrix.calculate(matrix.createRotateMatrix(-moveable.rotation / 180 * Math.PI, 3), [pos[0] - fixedPosition[0], pos[1] - fixedPosition[1], 1], 3), 2), originalX = _a[0], originalY = _a[1];
childEvent.datas.originalX = originalX;
childEvent.datas.originalY = originalY;
return childEvent;
}
function renderDirectionControlsByInfos(moveable, ableName, renderDirections, React) {
var _a = moveable.getState(), renderPoses = _a.renderPoses, rotationRad = _a.rotation, direction = _a.direction;
var zoom = getProps(moveable.props, ableName).zoom;
var degRotation = absDegree(rotationRad / Math.PI * 180);
var directionMap = {};
var renderState = moveable.renderState;
if (!renderState.renderDirectionMap) {
renderState.renderDirectionMap = {};
}
var renderDirectionMap = r