diff --git a/src/common/components/front-components/input-shape.tsx b/src/common/components/front-components/input-shape.tsx index 0281351e..f250793b 100644 --- a/src/common/components/front-components/input-shape.tsx +++ b/src/common/components/front-components/input-shape.tsx @@ -2,33 +2,40 @@ import { ShapeSizeRestrictions } from '@/core/model'; import { forwardRef } from 'react'; import { ShapeProps } from './shape.model'; import { Group, Rect, Text } from 'react-konva'; +import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-restrictions'; -export const getInputShapeSizeRestrictions = (): ShapeSizeRestrictions => ({ +const inputShapeRestrictions: ShapeSizeRestrictions = { minWidth: 60, minHeight: 50, maxWidth: -1, maxHeight: 50, defaultWidth: 190, defaultHeight: 50, -}); +}; + +export const getInputShapeSizeRestrictions = (): ShapeSizeRestrictions => + inputShapeRestrictions; export const InputShape = forwardRef( ({ x, y, width, height, id, onSelected, ...shapeProps }, ref) => { + const { width: restrictedWidth, height: restrictedHeight } = + fitSizeToShapeSizeRestrictions(inputShapeRestrictions, width, height); + return ( onSelected(id, 'input')} > ( { + const newWidth = + shapeSizeRestrictions.maxWidth !== -1 + ? Math.min(shapeSizeRestrictions.maxWidth, width) + : width; + + const newHeight = + shapeSizeRestrictions.maxHeight !== -1 + ? Math.min(shapeSizeRestrictions.maxHeight, height) + : height; + + return { + width: Math.max(newWidth, shapeSizeRestrictions.minWidth), + height: Math.max(newHeight, shapeSizeRestrictions.minHeight), + }; +}; diff --git a/src/core/model/index.ts b/src/core/model/index.ts index 4a1f6876..590dc9df 100644 --- a/src/core/model/index.ts +++ b/src/core/model/index.ts @@ -19,6 +19,16 @@ export type ShapeType = | 'timepickerinput'; /* | "text"| "button" | "radio" | "image"*/ +export interface Size { + width: number; + height: number; +} + +export interface Coord { + x: number; + y: number; +} + export interface ShapeModel { id: string; x: number; diff --git a/src/core/providers/canvas/canvas.model.ts b/src/core/providers/canvas/canvas.model.ts index 42f3765a..83d270ff 100644 --- a/src/core/providers/canvas/canvas.model.ts +++ b/src/core/providers/canvas/canvas.model.ts @@ -3,4 +3,6 @@ import { ShapeModel } from '@/core/model'; export interface CanvasContextModel { shapes: ShapeModel[]; setShapes: React.Dispatch>; + scale: number; + setScale: React.Dispatch>; } diff --git a/src/core/providers/canvas/canvas.provider.tsx b/src/core/providers/canvas/canvas.provider.tsx index 42b632a8..4b3a65b8 100644 --- a/src/core/providers/canvas/canvas.provider.tsx +++ b/src/core/providers/canvas/canvas.provider.tsx @@ -9,9 +9,10 @@ interface Props { export const CanvasProvider: React.FC = props => { const { children } = props; const [shapes, setShapes] = React.useState([]); + const [scale, setScale] = React.useState(1); return ( - + {children} ); diff --git a/src/pods/canvas/canvas.model.ts b/src/pods/canvas/canvas.model.ts index 563216bb..e083a0ce 100644 --- a/src/pods/canvas/canvas.model.ts +++ b/src/pods/canvas/canvas.model.ts @@ -1,5 +1,6 @@ -import { ShapeModel, ShapeType } from '@/core/model'; +import { Coord, ShapeType, Size, ShapeModel } from '@/core/model'; import { v4 as uuidv4 } from 'uuid'; + import { getComboBoxShapeSizeRestrictions, getInputShapeSizeRestrictions, @@ -11,16 +12,6 @@ import { } from '@/common/components/front-components'; import { getBrowserWindowShapeSizeRestrictions } from '@/common/components/front-containers'; -export interface Size { - width: number; - height: number; -} - -export interface Coord { - x: number; - y: number; -} - const getDefaultSizeFromShape = (shapeType: ShapeType): Size => { switch (shapeType) { case 'combobox': diff --git a/src/pods/canvas/canvas.pod.tsx b/src/pods/canvas/canvas.pod.tsx index 0e7345af..846d31b2 100644 --- a/src/pods/canvas/canvas.pod.tsx +++ b/src/pods/canvas/canvas.pod.tsx @@ -14,9 +14,10 @@ import { moveZIndexTopOneLevel, moveZIndexToTop, } from './zindex.util'; +import { ShapeModel } from '@/core/model'; export const CanvasPod = () => { - const { shapes, setShapes } = useCanvasContext(); + const { shapes, setShapes, scale } = useCanvasContext(); const { shapeRefs, @@ -98,6 +99,7 @@ export const CanvasPod = () => { onMouseDown={handleClearSelection} onTouchStart={handleClearSelection} ref={stageRef} + scale={{ x: scale, y: scale }} > { diff --git a/src/pods/canvas/canvas.util.ts b/src/pods/canvas/canvas.util.ts index c3dbb860..abe25c1f 100644 --- a/src/pods/canvas/canvas.util.ts +++ b/src/pods/canvas/canvas.util.ts @@ -1,6 +1,6 @@ import { ShapeSizeRestrictions, ShapeType } from '@/core/model'; import { getButtonShapeSizeRestrictions } from '@/common/components/front-components/button-shape'; -import { Coord, Size } from './canvas.model'; +import { Coord } from '@/core/model'; import { getComboBoxShapeSizeRestrictions, getInputShapeSizeRestrictions, @@ -14,28 +14,6 @@ import { getBrowserWindowShapeSizeRestrictions } from '@/common/components/front import { DragLocationHistory } from '@atlaskit/pragmatic-drag-and-drop/dist/types/internal-types'; import { Stage } from 'konva/lib/Stage'; -// TODO Add Unit tests, issue: #45 -export const fitSizeToShapeSizeRestrictions = ( - shapeSizeRestrictions: ShapeSizeRestrictions, - width: number, - height: number -): Size => { - const newWidth = - shapeSizeRestrictions.maxWidth !== -1 - ? Math.min(shapeSizeRestrictions.maxWidth, width) - : width; - - const newHeight = - shapeSizeRestrictions.maxHeight !== -1 - ? Math.min(shapeSizeRestrictions.maxHeight, height) - : height; - - return { - width: Math.max(newWidth, shapeSizeRestrictions.minWidth), - height: Math.max(newHeight, shapeSizeRestrictions.minHeight), - }; -}; - const defaultShapeSizeRestrictions: ShapeSizeRestrictions = { minWidth: 0, minHeight: 0, diff --git a/src/pods/canvas/shape-renderer/index.tsx b/src/pods/canvas/shape-renderer/index.tsx index 7b7da63e..a69f1257 100644 --- a/src/pods/canvas/shape-renderer/index.tsx +++ b/src/pods/canvas/shape-renderer/index.tsx @@ -1,4 +1,4 @@ -import { ShapeModel } from '../canvas.model'; +import { ShapeModel } from '@/core/model'; import { ShapeRendererProps } from './model'; import { renderComboBox, diff --git a/src/pods/canvas/shape-renderer/simple-component/button.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/button.renderer.tsx index aa707c4a..3e782bf3 100644 --- a/src/pods/canvas/shape-renderer/simple-component/button.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/button.renderer.tsx @@ -1,5 +1,5 @@ +import { ShapeModel } from '@/core/model'; import { ShapeRendererProps } from '../model'; -import { ShapeModel } from '../../canvas.model'; import { ButtonShape } from '@/common/components/front-components/button-shape'; export const renderButton = ( diff --git a/src/pods/canvas/shape-renderer/simple-component/checkbox.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/checkbox.renderer.tsx index 0be31793..55164e09 100644 --- a/src/pods/canvas/shape-renderer/simple-component/checkbox.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/checkbox.renderer.tsx @@ -1,6 +1,6 @@ import { CheckBoxShape } from '@/common/components/front-components/checkbox-shape'; import { ShapeRendererProps } from '../model'; -import { ShapeModel } from '../../canvas.model'; +import { ShapeModel } from '@/core/model'; export const renderCheckbox = ( shape: ShapeModel, diff --git a/src/pods/canvas/shape-renderer/simple-component/combobox.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/combobox.renderer.tsx index 46f88ba5..64610a25 100644 --- a/src/pods/canvas/shape-renderer/simple-component/combobox.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/combobox.renderer.tsx @@ -1,6 +1,6 @@ import { ComboBoxShape } from '@/common/components/front-components'; -import { ShapeModel } from '../../canvas.model'; import { ShapeRendererProps } from '../model'; +import { ShapeModel } from '@/core/model'; export const renderComboBox = ( shape: ShapeModel, diff --git a/src/pods/canvas/shape-renderer/simple-component/datepickerinput.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/datepickerinput.renderer.tsx index c7f6a18a..5fafd0f8 100644 --- a/src/pods/canvas/shape-renderer/simple-component/datepickerinput.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/datepickerinput.renderer.tsx @@ -1,6 +1,6 @@ import { DatepickerInputShape } from '@/common/components/front-components'; -import { ShapeModel } from '../../canvas.model'; import { ShapeRendererProps } from '../model'; +import { ShapeModel } from '@/core/model'; export const renderDatepickerinput = ( shape: ShapeModel, diff --git a/src/pods/canvas/shape-renderer/simple-component/input.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/input.renderer.tsx index ed449d5b..0b19b4d6 100644 --- a/src/pods/canvas/shape-renderer/simple-component/input.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/input.renderer.tsx @@ -1,6 +1,6 @@ import { InputShape } from '@/common/components/front-components/input-shape'; import { ShapeRendererProps } from '../model'; -import { ShapeModel } from '../../canvas.model'; +import { ShapeModel } from '@/core/model'; export const renderInput = ( shape: ShapeModel, diff --git a/src/pods/canvas/shape-renderer/simple-component/notfound.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/notfound.renderer.tsx index c31fc151..55336ce0 100644 --- a/src/pods/canvas/shape-renderer/simple-component/notfound.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/notfound.renderer.tsx @@ -1,4 +1,4 @@ -import { ShapeModel } from '../../canvas.model'; +import { ShapeModel } from '@/core/model'; import { ShapeRendererProps } from '../model'; import { Group, Text } from 'react-konva'; diff --git a/src/pods/canvas/shape-renderer/simple-component/textarea.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/textarea.renderer.tsx index c83b1969..76ea45fa 100644 --- a/src/pods/canvas/shape-renderer/simple-component/textarea.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/textarea.renderer.tsx @@ -1,6 +1,6 @@ import { TextAreaShape } from '@/common/components/front-components/textarea-shape'; import { ShapeRendererProps } from '../model'; -import { ShapeModel } from '../../canvas.model'; +import { ShapeModel } from '@/core/model'; export const renderTextArea = ( shape: ShapeModel, diff --git a/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx index 406487cb..2b5e1bb5 100644 --- a/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/timepickerinput.renderer.tsx @@ -1,6 +1,6 @@ import { TimepickerInputShape } from '@/common/components/front-components'; -import { ShapeModel } from '../../canvas.model'; import { ShapeRendererProps } from '../model'; +import { ShapeModel } from '@/core/model'; export const renderTimepickerinput = ( shape: ShapeModel, diff --git a/src/pods/canvas/shape-renderer/simple-component/toggleswitch.renderer.tsx b/src/pods/canvas/shape-renderer/simple-component/toggleswitch.renderer.tsx index fd470bac..015832ed 100644 --- a/src/pods/canvas/shape-renderer/simple-component/toggleswitch.renderer.tsx +++ b/src/pods/canvas/shape-renderer/simple-component/toggleswitch.renderer.tsx @@ -1,5 +1,5 @@ +import { ShapeModel } from '@/core/model'; import { ShapeRendererProps } from '../model'; -import { ShapeModel } from '../../canvas.model'; import { ToggleSwitch } from '@/common/components/front-components/toggleswitch-shape'; export const renderToggleSwitch = ( diff --git a/src/pods/canvas/shape-renderer/simple-container/browserwindow.render.tsx b/src/pods/canvas/shape-renderer/simple-container/browserwindow.render.tsx index 308d4b3f..fdc4af37 100644 --- a/src/pods/canvas/shape-renderer/simple-container/browserwindow.render.tsx +++ b/src/pods/canvas/shape-renderer/simple-container/browserwindow.render.tsx @@ -1,6 +1,6 @@ import { BrowserWindowShape } from '@/common/components/front-containers'; -import { ShapeModel } from '../../canvas.model'; import { ShapeRendererProps } from '../model'; +import { ShapeModel } from '@/core/model'; export const renderBrowserWindow = ( shape: ShapeModel, diff --git a/src/pods/canvas/use-monitor-shape.hook.ts b/src/pods/canvas/use-monitor-shape.hook.ts index 0c51ddd7..10c127ae 100644 --- a/src/pods/canvas/use-monitor-shape.hook.ts +++ b/src/pods/canvas/use-monitor-shape.hook.ts @@ -7,7 +7,8 @@ import { convertFromDivElementCoordsToKonvaCoords, } from './canvas.util'; import Konva from 'konva'; -import { createShape, ShapeModel } from './canvas.model'; +import { createShape } from './canvas.model'; +import { ShapeModel } from '@/core/model'; export const useMonitorShape = ( dropRef: React.MutableRefObject, diff --git a/src/pods/canvas/use-selection.hook.ts b/src/pods/canvas/use-selection.hook.ts index e3963413..3d409520 100644 --- a/src/pods/canvas/use-selection.hook.ts +++ b/src/pods/canvas/use-selection.hook.ts @@ -1,9 +1,7 @@ import { useEffect, useRef, useState } from 'react'; -import { ShapeModel, ShapeRefs } from './canvas.model'; +import { ShapeRefs } from './canvas.model'; import Konva from 'konva'; -import { ShapeType } from '@/core/model'; - - +import { ShapeModel, ShapeType } from '@/core/model'; export const useSelection = (shapes: ShapeModel[]) => { const transformerRef = useRef(null); diff --git a/src/pods/canvas/use-transform.hook.ts b/src/pods/canvas/use-transform.hook.ts index 1f77652d..c43af33b 100644 --- a/src/pods/canvas/use-transform.hook.ts +++ b/src/pods/canvas/use-transform.hook.ts @@ -1,11 +1,6 @@ import { Node, NodeConfig } from 'konva/lib/Node'; -import { Coord, ShapeModel, Size } from './canvas.model'; import { Box } from 'konva/lib/shapes/Transformer'; -import { - fitSizeToShapeSizeRestrictions, - getShapeSizeRestrictions, -} from './canvas.util'; -import { ShapeType } from '@/core/model'; +import { Coord, ShapeModel, ShapeType, Size } from '@/core/model'; interface TransFormSelectedInfo { selectedShapeRef: React.MutableRefObject | null>; @@ -17,8 +12,7 @@ export const useTransform = ( setShapes: (value: React.SetStateAction) => void, transformSelectedInfo: TransFormSelectedInfo ) => { - const { selectedShapeId, selectedShapeRef, selectedShapeType } = - transformSelectedInfo; + const { selectedShapeId, selectedShapeRef } = transformSelectedInfo; const updateShapeSizeAndPosition = ( id: string, @@ -54,17 +48,11 @@ export const useTransform = ( node.scaleY(1); }; - const handleTransformerBoundBoxFunc = (_: Box, newBox: Box) => { - const limitedSize = fitSizeToShapeSizeRestrictions( - getShapeSizeRestrictions(selectedShapeType), - newBox.width, - newBox.height - ); - return { - ...newBox, - width: limitedSize.width, - height: limitedSize.height, - }; + const handleTransformerBoundBoxFunc = (oldBox: Box, newBox: Box) => { + if (newBox.width < 5 || newBox.height < 5) { + return oldBox; + } + return newBox; }; return { handleTransform, handleTransformerBoundBoxFunc }; diff --git a/src/pods/canvas/zindex.util.ts b/src/pods/canvas/zindex.util.ts index 31080c24..7f378c5d 100644 --- a/src/pods/canvas/zindex.util.ts +++ b/src/pods/canvas/zindex.util.ts @@ -1,4 +1,4 @@ -import { ShapeModel } from './canvas.model'; +import { ShapeModel } from '@/core/model'; // TOO Add Unit tests to all these methods: #65 export const moveZIndexToTop = ( diff --git a/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx b/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx index 7558051c..b666d7bd 100644 --- a/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx +++ b/src/pods/toolbar/components/zoom-in-button/zoom-in-button.tsx @@ -1,10 +1,13 @@ import ToolbarButton from '../toolbar-button/toolbar-button'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; import { ZoomInIcon } from '@/common/components/icons/zoom-in.component'; +import { useCanvasContext } from '@/core/providers'; export const ZoomInButton = () => { + const { setScale } = useCanvasContext(); + const handleClick = () => { - console.log('ZoomIn'); + setScale(prevScale => prevScale * 1.1); }; return ( diff --git a/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx b/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx index 5f16ec03..18ca8b3f 100644 --- a/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx +++ b/src/pods/toolbar/components/zoom-out-component/zoom-out-button.tsx @@ -1,10 +1,13 @@ import { ZoomOutIcon } from '@/common/components/icons/zoom-out.component'; import ToolbarButton from '../toolbar-button/toolbar-button'; import classes from '@/pods/toolbar/toolbar.pod.module.css'; +import { useCanvasContext } from '@/core/providers'; export const ZoomOutButton = () => { + const { setScale } = useCanvasContext(); + const handleClick = () => { - console.log('ZoomOut'); + setScale(prevScale => prevScale * 0.9); }; return (