cbvirtua 1.0.48 → 1.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/canvas-example-main/canvas-example-main/.github/workflows/main.yml +62 -0
  2. package/canvas-example-main/canvas-example-main/README.md +13 -0
  3. package/canvas-example-main/canvas-example-main/curved.html +52 -0
  4. package/canvas-example-main/canvas-example-main/eslint.config.js +30 -0
  5. package/canvas-example-main/canvas-example-main/index.html +13 -0
  6. package/canvas-example-main/canvas-example-main/package.json +51 -0
  7. package/canvas-example-main/canvas-example-main/pnpm-lock.yaml +4760 -0
  8. package/canvas-example-main/canvas-example-main/postcss.config.js +6 -0
  9. package/canvas-example-main/canvas-example-main/public/vite.svg +1 -0
  10. package/canvas-example-main/canvas-example-main/src/App.tsx +17 -0
  11. package/canvas-example-main/canvas-example-main/src/assets/github.svg +1 -0
  12. package/canvas-example-main/canvas-example-main/src/assets/react.svg +1 -0
  13. package/canvas-example-main/canvas-example-main/src/components/Iconfont/demo.css +539 -0
  14. package/canvas-example-main/canvas-example-main/src/components/Iconfont/demo_index.html +418 -0
  15. package/canvas-example-main/canvas-example-main/src/components/Iconfont/iconfont.css +55 -0
  16. package/canvas-example-main/canvas-example-main/src/components/Iconfont/iconfont.js +1 -0
  17. package/canvas-example-main/canvas-example-main/src/components/Iconfont/iconfont.json +79 -0
  18. package/canvas-example-main/canvas-example-main/src/components/Iconfont/iconfont.ttf +0 -0
  19. package/canvas-example-main/canvas-example-main/src/components/Iconfont/iconfont.woff +0 -0
  20. package/canvas-example-main/canvas-example-main/src/components/Iconfont/iconfont.woff2 +0 -0
  21. package/canvas-example-main/canvas-example-main/src/components/Iconfont/index.tsx +39 -0
  22. package/canvas-example-main/canvas-example-main/src/main.css +9 -0
  23. package/canvas-example-main/canvas-example-main/src/main.tsx +10 -0
  24. package/canvas-example-main/canvas-example-main/src/pages/2048/g2048.ts +14 -0
  25. package/canvas-example-main/canvas-example-main/src/pages/2048/index.tsx +21 -0
  26. package/canvas-example-main/canvas-example-main/src/pages/clock/index.tsx +103 -0
  27. package/canvas-example-main/canvas-example-main/src/pages/demo/index.tsx +21 -0
  28. package/canvas-example-main/canvas-example-main/src/pages/editor/components/editor/index.module.less +3 -0
  29. package/canvas-example-main/canvas-example-main/src/pages/editor/components/editor/index.tsx +99 -0
  30. package/canvas-example-main/canvas-example-main/src/pages/editor/components/header/index.module.less +5 -0
  31. package/canvas-example-main/canvas-example-main/src/pages/editor/components/header/index.tsx +5 -0
  32. package/canvas-example-main/canvas-example-main/src/pages/editor/components/material/index.module.less +59 -0
  33. package/canvas-example-main/canvas-example-main/src/pages/editor/components/material/index.tsx +85 -0
  34. package/canvas-example-main/canvas-example-main/src/pages/editor/components/setting/index.module.less +7 -0
  35. package/canvas-example-main/canvas-example-main/src/pages/editor/components/setting/index.tsx +5 -0
  36. package/canvas-example-main/canvas-example-main/src/pages/editor/core/application.ts +35 -0
  37. package/canvas-example-main/canvas-example-main/src/pages/editor/core/cmp/base.ts +17 -0
  38. package/canvas-example-main/canvas-example-main/src/pages/editor/core/cmp/factory.ts +14 -0
  39. package/canvas-example-main/canvas-example-main/src/pages/editor/core/cmp/shape.tsx +43 -0
  40. package/canvas-example-main/canvas-example-main/src/pages/editor/core/editor.ts +61 -0
  41. package/canvas-example-main/canvas-example-main/src/pages/editor/core/type.ts +6 -0
  42. package/canvas-example-main/canvas-example-main/src/pages/editor/index.module.less +7 -0
  43. package/canvas-example-main/canvas-example-main/src/pages/editor/index.tsx +32 -0
  44. package/canvas-example-main/canvas-example-main/src/pages/editor/store/component-config.ts +61 -0
  45. package/canvas-example-main/canvas-example-main/src/pages/editor/store/components.ts +43 -0
  46. package/canvas-example-main/canvas-example-main/src/pages/editor/store/layout.ts +40 -0
  47. package/canvas-example-main/canvas-example-main/src/pages/home/index.tsx +59 -0
  48. package/canvas-example-main/canvas-example-main/src/pages/jigsaw/index.tsx +3 -0
  49. package/canvas-example-main/canvas-example-main/src/pages/minesweeper/bomber.png +0 -0
  50. package/canvas-example-main/canvas-example-main/src/pages/minesweeper/index.tsx +138 -0
  51. package/canvas-example-main/canvas-example-main/src/pages/minesweeper/mark.png +0 -0
  52. package/canvas-example-main/canvas-example-main/src/pages/minesweeper/minesweeper.ts +345 -0
  53. package/canvas-example-main/canvas-example-main/src/pages/minesweeper/utils.ts +24 -0
  54. package/canvas-example-main/canvas-example-main/src/pages/pageflip/index.tsx +200 -0
  55. package/canvas-example-main/canvas-example-main/src/pages/pageflip/page1.jpg +0 -0
  56. package/canvas-example-main/canvas-example-main/src/pages/practice/draw/index.ts +367 -0
  57. package/canvas-example-main/canvas-example-main/src/pages/practice/index.module.less +26 -0
  58. package/canvas-example-main/canvas-example-main/src/pages/practice/index.tsx +54 -0
  59. package/canvas-example-main/canvas-example-main/src/pages/shape-editor/control.ts +174 -0
  60. package/canvas-example-main/canvas-example-main/src/pages/shape-editor/editor.ts +91 -0
  61. package/canvas-example-main/canvas-example-main/src/pages/shape-editor/index.raw.tsx +159 -0
  62. package/canvas-example-main/canvas-example-main/src/pages/shape-editor/index.tsx +36 -0
  63. package/canvas-example-main/canvas-example-main/src/pages/shape-editor/shape.ts +248 -0
  64. package/canvas-example-main/canvas-example-main/src/router.tsx +53 -0
  65. package/canvas-example-main/canvas-example-main/src/utils/storage.ts +48 -0
  66. package/canvas-example-main/canvas-example-main/src/vite-env.d.ts +1 -0
  67. package/canvas-example-main/canvas-example-main/tailwind.config.js +8 -0
  68. package/canvas-example-main/canvas-example-main/tsconfig.app.json +30 -0
  69. package/canvas-example-main/canvas-example-main/tsconfig.json +7 -0
  70. package/canvas-example-main/canvas-example-main/tsconfig.node.json +22 -0
  71. package/canvas-example-main/canvas-example-main/vite.config.ts +18 -0
  72. package/package.json +1 -1
