Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deploy auto fit text plus b/w bug fix and show file name on footer #575

Merged
merged 18 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
153e466
update method calcTextWidth to calcTextDimensions
Alber-Writer Nov 20, 2024
f9834cc
Move calcTextDimensions method to common/utils folder
Alber-Writer Nov 20, 2024
7b68643
test shape resizing on fontsize changes
Alber-Writer Nov 20, 2024
eb41e57
refactor resize-on-fontsize-change to hook
Alber-Writer Nov 20, 2024
9f544f2
Merge branch 'dev' into feature/#538-Recalc-transformer-widht-height-…
brauliodiez Nov 21, 2024
6ba7fae
apply resize hook to single line front-text-components
Alber-Writer Nov 23, 2024
cb97c7f
handle resizing when multiline comps fontsize changes
Alber-Writer Nov 23, 2024
74ab664
Merge branch 'feature/#538-Recalc-transformer-widht-height-on-text-co…
Alber-Writer Nov 23, 2024
4fd3a08
#565 bw filters fixed when export
oleojake Nov 23, 2024
1e602ea
#569 show filename in footer
oleojake Nov 23, 2024
c8fc01a
Merge pull request #563 from Lemoncode/feature/#538-Recalc-transforme…
brauliodiez Nov 23, 2024
a7a0e4c
#569 fix filename in footer
oleojake Nov 24, 2024
0eeb096
#565 bug, checkbox updating bw image filter
oleojake Nov 24, 2024
a52536d
Merge branch 'dev' into Bug/#565-B/W-filter-when-exporting
brauliodiez Nov 24, 2024
4f8b823
Merge pull request #573 from Lemoncode/Bug/#565-B/W-filter-when-expor…
brauliodiez Nov 24, 2024
d497c81
#569 setFilename to empty when createNewFullDocument
oleojake Nov 24, 2024
14ff17e
Merge branch 'dev' into feature/#569-add-filename-to-footer
brauliodiez Nov 24, 2024
b9556d4
Merge pull request #574 from Lemoncode/feature/#569-add-filename-to-f…
brauliodiez Nov 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Layer } from 'konva/lib/Layer';
import { balanceSpacePerItem } from './balance-space';
import { calcTextWidth } from './calc-text-width';
import { calcTextDimensions } from '@/common/utils/calc-text-dimensions';

