import { MiBrushAttrs , MiBrushRepaintConfig , MiTools , MiToolsSyncData , Tools } from '@components/canvas/Tools' ; import { Canvas } from '@components/canvas/Canvas' ; import { MiPointGroup , Point } from '@components/canvas/Point' ; import { Utils } from '@components/canvas/Utils' ; import { MiRectConfig } from '@components/canvas/shapes/Rect' ; export class Marker extends Tools implements MiTools { name = 'marker' ; divisor = 4 ; protected data : MiPointGroup [ ] = [ ] ; param canvas constructor ( canvas ) { super ( canvas ) ; Tools . instances [ this . name ] = this ; } param args draw < A extends MiToolsSyncData [ ] > ( ... args ) { const data = args [ 0 ] as MiToolsSyncData ; this . rendering ( data . points , data . attrs , true , data . config ) ; } param points param attrs param repaint param config protected rendering ( points ? , attrs ? , repaint ? , config ? ) { points = points ?? this . getLastPoints ( this . data ) ; const ctx = config ?. ctx ?? this . getCurrentContext ( ) ; this . resetCtxAttrs ( ctx , attrs , this . divisor ) ; /** 临时属性(避免被覆盖) */ const tempPoints = Utils . deepCopy ( points ) as Point [ ] , tempRect = ( { ... config ?. rect } ?? { } ) as MiRectConfig ; ctx . save ( ) ; if ( config ) { /** 无限画布 */ if ( config . origin ) ctx . translate ( config . origin . x , config . origin . y ) ; /** 移动 */ if ( config . move ) { const isMoving = config . move . x !== 0 || config . move . y !== 0 ; if ( isMoving ) { this . moving ( tempPoints , config . move ) ; tempRect . x += config . move . x ; tempRect . y += config . move . y ; } } } /** 绘制选中框(重绘过程中...) */ if ( config ?. selection ) this . drawChoiceRect ( ctx , tempRect , config ) ; else this . drawCurve ( tempPoints , ctx ) ; ctx . restore ( ) ; } param points param ctx protected drawCurve ( points , ctx ? ) { ctx = ctx ?? this . getBufferContext ( ) ; ctx . beginPath ( ) ; let p1 = points [ 0 ] , p2 = points [ 1 ] ; for ( let i = 1 , len = points . length ; i < len ; i ++ ) { const midPoint = this . getMidPoint ( p1 , p2 ) ; ctx . quadraticCurveTo ( p1 . x , p1 . y , midPoint . x , midPoint . y ) ; p1 = points [ i ] ; p2 = points [ i + 1 ] ; } ctx . lineTo ( p1 . x , p1 . y ) ; ctx . stroke ( ) ; ctx . closePath ( ) ; } param event protected drawBegin ( event ) { this . data . push ( this . createPointGroup ( ) ) ; this . buffer = this . createBuffer ( this . getThickness ( this . divisor ) ) ; this . drawUpdate ( event ) ; } param event protected drawUpdate ( event ) { const point = this . createPoint ( event . clientX , event . clientY ) , lastPoints = this . getLastPoints ( this . data ) , lastPointsLen = lastPoints . length , lastPoint = lastPointsLen > 0 && lastPoints [ lastPointsLen - 1 ] , isPointsTooClose = lastPoint ? point . distance ( lastPoint ) <= Tools . distance : false ; if ( ! lastPoint || ! ( lastPoint && isPointsTooClose ) ) { lastPoints . push ( point ) ; this . drawCurve ( lastPoints ) ; } } param event protected drawEnd ( event ) { this . resetBuffer ( ( ) => { /** 渲染 */ this . rendering ( ) ; const data = Utils . deepCopy ( this . data ) , points = this . getLastPoints ( data ) ; /** 记录用于选择判断的方形并存储 */ this . drawRectWorker ( points , ( rect ) => { const params = { ... this . getDefaultSyncData ( ) , attrs : { ... this . getCtxAttrs ( ) } , points , rect , tool : this . name } as MiToolsSyncData ; this . saveLayerData ( params ) ; Tools . setTraces ( ) ; } ) ; } ) ; } }