Peter Millauer пре 3 дана
родитељ
комит
b22971ef35

+ 1
- 0
.gitignore Прегледај датотеку

11
 dist
11
 dist
12
 dist-ssr
12
 dist-ssr
13
 *.local
13
 *.local
14
+circles-pictures
14
 
15
 
15
 # Editor directories and files
16
 # Editor directories and files
16
 .vscode/*
17
 .vscode/*

+ 3
- 1
src/client/model/rpc-callbacks.ts Прегледај датотеку

1
 import { Stroke } from "./canvas-state";
1
 import { Stroke } from "./canvas-state";
2
 
2
 
3
-export type ListenCallbackParam = { strokeId: number, stroke: Stroke }
3
+export type StrokeStreamElement = { strokeId: number, stroke: Stroke }
4
+
5
+export type OnStrokeCallback = (state: StrokeStreamElement) => void

+ 5
- 15
src/client/services/draw/draw.client-service.ts Прегледај датотеку

23
         private readonly densityValue = document.getElementById('densityValue')!,
23
         private readonly densityValue = document.getElementById('densityValue')!,
24
 
24
 
25
         private readonly widthSlider = document.getElementById('widthSlider')!,
25
         private readonly widthSlider = document.getElementById('widthSlider')!,
26
-        private readonly widthValue = document.getElementById('widthValue')!, 
26
+        private readonly widthValue = document.getElementById('widthValue')!,
27
 
27
 
28
         private readonly menuButton = document.getElementById('menuButton')!,
28
         private readonly menuButton = document.getElementById('menuButton')!,
29
         private readonly drawer = document.getElementById('drawer')!,
29
         private readonly drawer = document.getElementById('drawer')!,
30
         private readonly closeButton = document.getElementById('closeButton')!,
30
         private readonly closeButton = document.getElementById('closeButton')!,
31
     ) {
31
     ) {
32
-        this.resizeCanvas()
33
         this.setupCanvasEvents()
32
         this.setupCanvasEvents()
34
-        window.addEventListener("resize", () => this.resizeCanvas());
35
-        this.cctx = canvas.getContext("2d")!
36
         this.currentColor = colorPicker!.getAttribute('value')!
33
         this.currentColor = colorPicker!.getAttribute('value')!
37
         this.currentDensity = Number(densitySlider!.getAttribute('value'))!
34
         this.currentDensity = Number(densitySlider!.getAttribute('value'))!
38
         this.currentWidth = Number(widthSlider!.getAttribute('value'))!
35
         this.currentWidth = Number(widthSlider!.getAttribute('value'))!
36
+
37
+        this.cctx = canvas.getContext("2d")!
39
     }
38
     }
40
 
39
 
41
     draw() {
40
     draw() {
42
-
43
-            console.log("drawing")
44
         const strokes: Stroke[] = this.stateService.getStrokes()
41
         const strokes: Stroke[] = this.stateService.getStrokes()
45
 
42
 
46
         this.cctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
43
         this.cctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
47
-        
48
-        this.cctx.globalAlpha = 1;
44
+
49
         strokes.forEach(stroke => {
45
         strokes.forEach(stroke => {
50
             this.cctx.fillStyle = stroke.color;
46
             this.cctx.fillStyle = stroke.color;
51
             this.drawCurve(stroke.points, stroke.density, stroke.width)
47
             this.drawCurve(stroke.points, stroke.density, stroke.width)
122
         });
118
         });
123
 
119
 
124
         document.addEventListener('click', (e) => {
120
         document.addEventListener('click', (e) => {
125
-            if(!e.target){
121
+            if (!e.target) {
126
                 return
122
                 return
127
             }
123
             }
128
             if (!this.drawer.contains(e.target as Node) && !this.menuButton.contains(e.target as Node)) {
124
             if (!this.drawer.contains(e.target as Node) && !this.menuButton.contains(e.target as Node)) {
132
 
128
 
133
     }
129
     }
134
 
130
 
135
-    private resizeCanvas() {
136
-        const size = Math.min(window.innerWidth, window.innerHeight) * 0.9;
137
-        this.canvas.width = size;
138
-        this.canvas.height = size;
139
-    }
140
-
141
     private drawCurve(points: Point[], density: number, width: number) {
131
     private drawCurve(points: Point[], density: number, width: number) {
142
         if (points.length < 2) return;
132
         if (points.length < 2) return;
143
 
133
 

+ 5
- 5
src/client/services/state/state.client-service.ts Прегледај датотеку

1
 import { RPCSocket } from "../../../../node_modules/rpclibrary/js/Index";
1
 import { RPCSocket } from "../../../../node_modules/rpclibrary/js/Index";
2
 import { CanvasState, Point, Stroke } from "../../model/canvas-state";
2
 import { CanvasState, Point, Stroke } from "../../model/canvas-state";
3
-import { ListenCallbackParam } from "../../model/rpc-callbacks";
3
+import { StrokeStreamElement } from "../../model/rpc-callbacks";
4
 import { ClientDrawService } from "../draw/draw.client-service";
4
 import { ClientDrawService } from "../draw/draw.client-service";
5
 
5
 
6
 
6
 
14
         const sock = await new RPCSocket(8080, 'localhost').connect();
14
         const sock = await new RPCSocket(8080, 'localhost').connect();
15
         this.remoteService = sock['StateService']
15
         this.remoteService = sock['StateService']
16
         this.canvasState = await this.getState()
16
         this.canvasState = await this.getState()
17
-        await this.remoteService.listen((listenDto: ListenCallbackParam) => {
18
-            if(!this.canvasState.strokes[listenDto.strokeId]){
19
-                this.canvasState.strokes[listenDto.strokeId] = listenDto.stroke
17
+        await this.remoteService.onStroke((s: StrokeStreamElement) => {
18
+            if(!this.canvasState.strokes[s.strokeId]){
19
+                this.canvasState.strokes[s.strokeId] = s.stroke
20
             }else{
20
             }else{
21
-                this.canvasState.strokes[listenDto.strokeId].points = [...this.canvasState.strokes[listenDto.strokeId].points, ...listenDto.stroke.points]
21
+                this.canvasState.strokes[s.strokeId].points = [...this.canvasState.strokes[s.strokeId].points, ...s.stroke.points]
22
             }
22
             }
23
             drawService.draw()
23
             drawService.draw()
24
         })
24
         })

+ 11
- 1
src/server/services/express/express.service.ts Прегледај датотеку

13
     @Inject(StateService)
13
     @Inject(StateService)
14
     private stateService: StateService;
14
     private stateService: StateService;
15
 
15
 
16
+    private connectionCount = 0;
17
+
16
     initialize() {
18
     initialize() {
17
         const app = express();
19
         const app = express();
18
         const PORT = 8080;
20
         const PORT = 8080;
28
         const rpcServer = new RPCServer([
30
         const rpcServer = new RPCServer([
29
             this.stateService,
31
             this.stateService,
30
 
32
 
31
-        ])
33
+        ], {
34
+            closeHandler: (socket) => {
35
+                this.connectionCount -= 1
36
+                if(this.connectionCount === 0){
37
+                    this.stateService.finalizePicture()
38
+                }
39
+            },
40
+            connectionHandler: (socket) => { this.connectionCount += 1 },
41
+        })
32
         rpcServer.attach(httpServer)
42
         rpcServer.attach(httpServer)
33
         rpcServer.listen(PORT)
43
         rpcServer.listen(PORT)
34
 
44
 

+ 28
- 12
src/server/services/state/state.service.ts Прегледај датотеку

1
 import { Singleton, Initializable } from "depents";
1
 import { Singleton, Initializable } from "depents";
2
 import { RPCExporter } from "rpclibrary";
2
 import { RPCExporter } from "rpclibrary";
3
 import { CanvasState, Point, Stroke } from "../../../client/model/canvas-state";
3
 import { CanvasState, Point, Stroke } from "../../../client/model/canvas-state";
4
-import { ListenCallbackParam } from "../../../client/model/rpc-callbacks";
4
+import { OnStrokeCallback } from "../../../client/model/rpc-callbacks";
5
+import * as fs from "fs";
6
+import * as path from "path";
5
 
7
 
6
 @Singleton()
8
 @Singleton()
7
 export class StateService implements Initializable, RPCExporter {
9
 export class StateService implements Initializable, RPCExporter {
8
     name = 'StateService' as const
10
     name = 'StateService' as const
9
 
11
 
10
     private canvasState: CanvasState = { strokes: [] }
12
     private canvasState: CanvasState = { strokes: [] }
11
-    private clients: Array<(param: ListenCallbackParam) => void> = []
13
+    private onStrokeCallbacks: Array<OnStrokeCallback> = []
12
 
14
 
13
     initialize() {
15
     initialize() {
14
         this.canvasState = { strokes: [] }
16
         this.canvasState = { strokes: [] }
15
-        this.clients = []
17
+        this.onStrokeCallbacks = []
16
     };
18
     };
17
 
19
 
18
     beginStroke = async (stroke: Stroke) => {
20
     beginStroke = async (stroke: Stroke) => {
19
         const strokeId = this.canvasState.strokes.length
21
         const strokeId = this.canvasState.strokes.length
20
         this.canvasState.strokes.push(stroke)
22
         this.canvasState.strokes.push(stroke)
21
-        this.updateclients(strokeId, stroke)
23
+        this.updateStrokeListeners(strokeId, stroke)
22
         return strokeId
24
         return strokeId
23
     }
25
     }
24
 
26
 
25
     addPoint = async (strokeId: number, point: Point) => {
27
     addPoint = async (strokeId: number, point: Point) => {
26
         this.canvasState.strokes[strokeId].points.push(point)
28
         this.canvasState.strokes[strokeId].points.push(point)
27
-        this.updateclients(strokeId, { ...this.canvasState.strokes[strokeId], points: [point] })
29
+        this.updateStrokeListeners(strokeId, { ...this.canvasState.strokes[strokeId], points: [point] })
28
     }
30
     }
29
 
31
 
30
-    listen = async (callback: (state: any) => Promise<void>) => {
31
-        this.clients = [...this.clients, callback]
32
-        return this.canvasState
32
+    onStroke = async (callback: OnStrokeCallback) => {
33
+        this.onStrokeCallbacks = [...this.onStrokeCallbacks, callback]
34
+        return
33
     }
35
     }
34
 
36
 
35
     getState = async (): Promise<CanvasState> => {
37
     getState = async (): Promise<CanvasState> => {
36
         return this.canvasState
38
         return this.canvasState
37
     }
39
     }
38
 
40
 
39
-    private updateclients = (strokeId: number, stroke: Stroke) => {
40
-        this.clients.forEach((client) => {
41
+    finalizePicture = () => {
42
+        const finalState = { ...this.canvasState }
43
+        this.canvasState = { strokes: [] }
44
+
45
+        const picturedir = path.join(__dirname, `../../../../circles-pictures/`);
46
+
47
+        if (!fs.existsSync(picturedir)) {
48
+            fs.mkdirSync(picturedir);
49
+        }
50
+
51
+        fs.writeFileSync(path.join(picturedir, `${Date.now()}.json`), JSON.stringify(finalState))
52
+        console.log(finalState)
53
+    }
54
+
55
+    private updateStrokeListeners = (strokeId: number, stroke: Stroke) => {
56
+        this.onStrokeCallbacks.forEach((client) => {
41
             client({ strokeId, stroke })
57
             client({ strokeId, stroke })
42
         })
58
         })
43
     }
59
     }
47
         this.addPoint,
63
         this.addPoint,
48
         this.getState,
64
         this.getState,
49
         {
65
         {
50
-            name: 'listen' as const,
51
-            hook: (cb: any) => { this.listen(cb) }
66
+            name: 'onStroke' as const,
67
+            hook: this.onStroke,
52
         }
68
         }
53
     ]
69
     ]
54
 
70
 

Loading…
Откажи
Сачувај