UNPKG

lost-sia

Version:

Single Image Annotation Tool

2 lines (1 loc) 9.09 kB
import{jsxs as L,jsx as p,Fragment as Xe}from"react/jsx-runtime";import{useState as m,useRef as fe,useEffect as D}from"react";import M from"../models/AnnotationTool.js";import i from"../models/EditorModes.js";import He from"../utils/KeyMapper.js";import a from"../models/KeyAction.js";import ge from"../Annotation/logic/Annotation.js";import $e from"../models/CanvasAction.js";import Ge from"../Annotation/ui/AnnotationComponent.js";import me from"../utils/mouse2.js";import N from"../models/AnnotationMode.js";import je from"./LabelInput.js";import{FontAwesomeIcon as Je}from"@fortawesome/react-fontawesome";import{faBan as Qe}from"@fortawesome/free-solid-svg-icons";import S from"../models/AnnotationStatus.js";import x from"../utils/transform2.js";import Ze from"../models/NotificationType.js";import qe from"../utils/TimeUtils.js";const Ct=({annotations:C=[],annotationSettings:W,defaultLabelId:J,image:Q,isFullscreen:ye=!1,isImageJunk:Z=!1,isPolygonSelectionMode:B=!1,polygonOperationResult:K={annotationsToDelete:[],polygonsToCreate:[]},possibleLabels:q,preventScrolling:ee=!0,selectedAnnotation:r,selectedAnnoTool:k,toolbarHeight:F=0,uiConfig:z,onAnnoCreated:Ee,onAnnoCreationFinished:te,onAnnoChanged:ne,onAnnoEditing:he=T=>{},onNotification:oe=T=>{},onRequestNewAnnoId:U,onSelectAnnotation:v,onSetSelectedTool:pe=T=>{},onShouldDeleteAnno:re})=>{const[T,A]=m(i.VIEW),[xe,Ce]=m(),[se,Te]=m(J),[R,Ae]=m({x:-1,y:-1}),[ie,ae]=m(0),V={x:R.x,y:R.y},[c,Y]=m({x:-1,y:-1}),[u,X]=m({x:-1,y:-1}),[y,ce]=m({x:-1,y:-1}),[d,P]=m(1),[f,w]=m({x:0,y:0}),H={x:f.x+ie,y:f.y},[E,$]=m(),[G,b]=m(!1),h=fe(null),g=fe(null),O=((e,t)=>{if(e.x===0||e.y===0||t.x===0||t.y===0)return 0;const n=t.x/e.x,o=t.y/e.y;return Math.min(n,o)})(c,u),Oe=()=>{if((g==null?void 0:g.current)===null)return{x:0,y:0};const e=c.x*O;if(z.imageCentered&&u.x>e){const l=(u.x-e)/2;ae(l)}else ae(0);const{top:t,left:n}=h.current.getBoundingClientRect(),o={x:n+window.scrollX,y:t+window.scrollY};Ae(o)},ve=new He(e=>_e(e)),Ie=e=>{A(i.CREATE);const t=x.convertStageCoordinatesToPercentaged([e],O,c);k===M.BBox&&t.push(t[0]);const n=U(),o=new ge(n,k,t);if(Ce(performance.now()),se!==void 0&&(o.labelIds=[se]),Ee(o),k===M.Point){const s={...o,coordinates:[e],annoTime:0};j(s)}},De=()=>{if(r&&![M.Line,M.Polygon].includes(r.type))return;const e=C.find(t=>t.internalId===(r==null?void 0:r.internalId));e!==void 0&&(e.mode=N.CREATE,e.status=S.CREATING,e.selectedNode=e.coordinates.length-1,A(i.ADD),pe(e.type),he(e))},Me=()=>{const e=r?r.internalId:0,t=C.find(n=>n.internalId>e);if(t)return v(t);if(C.length>0)return v(C[0])},Se=()=>{const e=r?r.internalId:0,t=[...C];t.sort((o,s)=>s.internalId-o.internalId);const n=t.find(o=>o.internalId<e);if(n)return v(n);if(C.length>0)return v(C[C.length-1])},we=()=>{if(r){const e=JSON.stringify(r);localStorage.setItem("lostAnnotationClipboard",e);const t={title:"Success",message:"Annotation copied",type:Ze.SUCCESS};oe(t)}},be=()=>{const e=localStorage.getItem("lostAnnotationClipboard");if(e==null)return;const t=JSON.parse(e);t.internalId=U(),t.externalId="",te(t,!0),v(t)},_e=e=>{switch(e){case a.EDIT_LABEL:r&&b(!0);break;case a.DELETE_ANNO:r&&re(r.internalId);break;case a.DELETE_ANNO_IN_CREATION:T===i.CREATE&&(re(r.internalId),A(i.VIEW));break;case a.ENTER_ANNO_ADD_MODE:console.log("KeyAction TODO: ENTER_ANNO_ADD_MODE");break;case a.LEAVE_ANNO_ADD_MODE:console.log("KeyAction TODO: LEAVE_ANNO_ADD_MODE");break;case a.UNDO:console.log("KeyAction TODO: UNDO");break;case a.REDO:console.log("KeyAction TODO: REDO");break;case a.TRAVERSE_ANNOS:Me();break;case a.TRAVERSE_ANNOS_BACKWARDS:Se();break;case a.CAM_MOVE_LEFT:_(20*d,0);break;case a.CAM_MOVE_RIGHT:_(-20*d,0);break;case a.CAM_MOVE_UP:_(0,20*d);break;case a.CAM_MOVE_DOWN:_(0,-20*d);break;case a.CAM_MOVE_STOP:console.log("KeyAction TODO: CAM_MOVE_STOP");break;case a.COPY_ANNOTATION:we();break;case a.PASTE_ANNOTATION:be();break;case a.RECREATE_ANNO:console.log("KeyAction TODO: RECREATE_ANNO"),De();break;default:console.log("Unknown KeyAction",e);break}},_=(e,t)=>{let n=f.x+e/d,o=f.y+t/d;const s=u.x*-.25,l=u.y*-.25,I=u.x*.75,Ye=u.y*.75;n<s&&(n+=25),n>I&&(n-=25),o<l&&(o+=25),o>Ye&&(o-=25),w({x:n,y:o})},Ne=(e=>y.x<=0||y.y<=0||c.x<=0||c.y<=0?[]:C.map(n=>({...n,coordinates:x.convertPercentagedCoordinatesToStage(n.coordinates,c,y)})))(),ke=()=>{if(A(i.VIEW),ce({x:-1,y:-1}),g.current!==null){const{width:e,height:t}=g.current.getBoundingClientRect();Y({x:e,y:t})}P(1),w({x:0,y:0}),$(void 0),b(!1)};D(()=>{if((h==null?void 0:h.current)!==void 0){const{width:e,height:t}=h.current.getBoundingClientRect(),n=t-F;X({x:e,y:n});const o=new ResizeObserver(()=>{const{width:s,height:l}=h.current.getBoundingClientRect(),I=l-F;X({x:s,y:I})});return o.observe(h.current),()=>o.disconnect()}ke()},[Q,ye]),D(()=>{Oe()},[g,f,u]),D(()=>{if(h.current===null)return;const{width:e,height:t}=h.current.getBoundingClientRect(),n=t-F;X({x:e,y:n})},[h]),D(()=>{if(g.current===null)return;const{width:e,height:t}=g.current.getBoundingClientRect();Y({x:e,y:t});const n=new ResizeObserver(()=>{const{width:o,height:s}=g.current.getBoundingClientRect();Y({x:o,y:s})});return n.observe(g.current),()=>n.disconnect()},[g]),D(()=>{if(O===0)return;const e={x:c.x*O,y:c.y*O};ce(e)},[O,c]),D(()=>{B&&K.polygonsToCreate!==void 0&&K.polygonsToCreate.forEach(e=>{const t=U(),n=new ge(t,e.type,x.convertPercentagedCoordinatesToStage(e.coordinates,c,y),N.VIEW,S.CREATED);j(n)})},[K]);const j=e=>{A(i.VIEW);const t={...e,mode:N.VIEW};if(e.type!==M.Point){const s=qe.getRoundedDuration(xe,performance.now());t.annoTime=s}const n=x.convertStageCoordinatesToPercentaged(e.coordinates,O,c);t.coordinates=n,ne(t);const o=k===M.Point||B;te(t,o)},Re=e=>{e.preventDefault(),ve.keyDown(e.key,e.shiftKey,e.ctrlKey)},Ve=e=>{e.preventDefault()},Pe=e=>{if(e.button!==0){if(e.button===1)A(i.CAMERA_MOVE);else if(e.button===2){if(!W.canCreate||T===i.ADD)return;const t=me.getAntiScaledMouseStagePosition(e,V,d,f),n={x:t.x-ie,y:t.y};Ie(n)}}},Le=()=>{ee&&(document.body.style.overflow="hidden")},We=e=>{switch(e.button){case 1:A(i.VIEW);break}},de=(e,t)=>{T===i.CAMERA_MOVE&&_(e,t)},Be=()=>{ee&&(document.body.style.overflow="")},Ke=e=>{const o=(e.deltaY<0?1:-1)>0?d*1.25:d/1.25,s=me.getAntiScaledMouseStagePosition(e,V,d,f),l=d/o,I={x:l*(s.x+f.x)-s.x,y:l*(s.y+f.y)-s.y};o<1?(P(1),(f.x!=0||f.y!=0)&&w({x:0,y:0})):o>200?(P(200),w(I)):(P(o),w(I))},Fe=(e,t)=>{if(t!==$e.ANNO_SELECTED){console.log("Unknown Canvas Action:",t);return}const n={...e,coordinates:x.convertStageCoordinatesToPercentaged([...e.coordinates],O,c)};v(n);const o=x.getMostLeftPoints(e.coordinates),s=x.getTopPoint(o)[0],l=x.convertStageToPage(s,V,d,f);$(l)},le=e=>{const t=x.convertStageCoordinatesToPercentaged(e.coordinates,O,c),n={...e,coordinates:t};n.status===S.LOADED&&(n.status=S.CHANGED),ne(n)},ze=()=>{if(T===i.CAMERA_MOVE)return p(Xe,{});const t=[i.CREATE,i.ADD,i.MOVE].includes(T),n=Ne.map(o=>{const s=o.internalId===(r==null?void 0:r.internalId);return t&&!s?p("g",{},`annotationComponent_${o.internalId}`):p(Ge,{scaledAnnotation:o,annotationSettings:W,possibleLabels:q,svgScale:d,svgTranslation:H,pageToStageOffset:V,nodeRadius:z.nodeRadius,strokeWidth:z.strokeWidth,isSelected:s,isDisabled:B&&s,onFinishAnnoCreate:j,onLabelIconClicked:()=>b(!0),onAction:Fe,onAnnoChanged:le,onAnnotationModeChange:l=>{l===N.MOVE&&A(i.MOVE),T===i.MOVE&&l===N.VIEW&&A(i.VIEW)},onNotification:oe},`annotationComponent_${o.internalId}`)});return p("g",{children:n})},Ue=()=>p("circle",{cx:y.x/2,cy:y.y/2,r:"100%",style:{opacity:0},onContextMenu:e=>e.preventDefault(),onClick:()=>{b(!1)}}),ue={x:R.x+u.x/2,y:R.y+u.y/2};return L("div",{ref:h,style:{width:"100%",height:"100%"},children:[p("div",{style:{position:"absolute",left:(E==null?void 0:E.x)!==void 0?E.x:0,top:(E==null?void 0:E.y)!==void 0?E.y:0,display:(E==null?void 0:E.y)!==void 0?"inherit":"none",zIndex:G?7e3:-1},children:p(je,{defaultLabelId:J,isVisible:G,selectedLabelsIds:r==null?void 0:r.labelIds,possibleLabels:q,isMultilabel:W.canHaveMultipleLabels,onLabelSelect:e=>{if(b(!1),e.length>0){const o=e.filter(s=>!r.labelIds.includes(s));o.length>0&&Te(o[0])}const t=r.status===S.LOADED?S.CHANGED:r.status,n={...r,coordinates:x.convertPercentagedCoordinatesToStage(r.coordinates,c,y),labelIds:[...e],status:t};le(n)}})}),Z&&L("div",{style:{position:"absolute",left:ue.x,top:ue.y,transform:"translate(-50%, -50%)",textAlign:"center",color:"white"},children:[p(Je,{icon:Qe,size:"5x",style:{marginBottom:15}}),p("h2",{children:"Marked as Junk"})]}),L("svg",{width:"100%",height:"100%",onKeyDown:Re,onKeyUp:Ve,onMouseMove:e=>de(e.movementX,e.movementY),tabIndex:0,children:[L("g",{transform:`scale(${d}) translate(${H.x}, ${H.y})`,onMouseOver:Le,onMouseLeave:Be,onMouseUp:We,onWheel:Ke,onMouseMove:e=>de(e.movementX,e.movementY),onClick:()=>{v(void 0)},children:[p("image",{onContextMenu:e=>e.preventDefault(),onMouseDown:e=>Pe(e),href:Q,ref:g,width:y.x>0?y.x:void 0,height:y.y>0?y.y:void 0}),ze()]}),G&&Ue(),Z&&p("rect",{x:"0",y:"0",width:u.x,height:u.y,style:{opacity:.8},onContextMenu:e=>e.preventDefault(),onClick:()=>{$(void 0)}})]})]})};export{Ct as default};