author laoluo
  import React , { useEffect , useRef , useImperativeHandle , useState } from 'react' ; import { ViewOperation , ImgUtils } from '@labelbee/lb-annotation' ; import { Spin } from 'antd/es' ; interface IProps { src : string ; size : { width : number ; height : number ; } ; style : { color ? : string ; fill ? : string ; thickness ? : number ; } ; annotations : any [ ] ; zoomChange ? : ( zoom : number ) => void ; backgroundStyle : React . CSSProperties ; onChange ? : ( type : 'hover' | 'selected' , ids : string [ ] ) => void ; showLoading ? : boolean ; } const DEFAULT_SIZE = { width : 1280 , height : 720 , } ; const AnnotationView = ( props , ref ) => { const { size = DEFAULT_SIZE , src , annotations = [ ] , style = { stroke : 'blue' , thickness : 3 , } , zoomChange , backgroundStyle = { } , onChange , showLoading = false , } = props ; const [ loading , setLoading ] = useState ( false ) ; const annotationRef = useRef < HTMLDivElement > ( null ) ; const viewOperation = useRef < ViewOperation > ( ) ; useImperativeHandle ( ref , ( ) => { const toolInstance = viewOperation . current ; if ( ! toolInstance ) { return { } ; } return { zoomIn : ( ) => toolInstance . zoomChanged ( true ) , zoomOut : ( ) => toolInstance . zoomChanged ( false ) , initImgPos : ( ) => toolInstance . initImgPos ( ) , toolInstance , } ; } , [ viewOperation . current ] ) ; useEffect ( ( ) => { if ( annotationRef . current ) { viewOperation . current = new ViewOperation ( { container : annotationRef . current , size , style , annotations , config : '{}' , } ) ; viewOperation . current . init ( ) ; } return ( ) => { viewOperation . current ?. destroy ( ) ; } ; } , [ ] ) ; useEffect ( ( ) => { if ( viewOperation . current ) { setLoading ( true ) ; viewOperation . current ?. setLoading ( true ) ; ImgUtils . load ( src ) . then ( ( imgNode ) => { viewOperation . current ?. setLoading ( false ) ; setLoading ( false ) ; viewOperation . current ?. setImgNode ( imgNode ) ; } ) . catch ( ( ) => { viewOperation . current ?. setLoading ( false ) ; setLoading ( false ) ; } ) ; } } , [ src ] ) ; /**
     * 基础数据绘制监听
     */ useEffect ( ( ) => { if ( viewOperation . current ) { viewOperation . current . updateData ( annotations ) ; } } , [ annotations ] ) ; /** 窗口大小监听 */ useEffect ( ( ) => { const toolInstance = viewOperation . current ; if ( toolInstance ?. setSize ) { toolInstance . setSize ( size ) ; } } , [ size ?. width , size ?. height ] ) ; useEffect ( ( ) => { if ( viewOperation . current ) { viewOperation . current ?. on ( 'onChange' , ( ... args ) => { onChange ?. apply ( null , args ) ; } ) ; viewOperation . current ?. on ( 'renderZoom' , ( zoom ) => { if ( zoomChange ) { zoomChange ( zoom ) ; } } ) ; } return ( ) => { viewOperation . current ?. unbindAll ( 'onChange' ) ; viewOperation . current ?. unbindAll ( 'renderZoom' ) ; } ; } , [ zoomChange , onChange ] ) ; const mainRender = ( < div ref = { annotationRef } style = { { position : 'relative' , ... size , ... backgroundStyle } } />); return ( < Spin spinning = { showLoading || loading } delay = { 300 } > { mainRender } < /Spin>); } ; export default React . forwardRef ( AnnotationView ) ;