advanced-cropper
Version:
The core of the advanced cropper libraries family
145 lines (142 loc) • 8.13 kB
JavaScript
import { __assign } from 'tslib';
import { isGreater, deepCompare } from '../../utils/index.js';
import { mergePositionRestrictions, coordinatesToPositionRestrictions, getCenter, applyScale, applyMove, diff, inverseMove, fitToPositionRestrictions, ratio } from '../../service/utils.js';
import { isInitializedState, getMinimumSize, getTransformedImageSize, getSizeRestrictions, getPositionRestrictions, getAspectRatio } from '../../service/helpers.js';
import { copyState } from '../../state/copyState.js';
import '../../types/index.js';
import '../../state/setCoordinates.js';
import { transformImage as transformImage$1 } from '../../state/transformImage.js';
import { anchoredResizeCoordinatesAlgorithm } from '../../algorithms/resizeCoordinatesAlgorithm.js';
import { defaultStencilConstraints } from '../../defaults/defaultStencilConstraints.js';
import { BoundingBoxType } from '../../extensions/fit-to-image/types.js';
import { approximateSizeInsideImage } from '../../extensions/fit-to-image/size.js';
import { fitToImage, moveToImage } from '../../extensions/fit-to-image/position.js';
import { getRotatedImage } from '../../extensions/fit-to-image/utils.js';
function stencilConstraints(rawSettings, stencilOptions) {
var defaultConstraints = defaultStencilConstraints({}, stencilOptions);
return __assign({ stencilBoundingBox: stencilOptions.boundingBox }, defaultConstraints);
}
function transformImage(state, settings, transform) {
var flip = transform.flip, rotate = transform.rotate, scale = transform.scale, move = transform.move;
if (flip) {
state = __assign(__assign({}, state), { transforms: __assign(__assign({}, state.transforms), { flip: {
horizontal: flip.horizontal ? !state.transforms.flip.horizontal : state.transforms.flip.horizontal,
vertical: flip.vertical ? !state.transforms.flip.vertical : state.transforms.flip.vertical,
} }) });
}
if (state.coordinates) {
if (!flip && !scale && !move) {
state.basis = state.basis || __assign({}, state.coordinates);
}
else {
state.basis = undefined;
}
}
return transformImage$1(state, settings, { rotate: rotate, move: move, scale: scale });
}
function resizeCoordinates(state, settings, anchor, directions, options) {
if (isInitializedState(state)) {
var result = copyState(state);
var minimumSize = getMinimumSize(result);
var imageSize = getTransformedImageSize(result);
var sizeRestrictions = getSizeRestrictions(result, settings);
result.coordinates = anchoredResizeCoordinatesAlgorithm(result.coordinates, anchor, directions, __assign(__assign({}, options), { compensate: false }), {
positionRestrictions: mergePositionRestrictions(getPositionRestrictions(result, settings), coordinatesToPositionRestrictions(result.visibleArea)),
sizeRestrictions: {
maxWidth: Math.min(sizeRestrictions.maxWidth, imageSize.width, result.visibleArea.width),
maxHeight: Math.min(sizeRestrictions.maxHeight, imageSize.height, result.visibleArea.height),
minWidth: Math.max(Math.min(sizeRestrictions.minWidth, result.visibleArea.width), minimumSize),
minHeight: Math.max(Math.min(sizeRestrictions.minHeight, result.visibleArea.height), minimumSize),
},
aspectRatio: getAspectRatio(result, settings),
});
var resizedCoordinates = __assign({}, result.coordinates);
var approximatedSize = approximateSizeInsideImage({
width: result.coordinates.width,
height: result.coordinates.height,
image: getRotatedImage(result),
boundingBox: settings.stencilBoundingBox,
aspectRatio: getAspectRatio(result, settings),
sizeRestrictions: getSizeRestrictions(result, settings),
});
result.coordinates = __assign({ left: getCenter(resizedCoordinates).left - approximatedSize.width / 2, top: getCenter(resizedCoordinates).top - approximatedSize.height / 2 }, approximatedSize);
if (isGreater(Math.abs(resizedCoordinates.height - result.coordinates.height), 0)) {
result.visibleArea = applyScale(result.visibleArea, result.visibleArea.height /
(result.visibleArea.height + resizedCoordinates.height - result.coordinates.height));
}
var fitDirections = fitToImage(result.coordinates, getRotatedImage(result), settings.stencilBoundingBox);
result.coordinates = applyMove(result.coordinates, fitDirections);
result.visibleArea = applyMove(result.visibleArea, fitDirections);
return result;
}
return state;
}
function defaultSize(state, settings) {
var imageSize = getTransformedImageSize(state);
return {
width: state.visibleArea ? state.visibleArea.width : imageSize.width,
height: state.visibleArea ? state.visibleArea.height : imageSize.height,
};
}
function fitStencilToImage(state, settings, action) {
if (isInitializedState(state) && action.immediately) {
var result = copyState(state);
if (action.name !== 'transformImage' && action.name !== 'transformImageEnd') {
if (!deepCompare(result.coordinates, result.basis)) {
result.basis = undefined;
}
}
var _a = settings.stencilBoundingBox, stencilBoundingBox = _a === void 0 ? BoundingBoxType.Rectangle : _a;
var desiredSize = result.basis ? result.basis : result.coordinates;
var size = approximateSizeInsideImage({
width: desiredSize.width,
height: desiredSize.height,
image: getRotatedImage(state),
aspectRatio: getAspectRatio(result, settings),
sizeRestrictions: getSizeRestrictions(result, settings),
boundingBox: stencilBoundingBox,
});
var previousCenter = getCenter(result.coordinates);
var currentCenter = getCenter(__assign(__assign({}, result.coordinates), size));
// Return to the original position adjusted for size's change
result.coordinates = applyMove(__assign(__assign({}, result.coordinates), size), diff(previousCenter, currentCenter));
// Move to fit image
result.coordinates = moveToImage(result.coordinates, getRotatedImage(result), stencilBoundingBox);
result.visibleArea = applyMove(result.visibleArea, inverseMove(fitToPositionRestrictions(result.coordinates, coordinatesToPositionRestrictions(result.visibleArea))));
return result;
}
return state;
}
function zoomStencil(state, settings, action) {
if (isInitializedState(state) && action.immediately) {
var result = copyState(state);
// Auto size
var stencil = {
width: 0,
height: 0,
};
if (ratio(result.boundary) > ratio(result.coordinates)) {
stencil.height = result.boundary.height;
stencil.width = stencil.height * ratio(result.coordinates);
}
else {
stencil.width = result.boundary.width;
stencil.height = stencil.width * ratio(result.coordinates);
}
// First of all try to resize visible area as much as possible:
result.visibleArea = applyScale(result.visibleArea, (result.coordinates.width * result.boundary.width) / (result.visibleArea.width * stencil.width));
if (ratio(result.boundary) > ratio(result.coordinates)) {
result.visibleArea.top = result.coordinates.top;
result.visibleArea.left =
result.coordinates.left - result.visibleArea.width / 2 + result.coordinates.width / 2;
}
else {
result.visibleArea.left = result.coordinates.left;
result.visibleArea.top =
result.coordinates.top - result.visibleArea.height / 2 + result.coordinates.height / 2;
}
return result;
}
return state;
}
export { defaultSize, fitStencilToImage, resizeCoordinates, stencilConstraints, transformImage, zoomStencil };