UNPKG

advanced-cropper

Version:

The core of the advanced cropper libraries family

145 lines (142 loc) 8.13 kB
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 };