advanced-cropper
Version:
The core of the advanced cropper libraries family
113 lines (108 loc) • 6.77 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
require('tslib');
var index = require('../utils/index.js');
var utils = require('../service/utils.js');
var helpers = require('../service/helpers.js');
var copyState = require('../state/copyState.js');
require('../types/index.js');
require('../state/setCoordinates.js');
function transformImageAlgorithm(state, settings, transform) {
var _a;
var _b = transform.scale, scale = _b === void 0 ? 1 : _b, _c = transform.move, move = _c === void 0 ? {} : _c;
if (helpers.isInitializedState(state)) {
var result = copyState.copyState(state);
// It's reversed because zooming in the image is actually zooming out visible area
var scaleFactor = 1 / (index.isNumber(scale) ? scale : scale.factor);
var scaleCenter = !index.isNumber(scale) ? scale.center : undefined;
var isAllowedScale = !index.isRoughlyEqual(scaleFactor, 1);
var areaScale = 1;
var stencilScale = 1;
result.visibleArea = utils.applyMove(result.visibleArea, {
left: move.left || 0,
top: move.top || 0,
});
var sizeRestrictions = helpers.getSizeRestrictions(result, settings);
var positionRestrictions = helpers.getPositionRestrictions(result, settings);
var areaSizeRestrictions = helpers.getAreaSizeRestrictions(result, settings);
var scaleRestrictions = {
stencil: {
minimum: Math.max(sizeRestrictions.minWidth ? sizeRestrictions.minWidth / result.coordinates.width : 0, sizeRestrictions.minHeight ? sizeRestrictions.minHeight / result.coordinates.height : 0),
maximum: Math.min(sizeRestrictions.maxWidth ? sizeRestrictions.maxWidth / result.coordinates.width : Infinity, sizeRestrictions.maxHeight ? sizeRestrictions.maxHeight / result.coordinates.height : Infinity, utils.maxScale(result.coordinates, utils.positionToSizeRestrictions(positionRestrictions))),
},
area: {
maximum: utils.maxScale(result.visibleArea, areaSizeRestrictions),
minimum: utils.minScale(result.visibleArea, areaSizeRestrictions),
},
};
// If there is scaling then begin scale
if (scaleFactor && isAllowedScale) {
// Determine scale factor
if (scaleFactor < 1) {
stencilScale = Math.max(scaleFactor, Math.max(scaleRestrictions.area.minimum, scaleRestrictions.stencil.minimum));
if (stencilScale > 1) {
stencilScale = 1;
}
}
else if (scaleFactor > 1) {
stencilScale = Math.min(scaleFactor, Math.min(scaleRestrictions.area.maximum, scaleRestrictions.stencil.maximum));
if (stencilScale < 1) {
stencilScale = 1;
}
}
}
if (stencilScale) {
// Resize stencil with area as much as possible
result.visibleArea = utils.applyScale(result.visibleArea, stencilScale, scaleCenter);
}
var relativeCoordinates = {
left: state.coordinates.left - state.visibleArea.left,
right: state.visibleArea.width + state.visibleArea.left - (state.coordinates.width + state.coordinates.left),
top: state.coordinates.top - state.visibleArea.top,
bottom: state.visibleArea.height + state.visibleArea.top - (state.coordinates.height + state.coordinates.top),
};
// Move the area to fit to the coordinates limits:
result.visibleArea = utils.moveToPositionRestrictions(result.visibleArea, {
left: positionRestrictions.left !== undefined
? positionRestrictions.left - relativeCoordinates.left * stencilScale
: undefined,
top: positionRestrictions.top !== undefined
? positionRestrictions.top - relativeCoordinates.top * stencilScale
: undefined,
bottom: positionRestrictions.bottom !== undefined
? positionRestrictions.bottom + relativeCoordinates.bottom * stencilScale
: undefined,
right: positionRestrictions.right !== undefined
? positionRestrictions.right + relativeCoordinates.right * stencilScale
: undefined,
});
// But the more important to fit are to the area restrictions, so we should fit it to that restrictions:
result.visibleArea = utils.moveToPositionRestrictions(result.visibleArea, helpers.getAreaPositionRestrictions(result, settings));
// Set the same coordinates of stencil inside visible area
result.coordinates.width = result.coordinates.width * stencilScale;
result.coordinates.height = result.coordinates.height * stencilScale;
result.coordinates.left = result.visibleArea.left + relativeCoordinates.left * stencilScale;
result.coordinates.top = result.visibleArea.top + relativeCoordinates.top * stencilScale;
// Move the coordinates to prevent the intersection with visible area and position restrictions
result.coordinates = utils.moveToPositionRestrictions(result.coordinates, utils.mergePositionRestrictions(utils.coordinatesToPositionRestrictions(result.visibleArea), positionRestrictions));
// Resize only area if stencil can't be resized and stencil resize is disabled
if (isAllowedScale && scaleFactor && ((_a = settings.transformImage) === null || _a === void 0 ? void 0 : _a.adjustStencil)) {
if (scaleFactor > 1) {
areaScale = Math.min(scaleRestrictions.area.maximum, scaleFactor) / stencilScale;
}
else if (scaleFactor < 1) {
areaScale = Math.max(result.coordinates.height / result.visibleArea.height, result.coordinates.width / result.visibleArea.width, scaleFactor / stencilScale);
}
if (areaScale !== 1) {
result.visibleArea = utils.applyScale(result.visibleArea, areaScale, scaleFactor > 1 ? scaleCenter : utils.getCenter(result.coordinates));
// Move to prevent the breaking of the area restrictions:
result.visibleArea = utils.moveToPositionRestrictions(result.visibleArea, helpers.getAreaPositionRestrictions(result, settings));
// Move to prevent the intersection with coordinates:
result.visibleArea = utils.applyMove(result.visibleArea, utils.inverseMove(utils.fitToPositionRestrictions(result.coordinates, utils.coordinatesToPositionRestrictions(result.visibleArea))));
}
}
return result;
}
return state;
}
exports.transformImageAlgorithm = transformImageAlgorithm;