@axah/ react-svg-编辑器
一个可堆肥的 React SVG 编辑器库. 支持绘制形状,自由手路径,文本,裁剪,缩放,并拖动——都在一个由PDF或图像源支持的可缩放的SVG画布内.
安装
pnpm add @axah/react-svg-editor
# or
npm install @axah/react-svg-editor
同伴依赖关系 (分别安装):
pnpm add react react-dom pdfjs-dist
快速示例
import { useState } from 'react';
import {
BackgroundSource,
UncontrolledEditor,
Artboard,
Drawables,
Cropables,
translateDrawable,
resizeDrawable,
} from '@axah/react-svg-editor';
import type { Drawable, Crop } from '@axah/react-svg-editor';
const pdfjs = async () => {
const lib = await import('pdfjs-dist');
lib.GlobalWorkerOptions.workerSrc = (
await import('pdfjs-dist/build/pdf.worker?worker&url')
).default;
return lib;
};
export default function App() {
const [drawMode, setDrawMode] = useState<'rect' | 'pen' | 'ellipse' | 'line' | 'text' | 'crop' | null>(null);
const [drawables, setDrawables] = useState<ReadonlyArray<Drawable>>([]);
const [crop, setCrop] = useState<Crop | undefined>();
return (
<BackgroundSource source="/document.pdf" pdfjs={pdfjs} hqPdf>
{(source) => {
if (source.state !== 'LOADED') return <div>{source.state}</div>;
return (
<UncontrolledEditor
allowDrag={drawMode === null}
drawMode={drawMode}
backgroundUrl={source.url}
width={source.width}
height={source.height}
rotate={0}
>
<Artboard
drawMode={drawMode}
width={source.width}
height={source.height}
drawingFill="transparent"
drawingStroke="#027180"
drawingStrokeWidth={4}
text={['Hello', 'World']}
fontSize={16}
minWidth={0}
minHeight={0}
onDrawStart={() => {}}
onDrawEnd={(d) => setDrawables((prev) => [...prev, d])}
onCropStart={() => {}}
onCropEnd={setCrop}
>
<Drawables
drawables={drawables}
diStrokeWidth={3}
width={source.width}
height={source.height}
onSelectDrawable={() => {}}
onDrawableTranslate={(id, x, y) =>
setDrawables((prev) =>
prev.map((d) => (d.id === id ? translateDrawable(d, x, y) : d)),
)
}
onResizeDrawable={(_e, id, hX, hY, nX, nY) =>
setDrawables((prev) =>
prev.map((d) => (d.id === id ? resizeDrawable(d, hX, hY, nX, nY) : d)),
)
}
/>
<Cropables
width={source.width}
height={source.height}
diStrokeWidth={3}
crop={crop}
canTransformCrop={drawMode === 'crop'}
onCropTranslate={(x, y) =>
setCrop((c) => c && { ...c, x: c.x + x, y: c.y + y })
}
onResizeCrop={(hX, hY, nX, nY) => {
/* resize crop logic */
}}
onRemoveCrop={() => setCrop(undefined)}
onConfirmCrop={() => setDrawMode(null)}
/>
</Artboard>
</UncontrolledEditor>
);
}}
</BackgroundSource>
);
}
关键概念
| 构成部分 | 目的 |
|---|---|
BackgroundSource | 装入 PDF 或图像 URL , 并提供尺寸 + blob URL |
Editor | 以缩放、平板、旋转方式控制 SVG 帆布 |
UncontrolledEditor | 环绕 Editor 内部管理缩放/翻译状态 |
Artboard | 路线绘制事件到活动绘图模式( R)rect, (中文(简体) ), ellipse, (中文(简体) ), line, (中文(简体) ), pen, (中文(简体) ), text, (中文(简体) ), crop(中文(简体) ) |
Drawables | 带有选择和调整手柄大小的所有绘图形状 |
Cropables | 作物区域覆盖和管理 |
translateDrawable | 翻译可画的纯助手 (x, y) |
resizeDrawable | 通过手柄角调整可绘图大小的纯助手 |
发展
# install dependencies
pnpm install
# start the dev preview app
pnpm start
# type-check
pnpm lint
# build the library
pnpm build
# check package exports compatibility
pnpm check:types
预览应用程序位于 src/App.tsx 并装入本地 PDF 从 public/pdf-test.pdf。 。 。 .
图书馆来源在 lib/。 。 。 .
释放
释放是通过 更改。 。 。 .
# create a changeset
pnpm changeset
# publish (runs lint + type checks + build first)
pnpm release