vue-poster-editor
Version:
A poster editor based on Vue.js
342 lines (292 loc) • 10.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _isArray2 = require('lodash/isArray');
var _isArray3 = _interopRequireDefault(_isArray2);
var _values2 = require('lodash/values');
var _values3 = _interopRequireDefault(_values2);
var _forEach2 = require('lodash/forEach');
var _forEach3 = _interopRequireDefault(_forEach2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var Vector = function Vector() {
var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
this.x = x;
this.y = y;
};
Vector.prototype = {
getMagnitude: function getMagnitude() {
return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2));
},
subtract: function subtract(vector) {
var v = new Vector();
v.x = this.x - vector.x;
v.y = this.y - vector.y;
return v;
},
dotProduct: function dotProduct(vector) {
return this.x * vector.x + this.y * vector.y;
},
edge: function edge(vector) {
return this.subtract(vector);
},
perpendicular: function perpendicular() {
var v = new Vector();
v.x = this.y;
v.y = 0 - this.x;
return v;
},
normalize: function normalize() {
var v = new Vector(0, 0);
var m = this.getMagnitude();
if (m !== 0) {
v.x = this.x / m;
v.y = this.y / m;
}
return v;
},
normal: function normal() {
var p = this.perpendicular();
return p.normalize();
}
};
var Projection = function Projection(min, max) {
this.min = min;
this.max = max;
};
Projection.prototype = {
overlaps: function overlaps(projection) {
return this.max > projection.min && projection.max > this.min;
}
};
exports.default = {
getBBox: function getBBox(rect, zoom) {
var rectRotate = this.intLimit(rect.rotate, 360);
var rectHeight = rect.height;
var rectWidth = rect.width;
var rotate = rectRotate > 90 && rectRotate < 180 || rectRotate > 270 && rectRotate < 360 ? 180 - rectRotate : rectRotate;
var rad = this.degToRad(rotate);
var height = Math.abs(Math.sin(rad) * rectWidth + Math.cos(rad) * rectHeight);
var width = Math.abs(Math.sin(rad) * rectHeight + Math.cos(rad) * rectWidth);
var dotX = rect.left + rectWidth / 2;
var dotY = rect.top + rectHeight / 2;
var left = dotX - width / 2;
var top = dotY - height / 2;
zoom = zoom || 1;
return {
rotate: rotate,
height: height * zoom,
width: width * zoom,
left: left * zoom,
top: top * zoom
};
},
getElementRect: function getElementRect(element, zoom) {
if (!zoom) {
zoom = 1;
}
var rect = {
padding: [0, 0, 0, 0],
height: zoom * element.height,
width: zoom * element.width,
left: zoom * element.left,
top: zoom * element.top,
clip: {
bottom: 0,
right: 0,
left: 0,
top: 0
}
};
if (element.padding) {
(0, _forEach3.default)(element.padding, function (val, i) {
rect.padding[i] = zoom * val;
});
}
if (element.clip) {
(0, _forEach3.default)(element.clip, function (val, k) {
rect.clip[k] = zoom * val;
});
}
rect.rotate = element.rotate;
rect.skewX = element.skewX;
rect.skewY = element.skewY;
return rect;
},
getBBoxByElement: function getBBoxByElement(element, zoom) {
var rect = this.getElementRect(element, zoom);
return this.getBBox(rect);
},
getBBoxByElements: function getBBoxByElements(elements, zoom) {
var self = this;
var top = Infinity;
var left = Infinity;
var right = -Infinity;
var bottom = -Infinity;
elements.forEach(function (element) {
var bbox = self.getBBoxByElement(element, zoom);
if (bbox.top < top) {
top = bbox.top;
}
if (bbox.left < left) {
left = bbox.left;
}
if (bbox.left + bbox.width > right) {
right = bbox.left + bbox.width;
}
if (bbox.top + bbox.height > bottom) {
bottom = bbox.top + bbox.height;
}
});
return {
rotate: 0,
height: bottom - top,
width: right - left,
left: left,
top: top
};
},
getRectIntersection: function getRectIntersection(rectA, rectB) {
var self = this;
var pointsA = this.getRectPoints(rectA);
var pointsB = this.getRectPoints(rectB);
if ((rectB.rotate === 0 || rectB.rotate === 360) && rectB.skewX === 0 && rectB.skewY === 0) {
if (rectA.left < rectB.left + rectB.width && rectA.left + rectA.width > rectB.left && rectA.top < rectB.top + rectB.height && rectA.height + rectA.top > rectB.top) {
return true;
} else {
return false;
}
}
var polygonsCollide = function polygonsCollide(polygon1, polygon2) {
var axes = void 0,
projection1 = void 0,
projection2 = void 0;
axes = self.getAxes(polygon1).concat(self.getAxes(polygon2));
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = axes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var axis = _step.value;
projection1 = self.project(axis, polygon1);
projection2 = self.project(axis, polygon2);
if (!projection1.overlaps(projection2)) return false;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return true;
};
return polygonsCollide(pointsA, pointsB);
},
project: function project(axis, points) {
var scalars = [];
var v = new Vector();
points = (0, _values3.default)(points);
points.forEach(function (point) {
v.x = point.x;
v.y = point.y;
scalars.push(v.dotProduct(axis));
});
return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));
},
getAxes: function getAxes(points) {
var v1 = new Vector();
var v2 = new Vector();
var axes = [];
points = (0, _values3.default)(points);
for (var i = 0, len = points.length - 1; i < len; i++) {
v1.x = points[i].x;
v1.y = points[i].y;
v2.x = points[i + 1].x;
v2.y = points[i + 1].y;
axes.push(v1.edge(v2).normal());
}
v1.x = points[points.length - 1].x;
v1.y = points[points.length - 1].y;
v2.x = points[0].x;
v2.y = points[0].y;
axes.push(v1.edge(v2).normal());
return axes;
},
getPointPosition: function getPointPosition(point, pivot) {
var angle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var _this = this;
var skewX = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
var skewY = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
var points = [].concat(point);
var radian = -angle / 180 * Math.PI;
var pivotX = pivot.x;
var pivotY = pivot.y;
if (skewX !== 0 || skewY !== 0) {
points = points.map(function (point) {
var skewedPoint = _this.getSkewPoint({ x: point.x, y: point.y }, { x: pivotX, y: pivotY }, skewX, skewY);
return skewedPoint;
});
}
points = points.map(function (point) {
var dx = point.x - pivotX;
var dy = -(point.y - pivotY);
point = _this.getRotationPoint({ x: dx, y: dy }, radian);
return {
x: pivotX + point.x,
y: pivotY - point.y
};
});
if ((0, _isArray3.default)(point)) {
return points;
} else {
return points[0];
}
},
getRectPoints: function getRectPoints(rect) {
var left = rect.left,
top = rect.top,
width = rect.width,
height = rect.height,
rotate = rect.rotate,
_rect$skewX = rect.skewX,
skewX = _rect$skewX === undefined ? 0 : _rect$skewX,
_rect$skewY = rect.skewY,
skewY = _rect$skewY === undefined ? 0 : _rect$skewY;
var pivot = {
x: left + width / 2,
y: top + height / 2
};
var points = [{ x: left, y: top }, { x: left + width, y: top }, { x: left + width, y: top + height }, { x: left, y: top + height }];
points = this.getPointPosition(points, pivot, rotate, skewX, skewY);
return { nw: points[0], ne: points[1], se: points[2], sw: points[3] };
},
getPointsByElement: function getPointsByElement(element) {
var zoom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var rect = this.getElementRect(element, zoom);
return this.getRectPoints(rect);
},
pointInRect: function pointInRect(x, y, rect) {
var pointRect = {
height: 1,
width: 1,
top: y,
left: x,
padding: [0, 0, 0, 0],
rotate: 0,
skewX: 0,
skewY: 0,
clip: { bottom: 0, right: 0, left: 0, top: 0 }
};
return this.getRectIntersection(pointRect, rect);
}
};
module.exports = exports['default'];