@@ -0,0 +1,21 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export default function Component() {
4
+ const canvasRef = useRef<HTMLCanvasElement>();
5
+
6
+ const draw = () => {
7
+ const canvas = canvasRef.current;
8
+ const ctx = canvasRef.current.getContext('2d');
9
+ console.log(canvas, ctx);
10
+ };
11
+
12
+ useEffect(() => {
13
+ draw();
14
+ }, []);
15
+
16
+ return (
17
+ <div className="w-[100vw] h-[100vh] flex items-center justify-center background-[#aaa] flex-col">
18
+ <canvas width={600} height={600} ref={canvasRef}></canvas>
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,103 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export default function Clock() {
4
+ const canvasRef = useRef<HTMLCanvasElement>();
5
+
6
+ const draw = () => {
7
+ const canvas = canvasRef.current;
8
+ const ctx = canvasRef.current.getContext('2d');
9
+
10
+ function drawClock() {
11
+ const now = new Date();
12
+ const hours = now.getHours();
13
+ const minutes = now.getMinutes();
14
+ const seconds = now.getSeconds();
15
+
16
+ const centerX = canvas.width / 2;
17
+ const centerY = canvas.height / 2;
18
+
19
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
20
+ drawFace(ctx, centerX, centerY, 150);
21
+ drawNumbers(ctx, centerX, centerY, 150);
22
+ drawTime(ctx, centerX, centerY, hours, minutes, seconds);
23
+ drawTicks(ctx, centerX, centerY, 150);
24
+ }
25
+
26
+ function drawFace(ctx: CanvasRenderingContext2D, x, y, radius) {
27
+ ctx.beginPath();
28
+ ctx.lineWidth = 2;
29
+ ctx.fillStyle = 'black';
30
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
31
+ ctx.stroke();
32
+ }
33
+
34
+ function drawTicks(ctx, x, y, radius) {
35
+ for (let i = 0; i < 60; i++) {
36
+ const angle = i * (Math.PI / 30);
37
+ const isHour = i % 5 === 0;
38
+ const len = isHour ? 15 : 10;
39
+ if (isHour) {
40
+ ctx.lineWidth = 2;
41
+ } else {
42
+ ctx.lineWidth = 1;
43
+ }
44
+ const innerX = x + (radius - len) * Math.sin(angle);
45
+ const innerY = y - (radius - len) * Math.cos(angle);
46
+ const outerX = x + radius * Math.sin(angle);
47
+ const outerY = y - radius * Math.cos(angle);
48
+
49
+ ctx.beginPath();
50
+ ctx.moveTo(innerX, innerY);
51
+ ctx.lineTo(outerX, outerY);
52
+ ctx.stroke();
53
+ }
54
+ }
55
+
56
+ function drawNumbers(ctx, x, y, radius) {
57
+ ctx.font = `${radius / 10}px Arial`;
58
+ ctx.textBaseline = 'middle';
59
+ ctx.textAlign = 'center';
60
+
61
+ for (let num = 1; num <= 12; num++) {
62
+ const angle = num * (Math.PI / 6);
63
+ const dx = x + radius * 0.8 * Math.sin(angle);
64
+ const dy = y - radius * 0.8 * Math.cos(angle);
65
+ ctx.fillText(num.toString(), dx, dy);
66
+ }
67
+ }
68
+
69
+ function drawTime(ctx, x, y, hours, minutes, seconds) {
70
+ hours = hours % 12;
71
+ hours = (hours * Math.PI) / 6 + (minutes * Math.PI) / 360;
72
+ drawHand(ctx, x, y, hours, 50, 6); // Hour hand
73
+
74
+ minutes = (minutes * Math.PI) / 30 + (seconds * Math.PI) / 1800;
75
+ drawHand(ctx, x, y, minutes, 70, 4); // Minute hand
76
+
77
+ seconds = (seconds * Math.PI) / 30;
78
+ drawHand(ctx, x, y, seconds, 90, 2); // Second hand
79
+ }
80
+
81
+ function drawHand(ctx, x, y, angle, length, width) {
82
+ ctx.beginPath();
83
+ ctx.lineWidth = width;
84
+ ctx.lineCap = 'round';
85
+ ctx.moveTo(x, y);
86
+ ctx.lineTo(x + length * Math.sin(angle), y - length * Math.cos(angle));
87
+ ctx.stroke();
88
+ }
89
+
90
+ setInterval(drawClock, 1000);
91
+ drawClock();
92
+ };
93
+
94
+ useEffect(() => {
95
+ draw();
96
+ }, []);
97
+
98
+ return (
99
+ <div className="w-[100vw] h-[100vh] flex items-center justify-center background-[#aaa] flex-col">
100
+ <canvas width={600} height={600} ref={canvasRef}></canvas>
101
+ </div>
102
+ );
103
+ }
@@ -0,0 +1,21 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export default function Component() {
4
+ const canvasRef = useRef<HTMLCanvasElement>();
5
+
6
+ const draw = () => {
7
+ const canvas = canvasRef.current;
8
+ const ctx = canvasRef.current.getContext('2d');
9
+ console.log(canvas, ctx);
10
+ };
11
+
12
+ useEffect(() => {
13
+ draw();
14
+ }, []);
15
+
16
+ return (
17
+ <div className="w-[100vw] h-[100vh] flex items-center justify-center background-[#aaa] flex-col">
18
+ <canvas width={600} height={600} ref={canvasRef}></canvas>
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,99 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import Editor from '../../core/editor';
4
+ import { useLayoutStore } from '../../store/layout';
5
+ import { useComponentStore } from '../../store/components';
6
+
7
+ import S from './index.module.less';
8
+
9
+ export default function EditorComponent() {
10
+ const { contentWidth, contentHeight } = useLayoutStore();
11
+ const { components, updateEditor } = useComponentStore();
12
+ const editorRef = useRef<Editor>();
13
+
14
+ useEffect(() => {
15
+ const id = 'editor-canvas-container';
16
+
17
+ const el = document.querySelector(`#${id}`);
18
+
19
+ let cancelContextMenuListener;
20
+
21
+ if (el) {
22
+ editorRef.current = new Editor({
23
+ width: contentWidth,
24
+ height: contentHeight,
25
+ frameHeight: 900,
26
+ frameWidth: 500,
27
+ view: id,
28
+ onMenuTap(event) {
29
+ console.log('event', event);
30
+ },
31
+ onSelect(event) {
32
+ // updateSelectCmp(event.value);
33
+ console.log(event);
34
+ },
35
+ onMove(event) {
36
+ console.log(event);
37
+ },
38
+ });
39
+
40
+ updateEditor(editorRef.current);
41
+
42
+ cancelContextMenuListener = document.addEventListener('click', () => {
43
+ setMenuPosition({ x: 0, y: 0 });
44
+ });
45
+ }
46
+
47
+ return () => {
48
+ if (editorRef.current) {
49
+ editorRef.current.destroy();
50
+ }
51
+
52
+ if (cancelContextMenuListener) {
53
+ document.removeEventListener('click', cancelContextMenuListener);
54
+ }
55
+ };
56
+ }, []);
57
+
58
+ useEffect(() => {
59
+ if (editorRef.current) {
60
+ editorRef.current.resize({ width: contentWidth, height: contentHeight });
61
+ }
62
+ }, [contentWidth, contentHeight]);
63
+
64
+ useEffect(() => {}, [components]);
65
+
66
+ const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 });
67
+
68
+ const Menu = ({ x, y }) => {
69
+ return createPortal(
70
+ <div
71
+ style={{
72
+ position: 'absolute',
73
+ left: x,
74
+ top: y,
75
+ background: '#f0f0f0',
76
+ padding: '5px',
77
+ border: '1px solid #ccc',
78
+ }}
79
+ >
80
+ <ul>
81
+ <li onClick={() => {}}>移除</li>
82
+ <li>置顶</li>
83
+ <li>置底</li>
84
+ </ul>
85
+ </div>,
86
+ document.body
87
+ );
88
+ };
89
+
90
+ return (
91
+ <main
92
+ className={S.editor}
93
+ style={{ width: contentWidth }}
94
+ id="editor-canvas-container"
95
+ >
96
+ {menuPosition.x !== 0 && <Menu x={menuPosition.x} y={menuPosition.y} />}
97
+ </main>
98
+ );
99
+ }
@@ -0,0 +1,5 @@
1
+ .header {
2
+ background-color: white;
3
+ height: 60px;
4
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
5
+ }
@@ -0,0 +1,5 @@
1
+ import S from './index.module.less';
2
+
3
+ export default function Header() {
4
+ return <header className={S.header}></header>;
5
+ }
@@ -0,0 +1,59 @@
1
+ .material {
2
+ height: 100%;
3
+ background-color: white;
4
+ position: relative;
5
+
6
+ .content {
7
+ display: flex;
8
+ flex-direction: row;
9
+ height: 100%;
10
+
11
+ .list {
12
+ width: 60px;
13
+ display: flex;
14
+ flex-direction: column;
15
+ align-items: center;
16
+ gap: 15px;
17
+
18
+ border-right: 1px solid #dcdee2;
19
+
20
+ .item {
21
+ display: flex;
22
+ flex-direction: column;
23
+ align-items: center;
24
+ cursor: pointer;
25
+ width: 100%;
26
+ border-right: 2px solid transparent;
27
+ }
28
+
29
+ .item-active {
30
+ border-right: 2px solid #2d8cf0;
31
+ }
32
+ }
33
+
34
+ .aside {
35
+ width: 300px;
36
+ position: relative;
37
+ display: flex;
38
+ flex-direction: row;
39
+ flex-wrap: wrap;
40
+ gap: 10px;
41
+ padding: 10px;
42
+
43
+ .item {
44
+ cursor: pointer;
45
+ }
46
+ }
47
+ }
48
+
49
+ .menu {
50
+ width: 30px;
51
+ height: 30px;
52
+ position: absolute;
53
+ right: -30px;
54
+ top: 50%;
55
+ transform: translate(0, -15px);
56
+ cursor: pointer;
57
+ z-index: 999999;
58
+ }
59
+ }
@@ -0,0 +1,85 @@
1
+ import { useMemo, useState } from 'react';
2
+ import classNames from 'classnames';
3
+
4
+ import Iconfont from '@/components/Iconfont';
5
+ import { useLayoutStore } from '../../store/layout';
6
+
7
+ import { useComponentStore } from '../../store/components';
8
+ import { useComponentConfigStore } from '../../store/component-config';
9
+ import S from './index.module.less';
10
+
11
+ export default function Material() {
12
+ const { componentConfig } = useComponentConfigStore();
13
+
14
+ const [activeType, setActiveType] = useState(componentConfig[0].type);
15
+ const { asideOpen, updateAsideOpen } = useLayoutStore();
16
+ const { addCmp } = useComponentStore();
17
+
18
+ const components = useMemo(() => {
19
+ const currentComponents = componentConfig.find(
20
+ (o) => o.type === activeType
21
+ );
22
+ return currentComponents.components;
23
+ }, [componentConfig, activeType]);
24
+
25
+ const Item = ({ item }) => {
26
+ return (
27
+ <div
28
+ className={classNames(
29
+ S.item,
30
+ item.type === activeType && S['item-active']
31
+ )}
32
+ onClick={() => {
33
+ setActiveType(item.type);
34
+ updateAsideOpen(true);
35
+ }}
36
+ >
37
+ <Iconfont name={item.icon} />
38
+ <span>{item.label}</span>
39
+ </div>
40
+ );
41
+ };
42
+
43
+ return (
44
+ <aside className={S.material}>
45
+ <div className={S.content}>
46
+ <div className={S.list}>
47
+ {componentConfig.map((item) => (
48
+ <Item item={item} key={item.type} />
49
+ ))}
50
+ </div>
51
+
52
+ {asideOpen && (
53
+ <div className={S.aside}>
54
+ {components.map((cmp) => {
55
+ return (
56
+ <div
57
+ className={S.item}
58
+ onClick={() => {
59
+ addCmp(cmp.model as any);
60
+ }}
61
+ key={cmp.name}
62
+ >
63
+ {typeof cmp.icon === 'string' ? (
64
+ <Iconfont name={cmp.icon}></Iconfont>
65
+ ) : (
66
+ cmp.icon()
67
+ )}
68
+ </div>
69
+ );
70
+ })}
71
+ </div>
72
+ )}
73
+ </div>
74
+
75
+ <div
76
+ className={S.menu}
77
+ onClick={() => {
78
+ updateAsideOpen(!asideOpen);
79
+ }}
80
+ >
81
+ {asideOpen ? <Iconfont name="jiantou1" /> : <Iconfont name="jiantou" />}
82
+ </div>
83
+ </aside>
84
+ );
85
+ }
@@ -0,0 +1,7 @@
1
+ .setting {
2
+ width: 300px;
3
+ height: 100%;
4
+ display: flex;
5
+
6
+ background-color: white;
7
+ }
@@ -0,0 +1,5 @@
1
+ import S from './index.module.less';
2
+
3
+ export default function Setting() {
4
+ return <div className={S.setting}>settings</div>;
5
+ }
@@ -0,0 +1,35 @@
1
+ import { App, Frame, IScreenSizeData } from 'leafer-ui';
2
+
3
+ export interface IApplicationConfig {
4
+ view: string;
5
+ width: number;
6
+ height: number;
7
+ }
8
+
9
+ export class Application {
10
+ config: IApplicationConfig;
11
+ app: App;
12
+ page: Frame;
13
+
14
+ constructor(config: IApplicationConfig) {
15
+ this.config = config;
16
+ const { view, width, height } = config;
17
+ this.app = new App({ view, width, height, editor: {} });
18
+
19
+ this.app.tree = this.app.addLeafer();
20
+ this.app.ground = this.app.addLeafer();
21
+ this.app.sky = this.app.addLeafer({ type: 'draw', usePartRender: false });
22
+ }
23
+
24
+ toJSON() {
25
+ return this.app.toJSON();
26
+ }
27
+
28
+ resize(sizeData: IScreenSizeData) {
29
+ this.app.resize(sizeData);
30
+ }
31
+
32
+ destroy() {
33
+ this.app.destroy();
34
+ }
35
+ }
@@ -0,0 +1,17 @@
1
+ import { ComponentType } from '../type';
2
+
3
+ export interface BaseModel {
4
+ x: number;
5
+ y: number;
6
+ width?: number;
7
+ height?: number;
8
+ editable: boolean;
9
+ type?: ComponentType;
10
+ }
11
+
12
+ export const baseModel: BaseModel = {
13
+ x: 0,
14
+ y: 0,
15
+ editable: true,
16
+ type: ComponentType.Rect,
17
+ };
@@ -0,0 +1,14 @@
1
+ import { Polygon, Rect } from 'leafer-ui';
2
+ import { BaseModel } from './base';
3
+ import { ComponentType } from '../type';
4
+
5
+ export function create(type: ComponentType, model: BaseModel) {
6
+ switch (type) {
7
+ case ComponentType.Rect:
8
+ return new Rect(model);
9
+ case ComponentType.Polygon:
10
+ return new Polygon(model);
11
+ }
12
+
13
+ return null;
14
+ }
@@ -0,0 +1,43 @@
1
+ import Iconfont from '@/components/Iconfont';
2
+ import { Component } from '../../store/component-config';
3
+ import { ComponentType } from '../type';
4
+ import { baseModel } from './base';
5
+
6
+ const rect: Component = {
7
+ name: '矩形',
8
+ icon: () => <Iconfont size={28} name="xingzhuang-juxing"></Iconfont>,
9
+ model: {
10
+ ...baseModel,
11
+ type: ComponentType.Rect,
12
+ width: 150,
13
+ height: 150,
14
+ fill: 'lime',
15
+ },
16
+ };
17
+
18
+ const triangle: Component = {
19
+ name: '三角形',
20
+ icon: () => <Iconfont size={28} name="xingzhuang-sanjiaoxing"></Iconfont>,
21
+ model: {
22
+ ...baseModel,
23
+ type: ComponentType.Polygon,
24
+ width: 100,
25
+ height: 100,
26
+ sides: 3,
27
+ fill: 'lime',
28
+ },
29
+ };
30
+
31
+ const circle: Component = {
32
+ name: '圆',
33
+ icon: () => <Iconfont size={28} name="yuanhuan"></Iconfont>,
34
+ model: {
35
+ ...baseModel,
36
+ type: ComponentType.Rect,
37
+ width: 150,
38
+ height: 150,
39
+ fill: 'lime',
40
+ },
41
+ };
42
+
43
+ export const shapeComponent = [rect, triangle, circle];
@@ -0,0 +1,61 @@
1
+ import {
2
+ Editor as LeaferEditor,
3
+ EditorEvent,
4
+ EditorMoveEvent,
5
+ } from '@leafer-in/editor';
6
+
7
+ import { Frame, PointerEvent } from 'leafer-ui';
8
+ import { Application, IApplicationConfig } from './application';
9
+
10
+ interface IEditorConfig extends IApplicationConfig {
11
+ frameWidth: number;
12
+ frameHeight: number;
13
+ onMenuTap?: (event) => void;
14
+ onSelect?: (event) => void;
15
+ onMove?: (event) => void;
16
+ }
17
+
18
+ export default class Editor extends Application {
19
+ declare config: IEditorConfig;
20
+
21
+ constructor(config: IEditorConfig) {
22
+ super(config);
23
+ this.config = config;
24
+
25
+ const { onMenuTap, onSelect, onMove } = config;
26
+
27
+ this.app.editor = new LeaferEditor({ continuousSelect: true });
28
+ this.app.sky.add(this.app.editor);
29
+
30
+ this.app.on(PointerEvent.MENU_TAP, onMenuTap);
31
+ this.app.editor.on(EditorEvent.SELECT, onSelect);
32
+ this.app.editor.on(EditorMoveEvent.MOVE, onMove);
33
+
34
+ this.initFrame();
35
+ }
36
+
37
+ initFrame() {
38
+ const { frameWidth, frameHeight } = this.config;
39
+
40
+ const centerX = this.app.width / 2 - frameWidth / 2;
41
+ const centerY = this.app.height / 2 - frameHeight / 2;
42
+ this.page = new Frame({
43
+ x: centerX,
44
+ y: centerY,
45
+ width: frameWidth,
46
+ height: frameHeight,
47
+ fill: 'white',
48
+ });
49
+
50
+ this.app.tree.add(this.page);
51
+ }
52
+
53
+ addCmp(cmp: any) {
54
+ this.page.add(cmp);
55
+ return cmp;
56
+ }
57
+
58
+ removeCmp() {}
59
+
60
+ updateCmp() {}
61
+ }
@@ -0,0 +1,6 @@
1
+ export enum ComponentType {
2
+ Rect = 'Rect',
3
+ Line = 'Line',
4
+ Ellipse = 'Ellipse',
5
+ Polygon = 'Polygon',
6
+ }
@@ -0,0 +1,7 @@
1
+ .content {
2
+ width: 100vw;
3
+ height: calc(100% - 60px);
4
+
5
+ display: flex;
6
+ flex-direction: row;
7
+ }
@@ -0,0 +1,32 @@
1
+ import { useEffect } from 'react';
2
+
3
+ import { useWindowSize } from 'react-use';
4
+
5
+ import Editor from './components/editor';
6
+ import Header from './components/header';
7
+ import Material from './components/material';
8
+ import Setting from './components/setting';
9
+
10
+ import { useLayoutStore } from './store/layout';
11
+
12
+ import S from './index.module.less';
13
+
14
+ export default function Component() {
15
+ const { updateContentWidth } = useLayoutStore();
16
+ const { width } = useWindowSize();
17
+
18
+ useEffect(() => {
19
+ updateContentWidth(width - 360);
20
+ }, [width]);
21
+
22
+ return (
23
+ <div className="bg-[#f2f3f5] h-[100vh] w-[100vw]">
24
+ <Header />
25
+ <div className={S.content}>
26
+ <Material />
27
+ <Editor />
28
+ <Setting />
29
+ </div>
30
+ </div>
31
+ );
32
+ }