import { Node } from './Node' ; import { RevasCanvas } from './Canvas' ; export function noop ( ) { } export const EMPTY_OBJECT = Object . freeze ( { } ) ; export const EMPTY_ARRAY = Object . freeze ( [ ] ) as any ; export function flatten ( array ) { const flattend = [ ] ; ( function flat ( array ) { array . forEach ( function ( el ) { if ( Array . isArray ( el ) ) { flat ( el ) ; } else { flattend . push ( el ) ; } } ) ; } ) ( array ) ; return flattend ; } export const now = typeof performance === 'object' && typeof performance . now === 'function' ? ( ) => performance . now ( ) : ( ) => Date . now ( ) ; function observeAnimatedValue ( value , observer ? , defaultValue ? ) { if ( value === undefined ) { return defaultValue ! ; } if ( value && value . getValue ) { return value . getValue ( observer ) ; } return value ; } export function applyAnimated ( style , callback ? ) { if ( style . animated ) { for ( const key in style ) { style [ key ] = observeAnimatedValue ( style [ key ] , callback ) ; } } return style ; } export function getMergedStyleFromNode ( node , callback ? ) { const { props : { style = EMPTY_ARRAY } , } = node ; return applyAnimated ( Object . assign ( { } , ... flatten ( [ style ] ) ) , callback ) ; } export function getFrameFromNode ( node ) { const { frame } = node ; return frame ; } export function sortByZIndexAscending ( a , b ) { const styleA = getMergedStyleFromNode ( a ) ; const styleB = getMergedStyleFromNode ( b ) ; return ( styleA . zIndex || 0 ) - ( styleB . zIndex || 0 ) ; } export function clamp ( n , min , max ) { return Math . min ( Math . max ( n , min ) , max ) ; } const ASTRAL_RANGE = /\ud83c[\udffb-\udfff](?=\ud83c[\udffb-\udfff])|(?:[^\ud800-\udfff][\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]?|[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/g ; const WORD_RANGE = /\w+|\ud83c[\udffb-\udfff](?=\ud83c[\udffb-\udfff])|(?:[^\ud800-\udfff][\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]?|[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/g ; export function getChars ( str ) { return str . match ( ASTRAL_RANGE ) || EMPTY_ARRAY ; } export function getWords ( str ) { return str . match ( WORD_RANGE ) || EMPTY_ARRAY ; } export function setShadow ( canvas , color , x = 0 , y = 0 , blur = 0 ) { if ( color && ( x || y || blur ) ) { const { context : ctx } = canvas ; const { shadowBlur , shadowColor , shadowOffsetX , shadowOffsetY } = ctx ; ctx . shadowBlur = blur ; ctx . shadowColor = color ; ctx . shadowOffsetX = x ; ctx . shadowOffsetY = y ; return function resetShadow ( ) { ctx . shadowBlur = shadowBlur ; ctx . shadowColor = shadowColor ; ctx . shadowOffsetX = shadowOffsetX ; ctx . shadowOffsetY = shadowOffsetY ; } ; } return noop ; } export function pushOpacity ( canvas , opacity ) { if ( opacity !== null && opacity < 1 && opacity >= 0 ) { const cachedOpacity = canvas . context . globalAlpha || 1 ; canvas . context . globalAlpha = cachedOpacity * opacity ; return function popOpacity ( ) { canvas . context . globalAlpha = cachedOpacity ; } ; } return noop ; } export type RevasAdapter = { createImage : ( ) => HTMLImageElement ; createOffscreenCanvas ? : ( width : number , height : number ) => RevasCanvas ; resetOffscreenCanvas ? : ( ctx : RevasCanvas , width : number , height : number ) => RevasCanvas ; } ; export const adapter = { createImage : ( ) => new Image ( ) , } ;