From 9e33579eada580a9b5f5a009686f0ef32293bf7d Mon Sep 17 00:00:00 2001
From: ssi02014
Date: Wed, 5 Apr 2023 15:34:47 +0900
Subject: [PATCH 1/3] =?UTF-8?q?feat:=20github=20actions=20ci/cd=20?=
=?UTF-8?q?=EA=B5=AC=EC=B6=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/workflows/npm-publish.yml | 38 +++++++++++++++++++++++++++++++
package.json | 2 +-
src/components/TG.styled.ts | 1 -
3 files changed, 39 insertions(+), 2 deletions(-)
create mode 100644 .github/workflows/npm-publish.yml
diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml
new file mode 100644
index 0000000..bb43518
--- /dev/null
+++ b/.github/workflows/npm-publish.yml
@@ -0,0 +1,38 @@
+name: Publish Package to npmjs
+on:
+ push:
+ branches:
+ - master
+jobs:
+ npm-publish:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout 🔔
+ uses: actions/checkout@v3
+ - name: Node Setup 🔔
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ registry-url: 'https://registry.npmjs.org'
+ - name: Install & Build 🔨
+ run: |
+ yarn
+ yarn build
+ - name: Publish 🚀
+ run: yarn publish
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+ storybook-publish:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout 🔔
+ uses: actions/checkout@v3
+ - name: Install & Build 🔨
+ run: |
+ yarn
+ yarn build:storybook
+ - name: Deploy 🚀
+ uses: JamesIves/github-pages-deploy-action@v4
+ with:
+ token: ${{ secrets.PUBLISH_TOKEN }}
+ folder: storybook-static
\ No newline at end of file
diff --git a/package.json b/package.json
index 9911c08..a740f13 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-thumbnail-generator",
- "version": "2.7.1",
+ "version": "2.8.0",
"description": "react-thumbnail-generator",
"main": "dist/index.js",
"module": "dist/index.js",
diff --git a/src/components/TG.styled.ts b/src/components/TG.styled.ts
index 5aab829..e256d3b 100644
--- a/src/components/TG.styled.ts
+++ b/src/components/TG.styled.ts
@@ -29,7 +29,6 @@ export const TGBodyWrapper = styled.section<{
display: flex;
justify-content: center;
min-width: ${({ isFullWidth }) => (isFullWidth ? '100%' : '600px')};
- min-height: 100vh;
border-radius: 7px;
box-shadow: 1px 1px 10px #cccccc;
z-index: 9999;
From 0970cf42177c53048a996aa1486753f1d249a28d Mon Sep 17 00:00:00 2001
From: ssi02014
Date: Wed, 5 Apr 2023 16:39:30 +0900
Subject: [PATCH 2/3] =?UTF-8?q?feat:=20line=20Height=20+=20=ED=8F=B4?=
=?UTF-8?q?=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20=EB=A6=AC=ED=8C=A9=ED=86=A0?=
=?UTF-8?q?=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/Canvas/index.tsx | 5 +-
.../{Divider.tsx => Divider/index.tsx} | 0
src/components/Inputs/RangeInput/index.tsx | 1 +
.../{TGHeader.tsx => Layout/Header/index.tsx} | 20 +--
src/components/Layout/styled.tsx | 91 +++++++++++
.../{TGPortal.tsx => Portal/index.tsx} | 6 +-
.../SelectItem.tsx} | 14 +-
.../{TGSelect.tsx => Select/index.tsx} | 20 +--
src/components/Select/styled.tsx | 58 +++++++
src/components/TG.styled.ts | 148 +-----------------
src/components/TG.tsx | 108 +++++++------
src/hooks/useDragAndDropText.tsx | 2 +-
src/lib/ThumbnailGenerator.tsx | 6 +-
src/types/canvas.ts | 1 +
src/utils/common.ts | 9 +-
15 files changed, 256 insertions(+), 233 deletions(-)
rename src/components/{Divider.tsx => Divider/index.tsx} (100%)
rename src/components/{TGHeader.tsx => Layout/Header/index.tsx} (62%)
create mode 100644 src/components/Layout/styled.tsx
rename src/components/{TGPortal.tsx => Portal/index.tsx} (79%)
rename src/components/{TGSelectItem.tsx => Select/SelectItem.tsx} (62%)
rename src/components/{TGSelect.tsx => Select/index.tsx} (86%)
create mode 100644 src/components/Select/styled.tsx
diff --git a/src/components/Canvas/index.tsx b/src/components/Canvas/index.tsx
index 2b5174b..37caec9 100644
--- a/src/components/Canvas/index.tsx
+++ b/src/components/Canvas/index.tsx
@@ -10,6 +10,7 @@ interface CanvasProps {
const Canvas = React.forwardRef(({ canvasState }: CanvasProps, ref: any) => {
const {
value,
+ lineHeight,
canvasWidth,
canvasHeight,
fontSize,
@@ -85,10 +86,10 @@ const Canvas = React.forwardRef(({ canvasState }: CanvasProps, ref: any) => {
lines: string[]
) => {
const size = +fontSize.replace('px', '');
- const lineHeight = size * 1.15;
+ const fontLineHeight = size + +lineHeight;
lines.forEach((line, idx) => {
- const { x, y } = getMultiLinePosition(lines.length, lineHeight, idx);
+ const { x, y } = getMultiLinePosition(lines.length, fontLineHeight, idx);
ctx.save();
ctx.translate(x, y);
diff --git a/src/components/Divider.tsx b/src/components/Divider/index.tsx
similarity index 100%
rename from src/components/Divider.tsx
rename to src/components/Divider/index.tsx
diff --git a/src/components/Inputs/RangeInput/index.tsx b/src/components/Inputs/RangeInput/index.tsx
index e6b95fb..8ebf5d0 100644
--- a/src/components/Inputs/RangeInput/index.tsx
+++ b/src/components/Inputs/RangeInput/index.tsx
@@ -28,6 +28,7 @@ const RangeInput = ({
void;
}
-const TGHeader = ({ onToggle }: TGHeaderProps) => {
+const Header = ({ onToggle }: HeaderProps) => {
const LimitWidthSize = window.innerWidth;
return (
-
+
-
+
Limit Width: {`${LimitWidthSize}px`}
-
-
+
+
);
};
-export default TGHeader;
+export default Header;
diff --git a/src/components/Layout/styled.tsx b/src/components/Layout/styled.tsx
new file mode 100644
index 0000000..7820e17
--- /dev/null
+++ b/src/components/Layout/styled.tsx
@@ -0,0 +1,91 @@
+import { getModalPosition } from '@utils/style';
+import styled from 'styled-components';
+
+export const HeaderWrapper = styled.div`
+ display: flex;
+ position: sticky;
+ top: 0;
+ flex-direction: column;
+ padding: 10px;
+ padding-bottom: 0;
+ background-color: #fff;
+
+ & > div:first-child {
+ justify-content: space-between;
+ align-items: center;
+ display: flex;
+ }
+
+ a {
+ color: #111111;
+ padding: 0;
+ margin: 0;
+ font-size: 0.875rem;
+ font-weight: bold;
+ text-decoration: none;
+
+ &:hover {
+ color: #3264b5;
+ }
+ }
+
+ button {
+ cursor: pointer;
+ transition: transform 0.2s;
+ &:hover {
+ transform: rotate(90deg);
+ }
+ }
+`;
+
+export const LimitSizeText = styled.div`
+ font-size: 0.85rem;
+ margin-top: 5px;
+ text-align: center;
+
+ span {
+ font-weight: bold;
+ }
+`;
+
+export const BodyWrapper = styled.section<{
+ modalPosition: 'left' | 'right' | 'center';
+ isFullWidth: boolean;
+}>`
+ position: fixed;
+ display: flex;
+ justify-content: center;
+ min-width: ${({ isFullWidth }) => (isFullWidth ? '100%' : '600px')};
+ border-radius: 7px;
+ box-shadow: 1px 1px 10px #cccccc;
+ z-index: 9999;
+ background-color: #ffffff;
+ flex-direction: column;
+ overflow: hidden;
+ font-family: Arial;
+
+ * {
+ box-sizing: border-box;
+ }
+
+ ${({ modalPosition }) => getModalPosition(modalPosition)}
+`;
+
+export const InnerWrapper = styled.div`
+ flex-direction: column;
+ width: 100%;
+ max-height: calc(100vh - 78px);
+ overflow-y: scroll;
+ overflow-x: auto;
+`;
+
+export const ContentWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ margin-bottom: 20px;
+
+ canvas + textarea {
+ margin-top: 10px;
+ }
+`;
diff --git a/src/components/TGPortal.tsx b/src/components/Portal/index.tsx
similarity index 79%
rename from src/components/TGPortal.tsx
rename to src/components/Portal/index.tsx
index 37b0330..b44f7a6 100644
--- a/src/components/TGPortal.tsx
+++ b/src/components/Portal/index.tsx
@@ -1,12 +1,12 @@
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
-interface TGPortalProps {
+interface PortalProps {
id?: string;
children: React.ReactNode;
}
-const TGPortal = ({ id, children }: TGPortalProps) => {
+const Portal = ({ id, children }: PortalProps) => {
const [portalElement, setPortalElement] = useState(null);
useEffect(() => {
@@ -17,4 +17,4 @@ const TGPortal = ({ id, children }: TGPortalProps) => {
return ReactDOM.createPortal(children, portalElement);
};
-export default TGPortal;
+export default Portal;
diff --git a/src/components/TGSelectItem.tsx b/src/components/Select/SelectItem.tsx
similarity index 62%
rename from src/components/TGSelectItem.tsx
rename to src/components/Select/SelectItem.tsx
index 168d7b9..a87f747 100644
--- a/src/components/TGSelectItem.tsx
+++ b/src/components/Select/SelectItem.tsx
@@ -1,8 +1,8 @@
import React, { useContext } from 'react';
-import { SelectListItem } from './TG.styled';
-import { SelectContext } from './TGSelect';
+import * as S from './styled';
+import { SelectContext } from './index';
-interface TGSelectItemProps {
+interface SelectItemProps {
children: string;
value: string | number;
}
@@ -12,18 +12,18 @@ interface SelectContextProps {
onChange: (value: string | number) => void;
}
-const TGSelectItem = ({ children, value }: TGSelectItemProps) => {
+const SelectItem = ({ children, value }: SelectItemProps) => {
const { selectValue, onChange } = useContext(
SelectContext
) as SelectContextProps;
return (
- onChange(value)}>
{children}
-
+
);
};
-export default TGSelectItem;
+export default SelectItem;
diff --git a/src/components/TGSelect.tsx b/src/components/Select/index.tsx
similarity index 86%
rename from src/components/TGSelect.tsx
rename to src/components/Select/index.tsx
index eff43c8..314502b 100644
--- a/src/components/TGSelect.tsx
+++ b/src/components/Select/index.tsx
@@ -6,8 +6,8 @@ import React, {
useEffect,
ComponentProps,
} from 'react';
-import { SelectWrapper, SelectInput, SelectItemContainer } from './TG.styled';
-import Icon from './Icon';
+import * as S from './styled';
+import Icon from '../Icon';
interface SelectContextProps {
color?: string;
@@ -28,7 +28,7 @@ export const SelectContext = React.createContext(
null
);
-const TGSelect = ({
+const Select = ({
children,
name,
color,
@@ -70,9 +70,9 @@ const TGSelect = ({
return (
-
+
-
@@ -84,11 +84,13 @@ const TGSelect = ({
)}
-
- {isOpenSelect && {children}}
-
+
+ {isOpenSelect && (
+ {children}
+ )}
+
);
};
-export default TGSelect;
+export default Select;
diff --git a/src/components/Select/styled.tsx b/src/components/Select/styled.tsx
new file mode 100644
index 0000000..f34cfaf
--- /dev/null
+++ b/src/components/Select/styled.tsx
@@ -0,0 +1,58 @@
+import styled from 'styled-components';
+
+// TG Select
+export const SelectWrapper = styled.div`
+ position: relative;
+ min-width: 150px;
+ max-width: 150px;
+
+ label {
+ font-size: 0.7rem;
+ color: #969696;
+ }
+`;
+
+export const SelectInput = styled.div<{ isOpenSelect: boolean }>`
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+ border: ${({ isOpenSelect }) =>
+ isOpenSelect ? `1px solid #0e1b30` : `1px solid #cccccc`};
+ border-radius: 5px;
+ padding: 6px 12px;
+
+ p {
+ margin: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.9rem;
+ }
+
+ &:hover {
+ border: 1px solid #0e1b30;
+ }
+`;
+
+export const SelectItemContainer = styled.ul`
+ position: absolute;
+ bottom: 20px;
+ width: 100%;
+ background-color: #fff;
+ box-shadow: 0 0 3px 0.5px #afafaf;
+ overflow-y: scroll;
+ list-style: none;
+ padding: 0;
+ max-height: 200px;
+`;
+
+export const SelectListItem = styled.li`
+ cursor: pointer;
+ padding: 10px 15px;
+ font-size: 0.9rem;
+
+ &:hover {
+ background-color: #ededed;
+ }
+`;
diff --git a/src/components/TG.styled.ts b/src/components/TG.styled.ts
index e256d3b..0d7d05e 100644
--- a/src/components/TG.styled.ts
+++ b/src/components/TG.styled.ts
@@ -1,5 +1,5 @@
import styled from 'styled-components';
-import { getIconPosition, getModalPosition } from '@utils/style';
+import { getIconPosition } from '@utils/style';
export const TGOpenButton = styled.button<{
iconPosition: [number, number, number, number];
@@ -21,95 +21,6 @@ export const TGOpenButton = styled.button<{
${({ iconPosition }) => getIconPosition(iconPosition)}
`;
-export const TGBodyWrapper = styled.section<{
- modalPosition: 'left' | 'right' | 'center';
- isFullWidth: boolean;
-}>`
- position: fixed;
- display: flex;
- justify-content: center;
- min-width: ${({ isFullWidth }) => (isFullWidth ? '100%' : '600px')};
- border-radius: 7px;
- box-shadow: 1px 1px 10px #cccccc;
- z-index: 9999;
- background-color: #ffffff;
- flex-direction: column;
- overflow: hidden;
- font-family: Arial;
-
- * {
- box-sizing: border-box;
- }
-
- ${({ modalPosition }) => getModalPosition(modalPosition)}
-`;
-
-export const TGLimitSizeText = styled.div`
- font-size: 0.85rem;
- margin-top: 5px;
- text-align: center;
-
- span {
- font-weight: bold;
- }
-`;
-
-export const TGInnerWrapper = styled.div`
- flex-direction: column;
- width: 100%;
- max-height: calc(100vh - 78px);
- overflow-y: scroll;
- overflow-x: auto;
-`;
-
-export const TGHeaderWrapper = styled.div`
- display: flex;
- position: sticky;
- top: 0;
- flex-direction: column;
- padding: 10px;
- padding-bottom: 0;
- background-color: #fff;
-
- & > div:first-child {
- justify-content: space-between;
- align-items: center;
- display: flex;
- }
-
- a {
- color: #111111;
- padding: 0;
- margin: 0;
- font-size: 0.875rem;
- font-weight: bold;
- text-decoration: none;
-
- &:hover {
- color: #3264b5;
- }
- }
-
- button {
- cursor: pointer;
- transition: transform 0.2s;
- &:hover {
- transform: rotate(90deg);
- }
- }
-`;
-
-export const TGContentWrapper = styled.div`
- display: flex;
- justify-content: center;
- flex-direction: column;
- margin-bottom: 20px;
-
- canvas + textarea {
- margin-top: 10px;
- }
-`;
-
export const TGTextarea = styled.textarea`
width: 350px;
height: auto;
@@ -163,60 +74,3 @@ export const TGControllerWrapper = styled.div`
margin-top: 20px;
}
`;
-
-// TG Select
-export const SelectWrapper = styled.div`
- position: relative;
- min-width: 150px;
- max-width: 150px;
-
- label {
- font-size: 0.7rem;
- color: #969696;
- }
-`;
-
-export const SelectInput = styled.div<{ isOpenSelect: boolean }>`
- display: flex;
- justify-content: space-between;
- align-items: center;
- cursor: pointer;
- border: ${({ isOpenSelect }) =>
- isOpenSelect ? `1px solid #0e1b30` : `1px solid #cccccc`};
- border-radius: 5px;
- padding: 6px 12px;
-
- p {
- margin: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 0.9rem;
- }
-
- &:hover {
- border: 1px solid #0e1b30;
- }
-`;
-
-export const SelectItemContainer = styled.ul`
- position: absolute;
- bottom: 20px;
- width: 100%;
- background-color: #fff;
- box-shadow: 0 0 3px 0.5px #afafaf;
- overflow-y: scroll;
- list-style: none;
- padding: 0;
- max-height: 200px;
-`;
-
-export const SelectListItem = styled.li`
- cursor: pointer;
- padding: 10px 15px;
- font-size: 0.9rem;
-
- &:hover {
- background-color: #ededed;
- }
-`;
diff --git a/src/components/TG.tsx b/src/components/TG.tsx
index 704103c..0ce7023 100644
--- a/src/components/TG.tsx
+++ b/src/components/TG.tsx
@@ -1,7 +1,6 @@
import React, { ChangeEvent, useMemo, useRef, useState } from 'react';
-import TGHeader from './TGHeader';
-import TGSelect from './TGSelect';
-import TGSelectItem from './TGSelectItem';
+import Select from './Select';
+import SelectItem from './Select/SelectItem';
import TextInput from './Inputs/TextInput';
import Icon from './Icon';
import FileInput from './Inputs/FileInput';
@@ -10,6 +9,7 @@ import Accordion from './Accordion';
import Canvas from './Canvas';
import ColorPicker from './ColorPicker';
import InputRange from './Inputs/RangeInput';
+import Header from './Layout/Header';
import {
fontFamilies,
fontSizes,
@@ -19,8 +19,9 @@ import {
import { CanvasState } from '../types/canvas';
import { fill, font, stroke, blur } from '@assets/icons';
import { Color, useColor } from 'react-color-palette';
+import { BodyWrapper, ContentWrapper, InnerWrapper } from './Layout/styled';
import * as S from './TG.styled';
-import { downloadCanvas, getValidMessage } from '@utils/common';
+import { downloadCanvas, getValidMessage, ValidType } from '@utils/common';
import { IconButton } from './Icon/styled';
interface TGProps {
@@ -46,6 +47,7 @@ const TG = ({
canvasHeight: '400',
imageType: 'png',
angle: '0',
+ lineHeight: '0',
isBlur: false,
selectedImage: null,
isBlockEvent: false,
@@ -57,6 +59,24 @@ const TG = ({
const canvasRef = useRef(null);
+ const canvasStateWithColors = useMemo(() => {
+ return {
+ ...canvasState,
+ bgColor,
+ fontColor,
+ strokeColor,
+ };
+ }, [canvasState, bgColor, fontColor, strokeColor]);
+
+ const fontFamilyOptions = useMemo(() => {
+ return [...additionalFontFamily, ...fontFamilies];
+ }, [additionalFontFamily]);
+
+ const defaultLineHeight = useMemo(
+ () => +canvasState.fontSize.replace('px', ''),
+ [canvasState.fontSize]
+ );
+
const toggleIsBlockEvent = () => {
setCanvasState({
...canvasState,
@@ -150,44 +170,32 @@ const TG = ({
downloadCanvas(canvasRef, canvasState.imageType);
};
- const handleChangeAngle = (e: ChangeEvent) => {
+ const handleChangeRange = (e: ChangeEvent) => {
const regex = /[^0-9]/g;
const { name, value } = e.target;
-
+ const min = name === 'angle' ? -360 : defaultLineHeight * -5;
+ const max = name === 'angle' ? 360 : defaultLineHeight * 3;
const replacedCallback = getReplaceCallback(name);
const replacedValue = value.replace(regex, replacedCallback);
const validMessage = getValidMessage(
- +value < -360 || +value > 360,
- 'fontAngle'
+ +value < min || +value > max,
+ name as ValidType
);
if (validMessage) return alert(validMessage);
setCanvasState({
...canvasState,
- angle: replacedValue,
+ [name]: replacedValue,
});
};
- const canvasStateWithColors = useMemo(() => {
- return {
- ...canvasState,
- bgColor,
- fontColor,
- strokeColor,
- };
- }, [canvasState, bgColor, fontColor, strokeColor]);
-
- const fontFamilyOptions = useMemo(() => {
- return [...additionalFontFamily, ...fontFamilies];
- }, [additionalFontFamily]);
-
return (
-
-
-
-
+
+
+
+
@@ -235,44 +243,52 @@ const TG = ({
min={-360}
max={360}
value={canvasState.angle}
- onChange={handleChangeAngle}
+ onChange={handleChangeRange}
+ />
+
-
{fontFamilyOptions.map((item) => (
-
+
{item}
-
+
))}
-
-
+
-
+
+
@@ -302,25 +318,25 @@ const TG = ({
-
{imageTypes.map((item) => (
-
+
{item}
-
+
))}
-
+
-
-
-
+
+
+
);
};
diff --git a/src/hooks/useDragAndDropText.tsx b/src/hooks/useDragAndDropText.tsx
index a07a4d6..1a6f9fe 100644
--- a/src/hooks/useDragAndDropText.tsx
+++ b/src/hooks/useDragAndDropText.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import { useState } from 'react';
const useDragAndDropText = (canvasWidth: number, canvasHeight: number) => {
const [dragAndDropTextData, setDragAndDropTextData] = useState({
diff --git a/src/lib/ThumbnailGenerator.tsx b/src/lib/ThumbnailGenerator.tsx
index 4dc5ab1..5eafdf7 100644
--- a/src/lib/ThumbnailGenerator.tsx
+++ b/src/lib/ThumbnailGenerator.tsx
@@ -3,7 +3,7 @@ import TG from '@components/TG';
import { TGOpenButton } from '@components/TG.styled';
import { toggleButton } from '@assets/icons';
import { Position, getIconSize } from '@utils/style';
-import TGPortal from '@components/TGPortal';
+import Portal from '@components/Portal';
import Icon from '@components/Icon';
interface ThumbnailGeneratorProps {
@@ -35,7 +35,7 @@ const ThumbnailGenerator = ({
return (
<>
-
+
{isOpen ? (
)}
-
+
>
);
};
diff --git a/src/types/canvas.ts b/src/types/canvas.ts
index 843776f..3e67beb 100644
--- a/src/types/canvas.ts
+++ b/src/types/canvas.ts
@@ -12,6 +12,7 @@ export interface CanvasState {
canvasWidth: string;
canvasHeight: string;
imageType: ImageTypes;
+ lineHeight: string;
angle: string;
isBlur: boolean;
selectedImage: HTMLImageElement | null;
diff --git a/src/utils/common.ts b/src/utils/common.ts
index b6406cb..e59fb9e 100644
--- a/src/utils/common.ts
+++ b/src/utils/common.ts
@@ -1,14 +1,13 @@
import React from 'react';
import { ImageTypes } from '../types/canvas';
-export const getValidMessage = (
- condition: boolean,
- type: 'imageSize' | 'canvasSize' | 'fontAngle'
-) => {
+export type ValidType = 'imageSize' | 'canvasSize' | 'angle' | 'lineHeight';
+export const getValidMessage = (condition: boolean, type: ValidType) => {
const message = {
imageSize: `Please register a picture smaller than "Limit Width"`,
canvasSize: `Please set the canvas width smaller than "Limit Width"`,
- fontAngle: 'Please set a value in the range of -360 to 360',
+ angle: 'Please set a value in the range of -360 to 360',
+ lineHeight: 'Please set a value in the range of 0 to 360',
} as { [key: string]: string };
if (condition) return message[type];
From c312aa1ce670fd5c97c31d8af6615353862f94d0 Mon Sep 17 00:00:00 2001
From: ssi02014
Date: Wed, 5 Apr 2023 16:40:41 +0900
Subject: [PATCH 3/3] docs: README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 53777e1..b762532 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,7 @@
- Resizing the canvas
- Filling the background with colors or pictures
- Choosing a blur effect
-- Selecting font family, size, stroke, color, and angle
+- Selecting font family, size, stroke, color, angle, lineHeight
- Dragging and dropping text on the canvas
- Adding custom web font families
- Selecting the modal button and its location