import { SyncEvent } from '../../event/SyncEvent' ; import { getMarkerByType } from '../../markers/types' ; import { TextMarker } from '../../markers/TextMarker/index' ; import { ToolbarItem } from '../../toolbar/ToolbarItem' ; import { createDivWithClassName } from '../../utils/dom' ; import { uuid } from '../../utils/uuid' ; import { AbstractWhiteboard } from '../AbstractWhiteboard/index' ; import { WhitepageSnap } from '../AbstractWhiteboard/snap' ; import { Drawboard } from './../../drawboard/Drawboard/index' ; import { Mode , Source } from './../../utils/types' ; import './index.css' ; const prefix = 'fcw-page' ; /** 白板中的每一页 */ export class WhitePage { id : string = uuid ( ) ; source : Source ; target : HTMLImageElement ; /** UI Options */ container : HTMLDivElement ; parentContainer ? : HTMLDivElement ; mode : Mode = 'master' ; /** Handlers */ drawboard : Drawboard ; whiteboard ? : AbstractWhiteboard ; mountContainer : HTMLElement ; constructor ( source , { mode , whiteboard , parentContainer , extraToolbarItems , } = { } ) { if ( mode ) { this . mode = mode ; } this . parentContainer = parentContainer ; this . whiteboard = whiteboard ; this . initSource ( source ) ; if ( this . mode === 'master' ) { this . initMaster ( extraToolbarItems ) ; } if ( this . mode === 'mirror' ) { this . initMirror ( ) ; } if ( whiteboard ) { this . mountContainer = whiteboard . drawboardMountPoint === 'body' ? document . body : this . whiteboard ! . target ; } } /** LifeCycle open - destroy */ public open ( ) { this . drawboard . open ( ) ; } public hide ( ) { this . drawboard . hide ( ) ; } public show ( ) { this . drawboard . show ( ) ; } public destroy ( ) { this . drawboard . destroy ( ) ; } /** 生成快照 */ public captureSnap ( ) { const markerSnaps = this . drawboard . markers . map ( m => m . captureSnap ( ) ) ; return { id : this . id , markers : markerSnaps , } ; } /** 应用快照 */ public applySnap ( snap ) { const markerIdsSet = new Set ( ) ; snap . markers . forEach ( markerSnap => { const marker = this . drawboard . markerMap [ markerSnap . id ] ; markerIdsSet . add ( markerSnap . id ) ; if ( marker ) { marker . applySnap ( markerSnap ) ; } else { const newMarker = this . drawboard . addMarker ( getMarkerByType ( markerSnap . type ) , { id : markerSnap . id , } ) ; newMarker . applySnap ( markerSnap ) ; } } ) ; this . drawboard . markers . forEach ( marker => { if ( ! markerIdsSet . has ( marker . id ) ) { this . drawboard . deleteMarkerWithEvent ( marker ) ; } } ) ; } /** 初始化源 */ private initSource ( source ) { if ( typeof source . imgSrc === 'string' && ! this . parentContainer ) { throw new Error ( 'Invalid source, If you set image url, you must also set parentContainer' ) ; } this . source = source ; if ( source . imgEle ) { this . target = source . imgEle ! ; } if ( typeof source . imgSrc === 'string' ) { this . container = createDivWithClassName ( prefix , this . parentContainer ! ) ; this . container . id = this . id ; this . target = document . createElement ( 'img' ) ; this . target . src = source . imgSrc ; this . target . alt = 'Siema image' ; this . container . appendChild ( this . target ) ; } } /** 以 Master 模式启动 */ protected initMaster ( extraToolbarItems ? ) { if ( this . whiteboard ) { this . drawboard = new Drawboard ( { imgEle : this . target } , { extraToolbarItems , mountContainer : this . mountContainer , page : this , onChange : ev => this . whiteboard ! . emit ( ev ) , } ) ; } else { this . drawboard = new Drawboard ( { imgEle : this . target } , { page : this , mountContainer : this . mountContainer } ) ; } } /** 以 Mirror 模式启动 */ protected initMirror ( ) { if ( ! this . whiteboard ) { throw new Error ( 'Invalid whiteboard' ) ; } this . drawboard = new Drawboard ( { imgEle : this . target } , { page : this , mountContainer : this . mountContainer } ) ; this . whiteboard ! . eventHub ! . on ( 'sync' , ( ev ) => { try { if ( ev . target === 'page' && ev . id === this . id ) { this . onPageSync ( ) ; } if ( ev . target === 'marker' ) { this . onMarkerSync ( ev ) ; } } catch ( e ) { console . warn ( e ) ; } } ) ; } /** 处理 Page 的同步事件 */ private onPageSync ( ) { } /** 处理 Marker 的同步事件 */ private onMarkerSync ( ev ) { if ( ! ev . marker ) { return ; } const id = ev . id ; if ( ev . event === 'addMarker' && ev . parentId === this . id ) { const marker = this . drawboard . markerMap [ id ! ] ; if ( ! marker ) { this . drawboard . addMarker ( getMarkerByType ( ev . marker . type ! ) , { id : ev . marker . id , originX : ev . marker . dx , originY : ev . marker . dy , } ) ; } } if ( ! id ) { return ; } if ( ev . event === 'removeMarker' ) { const marker = this . drawboard . markerMap [ id ] ; if ( marker ) { this . drawboard . deleteMarker ( marker ) ; } } if ( ev . event === 'moveMarker' || ev . event === 'resizeMarker' ) { const marker = this . drawboard . markerMap [ id ] ; if ( marker ) { marker . reactToManipulation ( ev . event , ev . marker ) ; } } if ( ev . event === 'inputMarker' ) { const marker = this . drawboard . markerMap [ id ] as TextMarker ; if ( marker ) { marker . setText ( ev . marker . text ! ) ; } } } }