react-native-arrow-follow
Version:
Arrow follow type schema in SVG
539 lines (468 loc) • 16 kB
JavaScript
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import React, { Component } from 'react';
import Svg, { Defs, Marker, Path } from 'react-native-svg';
import { StyleSheet, View } from 'react-native';
var CORNER;
(function (CORNER) {
CORNER["TOP_LEFT"] = "TOP_LEFT";
CORNER["TOP_RIGHT"] = "TOP_RIGHT";
CORNER["BOTTOM_LEFT"] = "BOTTOM_LEFT";
CORNER["BOTTOM_RIGHT"] = "BOTTOM_RIGHT";
})(CORNER || (CORNER = {}));
var DIRECTION;
(function (DIRECTION) {
DIRECTION["HORIZONTAL"] = "HORIZONTAL";
DIRECTION["VERTICAL"] = "VERTICAL";
})(DIRECTION || (DIRECTION = {}));
var HORIZONTAL;
(function (HORIZONTAL) {
HORIZONTAL["LEFT"] = "LEFT";
HORIZONTAL["RIGHT"] = "RIGHT";
})(HORIZONTAL || (HORIZONTAL = {}));
var VERTICAL;
(function (VERTICAL) {
VERTICAL["TOP"] = "TOP";
VERTICAL["BOTTOM"] = "BOTTOM";
})(VERTICAL || (VERTICAL = {}));
class ArrowFollow extends Component {
/**
* @type {number}
* @private
*/
/**
* @type {number}
* @private
*/
/**
* @type {number}
* @private
*/
/**
* @type {number}
* @private
*/
/**
* @type {number}
* @private
*/
/**
* @type {{width:number, height:number}}
* @private
*/
/**
* @param {IProps} props
*/
constructor(_props) {
super(_props);
_defineProperty(this, "_xl", void 0);
_defineProperty(this, "_xr", void 0);
_defineProperty(this, "_yt", void 0);
_defineProperty(this, "_yb", void 0);
_defineProperty(this, "_radium", void 0);
_defineProperty(this, "_triangle", void 0);
_defineProperty(this, "componentDidUpdate", prevProps => {
if (prevProps.size !== this.props.size || prevProps.width !== this.props.width || prevProps.height !== this.props.height || prevProps.start !== this.props.start || prevProps.end !== this.props.end) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({ ...this._build(this.props)
});
}
});
_defineProperty(this, "_build", props => {
var _props$size;
const _start = props.start.corner.split('_');
const _end = props.end.corner.split('_');
const {
width,
height
} = this._geCropView(props, _start, _end);
const //
aspectRatio = height / width,
viewBox = [0, 0, 1000, 1000 * aspectRatio],
size = viewBox[2] / width * ((_props$size = props.size) !== null && _props$size !== void 0 ? _props$size : 12) / 2;
this._xl = 0;
this._xr = viewBox[2];
this._yt = 0;
this._yb = viewBox[3];
this._radium = viewBox[2] / 4;
this._triangle = {
width: size * 3,
height: size * 3
};
const triangleOrient = this._arrowOrient(_end, props.end.direction);
const starPoint = this._getStart(_start, props.start.direction, _end, props.end.direction);
const centerPoints = this._startCenter(_start, props.start.direction, _end, props.end.direction);
const enPoint = this._getEnd(_end, props.end.direction);
const margins = this._getMarginView(_start, props.start.direction, _end, props.end.direction, props.width);
return {
aspectRatio,
viewBox,
size,
route: starPoint + centerPoints + enPoint,
triangleOrient,
margins,
width,
height
};
});
_defineProperty(this, "_geCropView", (props, [startVertical, startHorizontal], [endVertical, endHorizontal]) => {
var _props$size2;
const size = 1000 / props.width * ((_props$size2 = props.size) !== null && _props$size2 !== void 0 ? _props$size2 : 12) / 2;
const triangleWidth = size * 3 / 1000 * props.width;
const triangleWidthMiddle = triangleWidth / 2;
const self = triangleWidth / 5;
let dimensionsView = {
width: props.width,
height: props.height
};
if (props.start.direction !== props.end.direction) {
if (props.start.direction === DIRECTION.HORIZONTAL) {
if (startVertical === VERTICAL.TOP) {
dimensionsView.width += triangleWidthMiddle;
dimensionsView.height += self;
} else {
dimensionsView.width += triangleWidthMiddle;
dimensionsView.height += self;
}
} else {
if (startHorizontal === HORIZONTAL.LEFT) {
dimensionsView.width += self;
dimensionsView.height += triangleWidthMiddle;
} else {
dimensionsView.width += self;
dimensionsView.height += triangleWidthMiddle;
}
}
} else {
if (startVertical === endVertical || startHorizontal === endHorizontal) {
if (props.start.direction === DIRECTION.HORIZONTAL) {
dimensionsView.height += triangleWidthMiddle;
} else {
dimensionsView.width += triangleWidthMiddle;
}
} else {
if (props.start.direction === DIRECTION.HORIZONTAL) {
dimensionsView.height += triangleWidthMiddle + self / 2;
} else {
dimensionsView.width += triangleWidthMiddle + self / 2;
}
}
}
return dimensionsView;
});
_defineProperty(this, "_getMarginView", ([startVertical, startHorizontal], startPosition, [endVertical, endHorizontal], endPosition, width) => {
const {
_triangle
} = this;
const triangleWidthMiddle = _triangle.width / 2 / this._xr * width;
const self = _triangle.width / 5 / this._xr * width;
const margins = [];
if (startVertical === endVertical || startHorizontal === endHorizontal) {
if (startPosition === DIRECTION.HORIZONTAL) {
if (startVertical === VERTICAL.TOP) {
margins.push({
top: -triangleWidthMiddle
});
}
} else {
if (startHorizontal === HORIZONTAL.LEFT) {
margins.push({
left: -triangleWidthMiddle
});
}
}
} else if (startPosition !== endPosition) {
if (startPosition === DIRECTION.HORIZONTAL) {
if (startVertical === VERTICAL.TOP) {
margins.push({
top: -self
});
}
if (startHorizontal === HORIZONTAL.RIGHT) {
margins.push({
left: -triangleWidthMiddle
});
}
} else {
if (startHorizontal === HORIZONTAL.LEFT) {
margins.push({
left: -self
});
}
if (startVertical === VERTICAL.TOP) {// margins.push({ top: -self });
} else {
margins.push({
top: -triangleWidthMiddle
});
}
}
} else {
if (startPosition === DIRECTION.HORIZONTAL) {
if (startVertical === VERTICAL.TOP) {
margins.push({
top: -self
});
} else {
margins.push({
top: -triangleWidthMiddle
});
}
} else {
if (startHorizontal === HORIZONTAL.LEFT) {
margins.push({
left: -self
});
} else {
margins.push({
left: -triangleWidthMiddle
});
}
}
}
return margins;
});
_defineProperty(this, "_getStart", ([startVertical, startHorizontal], startPosition, [endVertical, endHorizontal], _) => {
const {
_xl,
_xr,
_yt,
_yb,
_triangle
} = this;
const triangleWidthMiddle = _triangle.width / 2;
const self = _triangle.width / 5;
let x, y;
if (startHorizontal === endHorizontal) {
x = startHorizontal === HORIZONTAL.LEFT ? _xl + triangleWidthMiddle : _xr - triangleWidthMiddle;
y = startVertical === VERTICAL.TOP ? _yt : _yb;
} else if (startVertical === endVertical) {
x = startHorizontal === HORIZONTAL.LEFT ? _xl : _xr;
y = startVertical === VERTICAL.TOP ? _yt + triangleWidthMiddle : _yb - triangleWidthMiddle;
} else {
if (startHorizontal === HORIZONTAL.LEFT) {
x = _xl;
if (startPosition === DIRECTION.VERTICAL) {
x += self;
}
} else {
x = _xr;
if (startPosition === DIRECTION.VERTICAL) {
x -= self;
}
}
if (startVertical === VERTICAL.TOP) {
y = _yt;
if (startPosition === DIRECTION.HORIZONTAL) {
y += self;
}
} else {
y = _yb;
if (startPosition === DIRECTION.HORIZONTAL) {
y -= self;
}
}
}
return `M${x},${y}`;
});
_defineProperty(this, "_startCenter", ([startVertical, startHorizontal], startPosition, [endVertical, endHorizontal], endPosition) => {
const {
_xl,
_xr,
_yt,
_yb,
_radium,
_triangle
} = this;
const self = _triangle.width / 5;
const triangleWidthMiddle = _triangle.width / 2;
if (startVertical === endVertical || startHorizontal === endHorizontal) {
return '';
} else if (startPosition !== endPosition) {
let // Bezier
Xs, Ys;
if (startHorizontal === HORIZONTAL.LEFT) {
if (startPosition === DIRECTION.VERTICAL) {
Xs = [_xl + self, _xl + self, _xl + _radium];
} else {
Xs = [_xr - triangleWidthMiddle - _radium, _xr - triangleWidthMiddle, _xr - triangleWidthMiddle];
}
} else {
if (startPosition === DIRECTION.VERTICAL) {
Xs = [_xr - self, _xr - self, _xr - self - _radium];
} else {
Xs = [_xl + triangleWidthMiddle + _radium, _xl + triangleWidthMiddle, _xl + triangleWidthMiddle];
}
}
if (startVertical === VERTICAL.TOP) {
if (startPosition === DIRECTION.VERTICAL) {
Ys = [_yb - triangleWidthMiddle - _radium, _yb - triangleWidthMiddle, _yb - triangleWidthMiddle];
} else {
Ys = [_yt + self, _yt + self, _yt + self + _radium];
}
} else {
if (startPosition === DIRECTION.VERTICAL) {
Ys = [_yt + triangleWidthMiddle + _radium, _yt + triangleWidthMiddle, _yt + triangleWidthMiddle];
} else {
Ys = [_yb - self, _yb - self, _yb - self - _radium];
}
}
return ` ${Xs[0]},${Ys[0]} Q${Xs[1]},${Ys[1]} ${Xs[2]},${Ys[2]}`;
} else {
const //
_xrMiddle = _xr / 2,
_ybMiddle = _yb / 2;
let // Bezier
X1s, Y1s, X2s, Y2s;
if (startHorizontal === HORIZONTAL.LEFT) {
if (startPosition === DIRECTION.VERTICAL) {
X1s = [_xl + self, _xl + self, _xl + self + _radium];
X2s = [_xr - triangleWidthMiddle - _radium, _xr - triangleWidthMiddle, _xr - triangleWidthMiddle];
} else {
X1s = [_xrMiddle - _radium, _xrMiddle, _xrMiddle];
X2s = [_xrMiddle, _xrMiddle, _xrMiddle + _radium];
}
} else {
if (startPosition === DIRECTION.VERTICAL) {
X1s = [_xr - self, _xr - self, _xr - self - _radium];
X2s = [_xl + triangleWidthMiddle + _radium, _xl + triangleWidthMiddle, _xl + triangleWidthMiddle];
} else {
X1s = [_xrMiddle + _radium, _xrMiddle, _xrMiddle];
X2s = [_xrMiddle, _xrMiddle, _xrMiddle - _radium];
}
}
if (startVertical === VERTICAL.TOP) {
if (startPosition === DIRECTION.VERTICAL) {
Y1s = [_ybMiddle - _radium, _ybMiddle, _ybMiddle];
Y2s = [_ybMiddle, _ybMiddle, _ybMiddle + _radium];
} else {
Y1s = [_yt + self, _yt + self, _yt + self + _radium];
Y2s = [_yb - triangleWidthMiddle - _radium, _yb - triangleWidthMiddle, _yb - triangleWidthMiddle];
}
} else {
if (startPosition === DIRECTION.VERTICAL) {
Y1s = [_ybMiddle + _radium, _ybMiddle, _ybMiddle];
Y2s = [_ybMiddle, _ybMiddle, _ybMiddle - _radium];
} else {
Y1s = [_yb - self, _yb - self, _yb - self - _radium];
Y2s = [_yt + triangleWidthMiddle + _radium, _yt + triangleWidthMiddle, _yt + triangleWidthMiddle];
}
}
return ` ${X1s[0]},${Y1s[0]} Q${X1s[1]},${Y1s[1]} ${X1s[2]},${Y1s[2]} L${X2s[0]},${Y2s[0]} Q${X2s[1]},${Y2s[1]} ${X2s[2]},${Y2s[2]}`;
}
});
_defineProperty(this, "_getEnd", ([endVertical, endHorizontal], direction) => {
const {
_xl,
_xr,
_yt,
_yb,
_triangle
} = this;
const triangleWidthMiddle = _triangle.width / 2;
let x, y;
if (endHorizontal === HORIZONTAL.LEFT) {
if (direction === DIRECTION.HORIZONTAL) {
x = _xl + _triangle.height;
} else {
x = _xl + triangleWidthMiddle;
}
} else {
if (direction === DIRECTION.HORIZONTAL) {
x = _xr - _triangle.height;
} else {
x = _xr - triangleWidthMiddle;
}
}
if (endVertical === VERTICAL.TOP) {
if (direction === DIRECTION.HORIZONTAL) {
y = _yt + triangleWidthMiddle;
} else {
y = _yt + _triangle.height;
}
} else {
if (direction === DIRECTION.HORIZONTAL) {
y = _yb - triangleWidthMiddle;
} else {
y = _yb - _triangle.height;
}
}
return ` L${x},${y}`;
});
_defineProperty(this, "_arrowOrient", ([endVertical, endHorizontal], endPosition) => {
let orient;
if (endPosition === DIRECTION.VERTICAL) {
if (endVertical === VERTICAL.TOP) {
orient = 90;
} else {
orient = -90;
}
} else {
if (endHorizontal === HORIZONTAL.LEFT) {
orient = 0;
} else {
orient = 180;
}
}
return orient;
});
_defineProperty(this, "render", () => {
const {
color
} = this.props;
const {
width,
height,
size,
viewBox,
route,
triangleOrient,
margins
} = this.state;
const fill = color !== null && color !== void 0 ? color : 'black';
return /*#__PURE__*/React.createElement(View, {
style: StyleSheet.flatten([{
width,
height
}, ...margins])
}, /*#__PURE__*/React.createElement(Svg, {
width: width,
height: height,
viewBox: viewBox.join(' '),
fill: fill,
strokeLinejoin: 'round',
strokeLinecap: 'butt'
}, /*#__PURE__*/React.createElement(Defs, null, /*#__PURE__*/React.createElement(Marker, {
id: "Triangle",
viewBox: "0 0 10 10",
refX: "0",
refY: "5" // @ts-ignore
,
markerUnits: "strokeWidth",
markerWidth: "4",
markerHeight: "3",
orient: triangleOrient
}, /*#__PURE__*/React.createElement(Path, {
fill: fill,
d: "M 0 0 L 10 5 L 0 10 z"
})), /*#__PURE__*/React.createElement(Path, {
id: 'TT',
stroke: "crimson",
d: "M 100,75 C 125,50 150,50 175,75"
})), /*#__PURE__*/React.createElement(Path, {
strokeLinejoin: 'round',
d: route,
fill: "none",
stroke: fill,
strokeWidth: size,
markerEnd: "url(#Triangle)"
})));
});
this.state = { ...this._build(_props)
};
}
/**
* @param {Readonly<IProps>} prevProps
*/
}
export { DIRECTION, HORIZONTAL, VERTICAL, CORNER };
export default ArrowFollow;
//# sourceMappingURL=ArrowFollow.js.map