lost-sia 3.1.3 → 3.1.4
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.
- package/dist/Sia.js +1 -1
- package/package.json +1 -1
- package/src/Sia.tsx +71 -53
package/dist/Sia.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as m,jsxs as Q}from"react/jsx-runtime";import{useRef as k,useState as r,useEffect as l}from"react";import{CSpinner as X}from"@coreui/react";import Cn from"./Canvas/Canvas.js";import _n from"./models/AnnotationTool.js";import Hn from"./Toolbar/Toolbar.js";import wn from"./models/AnnotationMode.js";import Y from"./models/AnnotationStatus.js";const jn=({additionalButtons:Z,allowedTools:T,polygonOperationResult:p={annotationsToDelete:[],polygonsToCreate:[]},annotationSettings:D,uiConfig:E,defaultAnnotationTool:$,defaultLabelId:nn,image:g,isLoading:F=!1,isPolygonSelectionMode:N=!1,initialAnnotations:v=void 0,initialImageLabelIds:C=void 0,initialIsImageJunk:tn=!1,possibleLabels:J,onAnnoCreated:en=(u,H)=>{},onAnnoCreationFinished:on=u=>{},onAnnoChanged:sn=u=>{},onAnnoDeleted:_=(u,H)=>{},onImageLabelsChanged:rn=()=>{},onIsImageJunk:an=()=>{},onNotification:dn=u=>{},onSelectAnnotation:R=u=>{},onTimeTravel:cn=u=>{}})=>{const H=k(null),[j,B]=r(),[I,f]=r([]),[L,ln]=r(),[c,w]=r(),[x,P]=r([]),[fn,un]=r(),[A,h]=r(),[U,W]=r($??_n.Point),a=k(I);l(()=>{a.current=I},[I]);const y=k(c);l(()=>{y.current=c},[c]);const S=n=>{const t=[...n];P(e=>{const s=[...e];return y.current!==void 0&&s.splice(y.current+1),s.push(t),s}),y.current=void 0,w(void 0)},[In,q]=r(C),[z,G]=r(),[b,mn]=r(!1),[M,V]=r([]),K=n=>{const t=a.current,e=t.findIndex(i=>i.internalId===n);if(e===-1)return;const s=[...t],o=s.splice(e,1)[0];a.current=s,f(s),h(void 0),S(s),_(o,s)},An=()=>{A!==void 0&&K(A.internalId)},hn=()=>{let n=0;const t=v.map(e=>({...e,internalId:n++,mode:wn.VIEW,selectedNode:1,status:e.status,annoTime:e.annoTime??0}));V([...new Array(n).keys()]),f(t),S(t)},gn=()=>{let n=0;for(;M.includes(n);)n++;const t=[...M];return t.push(n),V(t),n},vn=n=>{const t=[...a.current],e=t.findIndex(i=>i.internalId===A?.internalId);if(e===-1)return;const s=t.splice(e,1)[0];_(s,t);const o=[...t];o.push(n),f(o),h(n)},O=n=>{G(n),an(n)},xn=n=>{const t=c??x.length-1,e=t==x.length-1,s=t==0;if(e&&!n||s&&n)return;const o=t+(n?-1:1);w(o)},yn=n=>{const t=[],e=[],s=[];for(const o of n){const i=I.find(d=>d.internalId===o.internalId);i?JSON.stringify(i)!==JSON.stringify(o)&&s.push(o):t.push(o)}for(const o of I)n.find(d=>d.internalId===o.internalId)||e.push(o);return{addedAnnotations:t,removedAnnotations:e,changedAnnotations:s}};l(()=>{if(c==null||c<0||c>x.length-1)return;const t=[...x[c]];f(t);const e=yn(t);cn(e)},[c]),l(()=>{g===void 0&&(f([]),h(void 0),P([]),w(void 0))},[g]),l(()=>{G(tn),!(g!==void 0||v===void 0||v.length===0)&&hn()},[v]),l(()=>{q(C)},[C]),l(()=>{const t={...{canCreate:!0,canEdit:!0,canHaveMultipleLabels:!1,canLabel:!0,minimalArea:250},...D};ln(t)},[D]),l(()=>{const t={...{nodeRadius:4,strokeWidth:4,imageCentered:!1},...E};un(t)},[E]),l(()=>{const n={bbox:!0,point:!0,line:!0,junk:!0,polygon:!0};if(T===void 0)return B(n);B(T)},[T]);const Sn={position:"fixed",top:0,left:0,zIndex:1040,backgroundColor:"#ffff",width:"100%",height:"100%",padding:15},Tn={flex:"1 1 auto",minHeight:0,display:"flex",flexDirection:"column"};return j===void 0?m("div",{className:"d-flex justify-content-center",children:m(X,{color:"primary",style:{width:"5rem",height:"5rem"}})}):Q("div",{style:{...b?Sn:{},flex:"1 1 auto",minHeight:0,display:"flex",flexDirection:"column"},children:[m("div",{ref:H,style:{marginBottom:10},children:m(Hn,{annotationSettings:L,allowedTools:j,additionalButtons:Z,isDisabled:F,isFullscreen:b,isImageJunk:z,imageLabelIds:In,possibleLabels:J,selectedTool:U,onImageLabelsChanged:n=>{q(n),rn(n)},onSetIsFullscreen:mn,onSetIsImageJunk:O,onSetSelectedTool:W,onShouldDeleteSelectedAnnotation:An})}),Q("div",{style:Tn,children:[F&&m("div",{className:"d-flex justify-content-center",children:m(X,{color:"primary",style:{width:"5rem",height:"5rem",marginTop:200}})}),g&&I&&m(Cn,{annotations:I,annotationSettings:L,defaultLabelId:nn,image:g,isFullscreen:b,isImageJunk:z,isPolygonSelectionMode:N,selectedAnnotation:A,selectedAnnoTool:U,polygonOperationResult:p,possibleLabels:J,uiConfig:fn,onAnnoCreated:n=>{const t=[...a.current,n];a.current=t,f(t),en(n,t),h(n)},onAnnoChanged:n=>{const t=a.current.findIndex(e=>e.internalId===n.internalId);if(t!==-1){const e=[...a.current];e[t]=n,a.current=e,f(e),n.status!==Y.CREATING&&S(e)}sn(n)},onAnnoCreationFinished:(n,t)=>{const e={...n,status:Y.CREATED},s=N&&p?.annotationsToDelete!==void 0?[...p.annotationsToDelete,...A!==void 0?[A]:[]]:[],o=[...a.current];for(const i of s){const d=o.findIndex(pn=>pn.internalId===i.internalId);d!==-1&&o.splice(d,1)}if(t){const i=o.findIndex(d=>d.internalId===e.internalId);i!==-1&&o.splice(i,1),o.push(e)}else{const i=o.findIndex(d=>d.internalId===e.internalId);i!==-1&&(o[i]=e)}a.current=o,f(o),S(o),h(e),R(e);for(const i of s)_(i);on(e)},onAnnoEditing:vn,onSetIsImageJunk:O,onNotification:dn,onRequestNewAnnoId:gn,onSelectAnnotation:n=>{h(n),R(n)},onSetSelectedTool:W,onShouldDeleteAnno:K,onTraverseAnnotationHistory:xn})]})]})};export{jn as default};
|
package/package.json
CHANGED
package/src/Sia.tsx
CHANGED
|
@@ -95,24 +95,39 @@ const Sia = ({
|
|
|
95
95
|
defaultAnnotationTool ?? AnnotationTool.Point,
|
|
96
96
|
)
|
|
97
97
|
|
|
98
|
+
// refs to always have the latest state without stale closure issues
|
|
99
|
+
const annotationsRef = useRef<Annotation[]>(annotations)
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
annotationsRef.current = annotations
|
|
102
|
+
}, [annotations])
|
|
103
|
+
|
|
104
|
+
const annotationHistoryIndexRef = useRef<number | undefined>(annotationHistoryIndex)
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
annotationHistoryIndexRef.current = annotationHistoryIndex
|
|
107
|
+
}, [annotationHistoryIndex])
|
|
108
|
+
|
|
98
109
|
const updateAnnotationHistory = (annotations: Annotation[]) => {
|
|
99
110
|
const _annotations = [...annotations]
|
|
100
|
-
const _annotationHistory = [...annotationHistory]
|
|
101
111
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
setAnnotationHistory((prevHistory) => {
|
|
113
|
+
const _annotationHistory = [...prevHistory]
|
|
114
|
+
|
|
115
|
+
// user did some changes from within the past
|
|
116
|
+
// time to create an alternative timeline and delete the original one
|
|
117
|
+
if (annotationHistoryIndexRef.current !== undefined) {
|
|
118
|
+
// remove everything after the state the user is
|
|
119
|
+
_annotationHistory.splice(annotationHistoryIndexRef.current + 1)
|
|
120
|
+
}
|
|
108
121
|
|
|
109
122
|
// update the list with out latest change (it is always living in the present)
|
|
110
|
-
|
|
123
|
+
_annotationHistory.push(_annotations)
|
|
124
|
+
return _annotationHistory
|
|
125
|
+
})
|
|
126
|
+
|
|
111
127
|
|
|
112
128
|
// keep history index marker in the present
|
|
129
|
+
annotationHistoryIndexRef.current = undefined
|
|
113
130
|
setAnnotationHistoryIndex(undefined)
|
|
114
|
-
|
|
115
|
-
setAnnotationHistory(_annotationHistory)
|
|
116
131
|
}
|
|
117
132
|
|
|
118
133
|
// for adjusting the container/canvas size
|
|
@@ -137,17 +152,19 @@ const Sia = ({
|
|
|
137
152
|
const [usedInternalIds, setUsedInternalIds] = useState<number[]>([])
|
|
138
153
|
|
|
139
154
|
const deleteAnnotationByInternalId = (internalId: number) => {
|
|
140
|
-
|
|
141
|
-
const annoListIndex: number =
|
|
155
|
+
const currentAnnotations = annotationsRef.current
|
|
156
|
+
const annoListIndex: number = currentAnnotations.findIndex(
|
|
142
157
|
(anno) => anno.internalId === internalId,
|
|
143
158
|
)
|
|
144
159
|
|
|
145
|
-
|
|
146
|
-
const _annotations: Annotation[] = [...annotations]
|
|
160
|
+
if (annoListIndex === -1) return
|
|
147
161
|
|
|
162
|
+
const _annotations: Annotation[] = [...currentAnnotations]
|
|
163
|
+
|
|
148
164
|
// remove annotation
|
|
149
165
|
const removedAnno: Annotation = _annotations.splice(annoListIndex, 1)[0]
|
|
150
166
|
|
|
167
|
+
annotationsRef.current = _annotations
|
|
151
168
|
setAnnotations(_annotations)
|
|
152
169
|
setSelectedAnnotation(undefined)
|
|
153
170
|
updateAnnotationHistory(_annotations)
|
|
@@ -206,7 +223,7 @@ const Sia = ({
|
|
|
206
223
|
}
|
|
207
224
|
|
|
208
225
|
const handleAnnoEditing = (annotation: Annotation) => {
|
|
209
|
-
const _annotations: Annotation[] = [...
|
|
226
|
+
const _annotations: Annotation[] = [...annotationsRef.current]
|
|
210
227
|
|
|
211
228
|
// annotation is being edited - remove it from current annotations for this time
|
|
212
229
|
const selectedAnnotationIndex: number = _annotations.findIndex(
|
|
@@ -498,34 +515,30 @@ const Sia = ({
|
|
|
498
515
|
possibleLabels={possibleLabels}
|
|
499
516
|
uiConfig={uiConfig}
|
|
500
517
|
onAnnoCreated={(annotation: Annotation) => {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
})
|
|
518
|
+
const _annotations = [...annotationsRef.current, annotation]
|
|
519
|
+
annotationsRef.current = _annotations
|
|
520
|
+
setAnnotations(_annotations)
|
|
521
|
+
onAnnoCreated(annotation, _annotations)
|
|
506
522
|
setSelectedAnnotation(annotation)
|
|
507
523
|
// dont update history here - we dont have a finished anno at this point
|
|
508
524
|
}}
|
|
509
525
|
onAnnoChanged={(changedAnno: Annotation) => {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
(anno) => anno.internalId === changedAnno.internalId,
|
|
514
|
-
)
|
|
515
|
-
|
|
516
|
-
// only fire event if item found
|
|
517
|
-
if (annoListIndex === -1) return prev
|
|
526
|
+
const annoListIndex: number = annotationsRef.current.findIndex(
|
|
527
|
+
(anno) => anno.internalId === changedAnno.internalId,
|
|
528
|
+
)
|
|
518
529
|
|
|
519
|
-
|
|
530
|
+
if (annoListIndex !== -1) {
|
|
531
|
+
const _annotations: Annotation[] = [...annotationsRef.current]
|
|
520
532
|
_annotations[annoListIndex] = changedAnno
|
|
533
|
+
annotationsRef.current = _annotations
|
|
534
|
+
setAnnotations(_annotations)
|
|
535
|
+
|
|
521
536
|
|
|
522
537
|
// only update history for full/finished annotations
|
|
523
538
|
if (changedAnno.status !== AnnotationStatus.CREATING) {
|
|
524
539
|
updateAnnotationHistory(_annotations)
|
|
525
540
|
}
|
|
526
|
-
|
|
527
|
-
return _annotations
|
|
528
|
-
})
|
|
541
|
+
}
|
|
529
542
|
|
|
530
543
|
// inform the outside world about our change
|
|
531
544
|
// (kept outside the updater — side effects must not run inside setState)
|
|
@@ -551,30 +564,35 @@ const Sia = ({
|
|
|
551
564
|
]
|
|
552
565
|
: []
|
|
553
566
|
|
|
554
|
-
|
|
555
|
-
// update annotation list
|
|
556
|
-
const _annotations: Annotation[] = [...prev]
|
|
567
|
+
const _annotations: Annotation[] = [...annotationsRef.current]
|
|
557
568
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
if (hasAnnoJustBeenCreated) _annotations.push(finishedAnno)
|
|
567
|
-
else {
|
|
568
|
-
const annoListIndex: number = prev.findIndex(
|
|
569
|
-
(anno) => anno.internalId === finishedAnno.internalId,
|
|
570
|
-
)
|
|
571
|
-
_annotations[annoListIndex] = finishedAnno
|
|
572
|
-
}
|
|
569
|
+
// remove annotations consumed by polygon operation
|
|
570
|
+
for (const annotation of annosToDelete) {
|
|
571
|
+
const annoListIndex: number = _annotations.findIndex(
|
|
572
|
+
(anno) => anno.internalId === annotation.internalId,
|
|
573
|
+
)
|
|
574
|
+
if (annoListIndex !== -1) _annotations.splice(annoListIndex, 1)
|
|
575
|
+
}
|
|
573
576
|
|
|
574
|
-
|
|
577
|
+
if (hasAnnoJustBeenCreated) {
|
|
578
|
+
// replace the CREATING entry with the finished CREATED version
|
|
579
|
+
const existingIdx = _annotations.findIndex(
|
|
580
|
+
(a) => a.internalId === finishedAnno.internalId,
|
|
581
|
+
)
|
|
582
|
+
if (existingIdx !== -1) _annotations.splice(existingIdx, 1)
|
|
583
|
+
_annotations.push(finishedAnno)
|
|
584
|
+
} else {
|
|
585
|
+
const annoListIndex: number = _annotations.findIndex(
|
|
586
|
+
(anno) => anno.internalId === finishedAnno.internalId,
|
|
587
|
+
)
|
|
588
|
+
if (annoListIndex !== -1) _annotations[annoListIndex] = finishedAnno
|
|
589
|
+
}
|
|
575
590
|
|
|
576
|
-
|
|
577
|
-
|
|
591
|
+
annotationsRef.current = _annotations
|
|
592
|
+
setAnnotations(_annotations)
|
|
593
|
+
updateAnnotationHistory(_annotations)
|
|
594
|
+
setSelectedAnnotation(finishedAnno)
|
|
595
|
+
onSelectAnnotation(finishedAnno)
|
|
578
596
|
|
|
579
597
|
// Notify the server about the deletions (outside of the updater/setState!!!)
|
|
580
598
|
for (const annotation of annosToDelete) {
|