import { extend } from 'lodash' ; const TRACE = null ; export class Trace { private imageData : ImageData ; private options = { active : true , level : 128 , } ; constructor ( imageData ) { this . imageData = imageData ; this . isEnabled ( ) ; } static isEnabled ( ) { return ! ! TRACE ; } isEnabled ( ) { return ! ! TRACE ; } update ( opt ? ) { this . options = extend ( this . options , opt ) ; if ( this . isEnabled ( ) && this . options . active ) { const length = this . imageData . data . length ; for ( let i = 0 ; i < length ; i += 4 ) { if ( this . imageData . data [ i + 3 ] !== 255 ) { this . imageData . data [ i ] = 255 ; this . imageData . data [ i + 1 ] = 255 ; this . imageData . data [ i + 2 ] = 255 ; this . imageData . data [ i + 3 ] = 255 ; } } const canvas = document . createElement ( 'canvas' ) ; canvas . width = this . imageData . width ; canvas . height = this . imageData . height ; const ctx = canvas . getContext ( '2d' ) ; ctx . imageSmoothingEnabled = false ; ctx . putImageData ( this . imageData , 0 , 0 ) ; const trace = TRACE . traceCanvas ( canvas , { turdsize : Math . floor ( this . options . level / 2.55 ) , } ) ; const svg = TRACE . getSVG ( trace , 1.0 ) ; ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ; ctx . fillStyle = '#000' ; const getMatches = ( string , regex , index = 1 ) => { const matches = [ ] ; let match ; while ( match = regex . exec ( string ) ) { matches . push ( match [ index ] ) ; } return matches ; } ; const paths = getMatches ( svg , /.*?path[^\/]+d="(.*?)"/ig , 1 ) ; paths . forEach ( ( pathData ) => { ctx . fill ( new Path2D ( pathData ) ) ; } ) ; this . imageData = ctx . getImageData ( 0 , 0 , canvas . width , canvas . height ) ; } return this . imageData ; } }