mirror of
https://github.com/idrawjs/idraw
synced 2026-05-23 17:48:23 +00:00
refactor: refactor drawing svg
This commit is contained in:
parent
f10ba5ad60
commit
eec1ecf74a
29 changed files with 525 additions and 126 deletions
|
|
@ -39,6 +39,7 @@
|
|||
"@types/serve-handler": "^6.1.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.0",
|
||||
"@typescript-eslint/parser": "^5.57.0",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"babel-jest": "^29.5.0",
|
||||
"canvas": "^2.11.0",
|
||||
"chalk": "^5.2.0",
|
||||
|
|
|
|||
|
|
@ -259,8 +259,16 @@ export class Board {
|
|||
this._watcher.trigger('scrollY', scaleInfo);
|
||||
}
|
||||
|
||||
resize(newViewSize: Partial<ViewSizeInfo>) {
|
||||
resize(newViewSize: Pick<ViewSizeInfo, 'height' | 'width' | 'devicePixelRatio'>) {
|
||||
const viewSize = this._viewer.resize(newViewSize);
|
||||
const { width, height, devicePixelRatio } = newViewSize;
|
||||
const { viewContent } = this._opts;
|
||||
viewContent.viewContext.$resize({ width, height, devicePixelRatio });
|
||||
const canvas = viewContent.viewContext.canvas;
|
||||
canvas.style.width = `${width}px`;
|
||||
canvas.style.height = `${height}px`;
|
||||
viewContent.helperContext.$resize({ width, height, devicePixelRatio });
|
||||
viewContent.boardContext.$resize({ width, height, devicePixelRatio });
|
||||
this._viewer.drawFrame();
|
||||
this._watcher.trigger('resize', viewSize);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const defaultActiveStorage: ActiveStore = {
|
|||
contextHeight: 0,
|
||||
data: null,
|
||||
selectedUUIDs: [] as string[],
|
||||
selectedIndexs: [] as number[],
|
||||
selectedIndexes: [] as number[],
|
||||
scale: 1,
|
||||
offsetLeft: 0,
|
||||
offsetRight: 0,
|
||||
|
|
|
|||
|
|
@ -30,13 +30,14 @@ export class Viewer extends EventEmitter<BoardViewerEventMap> implements BoardVi
|
|||
this._drawFrameStatus = 'DRAWING';
|
||||
}
|
||||
const snapshot = this._drawFrameSnapshotQueue.shift();
|
||||
|
||||
const { renderer, viewContent, beforeDrawFrame, afterDrawFrame } = this._opts;
|
||||
|
||||
if (snapshot) {
|
||||
const { scale, offsetTop, offsetBottom, offsetLeft, offsetRight, width, height, contextHeight, contextWidth, devicePixelRatio } = snapshot.activeStore;
|
||||
const { viewContext, helperContext, boardContext } = viewContent;
|
||||
|
||||
if (snapshot?.activeStore.data) {
|
||||
const { scale, offsetTop, offsetBottom, offsetLeft, offsetRight, width, height, contextHeight, contextWidth, devicePixelRatio } = snapshot.activeStore;
|
||||
renderer.drawData(snapshot.activeStore.data, {
|
||||
scaleInfo: {
|
||||
scale,
|
||||
|
|
@ -55,7 +56,6 @@ export class Viewer extends EventEmitter<BoardViewerEventMap> implements BoardVi
|
|||
});
|
||||
}
|
||||
beforeDrawFrame({ snapshot });
|
||||
const { width, height } = boardContext.canvas;
|
||||
boardContext.clearRect(0, 0, width, height);
|
||||
boardContext.drawImage(viewContext.canvas, 0, 0, width, height);
|
||||
boardContext.drawImage(helperContext.canvas, 0, 0, width, height);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Data, CoreOptions, BoardMiddleware } from '@idraw/types';
|
||||
import type { Data, CoreOptions, BoardMiddleware, ViewSizeInfo } from '@idraw/types';
|
||||
import { Board } from '@idraw/board';
|
||||
import { createBoardContexts } from '@idraw/util';
|
||||
|
||||
|
|
@ -10,15 +10,13 @@ export class Core {
|
|||
private _board: Board;
|
||||
private _opts: CoreOptions;
|
||||
private _mount: HTMLDivElement;
|
||||
private _canvas: HTMLCanvasElement;
|
||||
constructor(mount: HTMLDivElement, opts: CoreOptions) {
|
||||
const { devicePixelRatio = 1 } = opts;
|
||||
const { devicePixelRatio = 1, width, height } = opts;
|
||||
this._opts = opts;
|
||||
this._mount = mount;
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = opts.width * devicePixelRatio;
|
||||
canvas.height = opts.height * devicePixelRatio;
|
||||
canvas.style.width = `${opts.width}px`;
|
||||
canvas.style.height = `${opts.height}px`;
|
||||
this._canvas = canvas;
|
||||
mount.appendChild(canvas);
|
||||
|
||||
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
||||
|
|
@ -33,6 +31,11 @@ export class Core {
|
|||
contextHeight: opts.contextHeight || opts.height
|
||||
});
|
||||
this._board = board;
|
||||
this.resize({
|
||||
width,
|
||||
height,
|
||||
devicePixelRatio
|
||||
});
|
||||
}
|
||||
|
||||
use(middleware: BoardMiddleware) {
|
||||
|
|
@ -54,4 +57,8 @@ export class Core {
|
|||
scrollY(num: number) {
|
||||
this._board.scrollY(num);
|
||||
}
|
||||
|
||||
resize(newViewSize: Pick<ViewSizeInfo, 'height' | 'width' | 'devicePixelRatio'>) {
|
||||
this._board.resize(newViewSize);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,7 +124,6 @@ export const MiddlewareSelector: BoardMiddleware = (opts) => {
|
|||
} else if (target.type === 'over-element' && target?.indexes?.length === 1 && target.indexes[0] >= 0 && target?.elements?.length === 1) {
|
||||
sharer.setActiveStorage('selectedIndexes', target?.indexes[0] >= 0 ? [target?.indexes[0]] : []);
|
||||
sharer.setSharedStorage(keyActionType, 'drag');
|
||||
} else if (target.type?.startsWith('resize-')) {
|
||||
} else if (target.type?.startsWith('resize-')) {
|
||||
sharer.setSharedStorage(keyResizeType, target.type);
|
||||
sharer.setSharedStorage(keyActionType, 'resize');
|
||||
|
|
|
|||
|
|
@ -4,12 +4,11 @@
|
|||
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
background: #f0f0f088;
|
||||
margin: 0; padding: 0; background: #1e1e1e;
|
||||
}
|
||||
#mount {
|
||||
margin-top: 50px;
|
||||
margin-left: 60px;
|
||||
margin-top: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
#mount canvas {
|
||||
border-right: 1px solid #aaaaaa40;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ const idraw = new iDraw(
|
|||
);
|
||||
idraw.setData(data);
|
||||
// idraw.scale(0.5);
|
||||
idraw.scale(2);
|
||||
idraw.scrollX(-80);
|
||||
idraw.scrollY(-80);
|
||||
// idraw.scale(2);
|
||||
// idraw.scrollX(-80);
|
||||
// idraw.scrollY(-80);
|
||||
|
||||
// const mount2 = document.querySelector('#mount') as HTMLDivElement;
|
||||
// const data2 = getData();
|
||||
|
|
|
|||
|
|
@ -6,14 +6,10 @@
|
|||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
background: #f0f0f088;
|
||||
}
|
||||
#mount {
|
||||
margin-top: 50px;
|
||||
margin-left: 60px;
|
||||
}
|
||||
#mount canvas {
|
||||
border-right: 1px solid #aaaaaa40;
|
||||
border-bottom: 1px solid #aaaaaa40;
|
||||
}
|
||||
canvas {
|
||||
/* border-right: 1px solid #aaaaaa40;
|
||||
border-bottom: 1px solid #aaaaaa40; */
|
||||
background-image:
|
||||
linear-gradient(#aaaaaa40 1px, transparent 0),
|
||||
linear-gradient(90deg, #aaaaaa40 1px, transparent 0),
|
||||
|
|
@ -21,10 +17,11 @@
|
|||
linear-gradient(90deg, #aaa 1px, transparent 0);
|
||||
background-size: 10px 10px, 10px 10px, 50px 50px, 50px 50px;
|
||||
background-color: #ffffff;
|
||||
margin: 0 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body></body>
|
||||
<script type="module" src="./main.ts"></script>
|
||||
<body>
|
||||
<div id="lab"></div>
|
||||
</body>
|
||||
<script type="module" src="./main.tsx"></script>
|
||||
</html>
|
||||
|
|
@ -1 +0,0 @@
|
|||
import '../src/index.ts';
|
||||
8
packages/lab/dev/main.tsx
Normal file
8
packages/lab/dev/main.tsx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { Lab } from '../src/index';
|
||||
|
||||
const dom = document.querySelector('#lab') as HTMLDivElement;
|
||||
const root = createRoot(dom);
|
||||
|
||||
root.render(<Lab />);
|
||||
|
|
@ -113,6 +113,36 @@ const data: Data = {
|
|||
desc: {
|
||||
bgColor: '#cddc39'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'xxxx-0010',
|
||||
name: 'text-002',
|
||||
x: 300,
|
||||
y: 100,
|
||||
w: 100,
|
||||
h: 60,
|
||||
type: 'text',
|
||||
desc: {
|
||||
fontSize: 16,
|
||||
text: [0, 1, 2, 3, 4].map((i) => `Hello Text ${i}`).join('\r\n'),
|
||||
// text: [0, 1, 2, 3, 4].map(i => `Hello Text ${i}`).join(''),
|
||||
fontWeight: 'bold',
|
||||
color: '#666666',
|
||||
borderRadius: 30,
|
||||
borderWidth: 2,
|
||||
borderColor: '#ff5722'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'xxx-0011',
|
||||
type: 'svg',
|
||||
x: 400,
|
||||
y: 100,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
svg: `<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M336 421m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" ></path><path d="M688 421m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" ></path><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2-44.3-18.7-84.1-45.6-118.3-79.8-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8c18.7-44.3 45.6-84.1 79.8-118.3 34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2 44.3 18.7 84.1 45.6 118.3 79.8 34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8c-18.7 44.3-45.6 84.1-79.8 118.2z"></path><path d="M664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-0.3-4.2-3.9-7.4-8.1-7.4H360c-4.6 0-8.2 3.8-8 8.4 4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6c0.2-4.6-3.4-8.4-8-8.4z" ></path></svg>`
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
import { Core, MiddlewareScroller, MiddlewareSelector } from '@idraw/core';
|
||||
import { getData } from './data';
|
||||
|
||||
const body = document.querySelector('body');
|
||||
const mount = document.createElement('div');
|
||||
body?.appendChild(mount);
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
|
||||
const options = {
|
||||
width,
|
||||
height,
|
||||
devicePixelRatio: window.devicePixelRatio,
|
||||
contextWidth: width,
|
||||
contextHeight: height
|
||||
};
|
||||
const core = new Core(mount, options);
|
||||
core.use(MiddlewareScroller);
|
||||
core.use(MiddlewareSelector);
|
||||
core.setData(getData());
|
||||
42
packages/lab/src/index.tsx
Normal file
42
packages/lab/src/index.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
import { Core, MiddlewareScroller, MiddlewareSelector } from '@idraw/core';
|
||||
import { getData } from './data';
|
||||
|
||||
export const Lab = () => {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useEffect(() => {
|
||||
if (ref?.current) {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
const devicePixelRatio = window.devicePixelRatio;
|
||||
const options = {
|
||||
width,
|
||||
height,
|
||||
devicePixelRatio,
|
||||
contextWidth: width,
|
||||
contextHeight: height
|
||||
};
|
||||
const core = new Core(ref.current, options);
|
||||
|
||||
core.use(MiddlewareScroller);
|
||||
core.use(MiddlewareSelector);
|
||||
core.setData(getData());
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
const devicePixelRatio = window.devicePixelRatio;
|
||||
core.resize({
|
||||
width,
|
||||
height,
|
||||
devicePixelRatio
|
||||
});
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
return (
|
||||
<div style={{ position: 'fixed', left: 0, right: 0, width: '100%', height: '100%' }}>
|
||||
<div ref={ref}></div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
87
packages/renderer/src/draw/base.ts
Normal file
87
packages/renderer/src/draw/base.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import { ViewContext2D, Element } from '@idraw/types';
|
||||
import { is, istype, isColorStr, rotateElement } from '@idraw/util';
|
||||
|
||||
export function clearContext(ctx: ViewContext2D) {
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.strokeStyle = '#000000';
|
||||
ctx.setLineDash([]);
|
||||
ctx.globalAlpha = 1;
|
||||
ctx.shadowColor = '#00000000';
|
||||
ctx.shadowOffsetX = 0;
|
||||
ctx.shadowOffsetY = 0;
|
||||
ctx.shadowBlur = 0;
|
||||
}
|
||||
|
||||
export function drawBox(ctx: ViewContext2D, elem: Element<'text' | 'rect'>, pattern: string | CanvasPattern | null): void {
|
||||
clearContext(ctx);
|
||||
drawBoxBorder(ctx, elem);
|
||||
clearContext(ctx);
|
||||
rotateElement(ctx, elem, () => {
|
||||
const { x, y, w, h } = elem;
|
||||
let r: number = elem.desc.borderRadius || 0;
|
||||
r = Math.min(r, w / 2, h / 2);
|
||||
if (w < r * 2 || h < r * 2) {
|
||||
r = 0;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.arcTo(x + w, y, x + w, y + h, r);
|
||||
ctx.arcTo(x + w, y + h, x, y + h, r);
|
||||
ctx.arcTo(x, y + h, x, y, r);
|
||||
ctx.arcTo(x, y, x + w, y, r);
|
||||
ctx.closePath();
|
||||
if (typeof pattern === 'string') {
|
||||
ctx.fillStyle = pattern;
|
||||
} else if (['CanvasPattern'].includes(istype.type(pattern))) {
|
||||
ctx.fillStyle = pattern as CanvasPattern;
|
||||
}
|
||||
ctx.fill();
|
||||
});
|
||||
}
|
||||
|
||||
export function drawBoxBorder(ctx: ViewContext2D, elem: Element<'text' | 'rect'>): void {
|
||||
clearContext(ctx);
|
||||
rotateElement(ctx, elem, () => {
|
||||
if (!(elem.desc.borderWidth && elem.desc.borderWidth > 0)) {
|
||||
return;
|
||||
}
|
||||
const bw = elem.desc.borderWidth;
|
||||
let borderColor = '#000000';
|
||||
if (isColorStr(elem.desc.borderColor) === true) {
|
||||
borderColor = elem.desc.borderColor as string;
|
||||
}
|
||||
const x = elem.x - bw / 2;
|
||||
const y = elem.y - bw / 2;
|
||||
const w = elem.w + bw;
|
||||
const h = elem.h + bw;
|
||||
|
||||
let r: number = elem.desc.borderRadius || 0;
|
||||
r = Math.min(r, w / 2, h / 2);
|
||||
if (r < w / 2 && r < h / 2) {
|
||||
r = r + bw / 2;
|
||||
}
|
||||
const { desc } = elem;
|
||||
if (desc.shadowColor !== undefined && isColorStr(desc.shadowColor)) {
|
||||
ctx.shadowColor = desc.shadowColor;
|
||||
}
|
||||
if (desc.shadowOffsetX !== undefined && is.number(desc.shadowOffsetX)) {
|
||||
ctx.shadowOffsetX = desc.shadowOffsetX;
|
||||
}
|
||||
if (desc.shadowOffsetY !== undefined && is.number(desc.shadowOffsetY)) {
|
||||
ctx.shadowOffsetY = desc.shadowOffsetY;
|
||||
}
|
||||
if (desc.shadowBlur !== undefined && is.number(desc.shadowBlur)) {
|
||||
ctx.shadowBlur = desc.shadowBlur;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.lineWidth = bw;
|
||||
ctx.strokeStyle = borderColor;
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.arcTo(x + w, y, x + w, y + h, r);
|
||||
ctx.arcTo(x + w, y + h, x, y + h, r);
|
||||
ctx.arcTo(x, y + h, x, y, r);
|
||||
ctx.arcTo(x, y, x + w, y, r);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
});
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ import type { Element, ElementType, Data, RendererDrawElementOptions, ViewContex
|
|||
import { drawCircle } from './circle';
|
||||
import { drawRect } from './rect';
|
||||
import { drawImage } from './image';
|
||||
import { drawText } from './text';
|
||||
import { drawSVG } from './svg';
|
||||
|
||||
export function drawElement(ctx: ViewContext2D, elem: Element<ElementType>, opts: RendererDrawElementOptions) {
|
||||
try {
|
||||
|
|
@ -14,10 +16,18 @@ export function drawElement(ctx: ViewContext2D, elem: Element<ElementType>, opts
|
|||
drawCircle(ctx, elem as Element<'circle'>, opts);
|
||||
break;
|
||||
}
|
||||
case 'text': {
|
||||
drawText(ctx, elem as Element<'text'>, opts);
|
||||
break;
|
||||
}
|
||||
case 'image': {
|
||||
drawImage(ctx, elem as Element<'image'>, opts);
|
||||
break;
|
||||
}
|
||||
case 'svg': {
|
||||
drawSVG(ctx, elem as Element<'svg'>, opts);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export { drawCircle } from './circle';
|
||||
export { drawRect } from './rect';
|
||||
export { drawImage } from './image';
|
||||
export { drawSVG } from './svg';
|
||||
export { drawText } from './text';
|
||||
export { drawElementList, drawElement } from './elements';
|
||||
|
|
|
|||
16
packages/renderer/src/draw/svg.ts
Normal file
16
packages/renderer/src/draw/svg.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { Element, RendererDrawElementOptions, ViewContext2D } from '@idraw/types';
|
||||
import { rotateElement } from '@idraw/util';
|
||||
|
||||
export function drawSVG(ctx: ViewContext2D, elem: Element<'svg'>, opts: RendererDrawElementOptions) {
|
||||
const content = opts.loader.getContent(elem.uuid);
|
||||
const { calculator, scaleInfo } = opts;
|
||||
const { x, y, w, h, angle } = calculator.elementSize(elem, scaleInfo);
|
||||
rotateElement(ctx, { x, y, w, h, angle }, () => {
|
||||
if (!content) {
|
||||
opts.loader.load(elem as Element<'svg'>);
|
||||
}
|
||||
if (elem.type === 'svg' && content) {
|
||||
ctx.drawImage(content, x, y, w, h);
|
||||
}
|
||||
});
|
||||
}
|
||||
142
packages/renderer/src/draw/text.ts
Normal file
142
packages/renderer/src/draw/text.ts
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
import type { Element, RendererDrawElementOptions, ViewContext2D } from '@idraw/types';
|
||||
import { rotateElement } from '@idraw/util';
|
||||
import { is, isColorStr } from '@idraw/util';
|
||||
import { clearContext, drawBox } from './base';
|
||||
|
||||
export function drawText(ctx: ViewContext2D, elem: Element<'text'>, opts: RendererDrawElementOptions) {
|
||||
clearContext(ctx);
|
||||
drawBox(ctx, elem, elem.desc.bgColor || 'transparent');
|
||||
rotateElement(ctx, elem, () => {
|
||||
const desc: Element<'text'>['desc'] = {
|
||||
...{
|
||||
fontSize: 12,
|
||||
fontFamily: 'sans-serif',
|
||||
textAlign: 'center'
|
||||
},
|
||||
...elem.desc
|
||||
};
|
||||
ctx.fillStyle = elem.desc.color;
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.$setFont({
|
||||
fontWeight: desc.fontWeight,
|
||||
fontSize: desc.fontSize,
|
||||
fontFamily: desc.fontFamily
|
||||
});
|
||||
const descText = desc.text.replace(/\r\n/gi, '\n');
|
||||
const fontHeight = desc.lineHeight || desc.fontSize;
|
||||
const descTextList = descText.split('\n');
|
||||
const lines: { text: string; width: number }[] = [];
|
||||
|
||||
let lineNum = 0;
|
||||
descTextList.forEach((tempText: string, idx: number) => {
|
||||
let lineText = '';
|
||||
|
||||
if (tempText.length > 0) {
|
||||
for (let i = 0; i < tempText.length; i++) {
|
||||
if (ctx.measureText(lineText + (tempText[i] || '')).width < ctx.$doPixelRatio(elem.w)) {
|
||||
lineText += tempText[i] || '';
|
||||
} else {
|
||||
lines.push({
|
||||
text: lineText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
||||
});
|
||||
lineText = tempText[i] || '';
|
||||
lineNum++;
|
||||
}
|
||||
if ((lineNum + 1) * fontHeight > elem.h) {
|
||||
break;
|
||||
}
|
||||
if (tempText.length - 1 === i) {
|
||||
if ((lineNum + 1) * fontHeight < elem.h) {
|
||||
lines.push({
|
||||
text: lineText,
|
||||
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
||||
});
|
||||
if (idx < descTextList.length - 1) {
|
||||
lineNum++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lines.push({
|
||||
text: '',
|
||||
width: 0
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
let startY = 0;
|
||||
if (lines.length * fontHeight < elem.h) {
|
||||
if (elem.desc.verticalAlign === 'top') {
|
||||
startY = 0;
|
||||
} else if (elem.desc.verticalAlign === 'bottom') {
|
||||
startY += elem.h - lines.length * fontHeight;
|
||||
} else {
|
||||
// middle and default
|
||||
startY += (elem.h - lines.length * fontHeight) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// draw text lines
|
||||
{
|
||||
const _y = elem.y + startY;
|
||||
if (desc.textShadowColor !== undefined && isColorStr(desc.textShadowColor)) {
|
||||
ctx.shadowColor = desc.textShadowColor;
|
||||
}
|
||||
if (desc.textShadowOffsetX !== undefined && is.number(desc.textShadowOffsetX)) {
|
||||
ctx.shadowOffsetX = desc.textShadowOffsetX;
|
||||
}
|
||||
if (desc.textShadowOffsetY !== undefined && is.number(desc.textShadowOffsetY)) {
|
||||
ctx.shadowOffsetY = desc.textShadowOffsetY;
|
||||
}
|
||||
if (desc.textShadowBlur !== undefined && is.number(desc.textShadowBlur)) {
|
||||
ctx.shadowBlur = desc.textShadowBlur;
|
||||
}
|
||||
lines.forEach((line, i) => {
|
||||
let _x = elem.x;
|
||||
if (desc.textAlign === 'center') {
|
||||
_x = elem.x + (elem.w - line.width) / 2;
|
||||
} else if (desc.textAlign === 'right') {
|
||||
_x = elem.x + (elem.w - line.width);
|
||||
}
|
||||
ctx.fillText(line.text, _x, _y + fontHeight * i);
|
||||
});
|
||||
clearContext(ctx);
|
||||
}
|
||||
|
||||
// draw text stroke
|
||||
if (isColorStr(desc.strokeColor) && desc.strokeWidth !== undefined && desc.strokeWidth > 0) {
|
||||
const _y = elem.y + startY;
|
||||
lines.forEach((line, i) => {
|
||||
let _x = elem.x;
|
||||
if (desc.textAlign === 'center') {
|
||||
_x = elem.x + (elem.w - line.width) / 2;
|
||||
} else if (desc.textAlign === 'right') {
|
||||
_x = elem.x + (elem.w - line.width);
|
||||
}
|
||||
if (desc.strokeColor !== undefined) {
|
||||
ctx.strokeStyle = desc.strokeColor;
|
||||
}
|
||||
if (desc.strokeWidth !== undefined && desc.strokeWidth > 0) {
|
||||
ctx.lineWidth = desc.strokeWidth;
|
||||
}
|
||||
ctx.strokeText(line.text, _x, _y + fontHeight * i);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// export function createTextSVG(elem: DataElement<'text'>): string {
|
||||
// const svg = `
|
||||
// <svg xmlns="http://www.w3.org/2000/svg" width="${elem.w}" height = "${elem.h}">
|
||||
// <foreignObject width="100%" height="100%">
|
||||
// <div xmlns = "http://www.w3.org/1999/xhtml" style="font-size: ${elem.desc.size}px; color:${elem.desc.color};">
|
||||
// <span>${elem.desc.text || ''}</span>
|
||||
// </div>
|
||||
// </foreignObject>
|
||||
// </svg>
|
||||
// `;
|
||||
// return svg;
|
||||
// }
|
||||
|
|
@ -100,6 +100,7 @@ export class Loader extends EventEmitter<LoaderEventMap> implements RendererLoad
|
|||
|
||||
private _loadResource(element: Element<LoadElementType>) {
|
||||
const item = this._createLoadItem(element);
|
||||
|
||||
this._currentLoadItemMap[element.uuid] = item;
|
||||
const loadFunc = this._loadFuncMap[element.type];
|
||||
if (typeof loadFunc === 'function') {
|
||||
|
|
@ -112,6 +113,7 @@ export class Loader extends EventEmitter<LoaderEventMap> implements RendererLoad
|
|||
this._emitLoad(item);
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
console.warn(`Load element source "${item.source}" fail`, err, element);
|
||||
item.endTime = Date.now();
|
||||
item.status = 'error';
|
||||
item.error = err;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
export interface ViewContext2DOptions {
|
||||
devicePixelRatio: number;
|
||||
fontFamily?: string;
|
||||
devicePixelRatio?: number;
|
||||
}
|
||||
|
||||
export interface ViewContext2D {
|
||||
|
|
@ -8,7 +7,11 @@ export interface ViewContext2D {
|
|||
|
||||
// extend API
|
||||
$getContext(): CanvasRenderingContext2D;
|
||||
$setFont(opts: { fontSize: number; fontFamily?: string; fontWeight?: 'bold' }): void;
|
||||
$setFont(opts: { fontSize: number; fontFamily?: string; fontWeight?: string }): void;
|
||||
$resize(opts: { width: number; height: number; devicePixelRatio: number }): void;
|
||||
|
||||
$undoPixelRatio(num: number): number;
|
||||
$doPixelRatio(num: number): number;
|
||||
|
||||
// CanvasRenderingContext2D API
|
||||
canvas: HTMLCanvasElement;
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@ export interface CoreOptions {
|
|||
devicePixelRatio?: number;
|
||||
contextWidth?: number;
|
||||
contextHeight?: number;
|
||||
onlyRender?: boolean;
|
||||
// onlyRender?: boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,22 @@ export interface ElementSize {
|
|||
angle?: number;
|
||||
}
|
||||
|
||||
interface ElementRectDesc {
|
||||
color?: string;
|
||||
bgColor?: string;
|
||||
interface ElementBaseDesc {
|
||||
borderWidth?: number;
|
||||
borderColor?: string;
|
||||
borderRadius?: number;
|
||||
shadowColor?: string;
|
||||
shadowOffsetX?: number;
|
||||
shadowOffsetY?: number;
|
||||
shadowBlur?: number;
|
||||
}
|
||||
|
||||
interface ElemenTextDesc {
|
||||
interface ElementRectDesc extends ElementBaseDesc {
|
||||
color?: string;
|
||||
bgColor?: string;
|
||||
}
|
||||
|
||||
interface ElemenTextDesc extends ElementBaseDesc {
|
||||
text: string;
|
||||
color: string;
|
||||
fontSize: number;
|
||||
|
|
@ -30,15 +39,6 @@ interface ElemenTextDesc {
|
|||
textShadowBlur?: number;
|
||||
}
|
||||
|
||||
interface ElementBaseDesc {
|
||||
borderWidth?: number;
|
||||
borderColor?: string;
|
||||
borderRadius?: number;
|
||||
shadowColor?: string;
|
||||
shadowOffsetX?: number;
|
||||
shadowOffsetY?: number;
|
||||
shadowBlur?: number;
|
||||
}
|
||||
interface ElementCircleDesc extends ElementBaseDesc {
|
||||
radius: number;
|
||||
bgColor?: string;
|
||||
|
|
@ -80,6 +80,7 @@ export interface ElementOperation {
|
|||
|
||||
export interface Element<T extends ElementType> extends ElementSize {
|
||||
uuid: string;
|
||||
name?: string;
|
||||
type: T;
|
||||
desc: ElementDescMap[T];
|
||||
operation?: ElementOperation;
|
||||
|
|
|
|||
|
|
@ -1,29 +1,25 @@
|
|||
import type { ViewContext2D, ViewContext2DOptions } from '@idraw/types';
|
||||
|
||||
export class Context2D implements ViewContext2D {
|
||||
private _opts: ViewContext2DOptions;
|
||||
private _ctx: CanvasRenderingContext2D;
|
||||
|
||||
// private _scale: number;
|
||||
// private _scrollX: number;
|
||||
// private _scrollY: number;
|
||||
private _devicePixelRatio = 1;
|
||||
// private _width: number = 0;
|
||||
// private _height: number = 0;
|
||||
|
||||
constructor(ctx: CanvasRenderingContext2D, opts: ViewContext2DOptions) {
|
||||
const _opts = { ...opts };
|
||||
if (!(_opts.devicePixelRatio > 0)) {
|
||||
_opts.devicePixelRatio = 1;
|
||||
} else {
|
||||
_opts.devicePixelRatio = _opts.devicePixelRatio;
|
||||
}
|
||||
this._opts = opts;
|
||||
const { devicePixelRatio = 1 } = opts;
|
||||
this._ctx = ctx;
|
||||
this._devicePixelRatio = devicePixelRatio;
|
||||
// this._width = ctx.canvas.width / devicePixelRatio;
|
||||
// this._height = ctx.canvas.height / devicePixelRatio;
|
||||
}
|
||||
|
||||
private _undoSize(num: number) {
|
||||
return this._opts.devicePixelRatio / num;
|
||||
$undoPixelRatio(num: number) {
|
||||
return num / this._devicePixelRatio;
|
||||
}
|
||||
private _doSize(num: number) {
|
||||
return this._opts.devicePixelRatio * num;
|
||||
$doPixelRatio(num: number) {
|
||||
return this._devicePixelRatio * num;
|
||||
}
|
||||
|
||||
$getContext(): CanvasRenderingContext2D {
|
||||
|
|
@ -35,11 +31,23 @@ export class Context2D implements ViewContext2D {
|
|||
if (opts.fontWeight === 'bold') {
|
||||
strList.push(`${opts.fontWeight}`);
|
||||
}
|
||||
strList.push(`${this._doSize(opts.fontSize || 12)}px`);
|
||||
strList.push(`${this.$doPixelRatio(opts.fontSize || 12)}px`);
|
||||
strList.push(`${opts.fontFamily || 'sans-serif'}`);
|
||||
this._ctx.font = `${strList.join(' ')}`;
|
||||
}
|
||||
|
||||
$resize(opts: { width: number; height: number; devicePixelRatio: number }) {
|
||||
const { width, height, devicePixelRatio } = opts;
|
||||
const { canvas } = this._ctx;
|
||||
canvas.width = width * devicePixelRatio;
|
||||
canvas.height = height * devicePixelRatio;
|
||||
// canvas.style.width = `${width}px`;
|
||||
// canvas.style.height = `${height}px`;
|
||||
// this._width = width;
|
||||
// this._height = height;
|
||||
this._devicePixelRatio = devicePixelRatio;
|
||||
}
|
||||
|
||||
get canvas() {
|
||||
return this._ctx.canvas;
|
||||
}
|
||||
|
|
@ -59,10 +67,10 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
get lineWidth() {
|
||||
return this._undoSize(this._ctx.lineWidth);
|
||||
return this.$undoPixelRatio(this._ctx.lineWidth);
|
||||
}
|
||||
set lineWidth(w: number) {
|
||||
this._ctx.lineWidth = this._doSize(w);
|
||||
this._ctx.lineWidth = this.$doPixelRatio(w);
|
||||
}
|
||||
|
||||
get textAlign(): CanvasTextAlign {
|
||||
|
|
@ -93,24 +101,24 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
get shadowOffsetX() {
|
||||
return this._undoSize(this._ctx.shadowOffsetX);
|
||||
return this.$undoPixelRatio(this._ctx.shadowOffsetX);
|
||||
}
|
||||
set shadowOffsetX(offsetX: number) {
|
||||
this._ctx.shadowOffsetX = this._doSize(offsetX);
|
||||
this._ctx.shadowOffsetX = this.$doPixelRatio(offsetX);
|
||||
}
|
||||
|
||||
get shadowOffsetY(): number {
|
||||
return this._undoSize(this._ctx.shadowOffsetY);
|
||||
return this.$undoPixelRatio(this._ctx.shadowOffsetY);
|
||||
}
|
||||
set shadowOffsetY(offsetY: number) {
|
||||
this._ctx.shadowOffsetY = this._doSize(offsetY);
|
||||
this._ctx.shadowOffsetY = this.$doPixelRatio(offsetY);
|
||||
}
|
||||
|
||||
get shadowBlur(): number {
|
||||
return this._undoSize(this._ctx.shadowBlur);
|
||||
return this.$undoPixelRatio(this._ctx.shadowBlur);
|
||||
}
|
||||
set shadowBlur(blur: number) {
|
||||
this._ctx.shadowBlur = this._doSize(blur);
|
||||
this._ctx.shadowBlur = this.$doPixelRatio(blur);
|
||||
}
|
||||
|
||||
fill(...args: [fillRule?: CanvasFillRule | undefined] | [path: Path2D, fillRule?: CanvasFillRule | undefined]): void {
|
||||
|
|
@ -118,19 +126,19 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean | undefined): void {
|
||||
return this._ctx.arc(this._doSize(x), this._doSize(y), this._doSize(radius), startAngle, endAngle, anticlockwise);
|
||||
return this._ctx.arc(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(radius), startAngle, endAngle, anticlockwise);
|
||||
}
|
||||
|
||||
rect(x: number, y: number, w: number, h: number) {
|
||||
return this._ctx.rect(this._doSize(x), this._doSize(y), this._doSize(w), this._doSize(h));
|
||||
return this._ctx.rect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
|
||||
}
|
||||
|
||||
fillRect(x: number, y: number, w: number, h: number) {
|
||||
return this._ctx.fillRect(this._doSize(x), this._doSize(y), this._doSize(w), this._doSize(h));
|
||||
return this._ctx.fillRect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
|
||||
}
|
||||
|
||||
clearRect(x: number, y: number, w: number, h: number) {
|
||||
return this._ctx.clearRect(this._doSize(x), this._doSize(y), this._doSize(w), this._doSize(h));
|
||||
return this._ctx.clearRect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
|
||||
}
|
||||
|
||||
beginPath() {
|
||||
|
|
@ -142,15 +150,15 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
lineTo(x: number, y: number) {
|
||||
return this._ctx.lineTo(this._doSize(x), this._doSize(y));
|
||||
return this._ctx.lineTo(this.$doPixelRatio(x), this.$doPixelRatio(y));
|
||||
}
|
||||
|
||||
moveTo(x: number, y: number) {
|
||||
return this._ctx.moveTo(this._doSize(x), this._doSize(y));
|
||||
return this._ctx.moveTo(this.$doPixelRatio(x), this.$doPixelRatio(y));
|
||||
}
|
||||
|
||||
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void {
|
||||
return this._ctx.arcTo(this._doSize(x1), this._doSize(y1), this._doSize(x2), this._doSize(y2), this._doSize(radius));
|
||||
return this._ctx.arcTo(this.$doPixelRatio(x1), this.$doPixelRatio(y1), this.$doPixelRatio(x2), this.$doPixelRatio(y2), this.$doPixelRatio(radius));
|
||||
}
|
||||
|
||||
getLineDash() {
|
||||
|
|
@ -158,7 +166,7 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
setLineDash(nums: number[]) {
|
||||
return this._ctx.setLineDash(nums.map((n) => this._doSize(n)));
|
||||
return this._ctx.setLineDash(nums.map((n) => this.$doPixelRatio(n)));
|
||||
}
|
||||
|
||||
stroke() {
|
||||
|
|
@ -166,7 +174,7 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
translate(x: number, y: number) {
|
||||
return this._ctx.translate(this._doSize(x), this._doSize(y));
|
||||
return this._ctx.translate(this.$doPixelRatio(x), this.$doPixelRatio(y));
|
||||
}
|
||||
|
||||
rotate(angle: number) {
|
||||
|
|
@ -188,17 +196,17 @@ export class Context2D implements ViewContext2D {
|
|||
if (args.length === 9) {
|
||||
return this._ctx.drawImage(
|
||||
image,
|
||||
this._doSize(sx),
|
||||
this._doSize(sy),
|
||||
this._doSize(sw),
|
||||
this._doSize(sh),
|
||||
this._doSize(dx),
|
||||
this._doSize(dy),
|
||||
this._doSize(dw),
|
||||
this._doSize(dh)
|
||||
this.$doPixelRatio(sx),
|
||||
this.$doPixelRatio(sy),
|
||||
this.$doPixelRatio(sw),
|
||||
this.$doPixelRatio(sh),
|
||||
this.$doPixelRatio(dx),
|
||||
this.$doPixelRatio(dy),
|
||||
this.$doPixelRatio(dw),
|
||||
this.$doPixelRatio(dh)
|
||||
);
|
||||
} else {
|
||||
return this._ctx.drawImage(image, this._doSize(dx), this._doSize(dy), this._doSize(dw), this._doSize(dh));
|
||||
return this._ctx.drawImage(image, this.$doPixelRatio(dx), this.$doPixelRatio(dy), this.$doPixelRatio(dw), this.$doPixelRatio(dh));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -207,22 +215,23 @@ export class Context2D implements ViewContext2D {
|
|||
}
|
||||
|
||||
measureText(text: string): TextMetrics {
|
||||
return this._ctx.measureText(text);
|
||||
const textMetrics = this._ctx.measureText(text);
|
||||
return textMetrics;
|
||||
}
|
||||
|
||||
fillText(text: string, x: number, y: number, maxWidth?: number | undefined): void {
|
||||
if (maxWidth !== undefined) {
|
||||
return this._ctx.fillText(text, this._doSize(x), this._doSize(y), this._doSize(maxWidth));
|
||||
return this._ctx.fillText(text, this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(maxWidth));
|
||||
} else {
|
||||
return this._ctx.fillText(text, this._doSize(x), this._doSize(y));
|
||||
return this._ctx.fillText(text, this.$doPixelRatio(x), this.$doPixelRatio(y));
|
||||
}
|
||||
}
|
||||
|
||||
strokeText(text: string, x: number, y: number, maxWidth?: number | undefined): void {
|
||||
if (maxWidth !== undefined) {
|
||||
return this._ctx.strokeText(text, this._doSize(x), this._doSize(y), this._doSize(maxWidth));
|
||||
return this._ctx.strokeText(text, this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(maxWidth));
|
||||
} else {
|
||||
return this._ctx.strokeText(text, this._doSize(x), this._doSize(y));
|
||||
return this._ctx.strokeText(text, this.$doPixelRatio(x), this.$doPixelRatio(y));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -248,10 +257,19 @@ export class Context2D implements ViewContext2D {
|
|||
endAngle: number,
|
||||
counterclockwise?: boolean | undefined
|
||||
) {
|
||||
this._ctx.ellipse(this._doSize(x), this._doSize(y), this._doSize(radiusX), this._doSize(radiusY), rotation, startAngle, endAngle, counterclockwise);
|
||||
this._ctx.ellipse(
|
||||
this.$doPixelRatio(x),
|
||||
this.$doPixelRatio(y),
|
||||
this.$doPixelRatio(radiusX),
|
||||
this.$doPixelRatio(radiusY),
|
||||
rotation,
|
||||
startAngle,
|
||||
endAngle,
|
||||
counterclockwise
|
||||
);
|
||||
}
|
||||
|
||||
isPointInPath(x: number, y: number) {
|
||||
return this._ctx.isPointInPath(this._doSize(x), this._doSize(y));
|
||||
return this._ctx.isPointInPath(this.$doPixelRatio(x), this.$doPixelRatio(y));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,10 +25,7 @@ function filterAmpersand(str: string): string {
|
|||
return str.replace(/\&/gi, '&');
|
||||
}
|
||||
|
||||
export async function loadHTML(
|
||||
html: string,
|
||||
opts: { width: number; height: number }
|
||||
): Promise<HTMLImageElement> {
|
||||
export async function loadHTML(html: string, opts: { width: number; height: number }): Promise<HTMLImageElement> {
|
||||
html = filterAmpersand(html);
|
||||
const dataURL = await parseHTMLToDataURL(html, opts);
|
||||
const image = await loadImage(dataURL);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
export function parseHTMLToDataURL(
|
||||
html: string,
|
||||
opts: { width: number; height: number }
|
||||
): Promise<string> {
|
||||
export function parseHTMLToDataURL(html: string, opts: { width: number; height: number }): Promise<string> {
|
||||
const { width, height } = opts;
|
||||
return new Promise((resolve, reject) => {
|
||||
const _svg = `
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ importers:
|
|||
'@typescript-eslint/parser':
|
||||
specifier: ^5.57.0
|
||||
version: 5.57.0(eslint@8.37.0)(typescript@5.0.3)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0(vite@4.2.1)
|
||||
babel-jest:
|
||||
specifier: ^29.5.0
|
||||
version: 29.5.0(@babel/core@7.21.4)
|
||||
|
|
@ -175,6 +178,12 @@ importers:
|
|||
|
||||
packages/lab:
|
||||
dependencies:
|
||||
'@idraw/core':
|
||||
specifier: ^0.4.0-alpha.0
|
||||
version: link:../core
|
||||
'@idraw/util':
|
||||
specifier: ^0.4.0-alpha.0
|
||||
version: link:../util
|
||||
react:
|
||||
specifier: ^18.2.0
|
||||
version: 18.2.0
|
||||
|
|
@ -182,6 +191,9 @@ importers:
|
|||
specifier: ^18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
devDependencies:
|
||||
'@idraw/types':
|
||||
specifier: ^0.4.0-alpha.0
|
||||
version: link:../types
|
||||
'@types/react':
|
||||
specifier: ^18.2.0
|
||||
version: 18.2.0
|
||||
|
|
@ -1162,6 +1174,26 @@ packages:
|
|||
'@babel/helper-plugin-utils': 7.20.2
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-react-jsx-self@7.21.0(@babel/core@7.21.4):
|
||||
resolution: {integrity: sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
'@babel/core': 7.21.4
|
||||
'@babel/helper-plugin-utils': 7.20.2
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-react-jsx-source@7.19.6(@babel/core@7.21.4):
|
||||
resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
dependencies:
|
||||
'@babel/core': 7.21.4
|
||||
'@babel/helper-plugin-utils': 7.20.2
|
||||
dev: true
|
||||
|
||||
/@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.21.4):
|
||||
resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
|
@ -3475,6 +3507,21 @@ packages:
|
|||
eslint-visitor-keys: 3.4.0
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-react@4.0.0(vite@4.2.1):
|
||||
resolution: {integrity: sha512-HX0XzMjL3hhOYm+0s95pb0Z7F8O81G7joUHgfDd/9J/ZZf5k4xX6QAMFkKsHFxaHlf6X7GD7+XuaZ66ULiJuhQ==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
vite: ^4.2.0
|
||||
dependencies:
|
||||
'@babel/core': 7.21.4
|
||||
'@babel/plugin-transform-react-jsx-self': 7.21.0(@babel/core@7.21.4)
|
||||
'@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.4)
|
||||
react-refresh: 0.14.0
|
||||
vite: 4.2.1(@types/node@18.15.11)(terser@5.16.8)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@yarnpkg/lockfile@1.1.0:
|
||||
resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==}
|
||||
dev: true
|
||||
|
|
@ -8420,6 +8467,11 @@ packages:
|
|||
resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
|
||||
dev: true
|
||||
|
||||
/react-refresh@0.14.0:
|
||||
resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/react@18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import chalk from 'chalk';
|
||||
import { createServer } from 'vite';
|
||||
import pluginReact from '@vitejs/plugin-react';
|
||||
import type { UserConfig } from 'vite';
|
||||
import { joinPackagePath } from './util/project';
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ function getViteConfig(): UserConfig {
|
|||
port: 8080,
|
||||
host: '127.0.0.1'
|
||||
},
|
||||
plugins: [],
|
||||
plugins: [pluginReact()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@idraw/types': joinPackagePath('types', 'src', 'index.ts'),
|
||||
|
|
@ -38,7 +39,7 @@ function getViteConfig(): UserConfig {
|
|||
}
|
||||
},
|
||||
esbuild: {
|
||||
include: [/\.ts$/, /\.js$/],
|
||||
include: [/\.(ts|tsx|js|jsx)$/],
|
||||
exclude: [/\.html$/]
|
||||
},
|
||||
optimizeDeps: {}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"sourceMap": false,
|
||||
"target": "ES6",
|
||||
|
|
|
|||
Loading…
Reference in a new issue