import { IComplete , IWriter } from 'src/cnchar-types/plugin/draw' ; import { IDrawOption } from 'src/cnchar-types/plugin/draw/common' ; import HanziWriter from 'src/cnchar-types/plugin/draw/hanzi-writer' ; const DRAW_MODE = { INITIAL : 0 , ANIMATION : 1 , STROKE : 2 , } ; export class AnimationWriter { writer : IWriter ; currentCharIndex : number ; currentStrokeIndex : number ; drawMode : number ; isPaused : boolean ; option : IDrawOption ; writers : Array < HanziWriter > ; strokeDrawLocked : boolean ; constructor ( writer ) { this . writer = writer ; this . option = writer . option ; this . writers = writer . writers ; this . isPaused = false ; this . drawMode = DRAW_MODE . INITIAL ; this . currentCharIndex = 0 ; this . currentStrokeIndex = 0 ; this . strokeDrawLocked = false ; } private _getCurrentCharStrokeNumber ( ) { return this . writers [ this . currentCharIndex ] . V . strokes . length ; } private _isStepMode ( ) { return this . option . stepByStep ; } private _animate ( complete = ( ) => { } ) { if ( this . _isStepMode ( ) ) { if ( this . option . showCharacter === false ) { this . writers . forEach ( writer => { writer . hideCharacter ( ) ; } ) ; } this . _animateStep ( 0 , complete ) ; } else { let index = 0 ; for ( let i = 0 ; i < this . writers . length ; i ++ ) { this . _animateSingle ( i , ( ) => { index ++ ; if ( index === this . writers . length ) { complete ( ) ; } } ) ; } } } drawNextStroke ( onComplete ) { if ( this . drawMode === DRAW_MODE . ANIMATION ) { console . warn ( '当前为自动绘制模式' ) ; return false ; } else if ( this . drawMode === DRAW_MODE . INITIAL ) { this . drawMode = DRAW_MODE . STROKE ; } if ( this . strokeDrawLocked ) { console . warn ( '请等待上一步绘制完成' ) ; return false ; } this . strokeDrawLocked = true ; if ( this . currentCharIndex === 0 && this . currentStrokeIndex === 0 ) { this . writers . forEach ( writer => { writer . hideCharacter ( ) ; } ) ; } this . writers [ this . currentCharIndex ] . animateStroke ( this . currentStrokeIndex , { onComplete : ( ) => { onComplete ( ) ; this . strokeDrawLocked = false ; } } ) ; const thisCharStrokeNumber = this . _getCurrentCharStrokeNumber ( ) ; if ( this . currentStrokeIndex >= thisCharStrokeNumber - 1 ) { this . currentStrokeIndex = 0 ; this . currentCharIndex ++ ; if ( this . currentCharIndex === this . writer . text . length ) { this . currentCharIndex = 0 ; } } else { this . currentStrokeIndex ++ ; } return true ; } start ( ) { if ( this . drawMode !== DRAW_MODE . INITIAL ) { console . warn ( '当前为手动绘制模式' ) ; return false ; } this . drawMode = DRAW_MODE . ANIMATION ; if ( this . option . loopAnimate ) { this . _loop ( ) ; } else { this . _animate ( this . option . animateComplete ) ; } return true ; } pause ( ) { if ( this . isPaused || ! this . _isStepMode ( ) ) return ; this . isPaused = true ; this . writers [ this . currentCharIndex ] . pauseAnimation ( ) ; } resume ( ) { if ( ! this . isPaused || ! this . _isStepMode ( ) ) return ; this . isPaused = false ; this . writers [ this . currentCharIndex ] . resumeAnimation ( ) ; } private _loop ( ) { const opt = this . option ; this . _animate ( ( ) => { if ( opt . animateComplete ) opt . animateComplete ( ) ; setTimeout ( ( ) => { this . _loop ( ) ; } , opt . delayBetweenStrokes ) ; } ) ; } private _animateSingle ( index , complete ) { if ( index >= this . writers . length ) { complete ( true ) ; return ; } this . writers [ index ] . animateCharacter ( { onComplete : ( ) => { complete ( false ) ; } } ) ; } private _animateStep ( index , complete = ( ) => { } ) { this . currentCharIndex = index ; this . _animateSingle ( index , ( end ) => { if ( ! end ) { setTimeout ( ( ) => { this . _animateStep ( index + 1 , complete ) ; } , this . option . delayBetweenStrokes ) ; } else { complete ( ) ; } } ) ; } }