import { CanvasGradient } from '@tarojs/api' ; interface IAction { func : ( ... arr : any [ ] ) => void ; args : any [ ] ; } const TextBaseLineMap = { top : 'top' , bottom : 'bottom' , middle : 'middle' , normal : 'alphabetic' } ; export class CanvasContext implements Taro . CanvasContext { __raw__ : CanvasRenderingContext2D ; actions : IAction [ ] = [ ] ; constructor ( canvas , ctx ) { this . canvas = canvas ; this . ctx = ctx ; } set ctx ( e ) { this . __raw__ = e ; } get ctx ( ) { return this . __raw__ || { } ; } canvas : HTMLCanvasElement ; protected emptyActions ( ) { this . actions . length = 0 ; } protected enqueueActions ( func , ... args ) { this . actions . push ( { func , args } ) ; } set fillStyle ( e ) { this . enqueueActions ( ( ) => { this . ctx . fillStyle = e ; } ) ; } get fillStyle ( ) { return this . ctx . fillStyle as string ; } set font ( e ) { this . ctx . font = e ; } get font ( ) { return this . ctx . font ; } set globalAlpha ( e ) { this . enqueueActions ( ( ) => { this . ctx . globalAlpha = e ; } ) ; } get globalAlpha ( ) { return this . ctx . globalAlpha ; } set globalCompositeOperation ( e ) { this . enqueueActions ( ( ) => { this . ctx . globalCompositeOperation = e ; } ) ; } get globalCompositeOperation ( ) { return this . ctx . globalCompositeOperation ; } set lineCap ( e ) { this . enqueueActions ( ( ) => { this . ctx . lineCap = e ; } ) ; } get lineCap ( ) { return this . ctx . lineCap ; } set lineDashOffset ( e ) { this . enqueueActions ( ( ) => { this . ctx . lineDashOffset = e ; } ) ; } get lineDashOffset ( ) { return this . ctx . lineDashOffset ; } set lineJoin ( e ) { this . enqueueActions ( ( ) => { this . ctx . lineJoin = e ; } ) ; } get lineJoin ( ) { return this . ctx . lineJoin ; } set lineWidth ( e ) { this . enqueueActions ( ( ) => { this . ctx . lineWidth = e ; } ) ; } get lineWidth ( ) { return this . ctx . lineWidth ; } set miterLimit ( e ) { this . enqueueActions ( ( ) => { this . ctx . miterLimit = e ; } ) ; } get miterLimit ( ) { return this . ctx . miterLimit ; } set shadowBlur ( e ) { this . enqueueActions ( ( ) => { this . ctx . shadowBlur = e ; } ) ; } get shadowBlur ( ) { return this . ctx . shadowBlur ; } set shadowColor ( e ) { this . enqueueActions ( ( ) => { this . ctx . shadowColor = e ; } ) ; } get shadowColor ( ) { return this . ctx . shadowColor ; } set shadowOffsetX ( e ) { this . enqueueActions ( ( ) => { this . ctx . shadowOffsetX = e ; } ) ; } get shadowOffsetX ( ) { return this . ctx . shadowOffsetX ; } set shadowOffsetY ( e ) { this . enqueueActions ( ( ) => { this . ctx . shadowOffsetY = e ; } ) ; } get shadowOffsetY ( ) { return this . ctx . shadowOffsetY ; } set strokeStyle ( e ) { this . enqueueActions ( ( ) => { this . ctx . strokeStyle = e ; } ) ; } get strokeStyle ( ) { return this . ctx . strokeStyle as string ; } /** 小程序文档中不包括 ↓↓↓ */ set textAlign ( e ) { this . ctx . textAlign = e ; } get textAlign ( ) { return this . ctx . textAlign ; } set textBaseline ( e ) { this . ctx . textBaseline = e ; } get textBaseline ( ) { return this . ctx . textBaseline ; } set direction ( e ) { this . ctx . direction = e ; } get direction ( ) { return this . ctx . direction ; } set imageSmoothingEnabled ( e ) { this . enqueueActions ( ( ) => { this . ctx . imageSmoothingEnabled = e ; } ) ; } get imageSmoothingEnabled ( ) { return this . ctx . imageSmoothingEnabled ; } set imageSmoothingQuality ( e ) { this . enqueueActions ( ( ) => { this . ctx . imageSmoothingQuality = e ; } ) ; } get imageSmoothingQuality ( ) { return this . ctx . imageSmoothingQuality ; } set filter ( e ) { this . enqueueActions ( ( ) => { this . ctx . filter = e ; } ) ; } get filter ( ) { return this . ctx . filter ; } /** 小程序文档中不包括 ↑↑↑ */ arc ( ... args ) { return this . enqueueActions ( this . ctx . arc , ... args ) ; } arcTo ( ... args ) { return this . enqueueActions ( this . ctx . arcTo , ... args ) ; } beginPath ( ... args ) { return this . enqueueActions ( this . ctx . beginPath , ... args ) ; } bezierCurveTo ( ... args ) { return this . enqueueActions ( this . ctx . bezierCurveTo , ... args ) ; } clearRect ( ... args ) { return this . enqueueActions ( this . ctx . clearRect , ... args ) ; } clip ( ... args ) { return this . enqueueActions ( this . ctx . clip , ... args ) ; } closePath ( ... args ) { return this . enqueueActions ( this . ctx . closePath , ... args ) ; } createPattern ( image , repetition ) { return this . createPattern ( image , repetition ) ; } todo async draw ( reserve ? , callback ? ) { try { if ( ! reserve ) { this . ctx . clearRect ( 0 , 0 , this . canvas . width , this . canvas . height ) ; } for ( const { func , args } of this . actions ) { await func . apply ( this . ctx , args ) ; } this . emptyActions ( ) ; callback && callback ( ) ; } catch ( e ) { throw { errMsg : e . message } ; } } drawImage ( imageResource , ... extra ) { type TExtra = [ number , number ] ; this . enqueueActions ( ( ) => { if ( typeof imageResource === 'string' ) { const img = new Image ( ) ; img . src = imageResource ; return new Promise < void > ( ( resolve , reject ) => { img . onload = ( ) => { this . ctx . drawImage ( img , ... extra as TExtra ) ; resolve ( ) ; } ; img . onerror = reject ; } ) ; } this . ctx . drawImage ( imageResource , ... extra as TExtra ) ; } ) ; } fill ( ... args ) { return this . enqueueActions ( this . ctx . fill , ... args ) ; } fillRect ( ... args ) { return this . enqueueActions ( this . ctx . fillRect , ... args ) ; } fillText ( ... args ) { return this . enqueueActions ( this . ctx . fillText , ... args ) ; } lineTo ( ... args ) { return this . enqueueActions ( this . ctx . lineTo , ... args ) ; } moveTo ( ... args ) { return this . enqueueActions ( this . ctx . moveTo , ... args ) ; } quadraticCurveTo ( ... args ) { return this . enqueueActions ( this . ctx . quadraticCurveTo , ... args ) ; } rect ( ... args ) { return this . enqueueActions ( this . ctx . rect , ... args ) ; } restore ( ... args ) { return this . enqueueActions ( this . ctx . restore , ... args ) ; } rotate ( ... args ) { return this . enqueueActions ( this . ctx . rotate , ... args ) ; } save ( ... args ) { return this . enqueueActions ( this . ctx . save , ... args ) ; } scale ( ... args ) { return this . enqueueActions ( this . ctx . scale , ... args ) ; } setFillStyle ( color ) { this . enqueueActions ( ( ) => { this . ctx . fillStyle = color ; } ) ; } setFontSize ( fontSize ) { this . font = `${ fontSize }px` ; } setGlobalAlpha ( alpha ) { this . globalAlpha = alpha ; } setLineCap ( lineCap ) { this . lineCap = lineCap ; } setLineDash ( pattern , offset ) { this . enqueueActions ( ( ) => { this . ctx . setLineDash ( pattern ) ; this . ctx . lineDashOffset = offset ; } ) ; } setLineJoin ( lineJoin ) { this . lineJoin = lineJoin ; } setLineWidth ( lineWidth ) { this . lineWidth = lineWidth ; } setMiterLimit ( miterLimit ) { this . miterLimit = miterLimit ; } setShadow ( offsetX , offsetY , blur , color ) { this . enqueueActions ( ( ) => { this . ctx . shadowOffsetX = offsetX ; this . ctx . shadowOffsetY = offsetY ; this . ctx . shadowColor = color ; this . ctx . shadowBlur = blur ; } ) ; } setStrokeStyle ( color ) { this . enqueueActions ( ( ) => { this . ctx . strokeStyle = color ; } ) ; } setTextAlign ( align ) { this . textAlign = align ; } setTextBaseline ( textBaseline ) { this . textBaseline = TextBaseLineMap [ textBaseline ] || 'alphabetic' ; } setTransform ( ... args ) { return this . enqueueActions ( this . ctx . setTransform , ... args ) ; } stroke ( ... args ) { return this . enqueueActions ( this . ctx . stroke , ... args ) ; } strokeRect ( ... args ) { return this . enqueueActions ( this . ctx . strokeRect , ... args ) ; } strokeText ( ... args ) { return this . enqueueActions ( this . ctx . strokeText , ... args ) ; } transform ( ... args ) { return this . enqueueActions ( this . ctx . transform , ... args ) ; } translate ( ... args ) { return this . enqueueActions ( this . ctx . translate , ... args ) ; } measureText ( text ) { return this . measureText ( text ) ; } createCircularGradient ( x , y , r ) { const radialGradient = this . ctx . createRadialGradient ( x , y , 0 , x , y , r ) ; return radialGradient ; } createLinearGradient ( x0 , y0 , x1 , y1 ) { return this . createLinearGradient ( x0 , y0 , x1 , y1 ) ; } }