export const adjustTabWidths = (args: {
tabs: string[];
Expand Down Expand Up @@ -35,9 +35,14 @@ export const adjustTabWidths = (args: {
}
const arrangeTabsInfo = tabs.reduce(
(acc: OriginalTabInfo[], tab, index): OriginalTabInfo[] => {
const tabFullTextWidth =
calcTextWidth(tab, font.fontSize, font.fontFamily, konvaLayer) +
totalInnerXPadding;
const { width: textWidth } = calcTextDimensions(
tab,
font.fontSize,
font.fontFamily,
konvaLayer
);

const tabFullTextWidth = textWidth + totalInnerXPadding;
const desiredWidth = Math.max(totalMinTabSpace, tabFullTextWidth);
return [
...acc,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { calcTextDimensions } from '@/common/utils/calc-text-dimensions';
import { useCanvasContext } from '@/core/providers';
import { useEffect, useRef } from 'react';

export const useResizeOnFontSizeChange = (
id: string,
coords: { x: number; y: number },
text: string,
fontSize: number,
fontVariant: string,
multiline: boolean = false
) => {
const previousFontSize = useRef(fontSize);
const { updateShapeSizeAndPosition, stageRef } = useCanvasContext();
const konvaLayer = stageRef.current?.getLayers()[0];

useEffect(() => {
if (previousFontSize.current !== fontSize) {
previousFontSize.current = fontSize;

const paragraphLines = _extractParagraphLines(text);
const longestLine = _findLongestString(paragraphLines);

const { width, height } = calcTextDimensions(
multiline ? longestLine : text,
fontSize,
fontVariant,
konvaLayer
);

updateShapeSizeAndPosition(
id,
coords,
{
width: width * 1.15,
height: multiline
? _calcParagraphTotalHeight(height, 0.8, paragraphLines.length)
: height,
},
true
);
}
}, [fontSize]);
};

/* Hook Helper functions */
function _extractParagraphLines(multilineText: string) {
return multilineText.split(/\r?\n/).filter(line => line.trim() !== '');
}

function _findLongestString(stringsArray: string[]): string {
return stringsArray.reduce((longest, current) =>
current.length > longest.length ? current : longest
);
}

function _calcParagraphTotalHeight(
heightPerLine: number,
lineHeight: number = 1.3,
linesQty: number
) {
return heightPerLine * lineHeight * linesQty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const heading1SizeRestrictions: ShapeSizeRestrictions = {
minWidth: 40,
Expand Down Expand Up @@ -56,6 +57,8 @@ export const Heading1Shape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const heading2SizeRestrictions: ShapeSizeRestrictions = {
minWidth: 40,
Expand Down Expand Up @@ -56,6 +57,8 @@ export const Heading2Shape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const heading3SizeRestrictions: ShapeSizeRestrictions = {
minWidth: 40,
Expand Down Expand Up @@ -57,6 +58,8 @@ export const Heading3Shape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const linkSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 40,
Expand Down Expand Up @@ -41,10 +42,8 @@ export const LinkShape = forwardRef<any, ShapeProps>((props, ref) => {

const { width: restrictedWidth, height: restrictedHeight } = restrictedSize;

const { textColor, textDecoration, fontSize, textAlignment } = useShapeProps(
otherProps,
BASIC_SHAPE
);
const { textColor, textDecoration, fontSize, textAlignment, fontVariant } =
useShapeProps(otherProps, BASIC_SHAPE);

const commonGroupProps = useGroupShapeProps(
props,
Expand All @@ -53,6 +52,8 @@ export const LinkShape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const normaltextSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 40,
Expand Down Expand Up @@ -56,6 +57,8 @@ export const NormaltextShape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const paragraphSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 200,
Expand Down Expand Up @@ -40,7 +41,7 @@ export const ParagraphShape = forwardRef<any, ShapeProps>((props, ref) => {
);
const { width: restrictedWidth, height: restrictedHeight } = restrictedSize;

const { textColor, fontSize, textAlignment } = useShapeProps(
const { textColor, fontSize, textAlignment, fontVariant } = useShapeProps(
otherProps,
BASIC_SHAPE
);
Expand All @@ -52,6 +53,8 @@ export const ParagraphShape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant, true);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fitSizeToShapeSizeRestrictions } from '@/common/utils/shapes/shape-rest
import { useShapeProps } from '../../shapes/use-shape-props.hook';
import { BASIC_SHAPE } from '../front-components/shape.const';
import { useGroupShapeProps } from '../mock-components.utils';
import { useResizeOnFontSizeChange } from './front-text-hooks/resize-fontsize-change.hook';

const smalltextSizeRestrictions: ShapeSizeRestrictions = {
minWidth: 40,
Expand Down Expand Up @@ -56,6 +57,8 @@ export const SmalltextShape = forwardRef<any, ShapeProps>((props, ref) => {
ref
);

useResizeOnFontSizeChange(id, { x, y }, text, fontSize, fontVariant);

return (
<Group {...commonGroupProps} {...shapeProps}>
<Text
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Layer } from 'konva/lib/Layer';

/**
* Virtually calculates the width that a text will occupy, by using a canvas.
* Virtually calculates the height and width that a text will occupy, by using a canvas.
* If a Konva Layer is provided, it will reuse the already existing canvas.
* Otherwise, it will create a canvas within the document, on the fly, to perform the measurement.
* Finaly, as a safety net, a very generic calculation is provided in case the other options are not available.
*/
export const calcTextWidth = (
export const calcTextDimensions = (
inputText: string,
fontSize: number,
fontfamily: string,
Expand All @@ -31,7 +31,10 @@ const _getTextWidthByKonvaMethod = (
) => {
const context = konvaLayer.getContext();
context.font = `${fontSize}px ${fontfamily}`;
return context.measureText(text).width;
const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } =
context.measureText(text);
const totalHeight = fontBoundingBoxAscent + fontBoundingBoxDescent;
return { width, height: totalHeight };
};

const _getTextCreatingNewCanvas = (
Expand All @@ -43,8 +46,13 @@ const _getTextCreatingNewCanvas = (
const context = canvas.getContext('2d');
if (context) {
context.font = `${fontSize}px ${fontfamily}`;
return context.measureText(text).width;
const { width, fontBoundingBoxAscent, fontBoundingBoxDescent } =
context.measureText(text);
const height = fontBoundingBoxAscent + fontBoundingBoxDescent;
return { width, height };
}
const charAverageWidth = fontSize * 0.7;
return text.length * charAverageWidth + charAverageWidth * 0.8;
const width = text.length * charAverageWidth + charAverageWidth * 0.8;
const height = fontSize * 1.5;
return { width, height };
};
1 change: 1 addition & 0 deletions src/core/local-disk/use-local-disk.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const useLocalDisk = () => {
reader.onload = () => {
const content = reader.result as string;
const parseData: QuickMockFileContract = JSON.parse(content);
setFileName(file.name);
if (parseData.version === '0.1') {
// Handle version 0.1 parsing
const appDocument =
Expand Down
1 change: 1 addition & 0 deletions src/core/providers/canvas/canvas.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export interface CanvasContextModel {
addNewPage: () => void;
duplicatePage: (pageIndex: number) => void;
getActivePage: () => Page;
getActivePageName: () => string;
setActivePage: (pageId: string) => void;
deletePage: (pageIndex: number) => void;
editPageTitle: (pageIndex: number, newName: string) => void;
Expand Down
6 changes: 6 additions & 0 deletions src/core/providers/canvas/canvas.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export const CanvasProvider: React.FC<Props> = props => {
return document.pages[document.activePageIndex];
};

const getActivePageName = () => {
return document.pages[document.activePageIndex].name;
};

const setActivePage = (pageId: string) => {
selectionInfo.clearSelection();
selectionInfo.shapeRefs.current = {};
Expand Down Expand Up @@ -179,6 +183,7 @@ export const CanvasProvider: React.FC<Props> = props => {

const createNewFullDocument = () => {
setDocument(createDefaultDocumentModel());
setFileName('');
};

const deleteSelectedShapes = () => {
Expand Down Expand Up @@ -318,6 +323,7 @@ export const CanvasProvider: React.FC<Props> = props => {
addNewPage,
duplicatePage,
getActivePage,
getActivePageName,
setActivePage,
deletePage,
editPageTitle,
Expand Down
21 changes: 18 additions & 3 deletions src/pods/footer/footer.pod.module.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
.container {
display: flex;
justify-content: center;
justify-content: space-between;
align-items: center;
background-color: var(--primary-50);
border-top: 1px solid var(--primary-100);
padding: var(--space-xs) var(--space-md);
}

.title {
flex-grow: 1;
.left,
.center,
.right {
flex: 1;
}

.left {
text-align: left;
}

.center {
text-align: center;
}

.right {
display: flex;
justify-content: flex-end;
}

.zoomContainer {
Expand Down
38 changes: 24 additions & 14 deletions src/pods/footer/footer.pod.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,33 @@ import classes from './footer.pod.module.css';
import { ZoomInButton, ZoomOutButton } from './components';

export const FooterPod = () => {
const { scale, setScale } = useCanvasContext();
const { scale, setScale, getActivePageName, fileName } = useCanvasContext();

return (
<footer className={classes.container}>
<p className={classes.title}>Quickmock - © Lemoncode</p>
<div className={classes.zoomContainer}>
<ZoomOutButton
scale={scale}
setScale={setScale}
className={classes.button}
/>
<p className={classes.zoomValue}>{(scale * 100).toFixed(0)} %</p>
<ZoomInButton
scale={scale}
setScale={setScale}
className={classes.button}
/>
<div className={classes.left}>
<p>
<strong>📄 {fileName == '' ? 'New' : fileName}</strong> -{' '}
{getActivePageName()}
</p>
</div>
<div className={classes.center}>
<p>Quickmock - © Lemoncode</p>
</div>
<div className={classes.right}>
<div className={classes.zoomContainer}>
<ZoomOutButton
scale={scale}
setScale={setScale}
className={classes.button}
/>
<p className={classes.zoomValue}>{(scale * 100).toFixed(0)} %</p>
<ZoomInButton
scale={scale}
setScale={setScale}
className={classes.button}
/>
</div>
</div>
</footer>
);
Expand Down
Loading