Skip to content

Commit

Permalink
Chore: add useZoom button to control zooming of the canvas from outsi…
Browse files Browse the repository at this point in the history
…de using the hook quicker
  • Loading branch information
AhmeeedMostafa authored and amrelbialy committed Dec 11, 2024
1 parent 5e98ffe commit e1e96df
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 92 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Changed
Added
- `tabsToolsIds` ==FORM==> TABS_TOOLS -- to be added --
- `tools` ==FORM==> TOOLS_ITEMS -- to be added -- the tool id should be the tool's name and used in the tab also.(to be checked)
- `keepAnnotationEventsEnabled`, `textContentRegex` -- to be added --
- `keepAnnotationEventsEnabled`, `textContentRegex`, `showFitCenterZoomButton` -- to be added --
- - `annotationComponents`, `moreAnnotationPreviewClasses`, -keepZoomOnSourceChange- -- to be added --
- Justify option for horizontal text alignment.
- Support creating a design (noHistoryRecord -- if true, won't be considered in the history state for this change --, background color, width & height) instead of editing image only.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,103 +1,41 @@
/** External Dependencies */
import React, { useState } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { MinusOutline, PlusOutline, PositionCenter } from '@scaleflex/icons';
import Menu from '@scaleflex/ui/core/menu';
import MenuItem, { MenuItemLabel } from '@scaleflex/ui/core/menu-item';

/** Internal Dependencies */
import { ZOOM_CANVAS } from 'actions';
import { DEFAULT_ZOOM_FACTOR, TOOLS_IDS } from 'utils/constants';
import { useStore } from 'hooks';
import getZoomFitFactor from 'utils/getZoomFitFactor';
import toPrecisedFloat from 'utils/toPrecisedFloat';
import useZoom from 'hooks/useZoom';
import {
StyledSmallButton,
StyledZoomPercentageLabel,
StyledZoomingWrapper,
} from './ZoomButtons.styled';
import { ZOOM_FACTORS_PRESETS } from './ZoomButtons.constants';

const MULTIPLY_ZOOM_FACTOR = 1.1;

const ZoomButtons = (props) => {
const ZoomButtons = ({ showFitCenterButton = true, ...props }) => {
const {
dispatch,
zoom = {},
toolId,
feedback,
t,
shownImageDimensions,
resize,
originalSource,
adjustments: { crop },
config: { useZoomPresetsMenu, showBackButton },
config: {
useZoomPresetsMenu,
showBackButton,
showFitCenterZoomButton = true,
},
} = useStore();
const isBlockerError = feedback.duration === 0;
const [zoomingMenuAnchorEl, setZoomingMenuAnchorEl] = useState(null);

const saveZoom = (zoomFactor, isAbsoluteZoom, zoomCustomLabel) => {
dispatch({
type: ZOOM_CANVAS,
payload: {
factor: zoomFactor,
isAbsoluteZoom,
customLabel: zoomCustomLabel,
},
});
};

const zoomIn = () => {
saveZoom(zoom.factor * MULTIPLY_ZOOM_FACTOR);
};

const fitCanvas = () => {
const usedAsOrgDimens =
(resize.width && resize.height && resize) ||
(crop.width && crop.height && crop) ||
shownImageDimensions;
const fitCanvasFactor = getZoomFitFactor(
(crop.width && crop.height && crop) || shownImageDimensions,
usedAsOrgDimens,
);
saveZoom(fitCanvasFactor || DEFAULT_ZOOM_FACTOR, true);
};

const zoomOut = () => {
saveZoom(zoom.factor / MULTIPLY_ZOOM_FACTOR);
};

const toggleZoomingMenu = (event) => {
setZoomingMenuAnchorEl(zoomingMenuAnchorEl || !event ? null : event.target);
};

const applyZoomFactorPreset = (factor, zoomCustomLabel) => {
if (factor === 'fit') {
fitCanvas();
toggleZoomingMenu();
return;
}

const factorToAchieveSelected =
resize.width || resize.height
? factor
: factor / shownImageDimensions.originalSourceInitialScale;
saveZoom(factorToAchieveSelected, true, zoomCustomLabel);
toggleZoomingMenu();
};

const getPreviewedZoomLevelLabel = () => {
if (zoom.customLabel) {
return zoom.customLabel;
}

const previewToRealImgFactor =
originalSource && !resize.width && !resize.height
? shownImageDimensions.originalSourceInitialScale * zoom.factor
: zoom.factor;
return `${toPrecisedFloat(previewToRealImgFactor * 100, 0) || '100'}%`;
};
const {
zoomOut,
zoomIn,
applyZoomFactorPreset,
getPreviewedZoomLevelLabel,
isZoomDisabled,
toggleZoomingMenu,
fitCanvas,
zoomingMenuAnchorEl,
} = useZoom();

const isZoomDisabled = toolId === TOOLS_IDS.CROP || isBlockerError;
const showFitButton = showFitCenterZoomButton && showFitCenterButton;

return (
<StyledZoomingWrapper className="FIE_buttons-zoom-btns" {...props}>
Expand Down Expand Up @@ -135,15 +73,17 @@ const ZoomButtons = (props) => {
>
<PlusOutline />
</StyledSmallButton>
<StyledSmallButton
onClick={() => applyZoomFactorPreset('fit')}
color="basic"
title={t('fitTitle')}
disabled={isZoomDisabled}
className="FIE_buttons-fit-btn"
>
<PositionCenter />
</StyledSmallButton>
{showFitButton && (
<StyledSmallButton
onClick={() => applyZoomFactorPreset('fit')}
color="basic"
title={t('fitTitle')}
disabled={isZoomDisabled}
className="FIE_buttons-fit-btn"
>
<PositionCenter />
</StyledSmallButton>
)}
<Menu
anchorEl={zoomingMenuAnchorEl}
onClose={toggleZoomingMenu}
Expand All @@ -164,4 +104,8 @@ const ZoomButtons = (props) => {
);
};

ZoomButtons.propTypes = {
showFitCenterButton: PropTypes.bool,
};

export default ZoomButtons;
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,5 @@ export default {
previewBgColor: undefined,
previewBgImage: undefined,
keepZoomOnSourceChange: false,
showFitCenterZoomButton: true,
};
2 changes: 2 additions & 0 deletions packages/react-filerobot-image-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@ export { default as useManageHistoryState } from './useManageHistoryState';
export { default as useAnnotationOrdering } from './useAnnotationOrdering';

export { default as useEditableTextId } from './useEditableTextId';

export { default as useZoom } from './useZoom';
105 changes: 105 additions & 0 deletions packages/react-filerobot-image-editor/src/hooks/useZoom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/** External Dependencies */
import { useState } from 'react';

/** Internal Dependencies */
import { ZOOM_CANVAS } from 'actions';
import getZoomFitFactor from 'utils/getZoomFitFactor';
import { DEFAULT_ZOOM_FACTOR, TOOLS_IDS } from 'utils/constants';
import toPrecisedFloat from 'utils/toPrecisedFloat';
import useStore from './useStore';

const MULTIPLY_ZOOM_FACTOR = 1.1;

const useZoom = () => {
const {
dispatch,
zoom = {},
toolId,
feedback,
shownImageDimensions,
resize,
originalSource,
adjustments: { crop },
} = useStore();
const isBlockerError = feedback.duration === 0;
const [zoomingMenuAnchorEl, setZoomingMenuAnchorEl] = useState(null);

const saveZoom = (zoomFactor, isAbsoluteZoom, zoomCustomLabel) => {
dispatch({
type: ZOOM_CANVAS,
payload: {
factor: zoomFactor,
isAbsoluteZoom,
customLabel: zoomCustomLabel,
},
});
};

const zoomIn = () => {
saveZoom(zoom.factor * MULTIPLY_ZOOM_FACTOR);
};

const fitCanvas = () => {
const usedAsOrgDimens =
(resize.width && resize.height && resize) ||
(crop.width && crop.height && crop) ||
shownImageDimensions;
const fitCanvasFactor = getZoomFitFactor(
(crop.width && crop.height && crop) || shownImageDimensions,
usedAsOrgDimens,
);
saveZoom(fitCanvasFactor || DEFAULT_ZOOM_FACTOR, true);
};

const zoomOut = () => {
saveZoom(zoom.factor / MULTIPLY_ZOOM_FACTOR);
};

const toggleZoomingMenu = (event) => {
setZoomingMenuAnchorEl(zoomingMenuAnchorEl || !event ? null : event.target);
};

const applyZoomFactorPreset = (factor, zoomCustomLabel) => {
if (factor === 'fit') {
fitCanvas();
toggleZoomingMenu();
return;
}

const factorToAchieveSelected =
resize.width || resize.height
? factor
: factor / shownImageDimensions.originalSourceInitialScale;
saveZoom(factorToAchieveSelected, true, zoomCustomLabel);
toggleZoomingMenu();
};

const getPreviewedZoomLevelLabel = () => {
if (zoom.customLabel) {
return zoom.customLabel;
}

const previewToRealImgFactor =
originalSource && !resize.width && !resize.height
? shownImageDimensions.originalSourceInitialScale * zoom.factor
: zoom.factor;
return `${toPrecisedFloat(previewToRealImgFactor * 100, 0) || '100'}%`;
};

const isZoomDisabled = toolId === TOOLS_IDS.CROP || isBlockerError;

return {
applyZoomFactorPreset,
getPreviewedZoomLevelLabel,
isZoomDisabled,
fitCanvas,
zoomIn,
zoomOut,
saveZoom,
toggleZoomingMenu,
zoomingMenuAnchorEl,
setZoomingMenuAnchorEl,
};
};

export default useZoom;

0 comments on commit e1e96df

Please sign in to comment.