@@ -2,10 +2,16 @@ import { useEffect, useRef, useState } from 'react';
2
2
import Konva from 'konva' ;
3
3
4
4
// STORES
5
- import { useTools } from '@/stores' ;
5
+ import { useFileDetails , useTools , useUserDataStore } from '@/stores' ;
6
6
import { useCanvasStore } from '@/stores' ;
7
+ import useIsSaving from '@/stores/footer/useIsSaving' ;
8
+
9
+ // SERVICES
10
+ import { updateFileData } from '@/backend/services/files/updateFileData' ;
11
+
7
12
8
13
export default function Canvas ( ) {
14
+
9
15
const [ isCanvasReady , setIsCanvasReady ] = useState ( false ) ;
10
16
11
17
// Refs for stage and layer
@@ -16,7 +22,17 @@ export default function Canvas() {
16
22
const [ selectedObject , setSelectedObject ] = useState < Konva . Shape | null > ( null ) ;
17
23
18
24
// State to store the JSON data of the canvas
19
- const { setJsonData } = useCanvasStore ( ) ;
25
+ const { jsonData, setJsonData } = useCanvasStore ( ) ;
26
+
27
+ // Get user details from store
28
+ const { userData } = useUserDataStore ( ) ;
29
+
30
+ // Get file details from store
31
+ const { fileDetails } = useFileDetails ( ) ;
32
+
33
+ // Check on the saving status
34
+ const { setIsSaving } = useIsSaving ( ) ;
35
+
20
36
21
37
const {
22
38
// Add Text
@@ -55,6 +71,65 @@ export default function Canvas() {
55
71
setVideoUrl,
56
72
} = useTools ( ) ;
57
73
74
+ // Function to load images and videos from URLs
75
+ const loadAssets = ( node : Konva . Node ) => {
76
+ if ( node . getClassName ( ) === 'Image' ) {
77
+ // Handle images
78
+ const imageUrl = node . getAttr ( 'imageUrl' ) ;
79
+ if ( imageUrl ) {
80
+ const image = new window . Image ( ) ;
81
+ image . src = imageUrl ;
82
+ image . onload = ( ) => {
83
+ node . setAttr ( 'image' , image ) ; // Set the loaded image
84
+ node . getLayer ( ) ?. batchDraw ( ) ; // Redraw the layer
85
+ } ;
86
+ }
87
+
88
+ // Handle videos
89
+ const videoUrl = node . getAttr ( 'videoUrl' ) ;
90
+ if ( videoUrl ) {
91
+ const video = document . createElement ( 'video' ) ;
92
+ video . src = videoUrl ;
93
+ video . autoplay = true ;
94
+ video . loop = true ;
95
+ video . muted = false ; // Ensure the video is muted for autoplay
96
+
97
+ video . onloadeddata = ( ) => {
98
+ node . setAttr ( 'image' , video ) ; // Set the video as the image
99
+ node . getLayer ( ) ?. batchDraw ( ) ; // Redraw the layer
100
+
101
+ // Restore playback state
102
+ const isPlaying = node . getAttr ( 'isPlaying' ) ;
103
+ if ( isPlaying ) {
104
+ video . play ( ) ;
105
+ } else {
106
+ video . pause ( ) ;
107
+ }
108
+
109
+ // Add click event to toggle play/pause
110
+ node . on ( 'click' , ( ) => {
111
+ if ( video . paused ) {
112
+ video . play ( ) ;
113
+ } else {
114
+ video . pause ( ) ;
115
+ }
116
+ node . getLayer ( ) ?. batchDraw ( ) ;
117
+ } ) ;
118
+
119
+ // Start the video frame update loop
120
+ const updateVideoFrame = ( ) => {
121
+ node . setAttr ( 'image' , video ) ;
122
+ node . getLayer ( ) ?. batchDraw ( ) ;
123
+ requestAnimationFrame ( updateVideoFrame ) ;
124
+ } ;
125
+
126
+ updateVideoFrame ( ) ;
127
+ } ;
128
+ }
129
+ }
130
+ } ;
131
+
132
+
58
133
// Initialize Konva stage and layer
59
134
useEffect ( ( ) => {
60
135
const stage = new Konva . Stage ( {
@@ -64,22 +139,28 @@ export default function Canvas() {
64
139
} ) ;
65
140
const layer = new Konva . Layer ( ) ;
66
141
67
- // Add a pointer cursor to the every shape on the layer
68
- layer . on ( 'mouseover' , ( e ) => {
69
- const shape = e . target ;
70
- document . body . style . cursor = 'pointer' ;
71
- shape . on ( 'mouseout' , ( ) => {
72
- document . body . style . cursor = 'default' ;
73
- } ) ;
74
- } ) ;
75
-
76
142
// Add layer to the stage
77
143
stage . add ( layer ) ;
78
144
79
145
// Save stage and layer in refs
80
146
stageRef . current = stage ;
81
147
layerRef . current = layer ;
82
148
149
+ // Load JSON data if it exists
150
+ if ( jsonData ) {
151
+ const loadedStage = Konva . Node . create ( jsonData , 'container' ) as Konva . Stage ;
152
+ stageRef . current = loadedStage ;
153
+ layerRef . current = loadedStage . getLayers ( ) [ 0 ] ;
154
+
155
+ // Add event listeners and load assets for all nodes
156
+ loadedStage . getLayers ( ) . forEach ( ( layer ) => {
157
+ layer . getChildren ( ) . forEach ( ( node ) => {
158
+ addEventListeners ( node ) ;
159
+ loadAssets ( node ) ; // Load images and videos
160
+ } ) ;
161
+ } ) ;
162
+ }
163
+
83
164
setIsCanvasReady ( true ) ;
84
165
} , [ ] ) ;
85
166
@@ -349,7 +430,7 @@ export default function Canvas() {
349
430
video . src = `${ videoUrl } ` ;
350
431
video . autoplay = true ;
351
432
video . loop = true ;
352
- // video.muted = true ;
433
+ video . muted = false ;
353
434
video . onloadeddata = ( ) => {
354
435
const myVideo = new Konva . Image ( {
355
436
x : 50 ,
@@ -488,6 +569,32 @@ export default function Canvas() {
488
569
} ;
489
570
} , [ selectedObject ] ) ;
490
571
572
+
573
+ // Update the JSON Data
574
+ function sentDataToBackend ( ) {
575
+ setIsSaving ( true ) ;
576
+ setTimeout ( async ( ) => {
577
+ await updateFileData (
578
+ fileDetails ?. $id ,
579
+ jsonData ,
580
+ userData ?. name
581
+ ) . then ( ( res ) => {
582
+ if ( res === true ) {
583
+ setIsSaving ( false ) ;
584
+ } else if ( res === false ) {
585
+ console . log ( 'Error while updating the file' , res )
586
+ setIsSaving ( false ) ;
587
+ }
588
+ } )
589
+ } , 5000 )
590
+ }
591
+
592
+ useEffect ( ( ) => {
593
+ sentDataToBackend ( ) ;
594
+ } , [ jsonData ] ) ;
595
+
596
+
597
+
491
598
return (
492
599
< div className = "bg-white my-2 mx-auto pr-5 border-[1px] border-gray-200 min-h-[500px] w-[970px]" >
493
600
{ /* Init canvas stage */ }
0 commit comments