pts.js 219 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439
  1. /*!
  2. * pts.js 0.10.5 - Copyright © 2017-2021 William Ngan and contributors.
  3. * Licensed under Apache 2.0 License.
  4. * See https://github.com/williamngan/pts for details.
  5. */
  6. (function webpackUniversalModuleDefinition(root, factory) {
  7. if(typeof exports === 'object' && typeof module === 'object')
  8. module.exports = factory();
  9. else if(typeof define === 'function' && define.amd)
  10. define([], factory);
  11. else if(typeof exports === 'object')
  12. exports["Pts"] = factory();
  13. else
  14. root["Pts"] = factory();
  15. })(this, function() {
  16. return /******/ (function(modules) { // webpackBootstrap
  17. /******/ // The module cache
  18. /******/ var installedModules = {};
  19. /******/
  20. /******/ // The require function
  21. /******/ function __webpack_require__(moduleId) {
  22. /******/
  23. /******/ // Check if module is in cache
  24. /******/ if(installedModules[moduleId]) {
  25. /******/ return installedModules[moduleId].exports;
  26. /******/ }
  27. /******/ // Create a new module (and put it into the cache)
  28. /******/ var module = installedModules[moduleId] = {
  29. /******/ i: moduleId,
  30. /******/ l: false,
  31. /******/ exports: {}
  32. /******/ };
  33. /******/
  34. /******/ // Execute the module function
  35. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  36. /******/
  37. /******/ // Flag the module as loaded
  38. /******/ module.l = true;
  39. /******/
  40. /******/ // Return the exports of the module
  41. /******/ return module.exports;
  42. /******/ }
  43. /******/
  44. /******/
  45. /******/ // expose the modules object (__webpack_modules__)
  46. /******/ __webpack_require__.m = modules;
  47. /******/
  48. /******/ // expose the module cache
  49. /******/ __webpack_require__.c = installedModules;
  50. /******/
  51. /******/ // define getter function for harmony exports
  52. /******/ __webpack_require__.d = function(exports, name, getter) {
  53. /******/ if(!__webpack_require__.o(exports, name)) {
  54. /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
  55. /******/ }
  56. /******/ };
  57. /******/
  58. /******/ // define __esModule on exports
  59. /******/ __webpack_require__.r = function(exports) {
  60. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  61. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  62. /******/ }
  63. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  64. /******/ };
  65. /******/
  66. /******/ // create a fake namespace object
  67. /******/ // mode & 1: value is a module id, require it
  68. /******/ // mode & 2: merge all properties of value into the ns
  69. /******/ // mode & 4: return value when already ns object
  70. /******/ // mode & 8|1: behave like require
  71. /******/ __webpack_require__.t = function(value, mode) {
  72. /******/ if(mode & 1) value = __webpack_require__(value);
  73. /******/ if(mode & 8) return value;
  74. /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  75. /******/ var ns = Object.create(null);
  76. /******/ __webpack_require__.r(ns);
  77. /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  78. /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  79. /******/ return ns;
  80. /******/ };
  81. /******/
  82. /******/ // getDefaultExport function for compatibility with non-harmony modules
  83. /******/ __webpack_require__.n = function(module) {
  84. /******/ var getter = module && module.__esModule ?
  85. /******/ function getDefault() { return module['default']; } :
  86. /******/ function getModuleExports() { return module; };
  87. /******/ __webpack_require__.d(getter, 'a', getter);
  88. /******/ return getter;
  89. /******/ };
  90. /******/
  91. /******/ // Object.prototype.hasOwnProperty.call
  92. /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  93. /******/
  94. /******/ // __webpack_public_path__
  95. /******/ __webpack_require__.p = "";
  96. /******/
  97. /******/
  98. /******/ // Load entry module and return exports
  99. /******/ return __webpack_require__(__webpack_require__.s = "./src/_lib.ts");
  100. /******/ })
  101. /************************************************************************/
  102. /******/ ({
  103. /***/ "./src/Canvas.ts":
  104. /*!***********************!*\
  105. !*** ./src/Canvas.ts ***!
  106. \***********************/
  107. /*! no static exports found */
  108. /***/ (function(module, exports, __webpack_require__) {
  109. "use strict";
  110. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  111. Object.defineProperty(exports, "__esModule", { value: true });
  112. exports.CanvasForm = exports.CanvasSpace = void 0;
  113. const Space_1 = __webpack_require__(/*! ./Space */ "./src/Space.ts");
  114. const Form_1 = __webpack_require__(/*! ./Form */ "./src/Form.ts");
  115. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  116. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  117. const Typography_1 = __webpack_require__(/*! ./Typography */ "./src/Typography.ts");
  118. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  119. const Image_1 = __webpack_require__(/*! ./Image */ "./src/Image.ts");
  120. class CanvasSpace extends Space_1.MultiTouchSpace {
  121. constructor(elem, callback) {
  122. super();
  123. this._pixelScale = 1;
  124. this._autoResize = true;
  125. this._bgcolor = "#e1e9f0";
  126. this._offscreen = false;
  127. this._initialResize = false;
  128. var _selector = null;
  129. var _existed = false;
  130. this.id = "pt";
  131. if (elem instanceof Element) {
  132. _selector = elem;
  133. this.id = "pts_existing_space";
  134. }
  135. else {
  136. let id = elem;
  137. id = (elem[0] === "#" || elem[0] === ".") ? elem : "#" + elem;
  138. _selector = document.querySelector(id);
  139. _existed = true;
  140. this.id = id.substr(1);
  141. }
  142. if (!_selector) {
  143. this._container = this._createElement("div", this.id + "_container");
  144. this._canvas = this._createElement("canvas", this.id);
  145. this._container.appendChild(this._canvas);
  146. document.body.appendChild(this._container);
  147. _existed = false;
  148. }
  149. else if (_selector.nodeName.toLowerCase() != "canvas") {
  150. this._container = _selector;
  151. this._canvas = this._createElement("canvas", this.id + "_canvas");
  152. this._container.appendChild(this._canvas);
  153. this._initialResize = true;
  154. }
  155. else {
  156. this._canvas = _selector;
  157. this._container = _selector.parentElement;
  158. this._autoResize = false;
  159. }
  160. setTimeout(this._ready.bind(this, callback), 100);
  161. this._ctx = this._canvas.getContext('2d');
  162. }
  163. _createElement(elem = "div", id) {
  164. let d = document.createElement(elem);
  165. d.setAttribute("id", id);
  166. return d;
  167. }
  168. _ready(callback) {
  169. if (!this._container)
  170. throw new Error(`Cannot initiate #${this.id} element`);
  171. this._isReady = true;
  172. this._resizeHandler(null);
  173. this.clear(this._bgcolor);
  174. this._canvas.dispatchEvent(new Event("ready"));
  175. for (let k in this.players) {
  176. if (this.players.hasOwnProperty(k)) {
  177. if (this.players[k].start)
  178. this.players[k].start(this.bound.clone(), this);
  179. }
  180. }
  181. this._pointer = this.center;
  182. this._initialResize = false;
  183. if (callback)
  184. callback(this.bound, this._canvas);
  185. }
  186. setup(opt) {
  187. this._bgcolor = opt.bgcolor ? opt.bgcolor : "transparent";
  188. this.autoResize = (opt.resize != undefined) ? opt.resize : false;
  189. if (opt.retina !== false) {
  190. let r1 = window ? window.devicePixelRatio || 1 : 1;
  191. let r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1;
  192. this._pixelScale = Math.max(1, r1 / r2);
  193. }
  194. if (opt.offscreen) {
  195. this._offscreen = true;
  196. this._offCanvas = this._createElement("canvas", this.id + "_offscreen");
  197. this._offCtx = this._offCanvas.getContext('2d');
  198. }
  199. else {
  200. this._offscreen = false;
  201. }
  202. return this;
  203. }
  204. set autoResize(auto) {
  205. if (!window)
  206. return;
  207. this._autoResize = auto;
  208. if (auto) {
  209. window.addEventListener('resize', this._resizeHandler.bind(this));
  210. }
  211. else {
  212. window.removeEventListener('resize', this._resizeHandler.bind(this));
  213. }
  214. }
  215. get autoResize() { return this._autoResize; }
  216. resize(b, evt) {
  217. this.bound = b;
  218. this._canvas.width = this.bound.size.x * this._pixelScale;
  219. this._canvas.height = this.bound.size.y * this._pixelScale;
  220. this._canvas.style.width = Math.floor(this.bound.size.x) + "px";
  221. this._canvas.style.height = Math.floor(this.bound.size.y) + "px";
  222. if (this._offscreen) {
  223. this._offCanvas.width = this.bound.size.x * this._pixelScale;
  224. this._offCanvas.height = this.bound.size.y * this._pixelScale;
  225. }
  226. if (this._pixelScale != 1) {
  227. this._ctx.scale(this._pixelScale, this._pixelScale);
  228. if (this._offscreen) {
  229. this._offCtx.scale(this._pixelScale, this._pixelScale);
  230. }
  231. }
  232. for (let k in this.players) {
  233. if (this.players.hasOwnProperty(k)) {
  234. let p = this.players[k];
  235. if (p.resize)
  236. p.resize(this.bound, evt);
  237. }
  238. }
  239. this.render(this._ctx);
  240. if (evt && !this.isPlaying)
  241. this.playOnce(0);
  242. return this;
  243. }
  244. _resizeHandler(evt) {
  245. if (!window)
  246. return;
  247. let b = (this._autoResize || this._initialResize) ? this._container.getBoundingClientRect() : this._canvas.getBoundingClientRect();
  248. if (b) {
  249. let box = Pt_1.Bound.fromBoundingRect(b);
  250. box.center = box.center.add(window.pageXOffset, window.pageYOffset);
  251. this.resize(box, evt);
  252. }
  253. }
  254. set background(bg) { this._bgcolor = bg; }
  255. get background() { return this._bgcolor; }
  256. get pixelScale() {
  257. return this._pixelScale;
  258. }
  259. get hasOffscreen() {
  260. return this._offscreen;
  261. }
  262. get offscreenCtx() { return this._offCtx; }
  263. get offscreenCanvas() { return this._offCanvas; }
  264. getForm() { return new CanvasForm(this); }
  265. get element() {
  266. return this._canvas;
  267. }
  268. get parent() {
  269. return this._container;
  270. }
  271. get ready() {
  272. return this._isReady;
  273. }
  274. get ctx() { return this._ctx; }
  275. clear(bg) {
  276. if (bg)
  277. this._bgcolor = bg;
  278. const lastColor = this._ctx.fillStyle;
  279. if (!this._bgcolor || this._bgcolor === "transparent") {
  280. this._ctx.clearRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
  281. }
  282. else {
  283. if (this._bgcolor.indexOf("rgba") === 0 || (this._bgcolor.length === 9 && this._bgcolor.indexOf("#") === 0)) {
  284. this._ctx.clearRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
  285. }
  286. this._ctx.fillStyle = this._bgcolor;
  287. this._ctx.fillRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
  288. }
  289. this._ctx.fillStyle = lastColor;
  290. return this;
  291. }
  292. clearOffscreen(bg) {
  293. if (this._offscreen) {
  294. if (bg) {
  295. this._offCtx.fillStyle = bg;
  296. this._offCtx.fillRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
  297. }
  298. else {
  299. this._offCtx.clearRect(-1, -1, this._offCanvas.width + 1, this._offCanvas.height + 1);
  300. }
  301. }
  302. return this;
  303. }
  304. playItems(time) {
  305. if (this._isReady) {
  306. this._ctx.save();
  307. if (this._offscreen)
  308. this._offCtx.save();
  309. super.playItems(time);
  310. this._ctx.restore();
  311. if (this._offscreen)
  312. this._offCtx.restore();
  313. this.render(this._ctx);
  314. }
  315. }
  316. dispose() {
  317. if (!window)
  318. return;
  319. window.removeEventListener('resize', this._resizeHandler.bind(this));
  320. this.stop();
  321. this.removeAll();
  322. return this;
  323. }
  324. recorder(downloadOrCallback, filetype = "webm", bitrate = 15000000) {
  325. let stream = this._canvas.captureStream();
  326. const recorder = new MediaRecorder(stream, { mimeType: `video/${filetype}`, bitsPerSecond: bitrate });
  327. recorder.ondataavailable = function (d) {
  328. let url = URL.createObjectURL(new Blob([d.data], { type: `video/${filetype}` }));
  329. if (typeof downloadOrCallback === "function") {
  330. downloadOrCallback(url);
  331. }
  332. else if (downloadOrCallback) {
  333. let a = document.createElement("a");
  334. a.href = url;
  335. a.download = `canvas_video.${filetype}`;
  336. a.click();
  337. a.remove();
  338. }
  339. };
  340. return recorder;
  341. }
  342. }
  343. exports.CanvasSpace = CanvasSpace;
  344. class CanvasForm extends Form_1.VisualForm {
  345. constructor(space) {
  346. super();
  347. this._style = {
  348. fillStyle: "#f03", strokeStyle: "#fff",
  349. lineWidth: 1, lineJoin: "bevel", lineCap: "butt",
  350. globalAlpha: 1
  351. };
  352. const _setup = (ctx) => {
  353. this._ctx = ctx;
  354. this._ctx.fillStyle = this._style.fillStyle;
  355. this._ctx.strokeStyle = this._style.strokeStyle;
  356. this._ctx.lineJoin = "bevel";
  357. this._ctx.font = this._font.value;
  358. this._ready = true;
  359. };
  360. if (space instanceof CanvasRenderingContext2D) {
  361. _setup(space);
  362. }
  363. else {
  364. this._space = space;
  365. this._space.add({ start: () => {
  366. _setup(this._space.ctx);
  367. } });
  368. }
  369. }
  370. get space() { return this._space; }
  371. get ctx() { return this._space.ctx; }
  372. useOffscreen(off = true, clear = false) {
  373. if (clear)
  374. this._space.clearOffscreen((typeof clear == "string") ? clear : null);
  375. this._ctx = (this._space.hasOffscreen && off) ? this._space.offscreenCtx : this._space.ctx;
  376. return this;
  377. }
  378. renderOffscreen(offset = [0, 0]) {
  379. if (this._space.hasOffscreen) {
  380. this._space.ctx.drawImage(this._space.offscreenCanvas, offset[0], offset[1], this._space.width, this._space.height);
  381. }
  382. }
  383. alpha(a) {
  384. this._ctx.globalAlpha = a;
  385. this._style.globalAlpha = a;
  386. return this;
  387. }
  388. fill(c) {
  389. if (typeof c == "boolean") {
  390. this.filled = c;
  391. }
  392. else {
  393. this.filled = true;
  394. this._style.fillStyle = c;
  395. this._ctx.fillStyle = c;
  396. }
  397. return this;
  398. }
  399. stroke(c, width, linejoin, linecap) {
  400. if (typeof c == "boolean") {
  401. this.stroked = c;
  402. }
  403. else {
  404. this.stroked = true;
  405. this._style.strokeStyle = c;
  406. this._ctx.strokeStyle = c;
  407. if (width) {
  408. this._ctx.lineWidth = width;
  409. this._style.lineWidth = width;
  410. }
  411. if (linejoin) {
  412. this._ctx.lineJoin = linejoin;
  413. this._style.lineJoin = linejoin;
  414. }
  415. if (linecap) {
  416. this._ctx.lineCap = linecap;
  417. this._style.lineCap = linecap;
  418. }
  419. }
  420. return this;
  421. }
  422. gradient(stops) {
  423. let vals = [];
  424. if (stops.length < 2)
  425. stops.push([0.99, "#000"], [1, "#000"]);
  426. for (let i = 0, len = stops.length; i < len; i++) {
  427. let t = typeof stops[i] === 'string' ? i * (1 / (stops.length - 1)) : stops[i][0];
  428. let v = typeof stops[i] === 'string' ? stops[i] : stops[i][1];
  429. vals.push([t, v]);
  430. }
  431. return (area1, area2) => {
  432. area1 = area1.map(a => a.abs());
  433. if (area2)
  434. area2.map(a => a.abs());
  435. let grad = area2
  436. ? this.ctx.createRadialGradient(area1[0][0], area1[0][1], area1[1][0], area2[0][0], area2[0][1], area2[1][0])
  437. : this.ctx.createLinearGradient(area1[0][0], area1[0][1], area1[1][0], area1[1][1]);
  438. for (let i = 0, len = vals.length; i < len; i++) {
  439. grad.addColorStop(vals[i][0], vals[i][1]);
  440. }
  441. return grad;
  442. };
  443. }
  444. composite(mode = 'source-over') {
  445. this.ctx.globalCompositeOperation = mode;
  446. return this;
  447. }
  448. clip() {
  449. this.ctx.clip();
  450. return this;
  451. }
  452. dash(segments = true, offset = 0) {
  453. if (!segments) {
  454. this._ctx.setLineDash([]);
  455. this._ctx.lineDashOffset = 0;
  456. }
  457. else {
  458. if (segments === true) {
  459. segments = [5, 5];
  460. }
  461. this._ctx.setLineDash([segments[0], segments[1]]);
  462. this._ctx.lineDashOffset = offset;
  463. }
  464. return this;
  465. }
  466. font(sizeOrFont, weight, style, lineHeight, family) {
  467. if (typeof sizeOrFont == "number") {
  468. this._font.size = sizeOrFont;
  469. if (family)
  470. this._font.face = family;
  471. if (weight)
  472. this._font.weight = weight;
  473. if (style)
  474. this._font.style = style;
  475. if (lineHeight)
  476. this._font.lineHeight = lineHeight;
  477. }
  478. else {
  479. this._font = sizeOrFont;
  480. }
  481. this._ctx.font = this._font.value;
  482. if (this._estimateTextWidth)
  483. this.fontWidthEstimate(true);
  484. return this;
  485. }
  486. fontWidthEstimate(estimate = true) {
  487. this._estimateTextWidth = (estimate) ? Typography_1.Typography.textWidthEstimator(((c) => this._ctx.measureText(c).width)) : undefined;
  488. return this;
  489. }
  490. getTextWidth(c) {
  491. return (!this._estimateTextWidth) ? this._ctx.measureText(c + " .").width : this._estimateTextWidth(c);
  492. }
  493. _textTruncate(str, width, tail = "") {
  494. return Typography_1.Typography.truncate(this.getTextWidth.bind(this), str, width, tail);
  495. }
  496. _textAlign(box, vertical, offset, center) {
  497. let _box = Util_1.Util.iterToArray(box);
  498. if (!Util_1.Util.arrayCheck(_box))
  499. return;
  500. if (!center)
  501. center = Op_1.Rectangle.center(_box);
  502. var px = _box[0][0];
  503. if (this._ctx.textAlign == "end" || this._ctx.textAlign == "right") {
  504. px = _box[1][0];
  505. }
  506. else if (this._ctx.textAlign == "center" || this._ctx.textAlign == "middle") {
  507. px = center[0];
  508. }
  509. var py = center[1];
  510. if (vertical == "top" || vertical == "start") {
  511. py = _box[0][1];
  512. }
  513. else if (vertical == "end" || vertical == "bottom") {
  514. py = _box[1][1];
  515. }
  516. return (offset) ? new Pt_1.Pt(px + offset[0], py + offset[1]) : new Pt_1.Pt(px, py);
  517. }
  518. reset() {
  519. for (let k in this._style) {
  520. if (this._style.hasOwnProperty(k)) {
  521. this._ctx[k] = this._style[k];
  522. }
  523. }
  524. this._font = new Form_1.Font();
  525. this._ctx.font = this._font.value;
  526. return this;
  527. }
  528. _paint() {
  529. if (this._filled)
  530. this._ctx.fill();
  531. if (this._stroked)
  532. this._ctx.stroke();
  533. }
  534. static point(ctx, p, radius = 5, shape = "square") {
  535. if (!p)
  536. return;
  537. if (!CanvasForm[shape])
  538. throw new Error(`${shape} is not a static function of CanvasForm`);
  539. CanvasForm[shape](ctx, p, radius);
  540. }
  541. point(p, radius = 5, shape = "square") {
  542. CanvasForm.point(this._ctx, p, radius, shape);
  543. this._paint();
  544. return this;
  545. }
  546. static circle(ctx, pt, radius = 10) {
  547. if (!pt)
  548. return;
  549. ctx.beginPath();
  550. ctx.arc(pt[0], pt[1], radius, 0, Util_1.Const.two_pi, false);
  551. ctx.closePath();
  552. }
  553. circle(pts) {
  554. let p = Util_1.Util.iterToArray(pts);
  555. CanvasForm.circle(this._ctx, p[0], p[1][0]);
  556. this._paint();
  557. return this;
  558. }
  559. static ellipse(ctx, pt, radius, rotation = 0, startAngle = 0, endAngle = Util_1.Const.two_pi, cc = false) {
  560. if (!pt || !radius)
  561. return;
  562. ctx.beginPath();
  563. ctx.ellipse(pt[0], pt[1], radius[0], radius[1], rotation, startAngle, endAngle, cc);
  564. }
  565. ellipse(pt, radius, rotation = 0, startAngle = 0, endAngle = Util_1.Const.two_pi, cc = false) {
  566. CanvasForm.ellipse(this._ctx, pt, radius, rotation, startAngle, endAngle, cc);
  567. this._paint();
  568. return this;
  569. }
  570. static arc(ctx, pt, radius, startAngle, endAngle, cc) {
  571. if (!pt)
  572. return;
  573. ctx.beginPath();
  574. ctx.arc(pt[0], pt[1], radius, startAngle, endAngle, cc);
  575. }
  576. arc(pt, radius, startAngle, endAngle, cc) {
  577. CanvasForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);
  578. this._paint();
  579. return this;
  580. }
  581. static square(ctx, pt, halfsize) {
  582. if (!pt)
  583. return;
  584. let x1 = pt[0] - halfsize;
  585. let y1 = pt[1] - halfsize;
  586. let x2 = pt[0] + halfsize;
  587. let y2 = pt[1] + halfsize;
  588. ctx.beginPath();
  589. ctx.moveTo(x1, y1);
  590. ctx.lineTo(x1, y2);
  591. ctx.lineTo(x2, y2);
  592. ctx.lineTo(x2, y1);
  593. ctx.closePath();
  594. }
  595. square(pt, halfsize) {
  596. CanvasForm.square(this._ctx, pt, halfsize);
  597. this._paint();
  598. return this;
  599. }
  600. static line(ctx, pts) {
  601. if (!Util_1.Util.arrayCheck(pts))
  602. return;
  603. let i = 0;
  604. ctx.beginPath();
  605. for (let it of pts) {
  606. if (it) {
  607. if (i++ > 0) {
  608. ctx.lineTo(it[0], it[1]);
  609. }
  610. else {
  611. ctx.moveTo(it[0], it[1]);
  612. }
  613. }
  614. }
  615. }
  616. line(pts) {
  617. CanvasForm.line(this._ctx, pts);
  618. this._paint();
  619. return this;
  620. }
  621. static polygon(ctx, pts) {
  622. if (!Util_1.Util.arrayCheck(pts))
  623. return;
  624. CanvasForm.line(ctx, pts);
  625. ctx.closePath();
  626. }
  627. polygon(pts) {
  628. CanvasForm.polygon(this._ctx, pts);
  629. this._paint();
  630. return this;
  631. }
  632. static rect(ctx, pts) {
  633. let p = Util_1.Util.iterToArray(pts);
  634. if (!Util_1.Util.arrayCheck(p))
  635. return;
  636. ctx.beginPath();
  637. ctx.moveTo(p[0][0], p[0][1]);
  638. ctx.lineTo(p[0][0], p[1][1]);
  639. ctx.lineTo(p[1][0], p[1][1]);
  640. ctx.lineTo(p[1][0], p[0][1]);
  641. ctx.closePath();
  642. }
  643. rect(pts) {
  644. CanvasForm.rect(this._ctx, pts);
  645. this._paint();
  646. return this;
  647. }
  648. static image(ctx, ptOrRect, img, orig) {
  649. let t = Util_1.Util.iterToArray(ptOrRect);
  650. let pos;
  651. if (typeof t[0] === "number") {
  652. pos = t;
  653. }
  654. else {
  655. if (orig) {
  656. let o = Util_1.Util.iterToArray(orig);
  657. pos = [o[0][0], o[0][1], o[1][0] - o[0][0], o[1][1] - o[0][1],
  658. t[0][0], t[0][1], t[1][0] - t[0][0], t[1][1] - t[0][1]];
  659. }
  660. else {
  661. pos = [t[0][0], t[0][1], t[1][0] - t[0][0], t[1][1] - t[0][1]];
  662. }
  663. }
  664. if (img instanceof Image_1.Img) {
  665. if (img.loaded) {
  666. ctx.drawImage(img.image, ...pos);
  667. }
  668. }
  669. else {
  670. ctx.drawImage(img, ...pos);
  671. }
  672. }
  673. image(ptOrRect, img, orig) {
  674. if (img instanceof Image_1.Img) {
  675. if (img.loaded) {
  676. CanvasForm.image(this._ctx, ptOrRect, img.image, orig);
  677. }
  678. }
  679. else {
  680. CanvasForm.image(this._ctx, ptOrRect, img, orig);
  681. }
  682. return this;
  683. }
  684. static imageData(ctx, ptOrRect, img) {
  685. let t = Util_1.Util.iterToArray(ptOrRect);
  686. if (typeof t[0] === "number") {
  687. ctx.putImageData(img, t[0], t[1]);
  688. }
  689. else {
  690. ctx.putImageData(img, t[0][0], t[0][1], t[0][0], t[0][1], t[1][0], t[1][1]);
  691. }
  692. }
  693. imageData(ptOrRect, img) {
  694. CanvasForm.imageData(this._ctx, ptOrRect, img);
  695. return this;
  696. }
  697. static text(ctx, pt, txt, maxWidth) {
  698. if (!pt)
  699. return;
  700. ctx.fillText(txt, pt[0], pt[1], maxWidth);
  701. }
  702. text(pt, txt, maxWidth) {
  703. CanvasForm.text(this._ctx, pt, txt, maxWidth);
  704. return this;
  705. }
  706. textBox(box, txt, verticalAlign = "middle", tail = "", overrideBaseline = true) {
  707. if (overrideBaseline)
  708. this._ctx.textBaseline = verticalAlign;
  709. let size = Op_1.Rectangle.size(box);
  710. let t = this._textTruncate(txt, size[0], tail);
  711. this.text(this._textAlign(box, verticalAlign), t[0]);
  712. return this;
  713. }
  714. paragraphBox(box, txt, lineHeight = 1.2, verticalAlign = "top", crop = true) {
  715. let b = Util_1.Util.iterToArray(box);
  716. let size = Op_1.Rectangle.size(b);
  717. this._ctx.textBaseline = "top";
  718. let lstep = this._font.size * lineHeight;
  719. let nextLine = (sub, buffer = [], cc = 0) => {
  720. if (!sub)
  721. return buffer;
  722. if (crop && cc * lstep > size[1] - lstep * 2)
  723. return buffer;
  724. if (cc > 10000)
  725. throw new Error("max recursion reached (10000)");
  726. let t = this._textTruncate(sub, size[0], "");
  727. let newln = t[0].indexOf("\n");
  728. if (newln >= 0) {
  729. buffer.push(t[0].substr(0, newln));
  730. return nextLine(sub.substr(newln + 1), buffer, cc + 1);
  731. }
  732. let dt = t[0].lastIndexOf(" ") + 1;
  733. if (dt <= 0 || t[1] === sub.length)
  734. dt = undefined;
  735. let line = t[0].substr(0, dt);
  736. buffer.push(line);
  737. return (t[1] <= 0 || t[1] === sub.length) ? buffer : nextLine(sub.substr((dt || t[1])), buffer, cc + 1);
  738. };
  739. let lines = nextLine(txt);
  740. let lsize = lines.length * lstep;
  741. let lbox = b;
  742. if (verticalAlign == "middle" || verticalAlign == "center") {
  743. let lpad = (size[1] - lsize) / 2;
  744. if (crop)
  745. lpad = Math.max(0, lpad);
  746. lbox = new Pt_1.Group(b[0].$add(0, lpad), b[1].$subtract(0, lpad));
  747. }
  748. else if (verticalAlign == "bottom") {
  749. lbox = new Pt_1.Group(b[0].$add(0, size[1] - lsize), b[1]);
  750. }
  751. else {
  752. lbox = new Pt_1.Group(b[0], b[0].$add(size[0], lsize));
  753. }
  754. let center = Op_1.Rectangle.center(lbox);
  755. for (let i = 0, len = lines.length; i < len; i++) {
  756. this.text(this._textAlign(lbox, "top", [0, i * lstep], center), lines[i]);
  757. }
  758. return this;
  759. }
  760. alignText(alignment = "left", baseline = "alphabetic") {
  761. if (baseline == "center")
  762. baseline = "middle";
  763. if (baseline == "baseline")
  764. baseline = "alphabetic";
  765. this._ctx.textAlign = alignment;
  766. this._ctx.textBaseline = baseline;
  767. return this;
  768. }
  769. log(txt) {
  770. let w = this._ctx.measureText(txt).width + 20;
  771. this.stroke(false).fill("rgba(0,0,0,.4)").rect([[0, 0], [w, 20]]);
  772. this.fill("#fff").text([10, 14], txt);
  773. return this;
  774. }
  775. }
  776. exports.CanvasForm = CanvasForm;
  777. /***/ }),
  778. /***/ "./src/Color.ts":
  779. /*!**********************!*\
  780. !*** ./src/Color.ts ***!
  781. \**********************/
  782. /*! no static exports found */
  783. /***/ (function(module, exports, __webpack_require__) {
  784. "use strict";
  785. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  786. Object.defineProperty(exports, "__esModule", { value: true });
  787. exports.Color = void 0;
  788. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  789. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  790. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  791. class Color extends Pt_1.Pt {
  792. constructor(...args) {
  793. super(...args);
  794. this._mode = "rgb";
  795. this._isNorm = false;
  796. }
  797. static from(...args) {
  798. let p = [1, 1, 1, 1];
  799. let c = Util_1.Util.getArgs(args);
  800. for (let i = 0, len = p.length; i < len; i++) {
  801. if (i < c.length)
  802. p[i] = c[i];
  803. }
  804. return new Color(p);
  805. }
  806. static fromHex(hex) {
  807. if (hex[0] == "#")
  808. hex = hex.substr(1);
  809. if (hex.length <= 3) {
  810. let fn = (i) => hex[i] || "F";
  811. hex = `${fn(0)}${fn(0)}${fn(1)}${fn(1)}${fn(2)}${fn(2)}`;
  812. }
  813. let alpha = 1;
  814. if (hex.length === 8) {
  815. alpha = hex.substr(6) && 0xFF / 255;
  816. hex = hex.substring(0, 6);
  817. }
  818. let hexVal = parseInt(hex, 16);
  819. return new Color(hexVal >> 16, hexVal >> 8 & 0xFF, hexVal & 0xFF, alpha);
  820. }
  821. static rgb(...args) { return Color.from(...args).toMode("rgb"); }
  822. static hsl(...args) { return Color.from(...args).toMode("hsl"); }
  823. static hsb(...args) { return Color.from(...args).toMode("hsb"); }
  824. static lab(...args) { return Color.from(...args).toMode("lab"); }
  825. static lch(...args) { return Color.from(...args).toMode("lch"); }
  826. static luv(...args) { return Color.from(...args).toMode("luv"); }
  827. static xyz(...args) { return Color.from(...args).toMode("xyz"); }
  828. static maxValues(mode) { return Color.ranges[mode].zipSlice(1).$take([0, 1, 2]); }
  829. get hex() { return this.toString("hex"); }
  830. get rgb() { return this.toString("rgb"); }
  831. get rgba() { return this.toString("rgba"); }
  832. clone() {
  833. let c = new Color(this);
  834. c.toMode(this._mode);
  835. return c;
  836. }
  837. toMode(mode, convert = false) {
  838. if (convert) {
  839. let fname = this._mode.toUpperCase() + "to" + mode.toUpperCase();
  840. if (Color[fname]) {
  841. this.to(Color[fname](this, this._isNorm, this._isNorm));
  842. }
  843. else {
  844. throw new Error("Cannot convert color with " + fname);
  845. }
  846. }
  847. this._mode = mode;
  848. return this;
  849. }
  850. get mode() { return this._mode; }
  851. get r() { return this[0]; }
  852. set r(n) { this[0] = n; }
  853. get g() { return this[1]; }
  854. set g(n) { this[1] = n; }
  855. get b() { return this[2]; }
  856. set b(n) { this[2] = n; }
  857. get h() { return (this._mode == "lch") ? this[2] : this[0]; }
  858. set h(n) {
  859. let i = (this._mode == "lch") ? 2 : 0;
  860. this[i] = n;
  861. }
  862. get s() { return this[1]; }
  863. set s(n) { this[1] = n; }
  864. get l() { return (this._mode == "hsl") ? this[2] : this[0]; }
  865. set l(n) {
  866. let i = (this._mode == "hsl") ? 2 : 0;
  867. this[i] = n;
  868. }
  869. get a() { return this[1]; }
  870. set a(n) { this[1] = n; }
  871. get c() { return this[1]; }
  872. set c(n) { this[1] = n; }
  873. get u() { return this[1]; }
  874. set u(n) { this[1] = n; }
  875. get v() { return this[2]; }
  876. set v(n) { this[2] = n; }
  877. set alpha(n) { if (this.length > 3)
  878. this[3] = n; }
  879. get alpha() { return (this.length > 3) ? this[3] : 1; }
  880. get normalized() { return this._isNorm; }
  881. set normalized(b) { this._isNorm = b; }
  882. normalize(toNorm = true) {
  883. if (this._isNorm == toNorm)
  884. return this;
  885. let ranges = Color.ranges[this._mode];
  886. for (let i = 0; i < 3; i++) {
  887. this[i] = (!toNorm)
  888. ? Num_1.Num.mapToRange(this[i], 0, 1, ranges[i][0], ranges[i][1])
  889. : Num_1.Num.mapToRange(this[i], ranges[i][0], ranges[i][1], 0, 1);
  890. }
  891. this._isNorm = toNorm;
  892. return this;
  893. }
  894. $normalize(toNorm = true) { return this.clone().normalize(toNorm); }
  895. toString(format = "mode") {
  896. if (format == "hex") {
  897. let _hex = (n) => {
  898. let s = Math.floor(n).toString(16);
  899. return (s.length < 2) ? '0' + s : s;
  900. };
  901. return `#${_hex(this[0])}${_hex(this[1])}${_hex(this[2])}`;
  902. }
  903. else if (format == "rgba") {
  904. return `rgba(${Math.floor(this[0])},${Math.floor(this[1])},${Math.floor(this[2])},${this.alpha})`;
  905. }
  906. else if (format == "rgb") {
  907. return `rgb(${Math.floor(this[0])},${Math.floor(this[1])},${Math.floor(this[2])})`;
  908. }
  909. else {
  910. return `${this._mode}(${this[0]},${this[1]},${this[2]},${this.alpha})`;
  911. }
  912. }
  913. static RGBtoHSL(rgb, normalizedInput = false, normalizedOutput = false) {
  914. let [r, g, b] = (!normalizedInput) ? rgb.$normalize() : rgb;
  915. let max = Math.max(r, g, b);
  916. let min = Math.min(r, g, b);
  917. let h = (max + min) / 2;
  918. let s = h;
  919. let l = h;
  920. if (max == min) {
  921. h = 0;
  922. s = 0;
  923. }
  924. else {
  925. let d = max - min;
  926. s = (l > 0.5) ? d / (2 - max - min) : d / (max + min);
  927. h = 0;
  928. if (max === r) {
  929. h = (g - b) / d + ((g < b) ? 6 : 0);
  930. }
  931. else if (max === g) {
  932. h = (b - r) / d + 2;
  933. }
  934. else if (max === b) {
  935. h = (r - g) / d + 4;
  936. }
  937. }
  938. return Color.hsl(((normalizedOutput) ? h / 60 : h * 60), s, l, rgb.alpha);
  939. }
  940. static HSLtoRGB(hsl, normalizedInput = false, normalizedOutput = false) {
  941. let [h, s, l] = hsl;
  942. if (!normalizedInput)
  943. h = h / 360;
  944. if (s == 0)
  945. return Color.rgb(l * 255, l * 255, l * 255, hsl.alpha);
  946. let q = (l <= 0.5) ? l * (1 + s) : l + s - (l * s);
  947. let p = 2 * l - q;
  948. let convert = (t) => {
  949. t = (t < 0) ? t + 1 : (t > 1) ? t - 1 : t;
  950. if (t * 6 < 1) {
  951. return p + (q - p) * t * 6;
  952. }
  953. else if (t * 2 < 1) {
  954. return q;
  955. }
  956. else if (t * 3 < 2) {
  957. return p + (q - p) * ((2 / 3) - t) * 6;
  958. }
  959. else {
  960. return p;
  961. }
  962. };
  963. let sc = (normalizedOutput) ? 1 : 255;
  964. return Color.rgb(sc * convert((h + 1 / 3)), sc * convert(h), sc * convert((h - 1 / 3)), hsl.alpha);
  965. }
  966. static RGBtoHSB(rgb, normalizedInput = false, normalizedOutput = false) {
  967. let [r, g, b] = (!normalizedInput) ? rgb.$normalize() : rgb;
  968. let max = Math.max(r, g, b);
  969. let min = Math.min(r, g, b);
  970. let d = max - min;
  971. let h = 0;
  972. let s = (max === 0) ? 0 : d / max;
  973. let v = max;
  974. if (max != min) {
  975. if (max === r) {
  976. h = (g - b) / d + ((g < b) ? 6 : 0);
  977. }
  978. else if (max === g) {
  979. h = (b - r) / d + 2;
  980. }
  981. else if (max === b) {
  982. h = (r - g) / d + 4;
  983. }
  984. }
  985. return Color.hsb(((normalizedOutput) ? h / 60 : h * 60), s, v, rgb.alpha);
  986. }
  987. static HSBtoRGB(hsb, normalizedInput = false, normalizedOutput = false) {
  988. let [h, s, v] = hsb;
  989. if (!normalizedInput)
  990. h = h / 360;
  991. let i = Math.floor(h * 6);
  992. let f = h * 6 - i;
  993. let p = v * (1 - s);
  994. let q = v * (1 - f * s);
  995. let t = v * (1 - (1 - f) * s);
  996. let pick = [
  997. [v, t, p], [q, v, p], [p, v, t],
  998. [p, q, v], [t, p, v], [v, p, q]
  999. ];
  1000. let c = pick[i % 6];
  1001. let sc = (normalizedOutput) ? 1 : 255;
  1002. return Color.rgb(sc * c[0], sc * c[1], sc * c[2], hsb.alpha);
  1003. }
  1004. static RGBtoLAB(rgb, normalizedInput = false, normalizedOutput = false) {
  1005. let c = (normalizedInput) ? rgb.$normalize(false) : rgb;
  1006. return Color.XYZtoLAB(Color.RGBtoXYZ(c), false, normalizedOutput);
  1007. }
  1008. static LABtoRGB(lab, normalizedInput = false, normalizedOutput = false) {
  1009. let c = (normalizedInput) ? lab.$normalize(false) : lab;
  1010. return Color.XYZtoRGB(Color.LABtoXYZ(c), false, normalizedOutput);
  1011. }
  1012. static RGBtoLCH(rgb, normalizedInput = false, normalizedOutput = false) {
  1013. let c = (normalizedInput) ? rgb.$normalize(false) : rgb;
  1014. return Color.LABtoLCH(Color.RGBtoLAB(c), false, normalizedOutput);
  1015. }
  1016. static LCHtoRGB(lch, normalizedInput = false, normalizedOutput = false) {
  1017. let c = (normalizedInput) ? lch.$normalize(false) : lch;
  1018. return Color.LABtoRGB(Color.LCHtoLAB(c), false, normalizedOutput);
  1019. }
  1020. static RGBtoLUV(rgb, normalizedInput = false, normalizedOutput = false) {
  1021. let c = (normalizedInput) ? rgb.$normalize(false) : rgb;
  1022. return Color.XYZtoLUV(Color.RGBtoXYZ(c), false, normalizedOutput);
  1023. }
  1024. static LUVtoRGB(luv, normalizedInput = false, normalizedOutput = false) {
  1025. let c = (normalizedInput) ? luv.$normalize(false) : luv;
  1026. return Color.XYZtoRGB(Color.LUVtoXYZ(c), false, normalizedOutput);
  1027. }
  1028. static RGBtoXYZ(rgb, normalizedInput = false, normalizedOutput = false) {
  1029. let c = (!normalizedInput) ? rgb.$normalize() : rgb.clone();
  1030. for (let i = 0; i < 3; i++) {
  1031. c[i] = (c[i] > 0.04045) ? Math.pow((c[i] + 0.055) / 1.055, 2.4) : c[i] / 12.92;
  1032. if (!normalizedOutput)
  1033. c[i] = c[i] * 100;
  1034. }
  1035. let cc = Color.xyz(c[0] * 0.4124564 + c[1] * 0.3575761 + c[2] * 0.1804375, c[0] * 0.2126729 + c[1] * 0.7151522 + c[2] * 0.0721750, c[0] * 0.0193339 + c[1] * 0.1191920 + c[2] * 0.9503041, rgb.alpha);
  1036. return (normalizedOutput) ? cc.normalize() : cc;
  1037. }
  1038. static XYZtoRGB(xyz, normalizedInput = false, normalizedOutput = false) {
  1039. let [x, y, z] = (!normalizedInput) ? xyz.$normalize() : xyz;
  1040. let rgb = [
  1041. x * 3.2404542 + y * -1.5371385 + z * -0.4985314,
  1042. x * -0.9692660 + y * 1.8760108 + z * 0.0415560,
  1043. x * 0.0556434 + y * -0.2040259 + z * 1.0572252
  1044. ];
  1045. for (let i = 0; i < 3; i++) {
  1046. rgb[i] = (rgb[i] < 0) ? 0 : (rgb[i] > 0.0031308) ? (1.055 * Math.pow(rgb[i], 1 / 2.4) - 0.055) : (12.92 * rgb[i]);
  1047. rgb[i] = Math.max(0, Math.min(1, rgb[i]));
  1048. if (!normalizedOutput)
  1049. rgb[i] = Math.round(rgb[i] * 255);
  1050. }
  1051. let cc = Color.rgb(rgb[0], rgb[1], rgb[2], xyz.alpha);
  1052. return (normalizedOutput) ? cc.normalize() : cc;
  1053. }
  1054. static XYZtoLAB(xyz, normalizedInput = false, normalizedOutput = false) {
  1055. let c = (normalizedInput) ? xyz.$normalize(false) : xyz.clone();
  1056. c.divide(Color.D65);
  1057. let fn = (n) => (n > 0.008856) ? Math.pow(n, 1 / 3) : (7.787 * n) + 16 / 116;
  1058. let cy = fn(c[1]);
  1059. let cc = Color.lab((116 * cy) - 16, 500 * (fn(c[0]) - cy), 200 * (cy - fn(c[2])), xyz.alpha);
  1060. return (normalizedOutput) ? cc.normalize() : cc;
  1061. }
  1062. static LABtoXYZ(lab, normalizedInput = false, normalizedOutput = false) {
  1063. let c = (normalizedInput) ? lab.$normalize(false) : lab;
  1064. let y = (c[0] + 16) / 116;
  1065. let x = (c[1] / 500) + y;
  1066. let z = y - c[2] / 200;
  1067. let fn = (n) => {
  1068. let nnn = n * n * n;
  1069. return (nnn > 0.008856) ? nnn : (n - 16 / 116) / 7.787;
  1070. };
  1071. let d = Color.D65;
  1072. let cc = Color.xyz(Math.max(0, d[0] * fn(x)), Math.max(0, d[1] * fn(y)), Math.max(0, d[2] * fn(z)), lab.alpha);
  1073. return (normalizedOutput) ? cc.normalize() : cc;
  1074. }
  1075. static XYZtoLUV(xyz, normalizedInput = false, normalizedOutput = false) {
  1076. let [x, y, z] = (normalizedInput) ? xyz.$normalize(false) : xyz;
  1077. let u = (4 * x) / (x + (15 * y) + (3 * z));
  1078. let v = (9 * y) / (x + (15 * y) + (3 * z));
  1079. y = y / 100;
  1080. y = (y > 0.008856) ? Math.pow(y, 1 / 3) : (7.787 * y + 16 / 116);
  1081. let refU = (4 * Color.D65[0]) / (Color.D65[0] + (15 * Color.D65[1]) + (3 * Color.D65[2]));
  1082. let refV = (9 * Color.D65[1]) / (Color.D65[0] + (15 * Color.D65[1]) + (3 * Color.D65[2]));
  1083. let L = (116 * y) - 16;
  1084. return Color.luv(L, 13 * L * (u - refU), 13 * L * (v - refV), xyz.alpha);
  1085. }
  1086. static LUVtoXYZ(luv, normalizedInput = false, normalizedOutput = false) {
  1087. let [l, u, v] = (normalizedInput) ? luv.$normalize(false) : luv;
  1088. let y = (l + 16) / 116;
  1089. let cubeY = y * y * y;
  1090. y = (cubeY > 0.008856) ? cubeY : (y - 16 / 116) / 7.787;
  1091. let refU = (4 * Color.D65[0]) / (Color.D65[0] + (15 * Color.D65[1]) + (3 * Color.D65[2]));
  1092. let refV = (9 * Color.D65[1]) / (Color.D65[0] + (15 * Color.D65[1]) + (3 * Color.D65[2]));
  1093. u = u / (13 * l) + refU;
  1094. v = v / (13 * l) + refV;
  1095. y = y * 100;
  1096. let x = -1 * (9 * y * u) / ((u - 4) * v - u * v);
  1097. let z = (9 * y - (15 * v * y) - (v * x)) / (3 * v);
  1098. return Color.xyz(x, y, z, luv.alpha);
  1099. }
  1100. static LABtoLCH(lab, normalizedInput = false, normalizedOutput = false) {
  1101. let c = (normalizedInput) ? lab.$normalize(false) : lab;
  1102. let h = Num_1.Geom.toDegree(Num_1.Geom.boundRadian(Math.atan2(c[2], c[1])));
  1103. return Color.lch(c[0], Math.sqrt(c[1] * c[1] + c[2] * c[2]), h, lab.alpha);
  1104. }
  1105. static LCHtoLAB(lch, normalizedInput = false, normalizedOutput = false) {
  1106. let c = (normalizedInput) ? lch.$normalize(false) : lch;
  1107. let rad = Num_1.Geom.toRadian(c[2]);
  1108. return Color.lab(c[0], Math.cos(rad) * c[1], Math.sin(rad) * c[1], lch.alpha);
  1109. }
  1110. }
  1111. exports.Color = Color;
  1112. Color.D65 = new Pt_1.Pt(95.047, 100, 108.883, 1);
  1113. Color.ranges = {
  1114. rgb: new Pt_1.Group(new Pt_1.Pt(0, 255), new Pt_1.Pt(0, 255), new Pt_1.Pt(0, 255)),
  1115. hsl: new Pt_1.Group(new Pt_1.Pt(0, 360), new Pt_1.Pt(0, 1), new Pt_1.Pt(0, 1)),
  1116. hsb: new Pt_1.Group(new Pt_1.Pt(0, 360), new Pt_1.Pt(0, 1), new Pt_1.Pt(0, 1)),
  1117. lab: new Pt_1.Group(new Pt_1.Pt(0, 100), new Pt_1.Pt(-128, 127), new Pt_1.Pt(-128, 127)),
  1118. lch: new Pt_1.Group(new Pt_1.Pt(0, 100), new Pt_1.Pt(0, 100), new Pt_1.Pt(0, 360)),
  1119. luv: new Pt_1.Group(new Pt_1.Pt(0, 100), new Pt_1.Pt(-134, 220), new Pt_1.Pt(-140, 122)),
  1120. xyz: new Pt_1.Group(new Pt_1.Pt(0, 100), new Pt_1.Pt(0, 100), new Pt_1.Pt(0, 100))
  1121. };
  1122. /***/ }),
  1123. /***/ "./src/Create.ts":
  1124. /*!***********************!*\
  1125. !*** ./src/Create.ts ***!
  1126. \***********************/
  1127. /*! no static exports found */
  1128. /***/ (function(module, exports, __webpack_require__) {
  1129. "use strict";
  1130. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  1131. Object.defineProperty(exports, "__esModule", { value: true });
  1132. exports.Delaunay = exports.Noise = exports.Create = void 0;
  1133. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  1134. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  1135. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  1136. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  1137. const LinearAlgebra_1 = __webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts");
  1138. class Create {
  1139. static distributeRandom(bound, count, dimensions = 2) {
  1140. let pts = new Pt_1.Group();
  1141. for (let i = 0; i < count; i++) {
  1142. let p = [bound.x + Math.random() * bound.width];
  1143. if (dimensions > 1)
  1144. p.push(bound.y + Math.random() * bound.height);
  1145. if (dimensions > 2)
  1146. p.push(bound.z + Math.random() * bound.depth);
  1147. pts.push(new Pt_1.Pt(p));
  1148. }
  1149. return pts;
  1150. }
  1151. static distributeLinear(line, count) {
  1152. let _line = Util_1.Util.iterToArray(line);
  1153. let ln = Op_1.Line.subpoints(_line, count - 2);
  1154. ln.unshift(_line[0]);
  1155. ln.push(_line[_line.length - 1]);
  1156. return ln;
  1157. }
  1158. static gridPts(bound, columns, rows, orientation = [0.5, 0.5]) {
  1159. if (columns === 0 || rows === 0)
  1160. throw new Error("grid columns and rows cannot be 0");
  1161. let unit = bound.size.$subtract(1).$divide(columns, rows);
  1162. let offset = unit.$multiply(orientation);
  1163. let g = new Pt_1.Group();
  1164. for (let r = 0; r < rows; r++) {
  1165. for (let c = 0; c < columns; c++) {
  1166. g.push(bound.topLeft.$add(unit.$multiply(c, r)).add(offset));
  1167. }
  1168. }
  1169. return g;
  1170. }
  1171. static gridCells(bound, columns, rows) {
  1172. if (columns === 0 || rows === 0)
  1173. throw new Error("grid columns and rows cannot be 0");
  1174. let unit = bound.size.$subtract(1).divide(columns, rows);
  1175. let g = [];
  1176. for (let r = 0; r < rows; r++) {
  1177. for (let c = 0; c < columns; c++) {
  1178. g.push(new Pt_1.Group(bound.topLeft.$add(unit.$multiply(c, r)), bound.topLeft.$add(unit.$multiply(c, r).add(unit))));
  1179. }
  1180. }
  1181. return g;
  1182. }
  1183. static radialPts(center, radius, count, angleOffset = -Util_1.Const.half_pi) {
  1184. let g = new Pt_1.Group();
  1185. let a = Util_1.Const.two_pi / count;
  1186. for (let i = 0; i < count; i++) {
  1187. g.push(new Pt_1.Pt(center).toAngle(a * i + angleOffset, radius, true));
  1188. }
  1189. return g;
  1190. }
  1191. static noisePts(pts, dx = 0.01, dy = 0.01, rows = 0, columns = 0) {
  1192. let seed = Math.random();
  1193. let g = new Pt_1.Group();
  1194. let i = 0;
  1195. for (let p of pts) {
  1196. let np = new Noise(p);
  1197. let r = (rows && rows > 0) ? Math.floor(i / rows) : i;
  1198. let c = (columns && columns > 0) ? i % columns : i;
  1199. np.initNoise(dx * c, dy * r);
  1200. np.seed(seed);
  1201. g.push(np);
  1202. i++;
  1203. }
  1204. return g;
  1205. }
  1206. static delaunay(pts) {
  1207. return Delaunay.from(pts);
  1208. }
  1209. }
  1210. exports.Create = Create;
  1211. const __noise_grad3 = [
  1212. [1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0],
  1213. [1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1],
  1214. [0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1]
  1215. ];
  1216. const __noise_permTable = [151, 160, 137, 91, 90, 15,
  1217. 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
  1218. 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
  1219. 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
  1220. 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
  1221. 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
  1222. 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
  1223. 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
  1224. 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
  1225. 129, 22, 39, 253, 9, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
  1226. 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
  1227. 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
  1228. 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180
  1229. ];
  1230. class Noise extends Pt_1.Pt {
  1231. constructor(...args) {
  1232. super(...args);
  1233. this.perm = [];
  1234. this._n = new Pt_1.Pt(0.01, 0.01);
  1235. this.perm = __noise_permTable.concat(__noise_permTable);
  1236. }
  1237. initNoise(...args) {
  1238. this._n = new Pt_1.Pt(...args);
  1239. return this;
  1240. }
  1241. step(x = 0, y = 0) {
  1242. this._n.add(x, y);
  1243. return this;
  1244. }
  1245. seed(s) {
  1246. if (s > 0 && s < 1)
  1247. s *= 65536;
  1248. s = Math.floor(s);
  1249. if (s < 256)
  1250. s |= s << 8;
  1251. for (let i = 0; i < 255; i++) {
  1252. let v = (i & 1) ? __noise_permTable[i] ^ (s & 255) : __noise_permTable[i] ^ ((s >> 8) & 255);
  1253. this.perm[i] = this.perm[i + 256] = v;
  1254. }
  1255. return this;
  1256. }
  1257. noise2D() {
  1258. let i = Math.max(0, Math.floor(this._n[0])) % 255;
  1259. let j = Math.max(0, Math.floor(this._n[1])) % 255;
  1260. let x = (this._n[0] % 255) - i;
  1261. let y = (this._n[1] % 255) - j;
  1262. let n00 = LinearAlgebra_1.Vec.dot(__noise_grad3[(i + this.perm[j]) % 12], [x, y, 0]);
  1263. let n01 = LinearAlgebra_1.Vec.dot(__noise_grad3[(i + this.perm[j + 1]) % 12], [x, y - 1, 0]);
  1264. let n10 = LinearAlgebra_1.Vec.dot(__noise_grad3[(i + 1 + this.perm[j]) % 12], [x - 1, y, 0]);
  1265. let n11 = LinearAlgebra_1.Vec.dot(__noise_grad3[(i + 1 + this.perm[j + 1]) % 12], [x - 1, y - 1, 0]);
  1266. let _fade = (f) => f * f * f * (f * (f * 6 - 15) + 10);
  1267. let tx = _fade(x);
  1268. return Num_1.Num.lerp(Num_1.Num.lerp(n00, n10, tx), Num_1.Num.lerp(n01, n11, tx), _fade(y));
  1269. }
  1270. }
  1271. exports.Noise = Noise;
  1272. class Delaunay extends Pt_1.Group {
  1273. constructor() {
  1274. super(...arguments);
  1275. this._mesh = [];
  1276. }
  1277. delaunay(triangleOnly = true) {
  1278. if (this.length < 3)
  1279. return [];
  1280. this._mesh = [];
  1281. let n = this.length;
  1282. let indices = [];
  1283. for (let i = 0; i < n; i++)
  1284. indices[i] = i;
  1285. indices.sort((i, j) => this[j][0] - this[i][0]);
  1286. let pts = this.slice();
  1287. let st = this._superTriangle();
  1288. pts = pts.concat(st);
  1289. let opened = [this._circum(n, n + 1, n + 2, st)];
  1290. let closed = [];
  1291. let tris = [];
  1292. for (let i = 0, len = indices.length; i < len; i++) {
  1293. let c = indices[i];
  1294. let edges = [];
  1295. let j = opened.length;
  1296. if (!this._mesh[c])
  1297. this._mesh[c] = {};
  1298. while (j--) {
  1299. let circum = opened[j];
  1300. let radius = circum.circle[1][0];
  1301. let d = pts[c].$subtract(circum.circle[0]);
  1302. if (d[0] > 0 && d[0] * d[0] > radius * radius) {
  1303. closed.push(circum);
  1304. tris.push(circum.triangle);
  1305. opened.splice(j, 1);
  1306. continue;
  1307. }
  1308. if (d[0] * d[0] + d[1] * d[1] - radius * radius > Util_1.Const.epsilon) {
  1309. continue;
  1310. }
  1311. edges.push(circum.i, circum.j, circum.j, circum.k, circum.k, circum.i);
  1312. opened.splice(j, 1);
  1313. }
  1314. Delaunay._dedupe(edges);
  1315. j = edges.length;
  1316. while (j > 1) {
  1317. opened.push(this._circum(edges[--j], edges[--j], c, false, pts));
  1318. }
  1319. }
  1320. for (let i = 0, len = opened.length; i < len; i++) {
  1321. let o = opened[i];
  1322. if (o.i < n && o.j < n && o.k < n) {
  1323. closed.push(o);
  1324. tris.push(o.triangle);
  1325. this._cache(o);
  1326. }
  1327. }
  1328. return (triangleOnly) ? tris : closed;
  1329. }
  1330. voronoi() {
  1331. let vs = [];
  1332. let n = this._mesh;
  1333. for (let i = 0, len = n.length; i < len; i++) {
  1334. vs.push(this.neighborPts(i, true));
  1335. }
  1336. return vs;
  1337. }
  1338. mesh() {
  1339. return this._mesh;
  1340. }
  1341. neighborPts(i, sort = false) {
  1342. let cs = new Pt_1.Group();
  1343. let n = this._mesh;
  1344. for (let k in n[i]) {
  1345. if (n[i].hasOwnProperty(k))
  1346. cs.push(n[i][k].circle[0]);
  1347. }
  1348. return (sort) ? Num_1.Geom.sortEdges(cs) : cs;
  1349. }
  1350. neighbors(i) {
  1351. let cs = [];
  1352. let n = this._mesh;
  1353. for (let k in n[i]) {
  1354. if (n[i].hasOwnProperty(k))
  1355. cs.push(n[i][k]);
  1356. }
  1357. return cs;
  1358. }
  1359. _cache(o) {
  1360. this._mesh[o.i][`${Math.min(o.j, o.k)}-${Math.max(o.j, o.k)}`] = o;
  1361. this._mesh[o.j][`${Math.min(o.i, o.k)}-${Math.max(o.i, o.k)}`] = o;
  1362. this._mesh[o.k][`${Math.min(o.i, o.j)}-${Math.max(o.i, o.j)}`] = o;
  1363. }
  1364. _superTriangle() {
  1365. let minPt = this[0];
  1366. let maxPt = this[0];
  1367. for (let i = 1, len = this.length; i < len; i++) {
  1368. minPt = minPt.$min(this[i]);
  1369. maxPt = maxPt.$max(this[i]);
  1370. }
  1371. let d = maxPt.$subtract(minPt);
  1372. let mid = minPt.$add(maxPt).divide(2);
  1373. let dmax = Math.max(d[0], d[1]);
  1374. return new Pt_1.Group(mid.$subtract(20 * dmax, dmax), mid.$add(0, 20 * dmax), mid.$add(20 * dmax, -dmax));
  1375. }
  1376. _triangle(i, j, k, pts = this) {
  1377. return new Pt_1.Group(pts[i], pts[j], pts[k]);
  1378. }
  1379. _circum(i, j, k, tri, pts = this) {
  1380. let t = tri || this._triangle(i, j, k, pts);
  1381. return {
  1382. i: i,
  1383. j: j,
  1384. k: k,
  1385. triangle: t,
  1386. circle: Op_1.Triangle.circumcircle(t)
  1387. };
  1388. }
  1389. static _dedupe(edges) {
  1390. let j = edges.length;
  1391. while (j > 1) {
  1392. let b = edges[--j];
  1393. let a = edges[--j];
  1394. let i = j;
  1395. while (i > 1) {
  1396. let n = edges[--i];
  1397. let m = edges[--i];
  1398. if ((a == m && b == n) || (a == n && b == m)) {
  1399. edges.splice(j, 2);
  1400. edges.splice(i, 2);
  1401. break;
  1402. }
  1403. }
  1404. }
  1405. return edges;
  1406. }
  1407. }
  1408. exports.Delaunay = Delaunay;
  1409. /***/ }),
  1410. /***/ "./src/Dom.ts":
  1411. /*!********************!*\
  1412. !*** ./src/Dom.ts ***!
  1413. \********************/
  1414. /*! no static exports found */
  1415. /***/ (function(module, exports, __webpack_require__) {
  1416. "use strict";
  1417. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  1418. Object.defineProperty(exports, "__esModule", { value: true });
  1419. exports.HTMLForm = exports.HTMLSpace = exports.DOMSpace = void 0;
  1420. const Space_1 = __webpack_require__(/*! ./Space */ "./src/Space.ts");
  1421. const Form_1 = __webpack_require__(/*! ./Form */ "./src/Form.ts");
  1422. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  1423. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  1424. class DOMSpace extends Space_1.MultiTouchSpace {
  1425. constructor(elem, callback) {
  1426. super();
  1427. this.id = "domspace";
  1428. this._autoResize = true;
  1429. this._bgcolor = "#e1e9f0";
  1430. this._css = {};
  1431. var _selector = null;
  1432. var _existed = false;
  1433. this.id = "pts";
  1434. if (elem instanceof Element) {
  1435. _selector = elem;
  1436. this.id = "pts_existing_space";
  1437. }
  1438. else {
  1439. _selector = document.querySelector(elem);
  1440. _existed = true;
  1441. this.id = elem.substr(1);
  1442. }
  1443. if (!_selector) {
  1444. this._container = DOMSpace.createElement("div", "pts_container");
  1445. this._canvas = DOMSpace.createElement("div", "pts_element");
  1446. this._container.appendChild(this._canvas);
  1447. document.body.appendChild(this._container);
  1448. _existed = false;
  1449. }
  1450. else {
  1451. this._canvas = _selector;
  1452. this._container = _selector.parentElement;
  1453. }
  1454. setTimeout(this._ready.bind(this, callback), 50);
  1455. }
  1456. static createElement(elem = "div", id, appendTo) {
  1457. let d = document.createElement(elem);
  1458. if (id)
  1459. d.setAttribute("id", id);
  1460. if (appendTo && appendTo.appendChild)
  1461. appendTo.appendChild(d);
  1462. return d;
  1463. }
  1464. _ready(callback) {
  1465. if (!this._container)
  1466. throw new Error(`Cannot initiate #${this.id} element`);
  1467. this._isReady = true;
  1468. this._resizeHandler(null);
  1469. this.clear(this._bgcolor);
  1470. this._canvas.dispatchEvent(new Event("ready"));
  1471. for (let k in this.players) {
  1472. if (this.players.hasOwnProperty(k)) {
  1473. if (this.players[k].start)
  1474. this.players[k].start(this.bound.clone(), this);
  1475. }
  1476. }
  1477. this._pointer = this.center;
  1478. this.refresh(false);
  1479. if (callback)
  1480. callback(this.bound, this._canvas);
  1481. }
  1482. setup(opt) {
  1483. if (opt.bgcolor) {
  1484. this._bgcolor = opt.bgcolor;
  1485. }
  1486. this.autoResize = (opt.resize != undefined) ? opt.resize : false;
  1487. return this;
  1488. }
  1489. getForm() {
  1490. return null;
  1491. }
  1492. set autoResize(auto) {
  1493. this._autoResize = auto;
  1494. if (auto) {
  1495. window.addEventListener('resize', this._resizeHandler.bind(this));
  1496. }
  1497. else {
  1498. delete this._css['width'];
  1499. delete this._css['height'];
  1500. window.removeEventListener('resize', this._resizeHandler.bind(this));
  1501. }
  1502. }
  1503. get autoResize() { return this._autoResize; }
  1504. resize(b, evt) {
  1505. this.bound = b;
  1506. this.styles({ width: `${b.width}px`, height: `${b.height}px` }, true);
  1507. for (let k in this.players) {
  1508. if (this.players.hasOwnProperty(k)) {
  1509. let p = this.players[k];
  1510. if (p.resize)
  1511. p.resize(this.bound, evt);
  1512. }
  1513. }
  1514. return this;
  1515. }
  1516. _resizeHandler(evt) {
  1517. let b = Pt_1.Bound.fromBoundingRect(this._container.getBoundingClientRect());
  1518. if (this._autoResize) {
  1519. this.styles({ width: "100%", height: "100%" }, true);
  1520. }
  1521. else {
  1522. this.styles({ width: `${b.width}px`, height: `${b.height}px` }, true);
  1523. }
  1524. this.resize(b, evt);
  1525. }
  1526. get element() {
  1527. return this._canvas;
  1528. }
  1529. get parent() {
  1530. return this._container;
  1531. }
  1532. get ready() { return this._isReady; }
  1533. clear(bg) {
  1534. if (bg)
  1535. this.background = bg;
  1536. this._canvas.innerHTML = "";
  1537. return this;
  1538. }
  1539. set background(bg) {
  1540. this._bgcolor = bg;
  1541. this._container.style.backgroundColor = this._bgcolor;
  1542. }
  1543. get background() { return this._bgcolor; }
  1544. style(key, val, update = false) {
  1545. this._css[key] = val;
  1546. if (update)
  1547. this._canvas.style[key] = val;
  1548. return this;
  1549. }
  1550. styles(styles, update = false) {
  1551. for (let k in styles) {
  1552. if (styles.hasOwnProperty(k))
  1553. this.style(k, styles[k], update);
  1554. }
  1555. return this;
  1556. }
  1557. static setAttr(elem, data) {
  1558. for (let k in data) {
  1559. if (data.hasOwnProperty(k)) {
  1560. elem.setAttribute(k, data[k]);
  1561. }
  1562. }
  1563. return elem;
  1564. }
  1565. static getInlineStyles(data) {
  1566. let str = "";
  1567. for (let k in data) {
  1568. if (data.hasOwnProperty(k)) {
  1569. if (data[k])
  1570. str += `${k}: ${data[k]}; `;
  1571. }
  1572. }
  1573. return str;
  1574. }
  1575. dispose() {
  1576. window.removeEventListener('resize', this._resizeHandler.bind(this));
  1577. this.stop();
  1578. this.removeAll();
  1579. return this;
  1580. }
  1581. }
  1582. exports.DOMSpace = DOMSpace;
  1583. class HTMLSpace extends DOMSpace {
  1584. getForm() {
  1585. return new HTMLForm(this);
  1586. }
  1587. static htmlElement(parent, name, id, autoClass = true) {
  1588. if (!parent || !parent.appendChild)
  1589. throw new Error("parent is not a valid DOM element");
  1590. let elem = document.querySelector(`#${id}`);
  1591. if (!elem) {
  1592. elem = document.createElement(name);
  1593. elem.setAttribute("id", id);
  1594. if (autoClass)
  1595. elem.setAttribute("class", id.substring(0, id.indexOf("-")));
  1596. parent.appendChild(elem);
  1597. }
  1598. return elem;
  1599. }
  1600. remove(player) {
  1601. let temp = this._container.querySelectorAll("." + HTMLForm.scopeID(player));
  1602. temp.forEach((el) => {
  1603. el.parentNode.removeChild(el);
  1604. });
  1605. return super.remove(player);
  1606. }
  1607. removeAll() {
  1608. this._container.innerHTML = "";
  1609. return super.removeAll();
  1610. }
  1611. }
  1612. exports.HTMLSpace = HTMLSpace;
  1613. class HTMLForm extends Form_1.VisualForm {
  1614. constructor(space) {
  1615. super();
  1616. this._style = {
  1617. "filled": true,
  1618. "stroked": true,
  1619. "background": "#f03",
  1620. "border-color": "#fff",
  1621. "color": "#000",
  1622. "border-width": "1px",
  1623. "border-radius": "0",
  1624. "border-style": "solid",
  1625. "opacity": 1,
  1626. "position": "absolute",
  1627. "top": 0,
  1628. "left": 0,
  1629. "width": 0,
  1630. "height": 0
  1631. };
  1632. this._ctx = {
  1633. group: null,
  1634. groupID: "pts",
  1635. groupCount: 0,
  1636. currentID: "pts0",
  1637. currentClass: "",
  1638. style: {},
  1639. };
  1640. this._ready = false;
  1641. this._space = space;
  1642. this._space.add({ start: () => {
  1643. this._ctx.group = this._space.element;
  1644. this._ctx.groupID = "pts_dom_" + (HTMLForm.groupID++);
  1645. this._ctx.style = Object.assign({}, this._style);
  1646. this._ready = true;
  1647. } });
  1648. }
  1649. get space() { return this._space; }
  1650. styleTo(k, v, unit = '') {
  1651. if (this._ctx.style[k] === undefined)
  1652. throw new Error(`${k} style property doesn't exist`);
  1653. this._ctx.style[k] = `${v}${unit}`;
  1654. }
  1655. alpha(a) {
  1656. this.styleTo("opacity", a);
  1657. return this;
  1658. }
  1659. fill(c) {
  1660. if (typeof c == "boolean") {
  1661. this.styleTo("filled", c);
  1662. if (!c)
  1663. this.styleTo("background", "transparent");
  1664. }
  1665. else {
  1666. this.styleTo("filled", true);
  1667. this.styleTo("background", c);
  1668. }
  1669. return this;
  1670. }
  1671. stroke(c, width, linejoin, linecap) {
  1672. if (typeof c == "boolean") {
  1673. this.styleTo("stroked", c);
  1674. if (!c)
  1675. this.styleTo("border-width", 0);
  1676. }
  1677. else {
  1678. this.styleTo("stroked", true);
  1679. this.styleTo("border-color", c);
  1680. this.styleTo("border-width", (width || 1) + "px");
  1681. }
  1682. return this;
  1683. }
  1684. fillText(c) {
  1685. this.styleTo("color", c);
  1686. return this;
  1687. }
  1688. cls(c) {
  1689. if (typeof c == "boolean") {
  1690. this._ctx.currentClass = "";
  1691. }
  1692. else {
  1693. this._ctx.currentClass = c;
  1694. }
  1695. return this;
  1696. }
  1697. font(sizeOrFont, weight, style, lineHeight, family) {
  1698. if (typeof sizeOrFont == "number") {
  1699. this._font.size = sizeOrFont;
  1700. if (family)
  1701. this._font.face = family;
  1702. if (weight)
  1703. this._font.weight = weight;
  1704. if (style)
  1705. this._font.style = style;
  1706. if (lineHeight)
  1707. this._font.lineHeight = lineHeight;
  1708. }
  1709. else {
  1710. this._font = sizeOrFont;
  1711. }
  1712. this._ctx.style['font'] = this._font.value;
  1713. return this;
  1714. }
  1715. reset() {
  1716. this._ctx.style = Object.assign({}, this._style);
  1717. this._font = new Form_1.Font(10, "sans-serif");
  1718. this._ctx.style['font'] = this._font.value;
  1719. return this;
  1720. }
  1721. updateScope(group_id, group) {
  1722. this._ctx.group = group;
  1723. this._ctx.groupID = group_id;
  1724. this._ctx.groupCount = 0;
  1725. this.nextID();
  1726. return this._ctx;
  1727. }
  1728. scope(item) {
  1729. if (!item || item.animateID == null)
  1730. throw new Error("item not defined or not yet added to Space");
  1731. return this.updateScope(HTMLForm.scopeID(item), this.space.element);
  1732. }
  1733. nextID() {
  1734. this._ctx.groupCount++;
  1735. this._ctx.currentID = `${this._ctx.groupID}-${this._ctx.groupCount}`;
  1736. return this._ctx.currentID;
  1737. }
  1738. static getID(ctx) {
  1739. return ctx.currentID || `p-${HTMLForm.domID++}`;
  1740. }
  1741. static scopeID(item) {
  1742. return `item-${item.animateID}`;
  1743. }
  1744. static style(elem, styles) {
  1745. let st = [];
  1746. if (!styles["filled"])
  1747. st.push("background: none");
  1748. if (!styles["stroked"])
  1749. st.push("border: none");
  1750. for (let k in styles) {
  1751. if (styles.hasOwnProperty(k) && k != "filled" && k != "stroked") {
  1752. let v = styles[k];
  1753. if (v) {
  1754. if (!styles["filled"] && k.indexOf('background') === 0) {
  1755. continue;
  1756. }
  1757. else if (!styles["stroked"] && k.indexOf('border-width') === 0) {
  1758. continue;
  1759. }
  1760. else {
  1761. st.push(`${k}: ${v}`);
  1762. }
  1763. }
  1764. }
  1765. }
  1766. return HTMLSpace.setAttr(elem, { style: st.join(";") });
  1767. }
  1768. static rectStyle(ctx, pt, size) {
  1769. ctx.style["left"] = pt[0] + "px";
  1770. ctx.style["top"] = pt[1] + "px";
  1771. ctx.style["width"] = size[0] + "px";
  1772. ctx.style["height"] = size[1] + "px";
  1773. return ctx;
  1774. }
  1775. static textStyle(ctx, pt) {
  1776. ctx.style["left"] = pt[0] + "px";
  1777. ctx.style["top"] = pt[1] + "px";
  1778. return ctx;
  1779. }
  1780. static point(ctx, pt, radius = 5, shape = "square") {
  1781. if (shape === "circle") {
  1782. return HTMLForm.circle(ctx, pt, radius);
  1783. }
  1784. else {
  1785. return HTMLForm.square(ctx, pt, radius);
  1786. }
  1787. }
  1788. point(pt, radius = 5, shape = "square") {
  1789. this.nextID();
  1790. if (shape == "circle")
  1791. this.styleTo("border-radius", "100%");
  1792. HTMLForm.point(this._ctx, pt, radius, shape);
  1793. return this;
  1794. }
  1795. static circle(ctx, pt, radius = 10) {
  1796. let elem = HTMLSpace.htmlElement(ctx.group, "div", HTMLForm.getID(ctx));
  1797. HTMLSpace.setAttr(elem, { class: `pts-form pts-circle ${ctx.currentClass}` });
  1798. HTMLForm.rectStyle(ctx, new Pt_1.Pt(pt).$subtract(radius), new Pt_1.Pt(radius * 2, radius * 2));
  1799. HTMLForm.style(elem, ctx.style);
  1800. return elem;
  1801. }
  1802. circle(pts) {
  1803. this.nextID();
  1804. this.styleTo("border-radius", "100%");
  1805. HTMLForm.circle(this._ctx, pts[0], pts[1][0]);
  1806. return this;
  1807. }
  1808. static square(ctx, pt, halfsize) {
  1809. let elem = HTMLSpace.htmlElement(ctx.group, "div", HTMLForm.getID(ctx));
  1810. HTMLSpace.setAttr(elem, { class: `pts-form pts-square ${ctx.currentClass}` });
  1811. HTMLForm.rectStyle(ctx, new Pt_1.Pt(pt).$subtract(halfsize), new Pt_1.Pt(halfsize * 2, halfsize * 2));
  1812. HTMLForm.style(elem, ctx.style);
  1813. return elem;
  1814. }
  1815. square(pt, halfsize) {
  1816. this.nextID();
  1817. HTMLForm.square(this._ctx, pt, halfsize);
  1818. return this;
  1819. }
  1820. static rect(ctx, pts) {
  1821. let p = Util_1.Util.iterToArray(pts);
  1822. if (!Util_1.Util.arrayCheck(p))
  1823. return;
  1824. let elem = HTMLSpace.htmlElement(ctx.group, "div", HTMLForm.getID(ctx));
  1825. HTMLSpace.setAttr(elem, { class: `pts-form pts-rect ${ctx.currentClass}` });
  1826. HTMLForm.rectStyle(ctx, p[0], p[1]);
  1827. HTMLForm.style(elem, ctx.style);
  1828. return elem;
  1829. }
  1830. rect(pts) {
  1831. this.nextID();
  1832. this.styleTo("border-radius", "0");
  1833. HTMLForm.rect(this._ctx, pts);
  1834. return this;
  1835. }
  1836. static text(ctx, pt, txt) {
  1837. let elem = HTMLSpace.htmlElement(ctx.group, "div", HTMLForm.getID(ctx));
  1838. HTMLSpace.setAttr(elem, { class: `pts-form pts-text ${ctx.currentClass}` });
  1839. elem.textContent = txt;
  1840. HTMLForm.textStyle(ctx, pt);
  1841. HTMLForm.style(elem, ctx.style);
  1842. return elem;
  1843. }
  1844. text(pt, txt) {
  1845. this.nextID();
  1846. HTMLForm.text(this._ctx, pt, txt);
  1847. return this;
  1848. }
  1849. log(txt) {
  1850. this.fill("#000").stroke("#fff", 0.5).text([10, 14], txt);
  1851. return this;
  1852. }
  1853. arc(pt, radius, startAngle, endAngle, cc) {
  1854. Util_1.Util.warn("arc is not implemented in HTMLForm");
  1855. return this;
  1856. }
  1857. line(pts) {
  1858. Util_1.Util.warn("line is not implemented in HTMLForm");
  1859. return this;
  1860. }
  1861. polygon(pts) {
  1862. Util_1.Util.warn("polygon is not implemented in HTMLForm");
  1863. return this;
  1864. }
  1865. }
  1866. exports.HTMLForm = HTMLForm;
  1867. HTMLForm.groupID = 0;
  1868. HTMLForm.domID = 0;
  1869. /***/ }),
  1870. /***/ "./src/Form.ts":
  1871. /*!*********************!*\
  1872. !*** ./src/Form.ts ***!
  1873. \*********************/
  1874. /*! no static exports found */
  1875. /***/ (function(module, exports, __webpack_require__) {
  1876. "use strict";
  1877. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  1878. Object.defineProperty(exports, "__esModule", { value: true });
  1879. exports.Font = exports.VisualForm = exports.Form = void 0;
  1880. class Form {
  1881. constructor() {
  1882. this._ready = false;
  1883. }
  1884. get ready() { return this._ready; }
  1885. }
  1886. exports.Form = Form;
  1887. class VisualForm extends Form {
  1888. constructor() {
  1889. super(...arguments);
  1890. this._filled = true;
  1891. this._stroked = true;
  1892. this._font = new Font(14, "sans-serif");
  1893. }
  1894. get filled() { return this._filled; }
  1895. set filled(b) { this._filled = b; }
  1896. get stroked() { return this._stroked; }
  1897. set stroked(b) { this._stroked = b; }
  1898. get currentFont() { return this._font; }
  1899. _multiple(groups, shape, ...rest) {
  1900. if (!groups)
  1901. return this;
  1902. for (let i = 0, len = groups.length; i < len; i++) {
  1903. this[shape](groups[i], ...rest);
  1904. }
  1905. return this;
  1906. }
  1907. alpha(a) {
  1908. return this;
  1909. }
  1910. fill(c) {
  1911. return this;
  1912. }
  1913. fillOnly(c) {
  1914. this.stroke(false);
  1915. return this.fill(c);
  1916. }
  1917. stroke(c, width, linejoin, linecap) {
  1918. return this;
  1919. }
  1920. strokeOnly(c, width, linejoin, linecap) {
  1921. this.fill(false);
  1922. return this.stroke(c, width, linejoin, linecap);
  1923. }
  1924. points(pts, radius, shape) {
  1925. if (!pts)
  1926. return;
  1927. for (let i = 0, len = pts.length; i < len; i++) {
  1928. this.point(pts[i], radius, shape);
  1929. }
  1930. return this;
  1931. }
  1932. circles(groups) {
  1933. return this._multiple(groups, "circle");
  1934. }
  1935. squares(groups) {
  1936. return this._multiple(groups, "square");
  1937. }
  1938. lines(groups) {
  1939. return this._multiple(groups, "line");
  1940. }
  1941. polygons(groups) {
  1942. return this._multiple(groups, "polygon");
  1943. }
  1944. rects(groups) {
  1945. return this._multiple(groups, "rect");
  1946. }
  1947. }
  1948. exports.VisualForm = VisualForm;
  1949. class Font {
  1950. constructor(size = 12, face = "sans-serif", weight = "", style = "", lineHeight = 1.5) {
  1951. this.size = size;
  1952. this.face = face;
  1953. this.style = style;
  1954. this.weight = weight;
  1955. this.lineHeight = lineHeight;
  1956. }
  1957. get value() { return `${this.style} ${this.weight} ${this.size}px/${this.lineHeight} ${this.face}`; }
  1958. toString() { return this.value; }
  1959. }
  1960. exports.Font = Font;
  1961. /***/ }),
  1962. /***/ "./src/Image.ts":
  1963. /*!**********************!*\
  1964. !*** ./src/Image.ts ***!
  1965. \**********************/
  1966. /*! no static exports found */
  1967. /***/ (function(module, exports, __webpack_require__) {
  1968. "use strict";
  1969. Object.defineProperty(exports, "__esModule", { value: true });
  1970. exports.Img = void 0;
  1971. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  1972. class Img {
  1973. constructor(editable = false, pixelScale = 1, crossOrigin) {
  1974. this._scale = 1;
  1975. this._loaded = false;
  1976. this._editable = editable;
  1977. this._scale = pixelScale;
  1978. this._img = new Image();
  1979. if (crossOrigin)
  1980. this._img.crossOrigin = "Anonymous";
  1981. }
  1982. static load(src, editable = false, pixelScale = 1, ready) {
  1983. let img = new Img(editable, pixelScale);
  1984. img.load(src).then(res => {
  1985. if (ready)
  1986. ready(res);
  1987. });
  1988. return img;
  1989. }
  1990. load(src) {
  1991. return new Promise((resolve, reject) => {
  1992. this._img.src = src;
  1993. this._img.onload = () => {
  1994. if (this._editable) {
  1995. if (!this._cv)
  1996. this._cv = document.createElement("canvas");
  1997. this._drawToScale(this._scale, this._img);
  1998. this._data = this._ctx.getImageData(0, 0, this._cv.width, this._cv.height);
  1999. }
  2000. this._loaded = true;
  2001. resolve(this);
  2002. };
  2003. this._img.onerror = (evt) => {
  2004. reject(evt);
  2005. };
  2006. });
  2007. }
  2008. _drawToScale(canvasScale, img) {
  2009. const cms = (typeof canvasScale === 'number') ? [canvasScale, canvasScale] : canvasScale;
  2010. const nw = img.width;
  2011. const nh = img.height;
  2012. this._cv.width = nw * cms[0];
  2013. this._cv.height = nh * cms[1];
  2014. this._ctx = this._cv.getContext('2d');
  2015. if (img)
  2016. this._ctx.drawImage(img, 0, 0, nw, nh, 0, 0, this._cv.width, this._cv.height);
  2017. }
  2018. bitmap(size) {
  2019. const w = (size) ? size[0] : this._cv.width;
  2020. const h = (size) ? size[1] : this._cv.height;
  2021. return createImageBitmap(this._cv, 0, 0, w, h);
  2022. }
  2023. sync() {
  2024. if (this._scale !== 1) {
  2025. this.bitmap().then(b => {
  2026. this._drawToScale(1 / this._scale, b);
  2027. this.load(this.toBase64());
  2028. });
  2029. }
  2030. else {
  2031. this._img.src = this.toBase64();
  2032. }
  2033. }
  2034. pixel(p, rescale = true) {
  2035. const s = (typeof rescale == 'number') ? rescale : (rescale ? this._scale : 1);
  2036. return Img.getPixel(this._data, [p[0] * s, p[1] * s]);
  2037. }
  2038. static getPixel(imgData, p) {
  2039. const no = new Pt_1.Pt(0, 0, 0, 0);
  2040. if (p[0] >= imgData.width || p[1] >= imgData.height)
  2041. return no;
  2042. const i = Math.floor(p[1]) * (imgData.width * 4) + (Math.floor(p[0]) * 4);
  2043. const d = imgData.data;
  2044. if (i >= d.length - 4)
  2045. return no;
  2046. return new Pt_1.Pt(d[i], d[i + 1], d[i + 2], d[i + 3]);
  2047. }
  2048. resize(sizeOrScale, asScale = false) {
  2049. let s = asScale ? sizeOrScale : [sizeOrScale[0] / this._img.naturalWidth, sizeOrScale[1] / this._img.naturalHeight];
  2050. this._drawToScale(s, this._img);
  2051. this._data = this._ctx.getImageData(0, 0, this._cv.width, this._cv.height);
  2052. return this;
  2053. }
  2054. crop(box) {
  2055. let p = box.topLeft.scale(this._scale);
  2056. let s = box.size.scale(this._scale);
  2057. return this._ctx.getImageData(p.x, p.y, s.x, s.y);
  2058. }
  2059. filter(css) {
  2060. this._ctx.filter = css;
  2061. this._ctx.drawImage(this._cv, 0, 0);
  2062. this._ctx.filter = "none";
  2063. return this;
  2064. }
  2065. cleanup() {
  2066. if (this._cv)
  2067. this._cv.remove();
  2068. if (this._img)
  2069. this._img.remove();
  2070. this._data = null;
  2071. }
  2072. static fromBlob(blob, editable = false, pixelScale = 1) {
  2073. let url = URL.createObjectURL(blob);
  2074. return new Img(editable, pixelScale).load(url);
  2075. }
  2076. static imageDataToBlob(data) {
  2077. return new Promise(function (resolve) {
  2078. let cv = document.createElement("canvas");
  2079. cv.width = data.width;
  2080. cv.height = data.height;
  2081. cv.getContext("2d").putImageData(data, 0, 0);
  2082. cv.toBlob(blob => {
  2083. resolve(blob);
  2084. cv.remove();
  2085. });
  2086. });
  2087. }
  2088. toBase64() {
  2089. return this._cv.toDataURL();
  2090. }
  2091. toBlob() {
  2092. return new Promise((resolve) => {
  2093. this._cv.toBlob(blob => resolve(blob));
  2094. });
  2095. }
  2096. get current() {
  2097. return this._editable ? this._cv : this._img;
  2098. }
  2099. get image() {
  2100. return this._img;
  2101. }
  2102. get canvas() {
  2103. return this._cv;
  2104. }
  2105. get data() {
  2106. return this._data;
  2107. }
  2108. get ctx() {
  2109. return this._ctx;
  2110. }
  2111. get loaded() {
  2112. return this._loaded;
  2113. }
  2114. get pixelScale() {
  2115. return this._scale;
  2116. }
  2117. get imageSize() {
  2118. return new Pt_1.Pt(this._img.width, this._img.height);
  2119. }
  2120. get canvasSize() {
  2121. return new Pt_1.Pt(this._cv.width, this._cv.height);
  2122. }
  2123. }
  2124. exports.Img = Img;
  2125. /***/ }),
  2126. /***/ "./src/LinearAlgebra.ts":
  2127. /*!******************************!*\
  2128. !*** ./src/LinearAlgebra.ts ***!
  2129. \******************************/
  2130. /*! no static exports found */
  2131. /***/ (function(module, exports, __webpack_require__) {
  2132. "use strict";
  2133. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  2134. Object.defineProperty(exports, "__esModule", { value: true });
  2135. exports.Mat = exports.Vec = void 0;
  2136. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  2137. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  2138. class Vec {
  2139. static add(a, b) {
  2140. if (typeof b == "number") {
  2141. for (let i = 0, len = a.length; i < len; i++)
  2142. a[i] += b;
  2143. }
  2144. else {
  2145. for (let i = 0, len = a.length; i < len; i++)
  2146. a[i] += b[i] || 0;
  2147. }
  2148. return a;
  2149. }
  2150. static subtract(a, b) {
  2151. if (typeof b == "number") {
  2152. for (let i = 0, len = a.length; i < len; i++)
  2153. a[i] -= b;
  2154. }
  2155. else {
  2156. for (let i = 0, len = a.length; i < len; i++)
  2157. a[i] -= b[i] || 0;
  2158. }
  2159. return a;
  2160. }
  2161. static multiply(a, b) {
  2162. if (typeof b == "number") {
  2163. for (let i = 0, len = a.length; i < len; i++)
  2164. a[i] *= b;
  2165. }
  2166. else {
  2167. if (a.length != b.length) {
  2168. throw new Error(`Cannot do element-wise multiply since the array lengths don't match: ${a.toString()} multiply-with ${b.toString()}`);
  2169. }
  2170. for (let i = 0, len = a.length; i < len; i++)
  2171. a[i] *= b[i];
  2172. }
  2173. return a;
  2174. }
  2175. static divide(a, b) {
  2176. if (typeof b == "number") {
  2177. if (b === 0)
  2178. throw new Error("Cannot divide by zero");
  2179. for (let i = 0, len = a.length; i < len; i++)
  2180. a[i] /= b;
  2181. }
  2182. else {
  2183. if (a.length != b.length) {
  2184. throw new Error(`Cannot do element-wise divide since the array lengths don't match. ${a.toString()} divide-by ${b.toString()}`);
  2185. }
  2186. for (let i = 0, len = a.length; i < len; i++)
  2187. a[i] /= b[i];
  2188. }
  2189. return a;
  2190. }
  2191. static dot(a, b) {
  2192. if (a.length != b.length)
  2193. throw new Error("Array lengths don't match");
  2194. let d = 0;
  2195. for (let i = 0, len = a.length; i < len; i++) {
  2196. d += a[i] * b[i];
  2197. }
  2198. return d;
  2199. }
  2200. static cross2D(a, b) {
  2201. return a[0] * b[1] - a[1] * b[0];
  2202. }
  2203. static cross(a, b) {
  2204. return new Pt_1.Pt((a[1] * b[2] - a[2] * b[1]), (a[2] * b[0] - a[0] * b[2]), (a[0] * b[1] - a[1] * b[0]));
  2205. }
  2206. static magnitude(a) {
  2207. return Math.sqrt(Vec.dot(a, a));
  2208. }
  2209. static unit(a, magnitude = undefined) {
  2210. let m = (magnitude === undefined) ? Vec.magnitude(a) : magnitude;
  2211. if (m === 0)
  2212. return Pt_1.Pt.make(a.length);
  2213. return Vec.divide(a, m);
  2214. }
  2215. static abs(a) {
  2216. return Vec.map(a, Math.abs);
  2217. }
  2218. static floor(a) {
  2219. return Vec.map(a, Math.floor);
  2220. }
  2221. static ceil(a) {
  2222. return Vec.map(a, Math.ceil);
  2223. }
  2224. static round(a) {
  2225. return Vec.map(a, Math.round);
  2226. }
  2227. static max(a) {
  2228. let m = Number.MIN_VALUE;
  2229. let index = 0;
  2230. for (let i = 0, len = a.length; i < len; i++) {
  2231. m = Math.max(m, a[i]);
  2232. if (m === a[i])
  2233. index = i;
  2234. }
  2235. return { value: m, index: index };
  2236. }
  2237. static min(a) {
  2238. let m = Number.MAX_VALUE;
  2239. let index = 0;
  2240. for (let i = 0, len = a.length; i < len; i++) {
  2241. m = Math.min(m, a[i]);
  2242. if (m === a[i])
  2243. index = i;
  2244. }
  2245. return { value: m, index: index };
  2246. }
  2247. static sum(a) {
  2248. let s = 0;
  2249. for (let i = 0, len = a.length; i < len; i++)
  2250. s += a[i];
  2251. return s;
  2252. }
  2253. static map(a, fn) {
  2254. for (let i = 0, len = a.length; i < len; i++) {
  2255. a[i] = fn(a[i], i, a);
  2256. }
  2257. return a;
  2258. }
  2259. }
  2260. exports.Vec = Vec;
  2261. class Mat {
  2262. static add(a, b) {
  2263. if (typeof b != "number") {
  2264. if (a[0].length != b[0].length)
  2265. throw new Error("Cannot add matrix if rows' and columns' size don't match.");
  2266. if (a.length != b.length)
  2267. throw new Error("Cannot add matrix if rows' and columns' size don't match.");
  2268. }
  2269. let g = new Pt_1.Group();
  2270. let isNum = typeof b == "number";
  2271. for (let i = 0, len = a.length; i < len; i++) {
  2272. g.push(a[i].$add((isNum) ? b : b[i]));
  2273. }
  2274. return g;
  2275. }
  2276. static multiply(a, b, transposed = false, elementwise = false) {
  2277. let g = new Pt_1.Group();
  2278. if (typeof b != "number") {
  2279. if (elementwise) {
  2280. if (a.length != b.length)
  2281. throw new Error("Cannot multiply matrix element-wise because the matrices' sizes don't match.");
  2282. for (let ai = 0, alen = a.length; ai < alen; ai++) {
  2283. g.push(a[ai].$multiply(b[ai]));
  2284. }
  2285. }
  2286. else {
  2287. if (!transposed && a[0].length != b.length)
  2288. throw new Error("Cannot multiply matrix if rows in matrix-a don't match columns in matrix-b.");
  2289. if (transposed && a[0].length != b[0].length)
  2290. throw new Error("Cannot multiply matrix if transposed and the columns in both matrices don't match.");
  2291. if (!transposed)
  2292. b = Mat.transpose(b);
  2293. for (let ai = 0, alen = a.length; ai < alen; ai++) {
  2294. let p = Pt_1.Pt.make(b.length, 0);
  2295. for (let bi = 0, blen = b.length; bi < blen; bi++) {
  2296. p[bi] = Vec.dot(a[ai], b[bi]);
  2297. }
  2298. g.push(p);
  2299. }
  2300. }
  2301. }
  2302. else {
  2303. for (let ai = 0, alen = a.length; ai < alen; ai++) {
  2304. g.push(a[ai].$multiply(b));
  2305. }
  2306. }
  2307. return g;
  2308. }
  2309. static zipSlice(g, index, defaultValue = false) {
  2310. let z = [];
  2311. for (let i = 0, len = g.length; i < len; i++) {
  2312. if (g[i].length - 1 < index && defaultValue === false)
  2313. throw `Index ${index} is out of bounds`;
  2314. z.push(g[i][index] || defaultValue);
  2315. }
  2316. return new Pt_1.Pt(z);
  2317. }
  2318. static zip(g, defaultValue = false, useLongest = false) {
  2319. let ps = new Pt_1.Group();
  2320. let len = (useLongest) ? g.reduce((a, b) => Math.max(a, b.length), 0) : g[0].length;
  2321. for (let i = 0; i < len; i++) {
  2322. ps.push(Mat.zipSlice(g, i, defaultValue));
  2323. }
  2324. return ps;
  2325. }
  2326. static transpose(g, defaultValue = false, useLongest = false) {
  2327. return Mat.zip(g, defaultValue, useLongest);
  2328. }
  2329. static transform2D(pt, m) {
  2330. let x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];
  2331. let y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];
  2332. return new Pt_1.Pt(x, y);
  2333. }
  2334. static scale2DMatrix(x, y) {
  2335. return new Pt_1.Group(new Pt_1.Pt(x, 0, 0), new Pt_1.Pt(0, y, 0), new Pt_1.Pt(0, 0, 1));
  2336. }
  2337. static rotate2DMatrix(cosA, sinA) {
  2338. return new Pt_1.Group(new Pt_1.Pt(cosA, sinA, 0), new Pt_1.Pt(-sinA, cosA, 0), new Pt_1.Pt(0, 0, 1));
  2339. }
  2340. static shear2DMatrix(tanX, tanY) {
  2341. return new Pt_1.Group(new Pt_1.Pt(1, tanX, 0), new Pt_1.Pt(tanY, 1, 0), new Pt_1.Pt(0, 0, 1));
  2342. }
  2343. static translate2DMatrix(x, y) {
  2344. return new Pt_1.Group(new Pt_1.Pt(1, 0, 0), new Pt_1.Pt(0, 1, 0), new Pt_1.Pt(x, y, 1));
  2345. }
  2346. static scaleAt2DMatrix(sx, sy, at) {
  2347. let m = Mat.scale2DMatrix(sx, sy);
  2348. m[2][0] = -at[0] * sx + at[0];
  2349. m[2][1] = -at[1] * sy + at[1];
  2350. return m;
  2351. }
  2352. static rotateAt2DMatrix(cosA, sinA, at) {
  2353. let m = Mat.rotate2DMatrix(cosA, sinA);
  2354. m[2][0] = at[0] * (1 - cosA) + at[1] * sinA;
  2355. m[2][1] = at[1] * (1 - cosA) - at[0] * sinA;
  2356. return m;
  2357. }
  2358. static shearAt2DMatrix(tanX, tanY, at) {
  2359. let m = Mat.shear2DMatrix(tanX, tanY);
  2360. m[2][0] = -at[1] * tanY;
  2361. m[2][1] = -at[0] * tanX;
  2362. return m;
  2363. }
  2364. static reflectAt2DMatrix(p1, p2) {
  2365. let intercept = Op_1.Line.intercept(p1, p2);
  2366. if (intercept == undefined) {
  2367. return [
  2368. new Pt_1.Pt([-1, 0, 0]),
  2369. new Pt_1.Pt([0, 1, 0]),
  2370. new Pt_1.Pt([p1[0] + p2[0], 0, 1])
  2371. ];
  2372. }
  2373. else {
  2374. let yi = intercept.yi;
  2375. let ang2 = Math.atan(intercept.slope) * 2;
  2376. let cosA = Math.cos(ang2);
  2377. let sinA = Math.sin(ang2);
  2378. return [
  2379. new Pt_1.Pt([cosA, sinA, 0]),
  2380. new Pt_1.Pt([sinA, -cosA, 0]),
  2381. new Pt_1.Pt([-yi * sinA, yi + yi * cosA, 1])
  2382. ];
  2383. }
  2384. }
  2385. }
  2386. exports.Mat = Mat;
  2387. /***/ }),
  2388. /***/ "./src/Num.ts":
  2389. /*!********************!*\
  2390. !*** ./src/Num.ts ***!
  2391. \********************/
  2392. /*! no static exports found */
  2393. /***/ (function(module, exports, __webpack_require__) {
  2394. "use strict";
  2395. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  2396. Object.defineProperty(exports, "__esModule", { value: true });
  2397. exports.Range = exports.Shaping = exports.Geom = exports.Num = void 0;
  2398. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  2399. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  2400. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  2401. const LinearAlgebra_1 = __webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts");
  2402. class Num {
  2403. static equals(a, b, threshold = 0.00001) {
  2404. return Math.abs(a - b) < threshold;
  2405. }
  2406. static lerp(a, b, t) {
  2407. return (1 - t) * a + t * b;
  2408. }
  2409. static clamp(val, min, max) {
  2410. return Math.max(min, Math.min(max, val));
  2411. }
  2412. static boundValue(val, min, max) {
  2413. let len = Math.abs(max - min);
  2414. let a = val % len;
  2415. if (a > max)
  2416. a -= len;
  2417. else if (a < min)
  2418. a += len;
  2419. return a;
  2420. }
  2421. static within(p, a, b) {
  2422. return p >= Math.min(a, b) && p <= Math.max(a, b);
  2423. }
  2424. static randomRange(a, b = 0) {
  2425. let r = (a > b) ? (a - b) : (b - a);
  2426. return a + Math.random() * r;
  2427. }
  2428. static randomPt(a, b) {
  2429. let p = new Pt_1.Pt(a.length);
  2430. let range = b ? LinearAlgebra_1.Vec.subtract(b, a) : a;
  2431. let start = b ? a : new Pt_1.Pt(a.length).fill(0);
  2432. for (let i = 0, len = p.length; i < len; i++) {
  2433. p[i] = Math.random() * range[i] + start[i];
  2434. }
  2435. return p;
  2436. }
  2437. static normalizeValue(n, a, b) {
  2438. let min = Math.min(a, b);
  2439. let max = Math.max(a, b);
  2440. return (n - min) / (max - min);
  2441. }
  2442. static sum(pts) {
  2443. let _pts = Util_1.Util.iterToArray(pts);
  2444. let c = new Pt_1.Pt(_pts[0]);
  2445. for (let i = 1, len = _pts.length; i < len; i++) {
  2446. LinearAlgebra_1.Vec.add(c, _pts[i]);
  2447. }
  2448. return c;
  2449. }
  2450. static average(pts) {
  2451. let _pts = Util_1.Util.iterToArray(pts);
  2452. return Num.sum(_pts).divide(_pts.length);
  2453. }
  2454. static cycle(t, method = Shaping.sineInOut) {
  2455. return method(t > 0.5 ? 2 - t * 2 : t * 2);
  2456. }
  2457. static mapToRange(n, currA, currB, targetA, targetB) {
  2458. if (currA == currB)
  2459. throw new Error("[currMin, currMax] must define a range that is not zero");
  2460. let min = Math.min(targetA, targetB);
  2461. let max = Math.max(targetA, targetB);
  2462. return Num.normalizeValue(n, currA, currB) * (max - min) + min;
  2463. }
  2464. }
  2465. exports.Num = Num;
  2466. class Geom {
  2467. static boundAngle(angle) {
  2468. return Num.boundValue(angle, 0, 360);
  2469. }
  2470. static boundRadian(radian) {
  2471. return Num.boundValue(radian, 0, Util_1.Const.two_pi);
  2472. }
  2473. static toRadian(angle) {
  2474. return angle * Util_1.Const.deg_to_rad;
  2475. }
  2476. static toDegree(radian) {
  2477. return radian * Util_1.Const.rad_to_deg;
  2478. }
  2479. static boundingBox(pts) {
  2480. let minPt, maxPt;
  2481. for (let p of pts) {
  2482. if (minPt == undefined) {
  2483. minPt = p.clone();
  2484. maxPt = p.clone();
  2485. }
  2486. else {
  2487. minPt = minPt.$min(p);
  2488. maxPt = maxPt.$max(p);
  2489. }
  2490. }
  2491. return new Pt_1.Group(minPt, maxPt);
  2492. }
  2493. static centroid(pts) {
  2494. return Num.average(pts);
  2495. }
  2496. static anchor(pts, ptOrIndex = 0, direction = "to") {
  2497. let method = (direction == "to") ? "subtract" : "add";
  2498. let i = 0;
  2499. for (let p of pts) {
  2500. if (typeof ptOrIndex == "number") {
  2501. if (ptOrIndex !== i)
  2502. p[method](pts[ptOrIndex]);
  2503. }
  2504. else {
  2505. p[method](ptOrIndex);
  2506. }
  2507. i++;
  2508. }
  2509. }
  2510. static interpolate(a, b, t = 0.5) {
  2511. let len = Math.min(a.length, b.length);
  2512. let d = Pt_1.Pt.make(len);
  2513. for (let i = 0; i < len; i++) {
  2514. d[i] = a[i] * (1 - t) + b[i] * t;
  2515. }
  2516. return d;
  2517. }
  2518. static perpendicular(pt, axis = Util_1.Const.xy) {
  2519. let y = axis[1];
  2520. let x = axis[0];
  2521. let p = new Pt_1.Pt(pt);
  2522. let pa = new Pt_1.Pt(p);
  2523. pa[x] = -p[y];
  2524. pa[y] = p[x];
  2525. let pb = new Pt_1.Pt(p);
  2526. pb[x] = p[y];
  2527. pb[y] = -p[x];
  2528. return new Pt_1.Group(pa, pb);
  2529. }
  2530. static isPerpendicular(p1, p2) {
  2531. return new Pt_1.Pt(p1).dot(p2) === 0;
  2532. }
  2533. static withinBound(pt, boundPt1, boundPt2) {
  2534. for (let i = 0, len = Math.min(pt.length, boundPt1.length, boundPt2.length); i < len; i++) {
  2535. if (!Num.within(pt[i], boundPt1[i], boundPt2[i]))
  2536. return false;
  2537. }
  2538. return true;
  2539. }
  2540. static sortEdges(pts) {
  2541. let _pts = Util_1.Util.iterToArray(pts);
  2542. let bounds = Geom.boundingBox(_pts);
  2543. let center = bounds[1].add(bounds[0]).divide(2);
  2544. let fn = (a, b) => {
  2545. if (a.length < 2 || b.length < 2)
  2546. throw new Error("Pt dimension cannot be less than 2");
  2547. let da = a.$subtract(center);
  2548. let db = b.$subtract(center);
  2549. if (da[0] >= 0 && db[0] < 0)
  2550. return 1;
  2551. if (da[0] < 0 && db[0] >= 0)
  2552. return -1;
  2553. if (da[0] == 0 && db[0] == 0) {
  2554. if (da[1] >= 0 || db[1] >= 0)
  2555. return (da[1] > db[1]) ? 1 : -1;
  2556. return (db[1] > da[1]) ? 1 : -1;
  2557. }
  2558. let det = da.$cross2D(db);
  2559. if (det < 0)
  2560. return 1;
  2561. if (det > 0)
  2562. return -1;
  2563. return (da[0] * da[0] + da[1] * da[1] > db[0] * db[0] + db[1] * db[1]) ? 1 : -1;
  2564. };
  2565. return _pts.sort(fn);
  2566. }
  2567. static scale(ps, scale, anchor) {
  2568. let pts = Util_1.Util.iterToArray((ps[0] !== undefined && typeof ps[0] == 'number') ? [ps] : ps);
  2569. let scs = (typeof scale == "number") ? Pt_1.Pt.make(pts[0].length, scale) : scale;
  2570. if (!anchor)
  2571. anchor = Pt_1.Pt.make(pts[0].length, 0);
  2572. for (let i = 0, len = pts.length; i < len; i++) {
  2573. let p = pts[i];
  2574. for (let k = 0, lenP = p.length; k < lenP; k++) {
  2575. p[k] = (anchor && anchor[k]) ? anchor[k] + (p[k] - anchor[k]) * scs[k] : p[k] * scs[k];
  2576. }
  2577. }
  2578. return Geom;
  2579. }
  2580. static rotate2D(ps, angle, anchor, axis) {
  2581. let pts = Util_1.Util.iterToArray((ps[0] !== undefined && typeof ps[0] == 'number') ? [ps] : ps);
  2582. let fn = (anchor) ? LinearAlgebra_1.Mat.rotateAt2DMatrix : LinearAlgebra_1.Mat.rotate2DMatrix;
  2583. if (!anchor)
  2584. anchor = Pt_1.Pt.make(pts[0].length, 0);
  2585. let cos = Math.cos(angle);
  2586. let sin = Math.sin(angle);
  2587. for (let i = 0, len = pts.length; i < len; i++) {
  2588. let p = (axis) ? pts[i].$take(axis) : pts[i];
  2589. p.to(LinearAlgebra_1.Mat.transform2D(p, fn(cos, sin, anchor)));
  2590. if (axis) {
  2591. for (let k = 0; k < axis.length; k++) {
  2592. pts[i][axis[k]] = p[k];
  2593. }
  2594. }
  2595. }
  2596. return Geom;
  2597. }
  2598. static shear2D(ps, scale, anchor, axis) {
  2599. let pts = Util_1.Util.iterToArray((ps[0] !== undefined && typeof ps[0] == 'number') ? [ps] : ps);
  2600. let s = (typeof scale == "number") ? [scale, scale] : scale;
  2601. if (!anchor)
  2602. anchor = Pt_1.Pt.make(pts[0].length, 0);
  2603. let fn = (anchor) ? LinearAlgebra_1.Mat.shearAt2DMatrix : LinearAlgebra_1.Mat.shear2DMatrix;
  2604. let tanx = Math.tan(s[0]);
  2605. let tany = Math.tan(s[1]);
  2606. for (let i = 0, len = pts.length; i < len; i++) {
  2607. let p = (axis) ? pts[i].$take(axis) : pts[i];
  2608. p.to(LinearAlgebra_1.Mat.transform2D(p, fn(tanx, tany, anchor)));
  2609. if (axis) {
  2610. for (let k = 0; k < axis.length; k++) {
  2611. pts[i][axis[k]] = p[k];
  2612. }
  2613. }
  2614. }
  2615. return Geom;
  2616. }
  2617. static reflect2D(ps, line, axis) {
  2618. let pts = Util_1.Util.iterToArray((ps[0] !== undefined && typeof ps[0] == 'number') ? [ps] : ps);
  2619. let _line = Util_1.Util.iterToArray(line);
  2620. let mat = LinearAlgebra_1.Mat.reflectAt2DMatrix(_line[0], _line[1]);
  2621. for (let i = 0, len = pts.length; i < len; i++) {
  2622. let p = (axis) ? pts[i].$take(axis) : pts[i];
  2623. p.to(LinearAlgebra_1.Mat.transform2D(p, mat));
  2624. if (axis) {
  2625. for (let k = 0; k < axis.length; k++) {
  2626. pts[i][axis[k]] = p[k];
  2627. }
  2628. }
  2629. }
  2630. return Geom;
  2631. }
  2632. static cosTable() {
  2633. let cos = new Float64Array(360);
  2634. for (let i = 0; i < 360; i++)
  2635. cos[i] = Math.cos(i * Math.PI / 180);
  2636. let find = (rad) => cos[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];
  2637. return { table: cos, cos: find };
  2638. }
  2639. static sinTable() {
  2640. let sin = new Float64Array(360);
  2641. for (let i = 0; i < 360; i++)
  2642. sin[i] = Math.sin(i * Math.PI / 180);
  2643. let find = (rad) => sin[Math.floor(Geom.boundAngle(Geom.toDegree(rad)))];
  2644. return { table: sin, sin: find };
  2645. }
  2646. }
  2647. exports.Geom = Geom;
  2648. class Shaping {
  2649. static linear(t, c = 1) {
  2650. return c * t;
  2651. }
  2652. static quadraticIn(t, c = 1) {
  2653. return c * t * t;
  2654. }
  2655. static quadraticOut(t, c = 1) {
  2656. return -c * t * (t - 2);
  2657. }
  2658. static quadraticInOut(t, c = 1) {
  2659. let dt = t * 2;
  2660. return (t < 0.5) ? c / 2 * t * t * 4 : -c / 2 * ((dt - 1) * (dt - 3) - 1);
  2661. }
  2662. static cubicIn(t, c = 1) {
  2663. return c * t * t * t;
  2664. }
  2665. static cubicOut(t, c = 1) {
  2666. let dt = t - 1;
  2667. return c * (dt * dt * dt + 1);
  2668. }
  2669. static cubicInOut(t, c = 1) {
  2670. let dt = t * 2;
  2671. return (t < 0.5) ? c / 2 * dt * dt * dt : c / 2 * ((dt - 2) * (dt - 2) * (dt - 2) + 2);
  2672. }
  2673. static exponentialIn(t, c = 1, p = 0.25) {
  2674. return c * Math.pow(t, 1 / p);
  2675. }
  2676. static exponentialOut(t, c = 1, p = 0.25) {
  2677. return c * Math.pow(t, p);
  2678. }
  2679. static sineIn(t, c = 1) {
  2680. return -c * Math.cos(t * Util_1.Const.half_pi) + c;
  2681. }
  2682. static sineOut(t, c = 1) {
  2683. return c * Math.sin(t * Util_1.Const.half_pi);
  2684. }
  2685. static sineInOut(t, c = 1) {
  2686. return -c / 2 * (Math.cos(Math.PI * t) - 1);
  2687. }
  2688. static cosineApprox(t, c = 1) {
  2689. let t2 = t * t;
  2690. let t4 = t2 * t2;
  2691. let t6 = t4 * t2;
  2692. return c * (4 * t6 / 9 - 17 * t4 / 9 + 22 * t2 / 9);
  2693. }
  2694. static circularIn(t, c = 1) {
  2695. return -c * (Math.sqrt(1 - t * t) - 1);
  2696. }
  2697. static circularOut(t, c = 1) {
  2698. let dt = t - 1;
  2699. return c * Math.sqrt(1 - dt * dt);
  2700. }
  2701. static circularInOut(t, c = 1) {
  2702. let dt = t * 2;
  2703. return (t < 0.5) ? -c / 2 * (Math.sqrt(1 - dt * dt) - 1) : c / 2 * (Math.sqrt(1 - (dt - 2) * (dt - 2)) + 1);
  2704. }
  2705. static elasticIn(t, c = 1, p = 0.7) {
  2706. let dt = t - 1;
  2707. let s = (p / Util_1.Const.two_pi) * 1.5707963267948966;
  2708. return c * (-Math.pow(2, 10 * dt) * Math.sin((dt - s) * Util_1.Const.two_pi / p));
  2709. }
  2710. static elasticOut(t, c = 1, p = 0.7) {
  2711. let s = (p / Util_1.Const.two_pi) * 1.5707963267948966;
  2712. return c * (Math.pow(2, -10 * t) * Math.sin((t - s) * Util_1.Const.two_pi / p)) + c;
  2713. }
  2714. static elasticInOut(t, c = 1, p = 0.6) {
  2715. let dt = t * 2;
  2716. let s = (p / Util_1.Const.two_pi) * 1.5707963267948966;
  2717. if (t < 0.5) {
  2718. dt -= 1;
  2719. return c * (-0.5 * (Math.pow(2, 10 * dt) * Math.sin((dt - s) * Util_1.Const.two_pi / p)));
  2720. }
  2721. else {
  2722. dt -= 1;
  2723. return c * (0.5 * (Math.pow(2, -10 * dt) * Math.sin((dt - s) * Util_1.Const.two_pi / p))) + c;
  2724. }
  2725. }
  2726. static bounceIn(t, c = 1) {
  2727. return c - Shaping.bounceOut((1 - t), c);
  2728. }
  2729. static bounceOut(t, c = 1) {
  2730. if (t < (1 / 2.75)) {
  2731. return c * (7.5625 * t * t);
  2732. }
  2733. else if (t < (2 / 2.75)) {
  2734. t -= 1.5 / 2.75;
  2735. return c * (7.5625 * t * t + 0.75);
  2736. }
  2737. else if (t < (2.5 / 2.75)) {
  2738. t -= 2.25 / 2.75;
  2739. return c * (7.5625 * t * t + 0.9375);
  2740. }
  2741. else {
  2742. t -= 2.625 / 2.75;
  2743. return c * (7.5625 * t * t + 0.984375);
  2744. }
  2745. }
  2746. static bounceInOut(t, c = 1) {
  2747. return (t < 0.5) ? Shaping.bounceIn(t * 2, c) / 2 : Shaping.bounceOut(t * 2 - 1, c) / 2 + c / 2;
  2748. }
  2749. static sigmoid(t, c = 1, p = 10) {
  2750. let d = p * (t - 0.5);
  2751. return c / (1 + Math.exp(-d));
  2752. }
  2753. static logSigmoid(t, c = 1, p = 0.7) {
  2754. p = Math.max(Util_1.Const.epsilon, Math.min(1 - Util_1.Const.epsilon, p));
  2755. p = 1 / (1 - p);
  2756. let A = 1 / (1 + Math.exp(((t - 0.5) * p * -2)));
  2757. let B = 1 / (1 + Math.exp(p));
  2758. let C = 1 / (1 + Math.exp(-p));
  2759. return c * (A - B) / (C - B);
  2760. }
  2761. static seat(t, c = 1, p = 0.5) {
  2762. if ((t < 0.5)) {
  2763. return c * (Math.pow(2 * t, 1 - p)) / 2;
  2764. }
  2765. else {
  2766. return c * (1 - (Math.pow(2 * (1 - t), 1 - p)) / 2);
  2767. }
  2768. }
  2769. static quadraticBezier(t, c = 1, p = [0.05, 0.95]) {
  2770. let a = (typeof p != "number") ? p[0] : p;
  2771. let b = (typeof p != "number") ? p[1] : 0.5;
  2772. let om2a = 1 - 2 * a;
  2773. if (om2a === 0) {
  2774. om2a = Util_1.Const.epsilon;
  2775. }
  2776. let d = (Math.sqrt(a * a + om2a * t) - a) / om2a;
  2777. return c * ((1 - 2 * b) * (d * d) + (2 * b) * d);
  2778. }
  2779. static cubicBezier(t, c = 1, p1 = [0.1, 0.7], p2 = [0.9, 0.2]) {
  2780. let curve = new Pt_1.Group(new Pt_1.Pt(0, 0), new Pt_1.Pt(p1), new Pt_1.Pt(p2), new Pt_1.Pt(1, 1));
  2781. return c * Op_1.Curve.bezierStep(new Pt_1.Pt(t * t * t, t * t, t, 1), Op_1.Curve.controlPoints(curve)).y;
  2782. }
  2783. static quadraticTarget(t, c = 1, p1 = [0.2, 0.35]) {
  2784. let a = Math.min(1 - Util_1.Const.epsilon, Math.max(Util_1.Const.epsilon, p1[0]));
  2785. let b = Math.min(1, Math.max(0, p1[1]));
  2786. let A = (1 - b) / (1 - a) - (b / a);
  2787. let B = (A * (a * a) - b) / a;
  2788. let y = A * (t * t) - B * t;
  2789. return c * Math.min(1, Math.max(0, y));
  2790. }
  2791. static cliff(t, c = 1, p = 0.5) {
  2792. return (t > p) ? c : 0;
  2793. }
  2794. static step(fn, steps, t, c, ...args) {
  2795. let s = 1 / steps;
  2796. let tt = Math.floor(t / s) * s;
  2797. return fn(tt, c, ...args);
  2798. }
  2799. }
  2800. exports.Shaping = Shaping;
  2801. class Range {
  2802. constructor(g) {
  2803. this._dims = 0;
  2804. this._source = Pt_1.Group.fromPtArray(g);
  2805. this.calc();
  2806. }
  2807. get max() { return this._max.clone(); }
  2808. get min() { return this._min.clone(); }
  2809. get magnitude() { return this._mag.clone(); }
  2810. calc() {
  2811. if (!this._source)
  2812. return;
  2813. let dims = this._source[0].length;
  2814. this._dims = dims;
  2815. let max = new Pt_1.Pt(dims);
  2816. let min = new Pt_1.Pt(dims);
  2817. let mag = new Pt_1.Pt(dims);
  2818. for (let i = 0; i < dims; i++) {
  2819. max[i] = Util_1.Const.min;
  2820. min[i] = Util_1.Const.max;
  2821. mag[i] = 0;
  2822. let s = this._source.zipSlice(i);
  2823. for (let k = 0, len = s.length; k < len; k++) {
  2824. max[i] = Math.max(max[i], s[k]);
  2825. min[i] = Math.min(min[i], s[k]);
  2826. mag[i] = max[i] - min[i];
  2827. }
  2828. }
  2829. this._max = max;
  2830. this._min = min;
  2831. this._mag = mag;
  2832. return this;
  2833. }
  2834. mapTo(min, max, exclude) {
  2835. let target = new Pt_1.Group();
  2836. for (let i = 0, len = this._source.length; i < len; i++) {
  2837. let g = this._source[i];
  2838. let n = new Pt_1.Pt(this._dims);
  2839. for (let k = 0; k < this._dims; k++) {
  2840. n[k] = (exclude && exclude[k]) ? g[k] : Num.mapToRange(g[k], this._min[k], this._max[k], min, max);
  2841. }
  2842. target.push(n);
  2843. }
  2844. return target;
  2845. }
  2846. append(pts, update = true) {
  2847. let _pts = Util_1.Util.iterToArray(pts);
  2848. if (_pts[0].length !== this._dims)
  2849. throw new Error(`Dimensions don't match. ${this._dims} dimensions in Range and ${_pts[0].length} provided in parameter. `);
  2850. this._source = this._source.concat(_pts);
  2851. if (update)
  2852. this.calc();
  2853. return this;
  2854. }
  2855. ticks(count) {
  2856. let g = new Pt_1.Group();
  2857. for (let i = 0; i <= count; i++) {
  2858. let p = new Pt_1.Pt(this._dims);
  2859. for (let k = 0, len = this._max.length; k < len; k++) {
  2860. p[k] = Num.lerp(this._min[k], this._max[k], i / count);
  2861. }
  2862. g.push(p);
  2863. }
  2864. return g;
  2865. }
  2866. }
  2867. exports.Range = Range;
  2868. /***/ }),
  2869. /***/ "./src/Op.ts":
  2870. /*!*******************!*\
  2871. !*** ./src/Op.ts ***!
  2872. \*******************/
  2873. /*! no static exports found */
  2874. /***/ (function(module, exports, __webpack_require__) {
  2875. "use strict";
  2876. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  2877. Object.defineProperty(exports, "__esModule", { value: true });
  2878. exports.Curve = exports.Polygon = exports.Triangle = exports.Circle = exports.Rectangle = exports.Line = void 0;
  2879. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  2880. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  2881. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  2882. const LinearAlgebra_1 = __webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts");
  2883. let _errorLength = (obj, param = "expected") => Util_1.Util.warn("Group's length is less than " + param, obj);
  2884. let _errorOutofBound = (obj, param = "") => Util_1.Util.warn(`Index ${param} is out of bound in Group`, obj);
  2885. class Line {
  2886. static fromAngle(anchor, angle, magnitude) {
  2887. let g = new Pt_1.Group(new Pt_1.Pt(anchor), new Pt_1.Pt(anchor));
  2888. g[1].toAngle(angle, magnitude, true);
  2889. return g;
  2890. }
  2891. static slope(p1, p2) {
  2892. return (p2[0] - p1[0] === 0) ? undefined : (p2[1] - p1[1]) / (p2[0] - p1[0]);
  2893. }
  2894. static intercept(p1, p2) {
  2895. if (p2[0] - p1[0] === 0) {
  2896. return undefined;
  2897. }
  2898. else {
  2899. let m = (p2[1] - p1[1]) / (p2[0] - p1[0]);
  2900. let c = p1[1] - m * p1[0];
  2901. return { slope: m, yi: c, xi: (m === 0) ? undefined : -c / m };
  2902. }
  2903. }
  2904. static sideOfPt2D(line, pt) {
  2905. let _line = Util_1.Util.iterToArray(line);
  2906. return (_line[1][0] - _line[0][0]) * (pt[1] - _line[0][1]) - (pt[0] - _line[0][0]) * (_line[1][1] - _line[0][1]);
  2907. }
  2908. static collinear(p1, p2, p3, threshold = 0.01) {
  2909. let a = new Pt_1.Pt(0, 0, 0).to(p1).$subtract(p2);
  2910. let b = new Pt_1.Pt(0, 0, 0).to(p1).$subtract(p3);
  2911. return a.$cross(b).divide(1000).equals(new Pt_1.Pt(0, 0, 0), threshold);
  2912. }
  2913. static magnitude(line) {
  2914. let _line = Util_1.Util.iterToArray(line);
  2915. return (_line.length >= 2) ? _line[1].$subtract(_line[0]).magnitude() : 0;
  2916. }
  2917. static magnitudeSq(line) {
  2918. let _line = Util_1.Util.iterToArray(line);
  2919. return (_line.length >= 2) ? _line[1].$subtract(_line[0]).magnitudeSq() : 0;
  2920. }
  2921. static perpendicularFromPt(line, pt, asProjection = false) {
  2922. let _line = Util_1.Util.iterToArray(line);
  2923. if (_line[0].equals(_line[1]))
  2924. return undefined;
  2925. let a = _line[0].$subtract(_line[1]);
  2926. let b = _line[1].$subtract(pt);
  2927. let proj = b.$subtract(a.$project(b));
  2928. return (asProjection) ? proj : proj.$add(pt);
  2929. }
  2930. static distanceFromPt(line, pt) {
  2931. let _line = Util_1.Util.iterToArray(line);
  2932. let projectionVector = Line.perpendicularFromPt(_line, pt, true);
  2933. if (projectionVector) {
  2934. return projectionVector.magnitude();
  2935. }
  2936. else {
  2937. return _line[0].$subtract(pt).magnitude();
  2938. }
  2939. }
  2940. static intersectRay2D(la, lb) {
  2941. let _la = Util_1.Util.iterToArray(la);
  2942. let _lb = Util_1.Util.iterToArray(lb);
  2943. let a = Line.intercept(_la[0], _la[1]);
  2944. let b = Line.intercept(_lb[0], _lb[1]);
  2945. let pa = _la[0];
  2946. let pb = _lb[0];
  2947. if (a == undefined) {
  2948. if (b == undefined)
  2949. return undefined;
  2950. let y1 = -b.slope * (pb[0] - pa[0]) + pb[1];
  2951. return new Pt_1.Pt(pa[0], y1);
  2952. }
  2953. else {
  2954. if (b == undefined) {
  2955. let y1 = -a.slope * (pa[0] - pb[0]) + pa[1];
  2956. return new Pt_1.Pt(pb[0], y1);
  2957. }
  2958. else if (b.slope != a.slope) {
  2959. let px = (a.slope * pa[0] - b.slope * pb[0] + pb[1] - pa[1]) / (a.slope - b.slope);
  2960. let py = a.slope * (px - pa[0]) + pa[1];
  2961. return new Pt_1.Pt(px, py);
  2962. }
  2963. else {
  2964. if (a.yi == b.yi) {
  2965. return new Pt_1.Pt(pa[0], pa[1]);
  2966. }
  2967. else {
  2968. return undefined;
  2969. }
  2970. }
  2971. }
  2972. }
  2973. static intersectLine2D(la, lb) {
  2974. let _la = Util_1.Util.iterToArray(la);
  2975. let _lb = Util_1.Util.iterToArray(lb);
  2976. let pt = Line.intersectRay2D(_la, _lb);
  2977. return (pt && Num_1.Geom.withinBound(pt, _la[0], _la[1]) && Num_1.Geom.withinBound(pt, _lb[0], _lb[1])) ? pt : undefined;
  2978. }
  2979. static intersectLineWithRay2D(line, ray) {
  2980. let _line = Util_1.Util.iterToArray(line);
  2981. let _ray = Util_1.Util.iterToArray(ray);
  2982. let pt = Line.intersectRay2D(_line, _ray);
  2983. return (pt && Num_1.Geom.withinBound(pt, _line[0], _line[1])) ? pt : undefined;
  2984. }
  2985. static intersectPolygon2D(lineOrRay, poly, sourceIsRay = false) {
  2986. let _lineOrRay = Util_1.Util.iterToArray(lineOrRay);
  2987. let _poly = Util_1.Util.iterToArray(poly);
  2988. let fn = sourceIsRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;
  2989. let pts = new Pt_1.Group();
  2990. for (let i = 0, len = _poly.length; i < len; i++) {
  2991. let next = (i === len - 1) ? 0 : i + 1;
  2992. let d = fn([_poly[i], _poly[next]], _lineOrRay);
  2993. if (d)
  2994. pts.push(d);
  2995. }
  2996. return (pts.length > 0) ? pts : undefined;
  2997. }
  2998. static intersectLines2D(lines1, lines2, isRay = false) {
  2999. let group = new Pt_1.Group();
  3000. let fn = isRay ? Line.intersectLineWithRay2D : Line.intersectLine2D;
  3001. for (let l1 of lines1) {
  3002. for (let l2 of lines2) {
  3003. let _ip = fn(l1, l2);
  3004. if (_ip)
  3005. group.push(_ip);
  3006. }
  3007. }
  3008. return group;
  3009. }
  3010. static intersectGridWithRay2D(ray, gridPt) {
  3011. let _ray = Util_1.Util.iterToArray(ray);
  3012. let t = Line.intercept(new Pt_1.Pt(_ray[0]).subtract(gridPt), new Pt_1.Pt(_ray[1]).subtract(gridPt));
  3013. let g = new Pt_1.Group();
  3014. if (t && t.xi)
  3015. g.push(new Pt_1.Pt(gridPt[0] + t.xi, gridPt[1]));
  3016. if (t && t.yi)
  3017. g.push(new Pt_1.Pt(gridPt[0], gridPt[1] + t.yi));
  3018. return g;
  3019. }
  3020. static intersectGridWithLine2D(line, gridPt) {
  3021. let _line = Util_1.Util.iterToArray(line);
  3022. let g = Line.intersectGridWithRay2D(_line, gridPt);
  3023. let gg = new Pt_1.Group();
  3024. for (let i = 0, len = g.length; i < len; i++) {
  3025. if (Num_1.Geom.withinBound(g[i], _line[0], _line[1]))
  3026. gg.push(g[i]);
  3027. }
  3028. return gg;
  3029. }
  3030. static intersectRect2D(line, rect) {
  3031. let _line = Util_1.Util.iterToArray(line);
  3032. let _rect = Util_1.Util.iterToArray(rect);
  3033. let box = Num_1.Geom.boundingBox(Pt_1.Group.fromPtArray(_line));
  3034. if (!Rectangle.hasIntersectRect2D(box, _rect))
  3035. return new Pt_1.Group();
  3036. return Line.intersectLines2D([_line], Rectangle.sides(_rect));
  3037. }
  3038. static subpoints(line, num) {
  3039. let _line = Util_1.Util.iterToArray(line);
  3040. let pts = new Pt_1.Group();
  3041. for (let i = 1; i <= num; i++) {
  3042. pts.push(Num_1.Geom.interpolate(_line[0], _line[1], i / (num + 1)));
  3043. }
  3044. return pts;
  3045. }
  3046. static crop(line, size, index = 0, cropAsCircle = true) {
  3047. let _line = Util_1.Util.iterToArray(line);
  3048. let tdx = (index === 0) ? 1 : 0;
  3049. let ls = _line[tdx].$subtract(_line[index]);
  3050. if (ls[0] === 0 || size[0] === 0)
  3051. return _line[index];
  3052. if (cropAsCircle) {
  3053. let d = ls.unit().multiply(size[1]);
  3054. return _line[index].$add(d);
  3055. }
  3056. else {
  3057. let rect = Rectangle.fromCenter(_line[index], size);
  3058. let sides = Rectangle.sides(rect);
  3059. let sideIdx = 0;
  3060. if (Math.abs(ls[1] / ls[0]) > Math.abs(size[1] / size[0])) {
  3061. sideIdx = (ls[1] < 0) ? 0 : 2;
  3062. }
  3063. else {
  3064. sideIdx = (ls[0] < 0) ? 3 : 1;
  3065. }
  3066. return Line.intersectRay2D(sides[sideIdx], _line);
  3067. }
  3068. }
  3069. static marker(line, size, graphic = ("arrow" || false), atTail = true) {
  3070. let _line = Util_1.Util.iterToArray(line);
  3071. let h = atTail ? 0 : 1;
  3072. let t = atTail ? 1 : 0;
  3073. let unit = _line[h].$subtract(_line[t]);
  3074. if (unit.magnitudeSq() === 0)
  3075. return new Pt_1.Group();
  3076. unit.unit();
  3077. let ps = Num_1.Geom.perpendicular(unit).multiply(size[0]).add(_line[t]);
  3078. if (graphic == "arrow") {
  3079. ps.add(unit.$multiply(size[1]));
  3080. return new Pt_1.Group(_line[t], ps[0], ps[1]);
  3081. }
  3082. else {
  3083. return new Pt_1.Group(ps[0], ps[1]);
  3084. }
  3085. }
  3086. static toRect(line) {
  3087. let _line = Util_1.Util.iterToArray(line);
  3088. return new Pt_1.Group(_line[0].$min(_line[1]), _line[0].$max(_line[1]));
  3089. }
  3090. }
  3091. exports.Line = Line;
  3092. class Rectangle {
  3093. static from(topLeft, widthOrSize, height) {
  3094. return Rectangle.fromTopLeft(topLeft, widthOrSize, height);
  3095. }
  3096. static fromTopLeft(topLeft, widthOrSize, height) {
  3097. let size = (typeof widthOrSize == "number") ? [widthOrSize, (height || widthOrSize)] : widthOrSize;
  3098. return new Pt_1.Group(new Pt_1.Pt(topLeft), new Pt_1.Pt(topLeft).add(size));
  3099. }
  3100. static fromCenter(center, widthOrSize, height) {
  3101. let half = (typeof widthOrSize == "number") ? [widthOrSize / 2, (height || widthOrSize) / 2] : new Pt_1.Pt(widthOrSize).divide(2);
  3102. return new Pt_1.Group(new Pt_1.Pt(center).subtract(half), new Pt_1.Pt(center).add(half));
  3103. }
  3104. static toCircle(pts, within = true) {
  3105. return Circle.fromRect(pts, within);
  3106. }
  3107. static toSquare(pts, enclose = false) {
  3108. let _pts = Util_1.Util.iterToArray(pts);
  3109. let s = Rectangle.size(_pts);
  3110. let m = (enclose) ? s.maxValue().value : s.minValue().value;
  3111. return Rectangle.fromCenter(Rectangle.center(_pts), m, m);
  3112. }
  3113. static size(pts) {
  3114. let p = Util_1.Util.iterToArray(pts);
  3115. return p[0].$max(p[1]).subtract(p[0].$min(p[1]));
  3116. }
  3117. static center(pts) {
  3118. let p = Util_1.Util.iterToArray(pts);
  3119. let min = p[0].$min(p[1]);
  3120. let max = p[0].$max(p[1]);
  3121. return min.add(max.$subtract(min).divide(2));
  3122. }
  3123. static corners(rect) {
  3124. let _rect = Util_1.Util.iterToArray(rect);
  3125. let p0 = _rect[0].$min(_rect[1]);
  3126. let p2 = _rect[0].$max(_rect[1]);
  3127. return new Pt_1.Group(p0, new Pt_1.Pt(p2.x, p0.y), p2, new Pt_1.Pt(p0.x, p2.y));
  3128. }
  3129. static sides(rect) {
  3130. let [p0, p1, p2, p3] = Rectangle.corners(rect);
  3131. return [
  3132. new Pt_1.Group(p0, p1), new Pt_1.Group(p1, p2),
  3133. new Pt_1.Group(p2, p3), new Pt_1.Group(p3, p0)
  3134. ];
  3135. }
  3136. static boundingBox(rects) {
  3137. let _rects = Util_1.Util.iterToArray(rects);
  3138. let merged = Util_1.Util.flatten(_rects, false);
  3139. let min = Pt_1.Pt.make(2, Number.MAX_VALUE);
  3140. let max = Pt_1.Pt.make(2, Number.MIN_VALUE);
  3141. for (let i = 0, len = merged.length; i < len; i++) {
  3142. let k = 0;
  3143. for (let m of merged[i]) {
  3144. min[k] = Math.min(min[k], m[k]);
  3145. max[k] = Math.max(max[k], m[k]);
  3146. if (++k >= 2)
  3147. break;
  3148. }
  3149. }
  3150. return new Pt_1.Group(min, max);
  3151. }
  3152. static polygon(rect) {
  3153. return Rectangle.corners(rect);
  3154. }
  3155. static quadrants(rect, center) {
  3156. let _rect = Util_1.Util.iterToArray(rect);
  3157. let corners = Rectangle.corners(_rect);
  3158. let _center = (center != undefined) ? new Pt_1.Pt(center) : Rectangle.center(_rect);
  3159. return corners.map((c) => new Pt_1.Group(c, _center).boundingBox());
  3160. }
  3161. static halves(rect, ratio = 0.5, asRows = false) {
  3162. let _rect = Util_1.Util.iterToArray(rect);
  3163. let min = _rect[0].$min(_rect[1]);
  3164. let max = _rect[0].$max(_rect[1]);
  3165. let mid = (asRows) ? Num_1.Num.lerp(min[1], max[1], ratio) : Num_1.Num.lerp(min[0], max[0], ratio);
  3166. return (asRows)
  3167. ? [new Pt_1.Group(min, new Pt_1.Pt(max[0], mid)), new Pt_1.Group(new Pt_1.Pt(min[0], mid), max)]
  3168. : [new Pt_1.Group(min, new Pt_1.Pt(mid, max[1])), new Pt_1.Group(new Pt_1.Pt(mid, min[1]), max)];
  3169. }
  3170. static withinBound(rect, pt) {
  3171. let _rect = Util_1.Util.iterToArray(rect);
  3172. return Num_1.Geom.withinBound(pt, _rect[0], _rect[1]);
  3173. }
  3174. static hasIntersectRect2D(rect1, rect2, resetBoundingBox = false) {
  3175. let _rect1 = Util_1.Util.iterToArray(rect1);
  3176. let _rect2 = Util_1.Util.iterToArray(rect2);
  3177. if (resetBoundingBox) {
  3178. _rect1 = Num_1.Geom.boundingBox(_rect1);
  3179. _rect2 = Num_1.Geom.boundingBox(_rect2);
  3180. }
  3181. if (_rect1[0][0] > _rect2[1][0] || _rect2[0][0] > _rect1[1][0])
  3182. return false;
  3183. if (_rect1[0][1] > _rect2[1][1] || _rect2[0][1] > _rect1[1][1])
  3184. return false;
  3185. return true;
  3186. }
  3187. static intersectRect2D(rect1, rect2) {
  3188. let _rect1 = Util_1.Util.iterToArray(rect1);
  3189. let _rect2 = Util_1.Util.iterToArray(rect2);
  3190. if (!Rectangle.hasIntersectRect2D(_rect1, _rect2))
  3191. return new Pt_1.Group();
  3192. return Line.intersectLines2D(Rectangle.sides(_rect1), Rectangle.sides(_rect2));
  3193. }
  3194. }
  3195. exports.Rectangle = Rectangle;
  3196. class Circle {
  3197. static fromRect(pts, enclose = false) {
  3198. let _pts = Util_1.Util.iterToArray(pts);
  3199. let r = 0;
  3200. let min = r = Rectangle.size(_pts).minValue().value / 2;
  3201. if (enclose) {
  3202. let max = Rectangle.size(_pts).maxValue().value / 2;
  3203. r = Math.sqrt(min * min + max * max);
  3204. }
  3205. else {
  3206. r = min;
  3207. }
  3208. return new Pt_1.Group(Rectangle.center(_pts), new Pt_1.Pt(r, r));
  3209. }
  3210. static fromTriangle(pts, enclose = false) {
  3211. if (enclose) {
  3212. return Triangle.circumcircle(pts);
  3213. }
  3214. else {
  3215. return Triangle.incircle(pts);
  3216. }
  3217. }
  3218. static fromCenter(pt, radius) {
  3219. return new Pt_1.Group(new Pt_1.Pt(pt), new Pt_1.Pt(radius, radius));
  3220. }
  3221. static withinBound(pts, pt, threshold = 0) {
  3222. let _pts = Util_1.Util.iterToArray(pts);
  3223. let d = _pts[0].$subtract(pt);
  3224. return d.dot(d) + threshold < _pts[1].x * _pts[1].x;
  3225. }
  3226. static intersectRay2D(circle, ray) {
  3227. let _pts = Util_1.Util.iterToArray(circle);
  3228. let _ray = Util_1.Util.iterToArray(ray);
  3229. let d = _ray[0].$subtract(_ray[1]);
  3230. let f = _pts[0].$subtract(_ray[0]);
  3231. let a = d.dot(d);
  3232. let b = f.dot(d);
  3233. let c = f.dot(f) - _pts[1].x * _pts[1].x;
  3234. let p = b / a;
  3235. let q = c / a;
  3236. let disc = p * p - q;
  3237. if (disc < 0) {
  3238. return new Pt_1.Group();
  3239. }
  3240. else {
  3241. let discSqrt = Math.sqrt(disc);
  3242. let t1 = -p + discSqrt;
  3243. let p1 = _ray[0].$subtract(d.$multiply(t1));
  3244. if (disc === 0)
  3245. return new Pt_1.Group(p1);
  3246. let t2 = -p - discSqrt;
  3247. let p2 = _ray[0].$subtract(d.$multiply(t2));
  3248. return new Pt_1.Group(p1, p2);
  3249. }
  3250. }
  3251. static intersectLine2D(circle, line) {
  3252. let _pts = Util_1.Util.iterToArray(circle);
  3253. let _line = Util_1.Util.iterToArray(line);
  3254. let ps = Circle.intersectRay2D(_pts, _line);
  3255. let g = new Pt_1.Group();
  3256. if (ps.length > 0) {
  3257. for (let i = 0, len = ps.length; i < len; i++) {
  3258. if (Rectangle.withinBound(_line, ps[i]))
  3259. g.push(ps[i]);
  3260. }
  3261. }
  3262. return g;
  3263. }
  3264. static intersectCircle2D(circle1, circle2) {
  3265. let _pts = Util_1.Util.iterToArray(circle1);
  3266. let _circle = Util_1.Util.iterToArray(circle2);
  3267. let dv = _circle[0].$subtract(_pts[0]);
  3268. let dr2 = dv.magnitudeSq();
  3269. let dr = Math.sqrt(dr2);
  3270. let ar = _pts[1].x;
  3271. let br = _circle[1].x;
  3272. let ar2 = ar * ar;
  3273. let br2 = br * br;
  3274. if (dr > ar + br) {
  3275. return new Pt_1.Group();
  3276. }
  3277. else if (dr < Math.abs(ar - br)) {
  3278. return new Pt_1.Group(_pts[0].clone());
  3279. }
  3280. else {
  3281. let a = (ar2 - br2 + dr2) / (2 * dr);
  3282. let h = Math.sqrt(ar2 - a * a);
  3283. let p = dv.$multiply(a / dr).add(_pts[0]);
  3284. return new Pt_1.Group(new Pt_1.Pt(p.x + h * dv.y / dr, p.y - h * dv.x / dr), new Pt_1.Pt(p.x - h * dv.y / dr, p.y + h * dv.x / dr));
  3285. }
  3286. }
  3287. static intersectRect2D(circle, rect) {
  3288. let _pts = Util_1.Util.iterToArray(circle);
  3289. let _rect = Util_1.Util.iterToArray(rect);
  3290. let sides = Rectangle.sides(_rect);
  3291. let g = [];
  3292. for (let i = 0, len = sides.length; i < len; i++) {
  3293. let ps = Circle.intersectLine2D(_pts, sides[i]);
  3294. if (ps.length > 0)
  3295. g.push(ps);
  3296. }
  3297. return Util_1.Util.flatten(g);
  3298. }
  3299. static toRect(circle, within = false) {
  3300. let _pts = Util_1.Util.iterToArray(circle);
  3301. let r = _pts[1][0];
  3302. if (within) {
  3303. let half = Math.sqrt(r * r) / 2;
  3304. return new Pt_1.Group(_pts[0].$subtract(half), _pts[0].$add(half));
  3305. }
  3306. else {
  3307. return new Pt_1.Group(_pts[0].$subtract(r), _pts[0].$add(r));
  3308. }
  3309. }
  3310. static toTriangle(circle, within = true) {
  3311. let _pts = Util_1.Util.iterToArray(circle);
  3312. if (within) {
  3313. let ang = -Math.PI / 2;
  3314. let inc = Math.PI * 2 / 3;
  3315. let g = new Pt_1.Group();
  3316. for (let i = 0; i < 3; i++) {
  3317. g.push(_pts[0].clone().toAngle(ang, _pts[1][0], true));
  3318. ang += inc;
  3319. }
  3320. return g;
  3321. }
  3322. else {
  3323. return Triangle.fromCenter(_pts[0], _pts[1][0]);
  3324. }
  3325. }
  3326. }
  3327. exports.Circle = Circle;
  3328. class Triangle {
  3329. static fromRect(rect) {
  3330. let _rect = Util_1.Util.iterToArray(rect);
  3331. let top = _rect[0].$add(_rect[1]).divide(2);
  3332. top.y = _rect[0][1];
  3333. let left = _rect[1].clone();
  3334. left.x = _rect[0][0];
  3335. return new Pt_1.Group(top, _rect[1].clone(), left);
  3336. }
  3337. static fromCircle(circle) {
  3338. return Circle.toTriangle(circle, true);
  3339. }
  3340. static fromCenter(pt, size) {
  3341. return Triangle.fromCircle(Circle.fromCenter(pt, size));
  3342. }
  3343. static medial(tri) {
  3344. let _pts = Util_1.Util.iterToArray(tri);
  3345. if (_pts.length < 3)
  3346. return _errorLength(new Pt_1.Group(), 3);
  3347. return Polygon.midpoints(_pts, true);
  3348. }
  3349. static oppositeSide(tri, index) {
  3350. let _pts = Util_1.Util.iterToArray(tri);
  3351. if (_pts.length < 3)
  3352. return _errorLength(new Pt_1.Group(), 3);
  3353. if (index === 0) {
  3354. return Pt_1.Group.fromPtArray([_pts[1], _pts[2]]);
  3355. }
  3356. else if (index === 1) {
  3357. return Pt_1.Group.fromPtArray([_pts[0], _pts[2]]);
  3358. }
  3359. else {
  3360. return Pt_1.Group.fromPtArray([_pts[0], _pts[1]]);
  3361. }
  3362. }
  3363. static altitude(tri, index) {
  3364. let _pts = Util_1.Util.iterToArray(tri);
  3365. let opp = Triangle.oppositeSide(_pts, index);
  3366. if (opp.length > 1) {
  3367. return new Pt_1.Group(_pts[index], Line.perpendicularFromPt(opp, _pts[index]));
  3368. }
  3369. else {
  3370. return new Pt_1.Group();
  3371. }
  3372. }
  3373. static orthocenter(tri) {
  3374. let _pts = Util_1.Util.iterToArray(tri);
  3375. if (_pts.length < 3)
  3376. return _errorLength(undefined, 3);
  3377. let a = Triangle.altitude(_pts, 0);
  3378. let b = Triangle.altitude(_pts, 1);
  3379. return Line.intersectRay2D(a, b);
  3380. }
  3381. static incenter(tri) {
  3382. let _pts = Util_1.Util.iterToArray(tri);
  3383. if (_pts.length < 3)
  3384. return _errorLength(undefined, 3);
  3385. let a = Polygon.bisector(_pts, 0).add(_pts[0]);
  3386. let b = Polygon.bisector(_pts, 1).add(_pts[1]);
  3387. return Line.intersectRay2D(new Pt_1.Group(_pts[0], a), new Pt_1.Group(_pts[1], b));
  3388. }
  3389. static incircle(tri, center) {
  3390. let _pts = Util_1.Util.iterToArray(tri);
  3391. let c = (center) ? center : Triangle.incenter(_pts);
  3392. let area = Polygon.area(_pts);
  3393. let perim = Polygon.perimeter(_pts, true);
  3394. let r = 2 * area / perim.total;
  3395. return Circle.fromCenter(c, r);
  3396. }
  3397. static circumcenter(tri) {
  3398. let _pts = Util_1.Util.iterToArray(tri);
  3399. let md = Triangle.medial(_pts);
  3400. let a = [md[0], Num_1.Geom.perpendicular(_pts[0].$subtract(md[0])).p1.$add(md[0])];
  3401. let b = [md[1], Num_1.Geom.perpendicular(_pts[1].$subtract(md[1])).p1.$add(md[1])];
  3402. return Line.intersectRay2D(a, b);
  3403. }
  3404. static circumcircle(tri, center) {
  3405. let _pts = Util_1.Util.iterToArray(tri);
  3406. let c = (center) ? center : Triangle.circumcenter(_pts);
  3407. let r = _pts[0].$subtract(c).magnitude();
  3408. return Circle.fromCenter(c, r);
  3409. }
  3410. }
  3411. exports.Triangle = Triangle;
  3412. class Polygon {
  3413. static centroid(pts) {
  3414. return Num_1.Geom.centroid(pts);
  3415. }
  3416. static rectangle(center, widthOrSize, height) {
  3417. return Rectangle.corners(Rectangle.fromCenter(center, widthOrSize, height));
  3418. }
  3419. static fromCenter(center, radius, sides) {
  3420. let g = new Pt_1.Group();
  3421. for (let i = 0; i < sides; i++) {
  3422. let ang = Math.PI * 2 * i / sides;
  3423. g.push(new Pt_1.Pt(Math.cos(ang) * radius, Math.sin(ang) * radius).add(center));
  3424. }
  3425. return g;
  3426. }
  3427. static lineAt(pts, index) {
  3428. let _pts = Util_1.Util.iterToArray(pts);
  3429. if (index < 0 || index >= _pts.length)
  3430. throw new Error("index out of the Polygon's range");
  3431. return new Pt_1.Group(_pts[index], (index === _pts.length - 1) ? _pts[0] : _pts[index + 1]);
  3432. }
  3433. static lines(poly, closePath = true) {
  3434. let _pts = Util_1.Util.iterToArray(poly);
  3435. if (_pts.length < 2)
  3436. return _errorLength(new Pt_1.Group(), 2);
  3437. let sp = Util_1.Util.split(_pts, 2, 1);
  3438. if (closePath)
  3439. sp.push(new Pt_1.Group(_pts[_pts.length - 1], _pts[0]));
  3440. return sp.map((g) => g);
  3441. }
  3442. static midpoints(poly, closePath = false, t = 0.5) {
  3443. let sides = Polygon.lines(poly, closePath);
  3444. let mids = sides.map((s) => Num_1.Geom.interpolate(s[0], s[1], t));
  3445. return mids;
  3446. }
  3447. static adjacentSides(poly, index, closePath = false) {
  3448. let _pts = Util_1.Util.iterToArray(poly);
  3449. if (_pts.length < 2)
  3450. return _errorLength(new Pt_1.Group(), 2);
  3451. if (index < 0 || index >= _pts.length)
  3452. return _errorOutofBound(new Pt_1.Group(), index);
  3453. let gs = [];
  3454. let left = index - 1;
  3455. if (closePath && left < 0)
  3456. left = _pts.length - 1;
  3457. if (left >= 0)
  3458. gs.push(new Pt_1.Group(_pts[index], _pts[left]));
  3459. let right = index + 1;
  3460. if (closePath && right > _pts.length - 1)
  3461. right = 0;
  3462. if (right <= _pts.length - 1)
  3463. gs.push(new Pt_1.Group(_pts[index], _pts[right]));
  3464. return gs;
  3465. }
  3466. static bisector(poly, index) {
  3467. let sides = Polygon.adjacentSides(poly, index, true);
  3468. if (sides.length >= 2) {
  3469. let a = sides[0][1].$subtract(sides[0][0]).unit();
  3470. let b = sides[1][1].$subtract(sides[1][0]).unit();
  3471. return a.add(b).divide(2);
  3472. }
  3473. else {
  3474. return undefined;
  3475. }
  3476. }
  3477. static perimeter(poly, closePath = false) {
  3478. let lines = Polygon.lines(poly, closePath);
  3479. let mag = 0;
  3480. let p = Pt_1.Pt.make(lines.length, 0);
  3481. for (let i = 0, len = lines.length; i < len; i++) {
  3482. let m = Line.magnitude(lines[i]);
  3483. mag += m;
  3484. p[i] = m;
  3485. }
  3486. return {
  3487. total: mag,
  3488. segments: p
  3489. };
  3490. }
  3491. static area(pts) {
  3492. let _pts = Util_1.Util.iterToArray(pts);
  3493. if (_pts.length < 3)
  3494. return _errorLength(new Pt_1.Group(), 3);
  3495. let det = (a, b) => a[0] * b[1] - a[1] * b[0];
  3496. let area = 0;
  3497. for (let i = 0, len = _pts.length; i < len; i++) {
  3498. if (i < _pts.length - 1) {
  3499. area += det(_pts[i], _pts[i + 1]);
  3500. }
  3501. else {
  3502. area += det(_pts[i], _pts[0]);
  3503. }
  3504. }
  3505. return Math.abs(area / 2);
  3506. }
  3507. static convexHull(pts, sorted = false) {
  3508. let _pts = Util_1.Util.iterToArray(pts);
  3509. if (_pts.length < 3)
  3510. return _errorLength(new Pt_1.Group(), 3);
  3511. if (!sorted) {
  3512. _pts = _pts.slice();
  3513. _pts.sort((a, b) => a[0] - b[0]);
  3514. }
  3515. let left = (a, b, c) => {
  3516. return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]) > 0;
  3517. };
  3518. let dq = [];
  3519. let bot = _pts.length - 2;
  3520. let top = bot + 3;
  3521. dq[bot] = _pts[2];
  3522. dq[top] = _pts[2];
  3523. if (left(_pts[0], _pts[1], _pts[2])) {
  3524. dq[bot + 1] = _pts[0];
  3525. dq[bot + 2] = _pts[1];
  3526. }
  3527. else {
  3528. dq[bot + 1] = _pts[1];
  3529. dq[bot + 2] = _pts[0];
  3530. }
  3531. for (let i = 3, len = _pts.length; i < len; i++) {
  3532. let pt = _pts[i];
  3533. if (left(dq[bot], dq[bot + 1], pt) && left(dq[top - 1], dq[top], pt)) {
  3534. continue;
  3535. }
  3536. while (!left(dq[bot], dq[bot + 1], pt)) {
  3537. bot += 1;
  3538. }
  3539. bot -= 1;
  3540. dq[bot] = pt;
  3541. while (!left(dq[top - 1], dq[top], pt)) {
  3542. top -= 1;
  3543. }
  3544. top += 1;
  3545. dq[top] = pt;
  3546. }
  3547. let hull = new Pt_1.Group();
  3548. for (let h = 0; h < (top - bot); h++) {
  3549. hull.push(dq[bot + h]);
  3550. }
  3551. return hull;
  3552. }
  3553. static network(poly, originIndex = 0) {
  3554. let _pts = Util_1.Util.iterToArray(poly);
  3555. let g = [];
  3556. for (let i = 0, len = _pts.length; i < len; i++) {
  3557. if (i != originIndex)
  3558. g.push(new Pt_1.Group(_pts[originIndex], _pts[i]));
  3559. }
  3560. return g;
  3561. }
  3562. static nearestPt(poly, pt) {
  3563. let _near = Number.MAX_VALUE;
  3564. let _item = -1;
  3565. let i = 0;
  3566. for (let p of poly) {
  3567. let d = p.$subtract(pt).magnitudeSq();
  3568. if (d < _near) {
  3569. _near = d;
  3570. _item = i;
  3571. }
  3572. i++;
  3573. }
  3574. return _item;
  3575. }
  3576. static projectAxis(poly, unitAxis) {
  3577. let _poly = Util_1.Util.iterToArray(poly);
  3578. let dot = unitAxis.dot(_poly[0]);
  3579. let d = new Pt_1.Pt(dot, dot);
  3580. for (let n = 1, len = _poly.length; n < len; n++) {
  3581. dot = unitAxis.dot(_poly[n]);
  3582. d = new Pt_1.Pt(Math.min(dot, d[0]), Math.max(dot, d[1]));
  3583. }
  3584. return d;
  3585. }
  3586. static _axisOverlap(poly1, poly2, unitAxis) {
  3587. let pa = Polygon.projectAxis(poly1, unitAxis);
  3588. let pb = Polygon.projectAxis(poly2, unitAxis);
  3589. return (pa[0] < pb[0]) ? pb[0] - pa[1] : pa[0] - pb[1];
  3590. }
  3591. static hasIntersectPoint(poly, pt) {
  3592. let _poly = Util_1.Util.iterToArray(poly);
  3593. let c = false;
  3594. for (let i = 0, len = _poly.length; i < len; i++) {
  3595. let ln = Polygon.lineAt(_poly, i);
  3596. if (((ln[0][1] > pt[1]) != (ln[1][1] > pt[1])) &&
  3597. (pt[0] < (ln[1][0] - ln[0][0]) * (pt[1] - ln[0][1]) / (ln[1][1] - ln[0][1]) + ln[0][0])) {
  3598. c = !c;
  3599. }
  3600. }
  3601. return c;
  3602. }
  3603. static hasIntersectCircle(poly, circle) {
  3604. let _poly = Util_1.Util.iterToArray(poly);
  3605. let _circle = Util_1.Util.iterToArray(circle);
  3606. let info = {
  3607. which: -1,
  3608. dist: 0,
  3609. normal: null,
  3610. edge: null,
  3611. vertex: null,
  3612. };
  3613. let c = _circle[0];
  3614. let r = _circle[1][0];
  3615. let minDist = Number.MAX_SAFE_INTEGER;
  3616. for (let i = 0, len = _poly.length; i < len; i++) {
  3617. let edge = Polygon.lineAt(_poly, i);
  3618. let axis = new Pt_1.Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
  3619. let poly2 = new Pt_1.Group(c.$add(axis.$multiply(r)), c.$subtract(axis.$multiply(r)));
  3620. let dist = Polygon._axisOverlap(_poly, poly2, axis);
  3621. if (dist > 0) {
  3622. return null;
  3623. }
  3624. else if (Math.abs(dist) < minDist) {
  3625. let check = Rectangle.withinBound(edge, Line.perpendicularFromPt(edge, c)) || Circle.intersectLine2D(circle, edge).length > 0;
  3626. if (check) {
  3627. info.edge = edge;
  3628. info.normal = axis;
  3629. minDist = Math.abs(dist);
  3630. info.which = i;
  3631. }
  3632. }
  3633. }
  3634. if (!info.edge)
  3635. return null;
  3636. let dir = c.$subtract(Polygon.centroid(_poly)).dot(info.normal);
  3637. if (dir < 0)
  3638. info.normal.multiply(-1);
  3639. info.dist = minDist;
  3640. info.vertex = c;
  3641. return info;
  3642. }
  3643. static hasIntersectPolygon(poly1, poly2) {
  3644. let _poly1 = Util_1.Util.iterToArray(poly1);
  3645. let _poly2 = Util_1.Util.iterToArray(poly2);
  3646. let info = {
  3647. which: -1,
  3648. dist: 0,
  3649. normal: new Pt_1.Pt(),
  3650. edge: new Pt_1.Group(),
  3651. vertex: new Pt_1.Pt()
  3652. };
  3653. let minDist = Number.MAX_SAFE_INTEGER;
  3654. for (let i = 0, plen = (_poly1.length + _poly2.length); i < plen; i++) {
  3655. let edge = (i < _poly1.length) ? Polygon.lineAt(_poly1, i) : Polygon.lineAt(_poly2, i - _poly1.length);
  3656. let axis = new Pt_1.Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
  3657. let dist = Polygon._axisOverlap(_poly1, _poly2, axis);
  3658. if (dist > 0) {
  3659. return null;
  3660. }
  3661. else if (Math.abs(dist) < minDist) {
  3662. info.edge = edge;
  3663. info.normal = axis;
  3664. minDist = Math.abs(dist);
  3665. info.which = (i < _poly1.length) ? 0 : 1;
  3666. }
  3667. }
  3668. info.dist = minDist;
  3669. let b1 = (info.which === 0) ? _poly2 : _poly1;
  3670. let b2 = (info.which === 0) ? _poly1 : _poly2;
  3671. let c1 = Polygon.centroid(b1);
  3672. let c2 = Polygon.centroid(b2);
  3673. let dir = c1.$subtract(c2).dot(info.normal);
  3674. if (dir < 0)
  3675. info.normal.multiply(-1);
  3676. let smallest = Number.MAX_SAFE_INTEGER;
  3677. for (let i = 0, len = b1.length; i < len; i++) {
  3678. let d = info.normal.dot(b1[i].$subtract(c2));
  3679. if (d < smallest) {
  3680. smallest = d;
  3681. info.vertex = b1[i];
  3682. }
  3683. }
  3684. return info;
  3685. }
  3686. static intersectPolygon2D(poly1, poly2) {
  3687. let _poly1 = Util_1.Util.iterToArray(poly1);
  3688. let _poly2 = Util_1.Util.iterToArray(poly2);
  3689. let lp = Polygon.lines(_poly1);
  3690. let g = [];
  3691. for (let i = 0, len = lp.length; i < len; i++) {
  3692. let ins = Line.intersectPolygon2D(lp[i], _poly2, false);
  3693. if (ins)
  3694. g.push(ins);
  3695. }
  3696. return Util_1.Util.flatten(g, true);
  3697. }
  3698. static toRects(polys) {
  3699. let boxes = [];
  3700. for (let g of polys) {
  3701. boxes.push(Num_1.Geom.boundingBox(g));
  3702. }
  3703. let merged = Util_1.Util.flatten(boxes, false);
  3704. boxes.unshift(Num_1.Geom.boundingBox(merged));
  3705. return boxes;
  3706. }
  3707. }
  3708. exports.Polygon = Polygon;
  3709. class Curve {
  3710. static getSteps(steps) {
  3711. let ts = new Pt_1.Group();
  3712. for (let i = 0; i <= steps; i++) {
  3713. let t = i / steps;
  3714. ts.push(new Pt_1.Pt(t * t * t, t * t, t, 1));
  3715. }
  3716. return ts;
  3717. }
  3718. static controlPoints(pts, index = 0, copyStart = false) {
  3719. let _pts = Util_1.Util.iterToArray(pts);
  3720. if (index > _pts.length - 1)
  3721. return new Pt_1.Group();
  3722. let _index = (i) => (i < _pts.length - 1) ? i : _pts.length - 1;
  3723. let p0 = _pts[index];
  3724. index = (copyStart) ? index : index + 1;
  3725. return new Pt_1.Group(p0, _pts[_index(index++)], _pts[_index(index++)], _pts[_index(index++)]);
  3726. }
  3727. static _calcPt(ctrls, params) {
  3728. let x = ctrls.reduce((a, c, i) => a + c.x * params[i], 0);
  3729. let y = ctrls.reduce((a, c, i) => a + c.y * params[i], 0);
  3730. if (ctrls[0].length > 2) {
  3731. let z = ctrls.reduce((a, c, i) => a + c.z * params[i], 0);
  3732. return new Pt_1.Pt(x, y, z);
  3733. }
  3734. return new Pt_1.Pt(x, y);
  3735. }
  3736. static catmullRom(pts, steps = 10) {
  3737. let _pts = Util_1.Util.iterToArray(pts);
  3738. if (_pts.length < 2)
  3739. return new Pt_1.Group();
  3740. let ps = new Pt_1.Group();
  3741. let ts = Curve.getSteps(steps);
  3742. let c = Curve.controlPoints(_pts, 0, true);
  3743. for (let i = 0; i <= steps; i++) {
  3744. ps.push(Curve.catmullRomStep(ts[i], c));
  3745. }
  3746. let k = 0;
  3747. while (k < _pts.length - 2) {
  3748. let cp = Curve.controlPoints(_pts, k);
  3749. if (cp.length > 0) {
  3750. for (let i = 0; i <= steps; i++) {
  3751. ps.push(Curve.catmullRomStep(ts[i], cp));
  3752. }
  3753. k++;
  3754. }
  3755. }
  3756. return ps;
  3757. }
  3758. static catmullRomStep(step, ctrls) {
  3759. let m = new Pt_1.Group(new Pt_1.Pt(-0.5, 1, -0.5, 0), new Pt_1.Pt(1.5, -2.5, 0, 1), new Pt_1.Pt(-1.5, 2, 0.5, 0), new Pt_1.Pt(0.5, -0.5, 0, 0));
  3760. return Curve._calcPt(ctrls, LinearAlgebra_1.Mat.multiply([step], m, true)[0]);
  3761. }
  3762. static cardinal(pts, steps = 10, tension = 0.5) {
  3763. let _pts = Util_1.Util.iterToArray(pts);
  3764. if (_pts.length < 2)
  3765. return new Pt_1.Group();
  3766. let ps = new Pt_1.Group();
  3767. let ts = Curve.getSteps(steps);
  3768. let c = Curve.controlPoints(_pts, 0, true);
  3769. for (let i = 0; i <= steps; i++) {
  3770. ps.push(Curve.cardinalStep(ts[i], c, tension));
  3771. }
  3772. let k = 0;
  3773. while (k < _pts.length - 2) {
  3774. let cp = Curve.controlPoints(_pts, k);
  3775. if (cp.length > 0) {
  3776. for (let i = 0; i <= steps; i++) {
  3777. ps.push(Curve.cardinalStep(ts[i], cp, tension));
  3778. }
  3779. k++;
  3780. }
  3781. }
  3782. return ps;
  3783. }
  3784. static cardinalStep(step, ctrls, tension = 0.5) {
  3785. let m = new Pt_1.Group(new Pt_1.Pt(-1, 2, -1, 0), new Pt_1.Pt(-1, 1, 0, 0), new Pt_1.Pt(1, -2, 1, 0), new Pt_1.Pt(1, -1, 0, 0));
  3786. let h = LinearAlgebra_1.Mat.multiply([step], m, true)[0].multiply(tension);
  3787. let h2 = (2 * step[0] - 3 * step[1] + 1);
  3788. let h3 = -2 * step[0] + 3 * step[1];
  3789. let pt = Curve._calcPt(ctrls, h);
  3790. pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
  3791. pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
  3792. if (pt.length > 2)
  3793. pt.z += h2 * ctrls[1].z + h3 * ctrls[2].z;
  3794. return pt;
  3795. }
  3796. static bezier(pts, steps = 10) {
  3797. let _pts = Util_1.Util.iterToArray(pts);
  3798. if (_pts.length < 4)
  3799. return new Pt_1.Group();
  3800. let ps = new Pt_1.Group();
  3801. let ts = Curve.getSteps(steps);
  3802. let k = 0;
  3803. while (k < _pts.length - 3) {
  3804. let c = Curve.controlPoints(_pts, k);
  3805. if (c.length > 0) {
  3806. for (let i = 0; i <= steps; i++) {
  3807. ps.push(Curve.bezierStep(ts[i], c));
  3808. }
  3809. k += 3;
  3810. }
  3811. }
  3812. return ps;
  3813. }
  3814. static bezierStep(step, ctrls) {
  3815. let m = new Pt_1.Group(new Pt_1.Pt(-1, 3, -3, 1), new Pt_1.Pt(3, -6, 3, 0), new Pt_1.Pt(-3, 3, 0, 0), new Pt_1.Pt(1, 0, 0, 0));
  3816. return Curve._calcPt(ctrls, LinearAlgebra_1.Mat.multiply([step], m, true)[0]);
  3817. }
  3818. static bspline(pts, steps = 10, tension = 1) {
  3819. let _pts = Util_1.Util.iterToArray(pts);
  3820. if (_pts.length < 2)
  3821. return new Pt_1.Group();
  3822. let ps = new Pt_1.Group();
  3823. let ts = Curve.getSteps(steps);
  3824. let k = 0;
  3825. while (k < _pts.length - 3) {
  3826. let c = Curve.controlPoints(_pts, k);
  3827. if (c.length > 0) {
  3828. if (tension !== 1) {
  3829. for (let i = 0; i <= steps; i++) {
  3830. ps.push(Curve.bsplineTensionStep(ts[i], c, tension));
  3831. }
  3832. }
  3833. else {
  3834. for (let i = 0; i <= steps; i++) {
  3835. ps.push(Curve.bsplineStep(ts[i], c));
  3836. }
  3837. }
  3838. k++;
  3839. }
  3840. }
  3841. return ps;
  3842. }
  3843. static bsplineStep(step, ctrls) {
  3844. let m = new Pt_1.Group(new Pt_1.Pt(-0.16666666666666666, 0.5, -0.5, 0.16666666666666666), new Pt_1.Pt(0.5, -1, 0, 0.6666666666666666), new Pt_1.Pt(-0.5, 0.5, 0.5, 0.16666666666666666), new Pt_1.Pt(0.16666666666666666, 0, 0, 0));
  3845. return Curve._calcPt(ctrls, LinearAlgebra_1.Mat.multiply([step], m, true)[0]);
  3846. }
  3847. static bsplineTensionStep(step, ctrls, tension = 1) {
  3848. let m = new Pt_1.Group(new Pt_1.Pt(-0.16666666666666666, 0.5, -0.5, 0.16666666666666666), new Pt_1.Pt(-1.5, 2, 0, -0.3333333333333333), new Pt_1.Pt(1.5, -2.5, 0.5, 0.16666666666666666), new Pt_1.Pt(0.16666666666666666, 0, 0, 0));
  3849. let h = LinearAlgebra_1.Mat.multiply([step], m, true)[0].multiply(tension);
  3850. let h2 = (2 * step[0] - 3 * step[1] + 1);
  3851. let h3 = -2 * step[0] + 3 * step[1];
  3852. let pt = Curve._calcPt(ctrls, h);
  3853. pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
  3854. pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
  3855. if (pt.length > 2)
  3856. pt.z += h2 * ctrls[1].z + h3 * ctrls[2].z;
  3857. return pt;
  3858. }
  3859. }
  3860. exports.Curve = Curve;
  3861. /***/ }),
  3862. /***/ "./src/Physics.ts":
  3863. /*!************************!*\
  3864. !*** ./src/Physics.ts ***!
  3865. \************************/
  3866. /*! no static exports found */
  3867. /***/ (function(module, exports, __webpack_require__) {
  3868. "use strict";
  3869. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  3870. Object.defineProperty(exports, "__esModule", { value: true });
  3871. exports.Body = exports.Particle = exports.World = void 0;
  3872. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  3873. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  3874. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  3875. class World {
  3876. constructor(bound, friction = 1, gravity = 0) {
  3877. this._lastTime = null;
  3878. this._gravity = new Pt_1.Pt();
  3879. this._friction = 1;
  3880. this._damping = 0.75;
  3881. this._particles = [];
  3882. this._bodies = [];
  3883. this._pnames = [];
  3884. this._bnames = [];
  3885. this._bound = Pt_1.Bound.fromGroup(bound);
  3886. this._friction = friction;
  3887. this._gravity = (typeof gravity === "number") ? new Pt_1.Pt(0, gravity) : new Pt_1.Pt(gravity);
  3888. return this;
  3889. }
  3890. get bound() { return this._bound; }
  3891. set bound(bound) { this._bound = bound; }
  3892. get gravity() { return this._gravity; }
  3893. set gravity(g) { this._gravity = g; }
  3894. get friction() { return this._friction; }
  3895. set friction(f) { this._friction = f; }
  3896. get damping() { return this._damping; }
  3897. set damping(f) { this._damping = f; }
  3898. get bodyCount() { return this._bodies.length; }
  3899. get particleCount() { return this._particles.length; }
  3900. body(id) {
  3901. let idx = id;
  3902. if (typeof id === "string" && id.length > 0) {
  3903. idx = this._bnames.indexOf(id);
  3904. }
  3905. if (!(idx >= 0))
  3906. return undefined;
  3907. return this._bodies[idx];
  3908. }
  3909. particle(id) {
  3910. let idx = id;
  3911. if (typeof id === "string" && id.length > 0) {
  3912. idx = this._pnames.indexOf(id);
  3913. }
  3914. if (!(idx >= 0))
  3915. return undefined;
  3916. return this._particles[idx];
  3917. }
  3918. bodyIndex(name) {
  3919. return this._bnames.indexOf(name);
  3920. }
  3921. particleIndex(name) {
  3922. return this._pnames.indexOf(name);
  3923. }
  3924. update(ms) {
  3925. let dt = ms / 1000;
  3926. this._updateParticles(dt);
  3927. this._updateBodies(dt);
  3928. }
  3929. drawParticles(fn) {
  3930. this._drawParticles = fn;
  3931. }
  3932. drawBodies(fn) {
  3933. this._drawBodies = fn;
  3934. }
  3935. add(p, name = '') {
  3936. if (p instanceof Body) {
  3937. this._bodies.push(p);
  3938. this._bnames.push(name);
  3939. }
  3940. else {
  3941. this._particles.push(p);
  3942. this._pnames.push(name);
  3943. }
  3944. return this;
  3945. }
  3946. _index(fn, id) {
  3947. let index = 0;
  3948. if (typeof id === "string") {
  3949. index = fn(id);
  3950. if (index < 0)
  3951. throw new Error(`Cannot find index of ${id}. You can use particleIndex() or bodyIndex() function to check existence by name.`);
  3952. }
  3953. else {
  3954. index = id;
  3955. }
  3956. return index;
  3957. }
  3958. removeBody(from, count = 1) {
  3959. const index = this._index(this.bodyIndex.bind(this), from);
  3960. const param = (index < 0) ? [index * -1 - 1, count] : [index, count];
  3961. this._bodies.splice(param[0], param[1]);
  3962. this._bnames.splice(param[0], param[1]);
  3963. return this;
  3964. }
  3965. removeParticle(from, count = 1) {
  3966. const index = this._index(this.particleIndex.bind(this), from);
  3967. const param = (index < 0) ? [index * -1 - 1, count] : [index, count];
  3968. this._particles.splice(param[0], param[1]);
  3969. this._pnames.splice(param[0], param[1]);
  3970. return this;
  3971. }
  3972. static edgeConstraint(p1, p2, dist, stiff = 1, precise = false) {
  3973. const m1 = 1 / (p1.mass || 1);
  3974. const m2 = 1 / (p2.mass || 1);
  3975. const mm = m1 + m2;
  3976. let delta = p2.$subtract(p1);
  3977. let distSq = dist * dist;
  3978. let d = (precise) ? (dist / delta.magnitude() - 1) : (distSq / (delta.dot(delta) + distSq) - 0.5);
  3979. let f = delta.$multiply(d * stiff);
  3980. p1.subtract(f.$multiply(m1 / mm));
  3981. p2.add(f.$multiply(m2 / mm));
  3982. return p1;
  3983. }
  3984. static boundConstraint(p, rect, damping = 0.75) {
  3985. let bound = Num_1.Geom.boundingBox(rect);
  3986. let np = p.$min(bound[1].subtract(p.radius)).$max(bound[0].add(p.radius));
  3987. if (np[0] === bound[0][0] || np[0] === bound[1][0]) {
  3988. let c = p.changed.$multiply(damping);
  3989. p.previous = np.$subtract(new Pt_1.Pt(-c[0], c[1]));
  3990. }
  3991. else if (np[1] === bound[0][1] || np[1] === bound[1][1]) {
  3992. let c = p.changed.$multiply(damping);
  3993. p.previous = np.$subtract(new Pt_1.Pt(c[0], -c[1]));
  3994. }
  3995. p.to(np);
  3996. }
  3997. integrate(p, dt, prevDt) {
  3998. p.addForce(this._gravity);
  3999. p.verlet(dt, this._friction, prevDt);
  4000. return p;
  4001. }
  4002. _updateParticles(dt) {
  4003. for (let i = 0, len = this._particles.length; i < len; i++) {
  4004. let p = this._particles[i];
  4005. this.integrate(p, dt, this._lastTime);
  4006. World.boundConstraint(p, this._bound, this._damping);
  4007. for (let k = i + 1; k < len; k++) {
  4008. if (i !== k) {
  4009. let p2 = this._particles[k];
  4010. p.collide(p2, this._damping);
  4011. }
  4012. }
  4013. if (this._drawParticles)
  4014. this._drawParticles(p, i);
  4015. }
  4016. this._lastTime = dt;
  4017. }
  4018. _updateBodies(dt) {
  4019. for (let i = 0, len = this._bodies.length; i < len; i++) {
  4020. let bds = this._bodies[i];
  4021. if (bds) {
  4022. for (let k = 0, klen = bds.length; k < klen; k++) {
  4023. let bk = bds[k];
  4024. World.boundConstraint(bk, this._bound, this._damping);
  4025. this.integrate(bk, dt, this._lastTime);
  4026. }
  4027. for (let k = i + 1; k < len; k++) {
  4028. bds.processBody(this._bodies[k]);
  4029. }
  4030. for (let m = 0, mlen = this._particles.length; m < mlen; m++) {
  4031. bds.processParticle(this._particles[m]);
  4032. }
  4033. bds.processEdges();
  4034. if (this._drawBodies)
  4035. this._drawBodies(bds, i);
  4036. }
  4037. }
  4038. }
  4039. }
  4040. exports.World = World;
  4041. class Particle extends Pt_1.Pt {
  4042. constructor(...args) {
  4043. super(...args);
  4044. this._mass = 1;
  4045. this._radius = 0;
  4046. this._force = new Pt_1.Pt();
  4047. this._prev = new Pt_1.Pt();
  4048. this._lock = false;
  4049. this._prev = this.clone();
  4050. }
  4051. get mass() { return this._mass; }
  4052. set mass(m) { this._mass = m; }
  4053. get radius() { return this._radius; }
  4054. set radius(f) { this._radius = f; }
  4055. get previous() { return this._prev; }
  4056. set previous(p) { this._prev = p; }
  4057. get force() { return this._force; }
  4058. set force(g) { this._force = g; }
  4059. get body() { return this._body; }
  4060. set body(b) { this._body = b; }
  4061. get lock() { return this._lock; }
  4062. set lock(b) {
  4063. this._lock = b;
  4064. this._lockPt = new Pt_1.Pt(this);
  4065. }
  4066. get changed() { return this.$subtract(this._prev); }
  4067. set position(p) {
  4068. this.previous.to(this);
  4069. if (this._lock)
  4070. this._lockPt = p;
  4071. this.to(p);
  4072. }
  4073. size(r) {
  4074. this._mass = r;
  4075. this._radius = r;
  4076. return this;
  4077. }
  4078. addForce(...args) {
  4079. this._force.add(...args);
  4080. return this._force;
  4081. }
  4082. verlet(dt, friction, lastDt) {
  4083. if (this._lock) {
  4084. this.to(this._lockPt);
  4085. }
  4086. else {
  4087. let lt = (lastDt) ? lastDt : dt;
  4088. let a = this._force.multiply(dt * (dt + lt) / 2);
  4089. let v = this.changed.multiply(friction * dt / lt).add(a);
  4090. this._prev = this.clone();
  4091. this.add(v);
  4092. this._force = new Pt_1.Pt();
  4093. }
  4094. return this;
  4095. }
  4096. hit(...args) {
  4097. this._prev.subtract(new Pt_1.Pt(...args).$divide(Math.sqrt(this._mass)));
  4098. return this;
  4099. }
  4100. collide(p2, damp = 1) {
  4101. let p1 = this;
  4102. let dp = p1.$subtract(p2);
  4103. let distSq = dp.magnitudeSq();
  4104. let dr = p1.radius + p2.radius;
  4105. if (distSq < dr * dr) {
  4106. let c1 = p1.changed;
  4107. let c2 = p2.changed;
  4108. let dist = Math.sqrt(distSq);
  4109. let d = dp.$multiply(((dist - dr) / dist) / 2);
  4110. let np1 = p1.$subtract(d);
  4111. let np2 = p2.$add(d);
  4112. p1.to(np1);
  4113. p2.to(np2);
  4114. let f1 = damp * dp.dot(c1) / distSq;
  4115. let f2 = damp * dp.dot(c2) / distSq;
  4116. let dm1 = p1.mass / (p1.mass + p2.mass);
  4117. let dm2 = p2.mass / (p1.mass + p2.mass);
  4118. c1.add(new Pt_1.Pt(f2 * dp[0] - f1 * dp[0], f2 * dp[1] - f1 * dp[1]).$multiply(dm2));
  4119. c2.add(new Pt_1.Pt(f1 * dp[0] - f2 * dp[0], f1 * dp[1] - f2 * dp[1]).$multiply(dm1));
  4120. p1.previous = p1.$subtract(c1);
  4121. p2.previous = p2.$subtract(c2);
  4122. }
  4123. }
  4124. toString() {
  4125. return `Particle: ${this[0]} ${this[1]} | previous ${this._prev[0]} ${this._prev[1]} | mass ${this._mass}`;
  4126. }
  4127. }
  4128. exports.Particle = Particle;
  4129. class Body extends Pt_1.Group {
  4130. constructor() {
  4131. super();
  4132. this._cs = [];
  4133. this._stiff = 1;
  4134. this._locks = {};
  4135. this._mass = 1;
  4136. }
  4137. static fromGroup(body, stiff = 1, autoLink = true, autoMass = true) {
  4138. let b = new Body().init(body);
  4139. if (autoLink)
  4140. b.linkAll(stiff);
  4141. if (autoMass)
  4142. b.autoMass();
  4143. return b;
  4144. }
  4145. init(body, stiff = 1) {
  4146. let c = new Pt_1.Pt();
  4147. for (let li of body) {
  4148. let p = new Particle(li);
  4149. p.body = this;
  4150. c.add(li);
  4151. this.push(p);
  4152. }
  4153. this._stiff = stiff;
  4154. return this;
  4155. }
  4156. get mass() { return this._mass; }
  4157. set mass(m) {
  4158. this._mass = m;
  4159. for (let i = 0, len = this.length; i < len; i++) {
  4160. this[i].mass = this._mass;
  4161. }
  4162. }
  4163. autoMass() {
  4164. this.mass = Math.sqrt(Op_1.Polygon.area(this)) / 10;
  4165. return this;
  4166. }
  4167. link(index1, index2, stiff) {
  4168. if (index1 < 0 || index1 >= this.length)
  4169. throw new Error("index1 is not in the Group's indices");
  4170. if (index2 < 0 || index2 >= this.length)
  4171. throw new Error("index1 is not in the Group's indices");
  4172. let d = this[index1].$subtract(this[index2]).magnitude();
  4173. this._cs.push([index1, index2, d, stiff || this._stiff]);
  4174. return this;
  4175. }
  4176. linkAll(stiff) {
  4177. let half = this.length / 2;
  4178. for (let i = 0, len = this.length; i < len; i++) {
  4179. let n = (i >= len - 1) ? 0 : i + 1;
  4180. this.link(i, n, stiff);
  4181. if (len > 4) {
  4182. let nd = (Math.floor(half / 2)) + 1;
  4183. let n2 = (i >= len - nd) ? i % len : i + nd;
  4184. this.link(i, n2, stiff);
  4185. }
  4186. if (i <= half - 1) {
  4187. this.link(i, Math.min(this.length - 1, i + Math.floor(half)));
  4188. }
  4189. }
  4190. }
  4191. linksToLines() {
  4192. let gs = [];
  4193. for (let i = 0, len = this._cs.length; i < len; i++) {
  4194. let ln = this._cs[i];
  4195. gs.push(new Pt_1.Group(this[ln[0]], this[ln[1]]));
  4196. }
  4197. return gs;
  4198. }
  4199. processEdges() {
  4200. for (let i = 0, len = this._cs.length; i < len; i++) {
  4201. let [m, n, d, s] = this._cs[i];
  4202. World.edgeConstraint(this[m], this[n], d, s);
  4203. }
  4204. }
  4205. processBody(b) {
  4206. let b1 = this;
  4207. let b2 = b;
  4208. let hit = Op_1.Polygon.hasIntersectPolygon(b1, b2);
  4209. if (hit) {
  4210. let cv = hit.normal.$multiply(hit.dist);
  4211. let t;
  4212. let eg = hit.edge;
  4213. if (Math.abs(eg[0][0] - eg[1][0]) > Math.abs(eg[0][1] - eg[1][1])) {
  4214. t = (hit.vertex[0] - cv[0] - eg[0][0]) / (eg[1][0] - eg[0][0]);
  4215. }
  4216. else {
  4217. t = (hit.vertex[1] - cv[1] - eg[0][1]) / (eg[1][1] - eg[0][1]);
  4218. }
  4219. let lambda = 1 / (t * t + (1 - t) * (1 - t));
  4220. let m0 = hit.vertex.body.mass || 1;
  4221. let m1 = hit.edge[0].body.mass || 1;
  4222. let mr0 = m0 / (m0 + m1);
  4223. let mr1 = m1 / (m0 + m1);
  4224. eg[0].subtract(cv.$multiply(mr0 * (1 - t) * lambda / 2));
  4225. eg[1].subtract(cv.$multiply(mr0 * t * lambda / 2));
  4226. hit.vertex.add(cv.$multiply(mr1));
  4227. }
  4228. }
  4229. processParticle(b) {
  4230. let b1 = this;
  4231. let b2 = b;
  4232. let hit = Op_1.Polygon.hasIntersectCircle(b1, Op_1.Circle.fromCenter(b, b.radius));
  4233. if (hit) {
  4234. let cv = hit.normal.$multiply(hit.dist);
  4235. let t;
  4236. let eg = hit.edge;
  4237. if (Math.abs(eg[0][0] - eg[1][0]) > Math.abs(eg[0][1] - eg[1][1])) {
  4238. t = (hit.vertex[0] - cv[0] - eg[0][0]) / (eg[1][0] - eg[0][0]);
  4239. }
  4240. else {
  4241. t = (hit.vertex[1] - cv[1] - eg[0][1]) / (eg[1][1] - eg[0][1]);
  4242. }
  4243. let lambda = 1 / (t * t + (1 - t) * (1 - t));
  4244. let m0 = hit.vertex.mass || b2.mass || 1;
  4245. let m1 = hit.edge[0].body.mass || 1;
  4246. let mr0 = m0 / (m0 + m1);
  4247. let mr1 = m1 / (m0 + m1);
  4248. eg[0].subtract(cv.$multiply(mr0 * (1 - t) * lambda / 2));
  4249. eg[1].subtract(cv.$multiply(mr0 * t * lambda / 2));
  4250. let c1 = b.changed.add(cv.$multiply(mr1));
  4251. b.previous = b.$subtract(c1);
  4252. }
  4253. }
  4254. }
  4255. exports.Body = Body;
  4256. /***/ }),
  4257. /***/ "./src/Play.ts":
  4258. /*!*********************!*\
  4259. !*** ./src/Play.ts ***!
  4260. \*********************/
  4261. /*! no static exports found */
  4262. /***/ (function(module, exports, __webpack_require__) {
  4263. "use strict";
  4264. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  4265. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  4266. return new (P || (P = Promise))(function (resolve, reject) {
  4267. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  4268. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  4269. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  4270. step((generator = generator.apply(thisArg, _arguments || [])).next());
  4271. });
  4272. };
  4273. Object.defineProperty(exports, "__esModule", { value: true });
  4274. exports.Sound = exports.Tempo = void 0;
  4275. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  4276. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  4277. class Tempo {
  4278. constructor(bpm) {
  4279. this._listeners = {};
  4280. this._listenerInc = 0;
  4281. this.bpm = bpm;
  4282. }
  4283. static fromBeat(ms) {
  4284. return new Tempo(60000 / ms);
  4285. }
  4286. get bpm() { return this._bpm; }
  4287. set bpm(n) {
  4288. this._bpm = n;
  4289. this._ms = 60000 / this._bpm;
  4290. }
  4291. get ms() { return this._ms; }
  4292. set ms(n) {
  4293. this._bpm = Math.floor(60000 / n);
  4294. this._ms = 60000 / this._bpm;
  4295. }
  4296. _createID(listener) {
  4297. let id = '';
  4298. if (typeof listener === 'function') {
  4299. id = '_b' + (this._listenerInc++);
  4300. }
  4301. else {
  4302. id = listener.name || '_b' + (this._listenerInc++);
  4303. }
  4304. return id;
  4305. }
  4306. every(beats) {
  4307. let self = this;
  4308. let p = Array.isArray(beats) ? beats[0] : beats;
  4309. return {
  4310. start: function (fn, offset = 0, name) {
  4311. let id = name || self._createID(fn);
  4312. self._listeners[id] = { name: id, beats: beats, period: p, index: 0, offset: offset, duration: -1, continuous: false, fn: fn };
  4313. return this;
  4314. },
  4315. progress: function (fn, offset = 0, name) {
  4316. let id = name || self._createID(fn);
  4317. self._listeners[id] = { name: id, beats: beats, period: p, index: 0, offset: offset, duration: -1, continuous: true, fn: fn };
  4318. return this;
  4319. }
  4320. };
  4321. }
  4322. track(time) {
  4323. for (let k in this._listeners) {
  4324. if (this._listeners.hasOwnProperty(k)) {
  4325. let li = this._listeners[k];
  4326. let _t = (li.offset) ? time + li.offset : time;
  4327. let ms = li.period * this._ms;
  4328. let isStart = false;
  4329. if (_t > li.duration + ms) {
  4330. li.duration = _t - (_t % this._ms);
  4331. if (Array.isArray(li.beats)) {
  4332. li.index = (li.index + 1) % li.beats.length;
  4333. li.period = li.beats[li.index];
  4334. }
  4335. isStart = true;
  4336. }
  4337. let count = Math.max(0, Math.ceil(Math.floor(li.duration / this._ms) / li.period));
  4338. let params = (li.continuous) ? [count, Num_1.Num.clamp((_t - li.duration) / ms, 0, 1), _t, isStart] : [count];
  4339. if (li.continuous || isStart) {
  4340. let done = li.fn.apply(li, params);
  4341. if (done)
  4342. delete this._listeners[li.name];
  4343. }
  4344. }
  4345. }
  4346. }
  4347. stop(name) {
  4348. if (this._listeners[name])
  4349. delete this._listeners[name];
  4350. }
  4351. animate(time, ftime) {
  4352. this.track(time);
  4353. }
  4354. resize(bound, evt) {
  4355. return;
  4356. }
  4357. action(type, px, py, evt) {
  4358. return;
  4359. }
  4360. }
  4361. exports.Tempo = Tempo;
  4362. class Sound {
  4363. constructor(type) {
  4364. this._playing = false;
  4365. this._type = type;
  4366. let _ctx = window.AudioContext || window.webkitAudioContext || false;
  4367. if (!_ctx)
  4368. throw (new Error("Your browser doesn't support Web Audio. (No AudioContext)"));
  4369. this._ctx = (_ctx) ? new _ctx() : undefined;
  4370. }
  4371. static from(node, ctx, type = "gen", stream) {
  4372. let s = new Sound(type);
  4373. s._node = node;
  4374. s._ctx = ctx;
  4375. if (stream)
  4376. s._stream = stream;
  4377. return s;
  4378. }
  4379. static load(source, crossOrigin = "anonymous") {
  4380. return new Promise((resolve, reject) => {
  4381. let s = new Sound("file");
  4382. s._source = (typeof source === 'string') ? new Audio(source) : source;
  4383. s._source.autoplay = false;
  4384. s._source.crossOrigin = crossOrigin;
  4385. s._source.addEventListener("ended", function () { s._playing = false; });
  4386. s._source.addEventListener('error', function () { reject("Error loading sound"); });
  4387. s._source.addEventListener('canplaythrough', function () {
  4388. s._node = s._ctx.createMediaElementSource(s._source);
  4389. resolve(s);
  4390. });
  4391. });
  4392. }
  4393. static loadAsBuffer(url) {
  4394. return new Promise((resolve, reject) => {
  4395. let request = new XMLHttpRequest();
  4396. request.open('GET', url, true);
  4397. request.responseType = 'arraybuffer';
  4398. let s = new Sound("file");
  4399. request.onload = function () {
  4400. s._ctx.decodeAudioData(request.response, function (buffer) {
  4401. s.createBuffer(buffer);
  4402. resolve(s);
  4403. }, (err) => reject("Error decoding audio"));
  4404. };
  4405. request.send();
  4406. });
  4407. }
  4408. createBuffer(buf) {
  4409. this._node = this._ctx.createBufferSource();
  4410. if (buf !== undefined)
  4411. this._buffer = buf;
  4412. this._node.buffer = this._buffer;
  4413. this._node.onended = () => { this._playing = false; };
  4414. return this;
  4415. }
  4416. static generate(type, val) {
  4417. let s = new Sound("gen");
  4418. return s._gen(type, val);
  4419. }
  4420. _gen(type, val) {
  4421. this._node = this._ctx.createOscillator();
  4422. let osc = this._node;
  4423. osc.type = type;
  4424. if (type === 'custom') {
  4425. osc.setPeriodicWave(val);
  4426. }
  4427. else {
  4428. osc.frequency.value = val;
  4429. }
  4430. return this;
  4431. }
  4432. static input(constraint) {
  4433. return __awaiter(this, void 0, void 0, function* () {
  4434. try {
  4435. let s = new Sound("input");
  4436. if (!s)
  4437. return undefined;
  4438. const c = constraint ? constraint : { audio: true, video: false };
  4439. s._stream = yield navigator.mediaDevices.getUserMedia(c);
  4440. s._node = s._ctx.createMediaStreamSource(s._stream);
  4441. return s;
  4442. }
  4443. catch (e) {
  4444. console.error("Cannot get audio from input device.");
  4445. return Promise.resolve(null);
  4446. }
  4447. });
  4448. }
  4449. get ctx() { return this._ctx; }
  4450. get node() { return this._node; }
  4451. get outputNode() { return this._outputNode; }
  4452. get stream() { return this._stream; }
  4453. get source() { return this._source; }
  4454. get buffer() { return this._buffer; }
  4455. set buffer(b) { this._buffer = b; }
  4456. get type() { return this._type; }
  4457. get playing() { return this._playing; }
  4458. get progress() {
  4459. let dur = 0;
  4460. let curr = 0;
  4461. if (!!this._buffer) {
  4462. dur = this._buffer.duration;
  4463. curr = (this._timestamp) ? this._ctx.currentTime - this._timestamp : 0;
  4464. }
  4465. else {
  4466. dur = this._source.duration;
  4467. curr = this._source.currentTime;
  4468. }
  4469. return curr / dur;
  4470. }
  4471. get playable() {
  4472. return (this._type === "input") ? this._node !== undefined : (!!this._buffer || this._source.readyState === 4);
  4473. }
  4474. get binSize() {
  4475. return this.analyzer.size;
  4476. }
  4477. get sampleRate() {
  4478. return this._ctx.sampleRate;
  4479. }
  4480. get frequency() {
  4481. return (this._type === "gen") ? this._node.frequency.value : 0;
  4482. }
  4483. set frequency(f) {
  4484. if (this._type === "gen")
  4485. this._node.frequency.value = f;
  4486. }
  4487. connect(node) {
  4488. this._node.connect(node);
  4489. return this;
  4490. }
  4491. setOutputNode(outputNode) {
  4492. this._outputNode = outputNode;
  4493. return this;
  4494. }
  4495. removeOutputNode() {
  4496. this._outputNode = null;
  4497. return this;
  4498. }
  4499. analyze(size = 256, minDb = -100, maxDb = -30, smooth = 0.8) {
  4500. let a = this._ctx.createAnalyser();
  4501. a.fftSize = size * 2;
  4502. a.minDecibels = minDb;
  4503. a.maxDecibels = maxDb;
  4504. a.smoothingTimeConstant = smooth;
  4505. this.analyzer = {
  4506. node: a,
  4507. size: a.frequencyBinCount,
  4508. data: new Uint8Array(a.frequencyBinCount)
  4509. };
  4510. this._node.connect(this.analyzer.node);
  4511. return this;
  4512. }
  4513. _domain(time) {
  4514. if (this.analyzer) {
  4515. if (time) {
  4516. this.analyzer.node.getByteTimeDomainData(this.analyzer.data);
  4517. }
  4518. else {
  4519. this.analyzer.node.getByteFrequencyData(this.analyzer.data);
  4520. }
  4521. return this.analyzer.data;
  4522. }
  4523. return new Uint8Array(0);
  4524. }
  4525. _domainTo(time, size, position = [0, 0], trim = [0, 0]) {
  4526. let data = (time) ? this.timeDomain() : this.freqDomain();
  4527. let g = new Pt_1.Group();
  4528. for (let i = trim[0], len = data.length - trim[1]; i < len; i++) {
  4529. g.push(new Pt_1.Pt(position[0] + size[0] * i / len, position[1] + size[1] * data[i] / 255));
  4530. }
  4531. return g;
  4532. }
  4533. timeDomain() {
  4534. return this._domain(true);
  4535. }
  4536. timeDomainTo(size, position = [0, 0], trim = [0, 0]) {
  4537. return this._domainTo(true, size, position, trim);
  4538. }
  4539. freqDomain() {
  4540. return this._domain(false);
  4541. }
  4542. freqDomainTo(size, position = [0, 0], trim = [0, 0]) {
  4543. return this._domainTo(false, size, position, trim);
  4544. }
  4545. reset() {
  4546. this.stop();
  4547. this._node.disconnect();
  4548. return this;
  4549. }
  4550. start(timeAt = 0) {
  4551. if (this._ctx.state === 'suspended')
  4552. this._ctx.resume();
  4553. if (this._type === "file") {
  4554. if (!!this._buffer) {
  4555. this._node.start(timeAt);
  4556. this._timestamp = this._ctx.currentTime + timeAt;
  4557. }
  4558. else {
  4559. this._source.play();
  4560. if (timeAt > 0)
  4561. this._source.currentTime = timeAt;
  4562. }
  4563. }
  4564. else if (this._type === "gen") {
  4565. this._gen(this._node.type, this._node.frequency.value);
  4566. this._node.start();
  4567. if (this.analyzer)
  4568. this._node.connect(this.analyzer.node);
  4569. }
  4570. (this._outputNode || this._node).connect(this._ctx.destination);
  4571. this._playing = true;
  4572. return this;
  4573. }
  4574. stop() {
  4575. if (this._playing)
  4576. (this._outputNode || this._node).disconnect(this._ctx.destination);
  4577. if (this._type === "file") {
  4578. if (!!this._buffer) {
  4579. if (this.progress < 1)
  4580. this._node.stop();
  4581. }
  4582. else {
  4583. this._source.pause();
  4584. }
  4585. }
  4586. else if (this._type === "gen") {
  4587. this._node.stop();
  4588. }
  4589. else if (this._type === "input") {
  4590. this._stream.getAudioTracks().forEach(track => track.stop());
  4591. }
  4592. this._playing = false;
  4593. return this;
  4594. }
  4595. toggle() {
  4596. if (this._playing) {
  4597. this.stop();
  4598. }
  4599. else {
  4600. this.start();
  4601. }
  4602. return this;
  4603. }
  4604. }
  4605. exports.Sound = Sound;
  4606. /***/ }),
  4607. /***/ "./src/Pt.ts":
  4608. /*!*******************!*\
  4609. !*** ./src/Pt.ts ***!
  4610. \*******************/
  4611. /*! no static exports found */
  4612. /***/ (function(module, exports, __webpack_require__) {
  4613. "use strict";
  4614. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  4615. Object.defineProperty(exports, "__esModule", { value: true });
  4616. exports.Bound = exports.Group = exports.Pt = void 0;
  4617. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  4618. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  4619. const LinearAlgebra_1 = __webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts");
  4620. class Pt extends Float32Array {
  4621. constructor(...args) {
  4622. if (args.length === 1 && typeof args[0] == "number") {
  4623. super(args[0]);
  4624. }
  4625. else {
  4626. super((args.length > 0) ? Util_1.Util.getArgs(args) : [0, 0]);
  4627. }
  4628. }
  4629. static make(dimensions, defaultValue = 0, randomize = false) {
  4630. let p = new Float32Array(dimensions);
  4631. if (defaultValue)
  4632. p.fill(defaultValue);
  4633. if (randomize) {
  4634. for (let i = 0, len = p.length; i < len; i++) {
  4635. p[i] = p[i] * Math.random();
  4636. }
  4637. }
  4638. return new Pt(p);
  4639. }
  4640. get id() { return this._id; }
  4641. set id(s) { this._id = s; }
  4642. get x() { return this[0]; }
  4643. set x(n) { this[0] = n; }
  4644. get y() { return this[1]; }
  4645. set y(n) { this[1] = n; }
  4646. get z() { return this[2]; }
  4647. set z(n) { this[2] = n; }
  4648. get w() { return this[3]; }
  4649. set w(n) { this[3] = n; }
  4650. clone() {
  4651. return new Pt(this);
  4652. }
  4653. equals(p, threshold = 0.000001) {
  4654. for (let i = 0, len = this.length; i < len; i++) {
  4655. if (Math.abs(this[i] - p[i]) > threshold)
  4656. return false;
  4657. }
  4658. return true;
  4659. }
  4660. to(...args) {
  4661. let p = Util_1.Util.getArgs(args);
  4662. for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
  4663. this[i] = p[i];
  4664. }
  4665. return this;
  4666. }
  4667. $to(...args) {
  4668. return this.clone().to(...args);
  4669. }
  4670. toAngle(radian, magnitude, anchorFromPt = false) {
  4671. let m = (magnitude != undefined) ? magnitude : this.magnitude();
  4672. let change = [Math.cos(radian) * m, Math.sin(radian) * m];
  4673. return (anchorFromPt) ? this.add(change) : this.to(change);
  4674. }
  4675. op(fn) {
  4676. let self = this;
  4677. return (...params) => {
  4678. return fn(self, ...params);
  4679. };
  4680. }
  4681. ops(fns) {
  4682. let _ops = [];
  4683. for (let i = 0, len = fns.length; i < len; i++) {
  4684. _ops.push(this.op(fns[i]));
  4685. }
  4686. return _ops;
  4687. }
  4688. $take(axis) {
  4689. let p = [];
  4690. for (let i = 0, len = axis.length; i < len; i++) {
  4691. p.push(this[axis[i]] || 0);
  4692. }
  4693. return new Pt(p);
  4694. }
  4695. $concat(...args) {
  4696. return new Pt(this.toArray().concat(Util_1.Util.getArgs(args)));
  4697. }
  4698. add(...args) {
  4699. (args.length === 1 && typeof args[0] == "number") ? LinearAlgebra_1.Vec.add(this, args[0]) : LinearAlgebra_1.Vec.add(this, Util_1.Util.getArgs(args));
  4700. return this;
  4701. }
  4702. $add(...args) { return this.clone().add(...args); }
  4703. subtract(...args) {
  4704. (args.length === 1 && typeof args[0] == "number") ? LinearAlgebra_1.Vec.subtract(this, args[0]) : LinearAlgebra_1.Vec.subtract(this, Util_1.Util.getArgs(args));
  4705. return this;
  4706. }
  4707. $subtract(...args) { return this.clone().subtract(...args); }
  4708. multiply(...args) {
  4709. (args.length === 1 && typeof args[0] == "number") ? LinearAlgebra_1.Vec.multiply(this, args[0]) : LinearAlgebra_1.Vec.multiply(this, Util_1.Util.getArgs(args));
  4710. return this;
  4711. }
  4712. $multiply(...args) { return this.clone().multiply(...args); }
  4713. divide(...args) {
  4714. (args.length === 1 && typeof args[0] == "number") ? LinearAlgebra_1.Vec.divide(this, args[0]) : LinearAlgebra_1.Vec.divide(this, Util_1.Util.getArgs(args));
  4715. return this;
  4716. }
  4717. $divide(...args) { return this.clone().divide(...args); }
  4718. magnitudeSq() { return LinearAlgebra_1.Vec.dot(this, this); }
  4719. magnitude() { return LinearAlgebra_1.Vec.magnitude(this); }
  4720. unit(magnitude = undefined) {
  4721. LinearAlgebra_1.Vec.unit(this, magnitude);
  4722. return this;
  4723. }
  4724. $unit(magnitude = undefined) { return this.clone().unit(magnitude); }
  4725. dot(...args) { return LinearAlgebra_1.Vec.dot(this, Util_1.Util.getArgs(args)); }
  4726. $cross2D(...args) { return LinearAlgebra_1.Vec.cross2D(this, Util_1.Util.getArgs(args)); }
  4727. $cross(...args) { return LinearAlgebra_1.Vec.cross(this, Util_1.Util.getArgs(args)); }
  4728. $project(...args) {
  4729. return this.$multiply(this.dot(...args) / this.magnitudeSq());
  4730. }
  4731. projectScalar(...args) {
  4732. return this.dot(...args) / this.magnitude();
  4733. }
  4734. abs() {
  4735. LinearAlgebra_1.Vec.abs(this);
  4736. return this;
  4737. }
  4738. $abs() {
  4739. return this.clone().abs();
  4740. }
  4741. floor() {
  4742. LinearAlgebra_1.Vec.floor(this);
  4743. return this;
  4744. }
  4745. $floor() {
  4746. return this.clone().floor();
  4747. }
  4748. ceil() {
  4749. LinearAlgebra_1.Vec.ceil(this);
  4750. return this;
  4751. }
  4752. $ceil() {
  4753. return this.clone().ceil();
  4754. }
  4755. round() {
  4756. LinearAlgebra_1.Vec.round(this);
  4757. return this;
  4758. }
  4759. $round() {
  4760. return this.clone().round();
  4761. }
  4762. minValue() {
  4763. return LinearAlgebra_1.Vec.min(this);
  4764. }
  4765. maxValue() {
  4766. return LinearAlgebra_1.Vec.max(this);
  4767. }
  4768. $min(...args) {
  4769. let p = Util_1.Util.getArgs(args);
  4770. let m = this.clone();
  4771. for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
  4772. m[i] = Math.min(this[i], p[i]);
  4773. }
  4774. return m;
  4775. }
  4776. $max(...args) {
  4777. let p = Util_1.Util.getArgs(args);
  4778. let m = this.clone();
  4779. for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
  4780. m[i] = Math.max(this[i], p[i]);
  4781. }
  4782. return m;
  4783. }
  4784. angle(axis = Util_1.Const.xy) {
  4785. return Math.atan2(this[axis[1]], this[axis[0]]);
  4786. }
  4787. angleBetween(p, axis = Util_1.Const.xy) {
  4788. return Num_1.Geom.boundRadian(this.angle(axis)) - Num_1.Geom.boundRadian(p.angle(axis));
  4789. }
  4790. scale(scale, anchor) {
  4791. Num_1.Geom.scale(this, scale, anchor || Pt.make(this.length, 0));
  4792. return this;
  4793. }
  4794. rotate2D(angle, anchor, axis) {
  4795. Num_1.Geom.rotate2D(this, angle, anchor || Pt.make(this.length, 0), axis);
  4796. return this;
  4797. }
  4798. shear2D(scale, anchor, axis) {
  4799. Num_1.Geom.shear2D(this, scale, anchor || Pt.make(this.length, 0), axis);
  4800. return this;
  4801. }
  4802. reflect2D(line, axis) {
  4803. Num_1.Geom.reflect2D(this, line, axis);
  4804. return this;
  4805. }
  4806. toString() {
  4807. return `Pt(${this.join(", ")})`;
  4808. }
  4809. toArray() {
  4810. return [].slice.call(this);
  4811. }
  4812. toGroup() {
  4813. return new Group(Pt.make(this.length), this.clone());
  4814. }
  4815. toBound() {
  4816. return new Bound(Pt.make(this.length), this.clone());
  4817. }
  4818. }
  4819. exports.Pt = Pt;
  4820. class Group extends Array {
  4821. constructor(...args) {
  4822. super(...args);
  4823. }
  4824. get id() { return this._id; }
  4825. set id(s) { this._id = s; }
  4826. get p1() { return this[0]; }
  4827. get p2() { return this[1]; }
  4828. get p3() { return this[2]; }
  4829. get p4() { return this[3]; }
  4830. get q1() { return this[this.length - 1]; }
  4831. get q2() { return this[this.length - 2]; }
  4832. get q3() { return this[this.length - 3]; }
  4833. get q4() { return this[this.length - 4]; }
  4834. clone() {
  4835. let group = new Group();
  4836. for (let i = 0, len = this.length; i < len; i++) {
  4837. group.push(this[i].clone());
  4838. }
  4839. return group;
  4840. }
  4841. static fromArray(list) {
  4842. let g = new Group();
  4843. for (let li of list) {
  4844. let p = (li instanceof Pt) ? li : new Pt(li);
  4845. g.push(p);
  4846. }
  4847. return g;
  4848. }
  4849. static fromPtArray(list) {
  4850. return Group.from(list);
  4851. }
  4852. split(chunkSize, stride, loopBack = false) {
  4853. let sp = Util_1.Util.split(this, chunkSize, stride, loopBack);
  4854. return sp;
  4855. }
  4856. insert(pts, index = 0) {
  4857. Group.prototype.splice.apply(this, [index, 0, ...pts]);
  4858. return this;
  4859. }
  4860. remove(index = 0, count = 1) {
  4861. let param = (index < 0) ? [index * -1 - 1, count] : [index, count];
  4862. return Group.prototype.splice.apply(this, param);
  4863. }
  4864. segments(pts_per_segment = 2, stride = 1, loopBack = false) {
  4865. return this.split(pts_per_segment, stride, loopBack);
  4866. }
  4867. lines() { return this.segments(2, 1); }
  4868. centroid() {
  4869. return Num_1.Geom.centroid(this);
  4870. }
  4871. boundingBox() {
  4872. return Num_1.Geom.boundingBox(this);
  4873. }
  4874. anchorTo(ptOrIndex = 0) { Num_1.Geom.anchor(this, ptOrIndex, "to"); }
  4875. anchorFrom(ptOrIndex = 0) { Num_1.Geom.anchor(this, ptOrIndex, "from"); }
  4876. op(fn) {
  4877. let self = this;
  4878. return (...params) => {
  4879. return fn(self, ...params);
  4880. };
  4881. }
  4882. ops(fns) {
  4883. let _ops = [];
  4884. for (let i = 0, len = fns.length; i < len; i++) {
  4885. _ops.push(this.op(fns[i]));
  4886. }
  4887. return _ops;
  4888. }
  4889. interpolate(t) {
  4890. t = Num_1.Num.clamp(t, 0, 1);
  4891. let chunk = this.length - 1;
  4892. let tc = 1 / (this.length - 1);
  4893. let idx = Math.floor(t / tc);
  4894. return Num_1.Geom.interpolate(this[idx], this[Math.min(this.length - 1, idx + 1)], (t - idx * tc) * chunk);
  4895. }
  4896. moveBy(...args) {
  4897. return this.add(...args);
  4898. }
  4899. moveTo(...args) {
  4900. let d = new Pt(Util_1.Util.getArgs(args)).subtract(this[0]);
  4901. this.moveBy(d);
  4902. return this;
  4903. }
  4904. scale(scale, anchor) {
  4905. for (let i = 0, len = this.length; i < len; i++) {
  4906. Num_1.Geom.scale(this[i], scale, anchor || this[0]);
  4907. }
  4908. return this;
  4909. }
  4910. rotate2D(angle, anchor, axis) {
  4911. for (let i = 0, len = this.length; i < len; i++) {
  4912. Num_1.Geom.rotate2D(this[i], angle, anchor || this[0], axis);
  4913. }
  4914. return this;
  4915. }
  4916. shear2D(scale, anchor, axis) {
  4917. for (let i = 0, len = this.length; i < len; i++) {
  4918. Num_1.Geom.shear2D(this[i], scale, anchor || this[0], axis);
  4919. }
  4920. return this;
  4921. }
  4922. reflect2D(line, axis) {
  4923. for (let i = 0, len = this.length; i < len; i++) {
  4924. Num_1.Geom.reflect2D(this[i], line, axis);
  4925. }
  4926. return this;
  4927. }
  4928. sortByDimension(dim, desc = false) {
  4929. return this.sort((a, b) => (desc) ? b[dim] - a[dim] : a[dim] - b[dim]);
  4930. }
  4931. forEachPt(ptFn, ...args) {
  4932. if (!this[0][ptFn]) {
  4933. Util_1.Util.warn(`${ptFn} is not a function of Pt`);
  4934. return this;
  4935. }
  4936. for (let i = 0, len = this.length; i < len; i++) {
  4937. this[i] = this[i][ptFn](...args);
  4938. }
  4939. return this;
  4940. }
  4941. add(...args) {
  4942. return this.forEachPt("add", ...args);
  4943. }
  4944. subtract(...args) {
  4945. return this.forEachPt("subtract", ...args);
  4946. }
  4947. multiply(...args) {
  4948. return this.forEachPt("multiply", ...args);
  4949. }
  4950. divide(...args) {
  4951. return this.forEachPt("divide", ...args);
  4952. }
  4953. $matrixAdd(g) {
  4954. return LinearAlgebra_1.Mat.add(this, g);
  4955. }
  4956. $matrixMultiply(g, transposed = false, elementwise = false) {
  4957. return LinearAlgebra_1.Mat.multiply(this, g, transposed, elementwise);
  4958. }
  4959. zipSlice(index, defaultValue = false) {
  4960. return LinearAlgebra_1.Mat.zipSlice(this, index, defaultValue);
  4961. }
  4962. $zip(defaultValue = undefined, useLongest = false) {
  4963. return LinearAlgebra_1.Mat.zip(this, defaultValue, useLongest);
  4964. }
  4965. toString() {
  4966. return "Group[ " + this.reduce((p, c) => p + c.toString() + " ", "") + " ]";
  4967. }
  4968. }
  4969. exports.Group = Group;
  4970. class Bound extends Group {
  4971. constructor(...args) {
  4972. super(...args);
  4973. this._center = new Pt();
  4974. this._size = new Pt();
  4975. this._topLeft = new Pt();
  4976. this._bottomRight = new Pt();
  4977. this._inited = false;
  4978. this.init();
  4979. }
  4980. static fromBoundingRect(rect) {
  4981. let b = new Bound(new Pt(rect.left || 0, rect.top || 0), new Pt(rect.right || 0, rect.bottom || 0));
  4982. if (rect.width && rect.height)
  4983. b.size = new Pt(rect.width, rect.height);
  4984. return b;
  4985. }
  4986. static fromGroup(g) {
  4987. let _g = Util_1.Util.iterToArray(g);
  4988. if (_g.length < 2)
  4989. throw new Error("Cannot create a Bound from a group that has less than 2 Pt");
  4990. return new Bound(_g[0], _g[_g.length - 1]);
  4991. }
  4992. init() {
  4993. if (this.p1) {
  4994. this._size = this.p1.clone();
  4995. this._inited = true;
  4996. }
  4997. if (this.p1 && this.p2) {
  4998. let a = this.p1;
  4999. let b = this.p2;
  5000. this.topLeft = a.$min(b);
  5001. this._bottomRight = a.$max(b);
  5002. this._updateSize();
  5003. this._inited = true;
  5004. }
  5005. }
  5006. clone() {
  5007. return new Bound(this._topLeft.clone(), this._bottomRight.clone());
  5008. }
  5009. _updateSize() {
  5010. this._size = this._bottomRight.$subtract(this._topLeft).abs();
  5011. this._updateCenter();
  5012. }
  5013. _updateCenter() {
  5014. this._center = this._size.$multiply(0.5).add(this._topLeft);
  5015. }
  5016. _updatePosFromTop() {
  5017. this._bottomRight = this._topLeft.$add(this._size);
  5018. this._updateCenter();
  5019. }
  5020. _updatePosFromBottom() {
  5021. this._topLeft = this._bottomRight.$subtract(this._size);
  5022. this._updateCenter();
  5023. }
  5024. _updatePosFromCenter() {
  5025. let half = this._size.$multiply(0.5);
  5026. this._topLeft = this._center.$subtract(half);
  5027. this._bottomRight = this._center.$add(half);
  5028. }
  5029. get size() { return new Pt(this._size); }
  5030. set size(p) {
  5031. this._size = new Pt(p);
  5032. this._updatePosFromTop();
  5033. }
  5034. get center() { return new Pt(this._center); }
  5035. set center(p) {
  5036. this._center = new Pt(p);
  5037. this._updatePosFromCenter();
  5038. }
  5039. get topLeft() { return new Pt(this._topLeft); }
  5040. set topLeft(p) {
  5041. this._topLeft = new Pt(p);
  5042. this[0] = this._topLeft;
  5043. this._updateSize();
  5044. }
  5045. get bottomRight() { return new Pt(this._bottomRight); }
  5046. set bottomRight(p) {
  5047. this._bottomRight = new Pt(p);
  5048. this[1] = this._bottomRight;
  5049. this._updateSize();
  5050. }
  5051. get width() { return (this._size.length > 0) ? this._size.x : 0; }
  5052. set width(w) {
  5053. this._size.x = w;
  5054. this._updatePosFromTop();
  5055. }
  5056. get height() { return (this._size.length > 1) ? this._size.y : 0; }
  5057. set height(h) {
  5058. this._size.y = h;
  5059. this._updatePosFromTop();
  5060. }
  5061. get depth() { return (this._size.length > 2) ? this._size.z : 0; }
  5062. set depth(d) {
  5063. this._size.z = d;
  5064. this._updatePosFromTop();
  5065. }
  5066. get x() { return this.topLeft.x; }
  5067. get y() { return this.topLeft.y; }
  5068. get z() { return this.topLeft.z; }
  5069. get inited() { return this._inited; }
  5070. update() {
  5071. this._topLeft = this[0];
  5072. this._bottomRight = this[1];
  5073. this._updateSize();
  5074. return this;
  5075. }
  5076. }
  5077. exports.Bound = Bound;
  5078. /***/ }),
  5079. /***/ "./src/Space.ts":
  5080. /*!**********************!*\
  5081. !*** ./src/Space.ts ***!
  5082. \**********************/
  5083. /*! no static exports found */
  5084. /***/ (function(module, exports, __webpack_require__) {
  5085. "use strict";
  5086. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  5087. Object.defineProperty(exports, "__esModule", { value: true });
  5088. exports.MultiTouchSpace = exports.Space = void 0;
  5089. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  5090. const UI_1 = __webpack_require__(/*! ./UI */ "./src/UI.ts");
  5091. class Space {
  5092. constructor() {
  5093. this.id = "space";
  5094. this.bound = new Pt_1.Bound();
  5095. this._time = { prev: 0, diff: 0, end: -1 };
  5096. this.players = {};
  5097. this.playerCount = 0;
  5098. this._animID = -1;
  5099. this._pause = false;
  5100. this._refresh = undefined;
  5101. this._pointer = new Pt_1.Pt();
  5102. this._isReady = false;
  5103. this._playing = false;
  5104. }
  5105. refresh(b) {
  5106. this._refresh = b;
  5107. return this;
  5108. }
  5109. add(p) {
  5110. let player = (typeof p == "function") ? { animate: p } : p;
  5111. let k = this.playerCount++;
  5112. let pid = this.id + k;
  5113. this.players[pid] = player;
  5114. player.animateID = pid;
  5115. if (player.resize && this.bound.inited)
  5116. player.resize(this.bound);
  5117. if (this._refresh === undefined)
  5118. this._refresh = true;
  5119. return this;
  5120. }
  5121. remove(player) {
  5122. delete this.players[player.animateID];
  5123. return this;
  5124. }
  5125. removeAll() {
  5126. this.players = {};
  5127. return this;
  5128. }
  5129. play(time = 0) {
  5130. if (time === 0 && this._animID !== -1) {
  5131. return;
  5132. }
  5133. this._animID = requestAnimationFrame(this.play.bind(this));
  5134. if (this._pause)
  5135. return this;
  5136. this._time.diff = time - this._time.prev;
  5137. this._time.prev = time;
  5138. try {
  5139. this.playItems(time);
  5140. }
  5141. catch (err) {
  5142. cancelAnimationFrame(this._animID);
  5143. this._animID = -1;
  5144. this._playing = false;
  5145. throw err;
  5146. }
  5147. return this;
  5148. }
  5149. replay() {
  5150. this._time.end = -1;
  5151. this.play();
  5152. }
  5153. playItems(time) {
  5154. this._playing = true;
  5155. if (this._refresh)
  5156. this.clear();
  5157. if (this._isReady) {
  5158. for (let k in this.players) {
  5159. if (this.players[k].animate)
  5160. this.players[k].animate(time, this._time.diff, this);
  5161. }
  5162. }
  5163. if (this._time.end >= 0 && time > this._time.end) {
  5164. cancelAnimationFrame(this._animID);
  5165. this._animID = -1;
  5166. this._playing = false;
  5167. }
  5168. }
  5169. pause(toggle = false) {
  5170. this._pause = (toggle) ? !this._pause : true;
  5171. return this;
  5172. }
  5173. resume() {
  5174. this._pause = false;
  5175. return this;
  5176. }
  5177. stop(t = 0) {
  5178. this._time.end = t;
  5179. return this;
  5180. }
  5181. playOnce(duration = 5000) {
  5182. this.play();
  5183. this.stop(duration);
  5184. return this;
  5185. }
  5186. render(context) {
  5187. if (this._renderFunc)
  5188. this._renderFunc(context, this);
  5189. return this;
  5190. }
  5191. set customRendering(f) { this._renderFunc = f; }
  5192. get customRendering() { return this._renderFunc; }
  5193. get isPlaying() { return this._playing; }
  5194. get outerBound() { return this.bound.clone(); }
  5195. get innerBound() { return new Pt_1.Bound(Pt_1.Pt.make(this.size.length, 0), this.size.clone()); }
  5196. get size() { return this.bound.size.clone(); }
  5197. get center() { return this.size.divide(2); }
  5198. get width() { return this.bound.width; }
  5199. get height() { return this.bound.height; }
  5200. }
  5201. exports.Space = Space;
  5202. class MultiTouchSpace extends Space {
  5203. constructor() {
  5204. super(...arguments);
  5205. this._pressed = false;
  5206. this._dragged = false;
  5207. this._hasMouse = false;
  5208. this._hasTouch = false;
  5209. }
  5210. get pointer() {
  5211. let p = this._pointer.clone();
  5212. p.id = this._pointer.id;
  5213. return p;
  5214. }
  5215. bindCanvas(evt, callback, options = {}) {
  5216. this._canvas.addEventListener(evt, callback, options);
  5217. }
  5218. unbindCanvas(evt, callback) {
  5219. this._canvas.removeEventListener(evt, callback);
  5220. }
  5221. bindMouse(_bind = true) {
  5222. if (_bind) {
  5223. this.bindCanvas("mousedown", this._mouseDown.bind(this));
  5224. this.bindCanvas("mouseup", this._mouseUp.bind(this));
  5225. this.bindCanvas("mouseover", this._mouseOver.bind(this));
  5226. this.bindCanvas("mouseout", this._mouseOut.bind(this));
  5227. this.bindCanvas("mousemove", this._mouseMove.bind(this));
  5228. this.bindCanvas("click", this._mouseClick.bind(this));
  5229. this.bindCanvas("contextmenu", this._contextMenu.bind(this));
  5230. this._hasMouse = true;
  5231. }
  5232. else {
  5233. this.unbindCanvas("mousedown", this._mouseDown.bind(this));
  5234. this.unbindCanvas("mouseup", this._mouseUp.bind(this));
  5235. this.unbindCanvas("mouseover", this._mouseOver.bind(this));
  5236. this.unbindCanvas("mouseout", this._mouseOut.bind(this));
  5237. this.unbindCanvas("mousemove", this._mouseMove.bind(this));
  5238. this.unbindCanvas("click", this._mouseClick.bind(this));
  5239. this.unbindCanvas("contextmenu", this._contextMenu.bind(this));
  5240. this._hasMouse = false;
  5241. }
  5242. return this;
  5243. }
  5244. bindTouch(_bind = true) {
  5245. if (_bind) {
  5246. this.bindCanvas("touchstart", this._touchStart.bind(this), { passive: true });
  5247. this.bindCanvas("touchend", this._mouseUp.bind(this));
  5248. this.bindCanvas("touchmove", this._touchMove.bind(this), { passive: true });
  5249. this.bindCanvas("touchcancel", this._mouseOut.bind(this));
  5250. this._hasTouch = true;
  5251. }
  5252. else {
  5253. this.unbindCanvas("touchstart", this._touchStart.bind(this));
  5254. this.unbindCanvas("touchend", this._mouseUp.bind(this));
  5255. this.unbindCanvas("touchmove", this._touchMove.bind(this));
  5256. this.unbindCanvas("touchcancel", this._mouseOut.bind(this));
  5257. this._hasTouch = false;
  5258. }
  5259. return this;
  5260. }
  5261. touchesToPoints(evt, which = "touches") {
  5262. if (!evt || !evt[which])
  5263. return [];
  5264. let ts = [];
  5265. for (var i = 0; i < evt[which].length; i++) {
  5266. let t = evt[which].item(i);
  5267. ts.push(new Pt_1.Pt(t.pageX - this.bound.topLeft.x, t.pageY - this.bound.topLeft.y));
  5268. }
  5269. return ts;
  5270. }
  5271. _mouseAction(type, evt) {
  5272. let px = 0, py = 0;
  5273. if (evt instanceof MouseEvent) {
  5274. for (let k in this.players) {
  5275. if (this.players.hasOwnProperty(k)) {
  5276. let v = this.players[k];
  5277. px = evt.pageX - this.outerBound.x;
  5278. py = evt.pageY - this.outerBound.y;
  5279. if (v.action)
  5280. v.action(type, px, py, evt);
  5281. }
  5282. }
  5283. }
  5284. else {
  5285. for (let k in this.players) {
  5286. if (this.players.hasOwnProperty(k)) {
  5287. let v = this.players[k];
  5288. let c = evt.changedTouches && evt.changedTouches.length > 0;
  5289. let touch = evt.changedTouches.item(0);
  5290. px = (c) ? touch.pageX - this.outerBound.x : 0;
  5291. py = (c) ? touch.pageY - this.outerBound.y : 0;
  5292. if (v.action)
  5293. v.action(type, px, py, evt);
  5294. }
  5295. }
  5296. }
  5297. if (type) {
  5298. this._pointer.to(px, py);
  5299. this._pointer.id = type;
  5300. }
  5301. }
  5302. _mouseDown(evt) {
  5303. this._mouseAction(UI_1.UIPointerActions.down, evt);
  5304. this._pressed = true;
  5305. return false;
  5306. }
  5307. _mouseUp(evt) {
  5308. if (this._dragged) {
  5309. this._mouseAction(UI_1.UIPointerActions.drop, evt);
  5310. }
  5311. else {
  5312. this._mouseAction(UI_1.UIPointerActions.up, evt);
  5313. }
  5314. this._pressed = false;
  5315. this._dragged = false;
  5316. return false;
  5317. }
  5318. _mouseMove(evt) {
  5319. this._mouseAction(UI_1.UIPointerActions.move, evt);
  5320. if (this._pressed) {
  5321. this._dragged = true;
  5322. this._mouseAction(UI_1.UIPointerActions.drag, evt);
  5323. }
  5324. return false;
  5325. }
  5326. _mouseOver(evt) {
  5327. this._mouseAction(UI_1.UIPointerActions.over, evt);
  5328. return false;
  5329. }
  5330. _mouseOut(evt) {
  5331. this._mouseAction(UI_1.UIPointerActions.out, evt);
  5332. if (this._dragged)
  5333. this._mouseAction(UI_1.UIPointerActions.drop, evt);
  5334. this._dragged = false;
  5335. return false;
  5336. }
  5337. _mouseClick(evt) {
  5338. this._mouseAction(UI_1.UIPointerActions.click, evt);
  5339. this._pressed = false;
  5340. this._dragged = false;
  5341. return false;
  5342. }
  5343. _contextMenu(evt) {
  5344. this._mouseAction(UI_1.UIPointerActions.contextmenu, evt);
  5345. return false;
  5346. }
  5347. _touchMove(evt) {
  5348. this._mouseMove(evt);
  5349. evt.preventDefault();
  5350. return false;
  5351. }
  5352. _touchStart(evt) {
  5353. this._mouseDown(evt);
  5354. evt.preventDefault();
  5355. return false;
  5356. }
  5357. }
  5358. exports.MultiTouchSpace = MultiTouchSpace;
  5359. /***/ }),
  5360. /***/ "./src/Svg.ts":
  5361. /*!********************!*\
  5362. !*** ./src/Svg.ts ***!
  5363. \********************/
  5364. /*! no static exports found */
  5365. /***/ (function(module, exports, __webpack_require__) {
  5366. "use strict";
  5367. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  5368. Object.defineProperty(exports, "__esModule", { value: true });
  5369. exports.SVGForm = exports.SVGSpace = void 0;
  5370. const Form_1 = __webpack_require__(/*! ./Form */ "./src/Form.ts");
  5371. const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
  5372. const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
  5373. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  5374. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  5375. const Dom_1 = __webpack_require__(/*! ./Dom */ "./src/Dom.ts");
  5376. class SVGSpace extends Dom_1.DOMSpace {
  5377. constructor(elem, callback) {
  5378. super(elem, callback);
  5379. this._bgcolor = "#999";
  5380. if (this._canvas.nodeName.toLowerCase() != "svg") {
  5381. let s = SVGSpace.svgElement(this._canvas, "svg", `${this.id}_svg`);
  5382. this._container = this._canvas;
  5383. this._canvas = s;
  5384. }
  5385. }
  5386. getForm() { return new SVGForm(this); }
  5387. get element() {
  5388. return this._canvas;
  5389. }
  5390. resize(b, evt) {
  5391. super.resize(b, evt);
  5392. SVGSpace.setAttr(this.element, {
  5393. "viewBox": `0 0 ${this.bound.width} ${this.bound.height}`,
  5394. "width": `${this.bound.width}`,
  5395. "height": `${this.bound.height}`,
  5396. "xmlns": "http://www.w3.org/2000/svg",
  5397. "version": "1.1"
  5398. });
  5399. return this;
  5400. }
  5401. static svgElement(parent, name, id) {
  5402. if (!parent || !parent.appendChild)
  5403. throw new Error("parent is not a valid DOM element");
  5404. let elem = document.querySelector(`#${id}`);
  5405. if (!elem) {
  5406. elem = document.createElementNS("http://www.w3.org/2000/svg", name);
  5407. elem.setAttribute("id", id);
  5408. parent.appendChild(elem);
  5409. }
  5410. return elem;
  5411. }
  5412. remove(player) {
  5413. let temp = this._container.querySelectorAll("." + SVGForm.scopeID(player));
  5414. temp.forEach((el) => {
  5415. el.parentNode.removeChild(el);
  5416. });
  5417. return super.remove(player);
  5418. }
  5419. removeAll() {
  5420. this._container.innerHTML = "";
  5421. return super.removeAll();
  5422. }
  5423. }
  5424. exports.SVGSpace = SVGSpace;
  5425. class SVGForm extends Form_1.VisualForm {
  5426. constructor(space) {
  5427. super();
  5428. this._style = {
  5429. "filled": true,
  5430. "stroked": true,
  5431. "fill": "#f03",
  5432. "stroke": "#fff",
  5433. "stroke-width": 1,
  5434. "stroke-linejoin": "bevel",
  5435. "stroke-linecap": "sqaure",
  5436. "opacity": 1
  5437. };
  5438. this._ctx = {
  5439. group: null,
  5440. groupID: "pts",
  5441. groupCount: 0,
  5442. currentID: "pts0",
  5443. currentClass: "",
  5444. style: {},
  5445. };
  5446. this._ready = false;
  5447. this._space = space;
  5448. this._space.add({ start: () => {
  5449. this._ctx.group = this._space.element;
  5450. this._ctx.groupID = "pts_svg_" + (SVGForm.groupID++);
  5451. this._ctx.style = Object.assign({}, this._style);
  5452. this._ready = true;
  5453. } });
  5454. }
  5455. get space() { return this._space; }
  5456. styleTo(k, v) {
  5457. if (this._ctx.style[k] === undefined)
  5458. throw new Error(`${k} style property doesn't exist`);
  5459. this._ctx.style[k] = v;
  5460. }
  5461. alpha(a) {
  5462. this.styleTo("opacity", a);
  5463. return this;
  5464. }
  5465. fill(c) {
  5466. if (typeof c == "boolean") {
  5467. this.styleTo("filled", c);
  5468. }
  5469. else {
  5470. this.styleTo("filled", true);
  5471. this.styleTo("fill", c);
  5472. }
  5473. return this;
  5474. }
  5475. stroke(c, width, linejoin, linecap) {
  5476. if (typeof c == "boolean") {
  5477. this.styleTo("stroked", c);
  5478. }
  5479. else {
  5480. this.styleTo("stroked", true);
  5481. this.styleTo("stroke", c);
  5482. if (width)
  5483. this.styleTo("stroke-width", width);
  5484. if (linejoin)
  5485. this.styleTo("stroke-linejoin", linejoin);
  5486. if (linecap)
  5487. this.styleTo("stroke-linecap", linecap);
  5488. }
  5489. return this;
  5490. }
  5491. cls(c) {
  5492. if (typeof c == "boolean") {
  5493. this._ctx.currentClass = "";
  5494. }
  5495. else {
  5496. this._ctx.currentClass = c;
  5497. }
  5498. return this;
  5499. }
  5500. font(sizeOrFont, weight, style, lineHeight, family) {
  5501. if (typeof sizeOrFont == "number") {
  5502. this._font.size = sizeOrFont;
  5503. if (family)
  5504. this._font.face = family;
  5505. if (weight)
  5506. this._font.weight = weight;
  5507. if (style)
  5508. this._font.style = style;
  5509. if (lineHeight)
  5510. this._font.lineHeight = lineHeight;
  5511. }
  5512. else {
  5513. this._font = sizeOrFont;
  5514. }
  5515. this._ctx.style['font'] = this._font.value;
  5516. return this;
  5517. }
  5518. reset() {
  5519. this._ctx.style = Object.assign({}, this._style);
  5520. this._font = new Form_1.Font(10, "sans-serif");
  5521. this._ctx.style['font'] = this._font.value;
  5522. return this;
  5523. }
  5524. updateScope(group_id, group) {
  5525. this._ctx.group = group;
  5526. this._ctx.groupID = group_id;
  5527. this._ctx.groupCount = 0;
  5528. this.nextID();
  5529. return this._ctx;
  5530. }
  5531. scope(item) {
  5532. if (!item || item.animateID == null)
  5533. throw new Error("item not defined or not yet added to Space");
  5534. return this.updateScope(SVGForm.scopeID(item), this.space.element);
  5535. }
  5536. nextID() {
  5537. this._ctx.groupCount++;
  5538. this._ctx.currentID = `${this._ctx.groupID}-${this._ctx.groupCount}`;
  5539. return this._ctx.currentID;
  5540. }
  5541. static getID(ctx) {
  5542. return ctx.currentID || `p-${SVGForm.domID++}`;
  5543. }
  5544. static scopeID(item) {
  5545. return `item-${item.animateID}`;
  5546. }
  5547. static style(elem, styles) {
  5548. let st = [];
  5549. if (!styles["filled"])
  5550. st.push("fill: none");
  5551. if (!styles["stroked"])
  5552. st.push("stroke: none");
  5553. for (let k in styles) {
  5554. if (styles.hasOwnProperty(k) && k != "filled" && k != "stroked") {
  5555. let v = styles[k];
  5556. if (v) {
  5557. if (!styles["filled"] && k.indexOf('fill') === 0) {
  5558. continue;
  5559. }
  5560. else if (!styles["stroked"] && k.indexOf('stroke') === 0) {
  5561. continue;
  5562. }
  5563. else {
  5564. st.push(`${k}: ${v}`);
  5565. }
  5566. }
  5567. }
  5568. }
  5569. return Dom_1.DOMSpace.setAttr(elem, { style: st.join(";") });
  5570. }
  5571. static point(ctx, pt, radius = 5, shape = "square") {
  5572. if (shape === "circle") {
  5573. return SVGForm.circle(ctx, pt, radius);
  5574. }
  5575. else {
  5576. return SVGForm.square(ctx, pt, radius);
  5577. }
  5578. }
  5579. point(pt, radius = 5, shape = "square") {
  5580. this.nextID();
  5581. SVGForm.point(this._ctx, pt, radius, shape);
  5582. return this;
  5583. }
  5584. static circle(ctx, pt, radius = 10) {
  5585. let elem = SVGSpace.svgElement(ctx.group, "circle", SVGForm.getID(ctx));
  5586. Dom_1.DOMSpace.setAttr(elem, {
  5587. cx: pt[0],
  5588. cy: pt[1],
  5589. r: radius,
  5590. 'class': `pts-svgform pts-circle ${ctx.currentClass}`,
  5591. });
  5592. SVGForm.style(elem, ctx.style);
  5593. return elem;
  5594. }
  5595. circle(pts) {
  5596. this.nextID();
  5597. let p = Util_1.Util.iterToArray(pts);
  5598. SVGForm.circle(this._ctx, p[0], p[1][0]);
  5599. return this;
  5600. }
  5601. static arc(ctx, pt, radius, startAngle, endAngle, cc) {
  5602. let elem = SVGSpace.svgElement(ctx.group, "path", SVGForm.getID(ctx));
  5603. const start = new Pt_1.Pt(pt).toAngle(startAngle, radius, true);
  5604. const end = new Pt_1.Pt(pt).toAngle(endAngle, radius, true);
  5605. const diff = Num_1.Geom.boundAngle(endAngle) - Num_1.Geom.boundAngle(startAngle);
  5606. let largeArc = (diff > Util_1.Const.pi) ? true : false;
  5607. if (cc)
  5608. largeArc = !largeArc;
  5609. const sweep = (cc) ? "0" : "1";
  5610. const d = `M ${start[0]} ${start[1]} A ${radius} ${radius} 0 ${largeArc ? "1" : "0"} ${sweep} ${end[0]} ${end[1]}`;
  5611. Dom_1.DOMSpace.setAttr(elem, {
  5612. d: d,
  5613. 'class': `pts-svgform pts-arc ${ctx.currentClass}`,
  5614. });
  5615. SVGForm.style(elem, ctx.style);
  5616. return elem;
  5617. }
  5618. arc(pt, radius, startAngle, endAngle, cc) {
  5619. this.nextID();
  5620. SVGForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);
  5621. return this;
  5622. }
  5623. static square(ctx, pt, halfsize) {
  5624. let elem = SVGSpace.svgElement(ctx.group, "rect", SVGForm.getID(ctx));
  5625. Dom_1.DOMSpace.setAttr(elem, {
  5626. x: pt[0] - halfsize,
  5627. y: pt[1] - halfsize,
  5628. width: halfsize * 2,
  5629. height: halfsize * 2,
  5630. 'class': `pts-svgform pts-square ${ctx.currentClass}`,
  5631. });
  5632. SVGForm.style(elem, ctx.style);
  5633. return elem;
  5634. }
  5635. square(pt, halfsize) {
  5636. this.nextID();
  5637. SVGForm.square(this._ctx, pt, halfsize);
  5638. return this;
  5639. }
  5640. static line(ctx, pts) {
  5641. let points = SVGForm.pointsString(pts);
  5642. if (points.count < 2)
  5643. return;
  5644. if (points.count > 2)
  5645. return SVGForm._poly(ctx, points.string, false);
  5646. let elem = SVGSpace.svgElement(ctx.group, "line", SVGForm.getID(ctx));
  5647. let p = Util_1.Util.iterToArray(pts);
  5648. Dom_1.DOMSpace.setAttr(elem, {
  5649. x1: p[0][0],
  5650. y1: p[0][1],
  5651. x2: p[1][0],
  5652. y2: p[1][1],
  5653. 'class': `pts-svgform pts-line ${ctx.currentClass}`,
  5654. });
  5655. SVGForm.style(elem, ctx.style);
  5656. return elem;
  5657. }
  5658. line(pts) {
  5659. this.nextID();
  5660. SVGForm.line(this._ctx, pts);
  5661. return this;
  5662. }
  5663. static _poly(ctx, points, closePath = true) {
  5664. let elem = SVGSpace.svgElement(ctx.group, ((closePath) ? "polygon" : "polyline"), SVGForm.getID(ctx));
  5665. Dom_1.DOMSpace.setAttr(elem, {
  5666. points: points,
  5667. 'class': `pts-svgform pts-polygon ${ctx.currentClass}`,
  5668. });
  5669. SVGForm.style(elem, ctx.style);
  5670. return elem;
  5671. }
  5672. static pointsString(pts) {
  5673. let points = "";
  5674. let count = 0;
  5675. for (let p of pts) {
  5676. points += `${p[0]},${p[1]} `;
  5677. count++;
  5678. }
  5679. return { string: points, count: count };
  5680. }
  5681. static polygon(ctx, pts) {
  5682. let points = SVGForm.pointsString(pts);
  5683. return SVGForm._poly(ctx, points.string, true);
  5684. }
  5685. polygon(pts) {
  5686. this.nextID();
  5687. SVGForm.polygon(this._ctx, pts);
  5688. return this;
  5689. }
  5690. static rect(ctx, pts) {
  5691. if (!Util_1.Util.arrayCheck(pts))
  5692. return;
  5693. let elem = SVGSpace.svgElement(ctx.group, "rect", SVGForm.getID(ctx));
  5694. let bound = Pt_1.Group.fromArray(pts).boundingBox();
  5695. let size = Op_1.Rectangle.size(bound);
  5696. Dom_1.DOMSpace.setAttr(elem, {
  5697. x: bound[0][0],
  5698. y: bound[0][1],
  5699. width: size[0],
  5700. height: size[1],
  5701. 'class': `pts-svgform pts-rect ${ctx.currentClass}`,
  5702. });
  5703. SVGForm.style(elem, ctx.style);
  5704. return elem;
  5705. }
  5706. rect(pts) {
  5707. this.nextID();
  5708. SVGForm.rect(this._ctx, pts);
  5709. return this;
  5710. }
  5711. static text(ctx, pt, txt) {
  5712. let elem = SVGSpace.svgElement(ctx.group, "text", SVGForm.getID(ctx));
  5713. Dom_1.DOMSpace.setAttr(elem, {
  5714. "pointer-events": "none",
  5715. x: pt[0],
  5716. y: pt[1],
  5717. dx: 0, dy: 0,
  5718. 'class': `pts-svgform pts-text ${ctx.currentClass}`,
  5719. });
  5720. elem.textContent = txt;
  5721. SVGForm.style(elem, ctx.style);
  5722. return elem;
  5723. }
  5724. text(pt, txt) {
  5725. this.nextID();
  5726. SVGForm.text(this._ctx, pt, txt);
  5727. return this;
  5728. }
  5729. log(txt) {
  5730. this.fill("#000").stroke("#fff", 0.5).text([10, 14], txt);
  5731. return this;
  5732. }
  5733. }
  5734. exports.SVGForm = SVGForm;
  5735. SVGForm.groupID = 0;
  5736. SVGForm.domID = 0;
  5737. /***/ }),
  5738. /***/ "./src/Types.ts":
  5739. /*!**********************!*\
  5740. !*** ./src/Types.ts ***!
  5741. \**********************/
  5742. /*! no static exports found */
  5743. /***/ (function(module, exports, __webpack_require__) {
  5744. "use strict";
  5745. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  5746. Object.defineProperty(exports, "__esModule", { value: true });
  5747. /***/ }),
  5748. /***/ "./src/Typography.ts":
  5749. /*!***************************!*\
  5750. !*** ./src/Typography.ts ***!
  5751. \***************************/
  5752. /*! no static exports found */
  5753. /***/ (function(module, exports, __webpack_require__) {
  5754. "use strict";
  5755. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  5756. Object.defineProperty(exports, "__esModule", { value: true });
  5757. exports.Typography = void 0;
  5758. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  5759. class Typography {
  5760. static textWidthEstimator(fn, samples = ["M", "n", "."], distribution = [0.06, 0.8, 0.14]) {
  5761. let m = samples.map(fn);
  5762. let avg = new Pt_1.Pt(distribution).dot(m);
  5763. return (str) => str.length * avg;
  5764. }
  5765. static truncate(fn, str, width, tail = "") {
  5766. let trim = Math.floor(str.length * Math.min(1, width / fn(str)));
  5767. if (trim < str.length) {
  5768. trim = Math.max(0, trim - tail.length);
  5769. return [str.substr(0, trim) + tail, trim];
  5770. }
  5771. else {
  5772. return [str, str.length];
  5773. }
  5774. }
  5775. static fontSizeToBox(box, ratio = 1, byHeight = true) {
  5776. let bound = Pt_1.Bound.fromGroup(box);
  5777. let h = byHeight ? bound.height : bound.width;
  5778. let f = ratio * h;
  5779. return function (box2) {
  5780. let bound2 = Pt_1.Bound.fromGroup(box2);
  5781. let nh = (byHeight ? bound2.height : bound2.width) / h;
  5782. return f * nh;
  5783. };
  5784. }
  5785. static fontSizeToThreshold(threshold, direction = 0) {
  5786. return function (defaultSize, val) {
  5787. let d = defaultSize * val / threshold;
  5788. if (direction < 0)
  5789. return Math.min(d, defaultSize);
  5790. if (direction > 0)
  5791. return Math.max(d, defaultSize);
  5792. return d;
  5793. };
  5794. }
  5795. }
  5796. exports.Typography = Typography;
  5797. /***/ }),
  5798. /***/ "./src/UI.ts":
  5799. /*!*******************!*\
  5800. !*** ./src/UI.ts ***!
  5801. \*******************/
  5802. /*! no static exports found */
  5803. /***/ (function(module, exports, __webpack_require__) {
  5804. "use strict";
  5805. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  5806. Object.defineProperty(exports, "__esModule", { value: true });
  5807. exports.UIDragger = exports.UIButton = exports.UI = exports.UIPointerActions = exports.UIShape = void 0;
  5808. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  5809. const Op_1 = __webpack_require__(/*! ./Op */ "./src/Op.ts");
  5810. exports.UIShape = {
  5811. rectangle: "rectangle", circle: "circle", polygon: "polygon", polyline: "polyline", line: "line"
  5812. };
  5813. exports.UIPointerActions = {
  5814. up: "up", down: "down", move: "move", drag: "drag", uidrag: "uidrag", drop: "drop", uidrop: "uidrop", over: "over", out: "out", enter: "enter", leave: "leave", click: "click", contextmenu: "contextmenu", all: "all"
  5815. };
  5816. class UI {
  5817. constructor(group, shape, states = {}, id) {
  5818. this._holds = new Map();
  5819. this._group = Pt_1.Group.fromArray(group);
  5820. this._shape = shape;
  5821. this._id = id === undefined ? `ui_${(UI._counter++)}` : id;
  5822. this._states = states;
  5823. this._actions = {};
  5824. }
  5825. static fromRectangle(group, states, id) {
  5826. return new this(group, exports.UIShape.rectangle, states, id);
  5827. }
  5828. static fromCircle(group, states, id) {
  5829. return new this(group, exports.UIShape.circle, states, id);
  5830. }
  5831. static fromPolygon(group, states, id) {
  5832. return new this(group, exports.UIShape.polygon, states, id);
  5833. }
  5834. static fromUI(ui, states, id) {
  5835. return new this(ui.group, ui.shape, states || ui._states, id);
  5836. }
  5837. get id() { return this._id; }
  5838. set id(d) { this._id = d; }
  5839. get group() { return this._group; }
  5840. set group(d) { this._group = d; }
  5841. get shape() { return this._shape; }
  5842. set shape(d) { this._shape = d; }
  5843. state(key, value) {
  5844. if (!key)
  5845. return null;
  5846. if (value !== undefined) {
  5847. this._states[key] = value;
  5848. return this;
  5849. }
  5850. return this._states[key];
  5851. }
  5852. on(type, fn) {
  5853. if (!this._actions[type])
  5854. this._actions[type] = [];
  5855. return UI._addHandler(this._actions[type], fn);
  5856. }
  5857. off(type, which) {
  5858. if (!this._actions[type])
  5859. return false;
  5860. if (which === undefined) {
  5861. delete this._actions[type];
  5862. return true;
  5863. }
  5864. else {
  5865. return UI._removeHandler(this._actions[type], which);
  5866. }
  5867. }
  5868. listen(type, p, evt) {
  5869. if (this._actions[type] !== undefined) {
  5870. if (this._within(p) || Array.from(this._holds.values()).indexOf(type) >= 0) {
  5871. UI._trigger(this._actions[type], this, p, type, evt);
  5872. return true;
  5873. }
  5874. else if (this._actions['all']) {
  5875. UI._trigger(this._actions['all'], this, p, type, evt);
  5876. return true;
  5877. }
  5878. }
  5879. return false;
  5880. }
  5881. hold(type) {
  5882. let newKey = Math.max(0, ...Array.from(this._holds.keys())) + 1;
  5883. this._holds.set(newKey, type);
  5884. return newKey;
  5885. }
  5886. unhold(key) {
  5887. if (key !== undefined) {
  5888. this._holds.delete(key);
  5889. }
  5890. else {
  5891. this._holds.clear();
  5892. }
  5893. }
  5894. static track(uis, type, p, evt) {
  5895. for (let i = 0, len = uis.length; i < len; i++) {
  5896. uis[i].listen(type, p, evt);
  5897. }
  5898. }
  5899. render(fn) {
  5900. fn(this._group, this._states);
  5901. }
  5902. toString() {
  5903. return `UI ${this.group.toString}`;
  5904. }
  5905. _within(p) {
  5906. let fn = null;
  5907. if (this._shape === exports.UIShape.rectangle) {
  5908. fn = Op_1.Rectangle.withinBound;
  5909. }
  5910. else if (this._shape === exports.UIShape.circle) {
  5911. fn = Op_1.Circle.withinBound;
  5912. }
  5913. else if (this._shape === exports.UIShape.polygon) {
  5914. fn = Op_1.Polygon.hasIntersectPoint;
  5915. }
  5916. else {
  5917. return false;
  5918. }
  5919. return fn(this._group, p);
  5920. }
  5921. static _trigger(fns, target, pt, type, evt) {
  5922. if (fns) {
  5923. for (let i = 0, len = fns.length; i < len; i++) {
  5924. if (fns[i])
  5925. fns[i](target, pt, type, evt);
  5926. }
  5927. }
  5928. }
  5929. static _addHandler(fns, fn) {
  5930. if (fn) {
  5931. fns.push(fn);
  5932. return fns.length - 1;
  5933. }
  5934. else {
  5935. return -1;
  5936. }
  5937. }
  5938. static _removeHandler(fns, index) {
  5939. if (index >= 0 && index < fns.length) {
  5940. let temp = fns.length;
  5941. fns.splice(index, 1);
  5942. return (temp > fns.length);
  5943. }
  5944. else {
  5945. return false;
  5946. }
  5947. }
  5948. }
  5949. exports.UI = UI;
  5950. UI._counter = 0;
  5951. class UIButton extends UI {
  5952. constructor(group, shape, states = {}, id) {
  5953. super(group, shape, states, id);
  5954. this._hoverID = -1;
  5955. if (states.hover === undefined)
  5956. this._states['hover'] = false;
  5957. if (states.clicks === undefined)
  5958. this._states['clicks'] = 0;
  5959. const UA = exports.UIPointerActions;
  5960. this.on(UA.up, (target, pt, type, evt) => {
  5961. this.state('clicks', this._states.clicks + 1);
  5962. });
  5963. this.on(UA.move, (target, pt, type, evt) => {
  5964. let hover = this._within(pt);
  5965. if (hover && !this._states.hover) {
  5966. this.state('hover', true);
  5967. UI._trigger(this._actions[UA.enter], this, pt, UA.enter, evt);
  5968. var _capID = this.hold(UA.move);
  5969. this._hoverID = this.on(UA.move, (t, p) => {
  5970. if (!this._within(p) && !this.state('dragging')) {
  5971. this.state('hover', false);
  5972. UI._trigger(this._actions[UA.leave], this, pt, UA.leave, evt);
  5973. this.off(UA.move, this._hoverID);
  5974. this.unhold(_capID);
  5975. }
  5976. });
  5977. }
  5978. });
  5979. }
  5980. onClick(fn) {
  5981. return this.on(exports.UIPointerActions.up, fn);
  5982. }
  5983. offClick(id) {
  5984. return this.off(exports.UIPointerActions.up, id);
  5985. }
  5986. onContextMenu(fn) {
  5987. return this.on(exports.UIPointerActions.contextmenu, fn);
  5988. }
  5989. offContextMenu(id) {
  5990. return this.off(exports.UIPointerActions.contextmenu, id);
  5991. }
  5992. onHover(enter, leave) {
  5993. var ids = [undefined, undefined];
  5994. if (enter)
  5995. ids[0] = this.on(exports.UIPointerActions.enter, enter);
  5996. if (leave)
  5997. ids[1] = this.on(exports.UIPointerActions.leave, leave);
  5998. return ids;
  5999. }
  6000. offHover(enterID, leaveID) {
  6001. var s = [false, false];
  6002. if (enterID === undefined || enterID >= 0)
  6003. s[0] = this.off(exports.UIPointerActions.enter, enterID);
  6004. if (leaveID === undefined || leaveID >= 0)
  6005. s[1] = this.off(exports.UIPointerActions.leave, leaveID);
  6006. return s;
  6007. }
  6008. }
  6009. exports.UIButton = UIButton;
  6010. class UIDragger extends UIButton {
  6011. constructor(group, shape, states = {}, id) {
  6012. super(group, shape, states, id);
  6013. this._draggingID = -1;
  6014. this._moveHoldID = -1;
  6015. this._dropHoldID = -1;
  6016. this._upHoldID = -1;
  6017. if (states.dragging === undefined)
  6018. this._states['dragging'] = false;
  6019. if (states.moved === undefined)
  6020. this._states['moved'] = false;
  6021. if (states.offset === undefined)
  6022. this._states['offset'] = new Pt_1.Pt();
  6023. const UA = exports.UIPointerActions;
  6024. this.on(UA.down, (target, pt, type, evt) => {
  6025. if (this._moveHoldID === -1) {
  6026. this.state('dragging', true);
  6027. this.state('offset', new Pt_1.Pt(pt).subtract(target.group[0]));
  6028. this._moveHoldID = this.hold(UA.move);
  6029. }
  6030. if (this._dropHoldID === -1) {
  6031. this._dropHoldID = this.hold(UA.drop);
  6032. }
  6033. if (this._upHoldID === -1) {
  6034. this._upHoldID = this.hold(UA.up);
  6035. }
  6036. if (this._draggingID === -1) {
  6037. this._draggingID = this.on(UA.move, (t, p) => {
  6038. if (this.state('dragging')) {
  6039. UI._trigger(this._actions[UA.uidrag], t, p, UA.uidrag, evt);
  6040. this.state('moved', true);
  6041. }
  6042. });
  6043. }
  6044. });
  6045. const endDrag = (target, pt, type, evt) => {
  6046. this.state('dragging', false);
  6047. this.off(UA.move, this._draggingID);
  6048. this._draggingID = -1;
  6049. this.unhold(this._moveHoldID);
  6050. this._moveHoldID = -1;
  6051. this.unhold(this._dropHoldID);
  6052. this._dropHoldID = -1;
  6053. this.unhold(this._upHoldID);
  6054. this._upHoldID = -1;
  6055. if (this.state('moved')) {
  6056. UI._trigger(this._actions[UA.uidrop], target, pt, UA.uidrop, evt);
  6057. this.state('moved', false);
  6058. }
  6059. };
  6060. this.on(UA.drop, endDrag);
  6061. this.on(UA.up, endDrag);
  6062. this.on(UA.out, endDrag);
  6063. }
  6064. onDrag(fn) {
  6065. return this.on(exports.UIPointerActions.uidrag, fn);
  6066. }
  6067. offDrag(id) {
  6068. return this.off(exports.UIPointerActions.uidrag, id);
  6069. }
  6070. onDrop(fn) {
  6071. return this.on(exports.UIPointerActions.uidrop, fn);
  6072. }
  6073. offDrop(id) {
  6074. return this.off(exports.UIPointerActions.uidrop, id);
  6075. }
  6076. }
  6077. exports.UIDragger = UIDragger;
  6078. /***/ }),
  6079. /***/ "./src/Util.ts":
  6080. /*!*********************!*\
  6081. !*** ./src/Util.ts ***!
  6082. \*********************/
  6083. /*! no static exports found */
  6084. /***/ (function(module, exports, __webpack_require__) {
  6085. "use strict";
  6086. /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
  6087. Object.defineProperty(exports, "__esModule", { value: true });
  6088. exports.Util = exports.Const = void 0;
  6089. const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
  6090. exports.Const = {
  6091. xy: "xy",
  6092. yz: "yz",
  6093. xz: "xz",
  6094. xyz: "xyz",
  6095. horizontal: 0,
  6096. vertical: 1,
  6097. identical: 0,
  6098. right: 4,
  6099. bottom_right: 5,
  6100. bottom: 6,
  6101. bottom_left: 7,
  6102. left: 8,
  6103. top_left: 1,
  6104. top: 2,
  6105. top_right: 3,
  6106. epsilon: 0.0001,
  6107. max: Number.MAX_VALUE,
  6108. min: Number.MIN_VALUE,
  6109. pi: Math.PI,
  6110. two_pi: 6.283185307179586,
  6111. half_pi: 1.5707963267948966,
  6112. quarter_pi: 0.7853981633974483,
  6113. one_degree: 0.017453292519943295,
  6114. rad_to_deg: 57.29577951308232,
  6115. deg_to_rad: 0.017453292519943295,
  6116. gravity: 9.81,
  6117. newton: 0.10197,
  6118. gaussian: 0.3989422804014327
  6119. };
  6120. class Util {
  6121. static warnLevel(lv) {
  6122. if (lv) {
  6123. Util._warnLevel = lv;
  6124. }
  6125. return Util._warnLevel;
  6126. }
  6127. static getArgs(args) {
  6128. if (args.length < 1)
  6129. return [];
  6130. let pos = [];
  6131. let isArray = Array.isArray(args[0]) || ArrayBuffer.isView(args[0]);
  6132. if (typeof args[0] === 'number') {
  6133. pos = Array.prototype.slice.call(args);
  6134. }
  6135. else if (typeof args[0] === 'object' && !isArray) {
  6136. let a = ["x", "y", "z", "w"];
  6137. let p = args[0];
  6138. for (let i = 0; i < a.length; i++) {
  6139. if ((p.length && i >= p.length) || !(a[i] in p))
  6140. break;
  6141. pos.push(p[a[i]]);
  6142. }
  6143. }
  6144. else if (isArray) {
  6145. pos = [].slice.call(args[0]);
  6146. }
  6147. return pos;
  6148. }
  6149. static warn(message = "error", defaultReturn = undefined) {
  6150. if (Util.warnLevel() == "error") {
  6151. throw new Error(message);
  6152. }
  6153. else if (Util.warnLevel() == "warn") {
  6154. console.warn(message);
  6155. }
  6156. return defaultReturn;
  6157. }
  6158. static randomInt(range, start = 0) {
  6159. Util.warn("Util.randomInt is deprecated. Please use `Num.randomRange`");
  6160. return Math.floor(Math.random() * range) + start;
  6161. }
  6162. static split(pts, size, stride, loopBack = false, matchSize = true) {
  6163. let chunks = [];
  6164. let part = [];
  6165. let st = stride || size;
  6166. let index = 0;
  6167. if (pts.length <= 0 || st <= 0)
  6168. return [];
  6169. while (index < pts.length) {
  6170. part = [];
  6171. for (let k = 0; k < size; k++) {
  6172. if (loopBack) {
  6173. part.push(pts[(index + k) % pts.length]);
  6174. }
  6175. else {
  6176. if (index + k >= pts.length)
  6177. break;
  6178. part.push(pts[index + k]);
  6179. }
  6180. }
  6181. index += st;
  6182. if (!matchSize || (matchSize && part.length === size))
  6183. chunks.push(part);
  6184. }
  6185. return chunks;
  6186. }
  6187. static flatten(pts, flattenAsGroup = true) {
  6188. let arr = (flattenAsGroup) ? new Pt_1.Group() : new Array();
  6189. return arr.concat.apply(arr, pts);
  6190. }
  6191. static combine(a, b, op) {
  6192. let result = [];
  6193. for (let i = 0, len = a.length; i < len; i++) {
  6194. for (let k = 0, lenB = b.length; k < lenB; k++) {
  6195. result.push(op(a[i], b[k]));
  6196. }
  6197. }
  6198. return result;
  6199. }
  6200. static zip(arrays) {
  6201. let z = [];
  6202. for (let i = 0, len = arrays[0].length; i < len; i++) {
  6203. let p = [];
  6204. for (let k = 0; k < arrays.length; k++) {
  6205. p.push(arrays[k][i]);
  6206. }
  6207. z.push(p);
  6208. }
  6209. return z;
  6210. }
  6211. static stepper(max, min = 0, stride = 1, callback) {
  6212. let c = min;
  6213. return function () {
  6214. c += stride;
  6215. if (c >= max) {
  6216. c = min + (c - max);
  6217. }
  6218. if (callback)
  6219. callback(c);
  6220. return c;
  6221. };
  6222. }
  6223. static forRange(fn, range, start = 0, step = 1) {
  6224. let temp = [];
  6225. for (let i = start, len = range; i < len; i += step) {
  6226. temp[i] = fn(i);
  6227. }
  6228. return temp;
  6229. }
  6230. static load(url, callback) {
  6231. var request = new XMLHttpRequest();
  6232. request.open('GET', url, true);
  6233. request.onload = function () {
  6234. if (request.status >= 200 && request.status < 400) {
  6235. callback(request.responseText, true);
  6236. }
  6237. else {
  6238. callback(`Server error (${request.status}) when loading "${url}"`, false);
  6239. }
  6240. };
  6241. request.onerror = function () {
  6242. callback(`Unknown network error`, false);
  6243. };
  6244. request.send();
  6245. }
  6246. static performance(avgFrames = 10) {
  6247. let last = Date.now();
  6248. let avg = [];
  6249. return function () {
  6250. const now = Date.now();
  6251. avg.push(now - last);
  6252. if (avg.length >= avgFrames)
  6253. avg.shift();
  6254. last = now;
  6255. return Math.floor(avg.reduce((a, b) => a + b, 0) / avg.length);
  6256. };
  6257. }
  6258. static arrayCheck(pts, minRequired = 2) {
  6259. if (Array.isArray(pts) && pts.length < minRequired) {
  6260. Util.warn(`Requires ${minRequired} or more Pts in this Group.`);
  6261. return false;
  6262. }
  6263. return true;
  6264. }
  6265. static iterToArray(it) {
  6266. return (!Array.isArray(it)) ? [...it] : it;
  6267. }
  6268. static isMobile() {
  6269. return /iPhone|iPad|Android/i.test(navigator.userAgent);
  6270. }
  6271. }
  6272. exports.Util = Util;
  6273. Util._warnLevel = "mute";
  6274. /***/ }),
  6275. /***/ "./src/_lib.ts":
  6276. /*!*********************!*\
  6277. !*** ./src/_lib.ts ***!
  6278. \*********************/
  6279. /*! no static exports found */
  6280. /***/ (function(module, exports, __webpack_require__) {
  6281. "use strict";
  6282. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
  6283. if (k2 === undefined) k2 = k;
  6284. Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
  6285. }) : (function(o, m, k, k2) {
  6286. if (k2 === undefined) k2 = k;
  6287. o[k2] = m[k];
  6288. }));
  6289. var __exportStar = (this && this.__exportStar) || function(m, exports) {
  6290. for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
  6291. };
  6292. Object.defineProperty(exports, "__esModule", { value: true });
  6293. exports.quickStart = exports.namespace = void 0;
  6294. __exportStar(__webpack_require__(/*! ./Canvas */ "./src/Canvas.ts"), exports);
  6295. __exportStar(__webpack_require__(/*! ./Create */ "./src/Create.ts"), exports);
  6296. __exportStar(__webpack_require__(/*! ./Form */ "./src/Form.ts"), exports);
  6297. __exportStar(__webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts"), exports);
  6298. __exportStar(__webpack_require__(/*! ./Num */ "./src/Num.ts"), exports);
  6299. __exportStar(__webpack_require__(/*! ./Op */ "./src/Op.ts"), exports);
  6300. __exportStar(__webpack_require__(/*! ./Pt */ "./src/Pt.ts"), exports);
  6301. __exportStar(__webpack_require__(/*! ./Space */ "./src/Space.ts"), exports);
  6302. __exportStar(__webpack_require__(/*! ./Color */ "./src/Color.ts"), exports);
  6303. __exportStar(__webpack_require__(/*! ./Util */ "./src/Util.ts"), exports);
  6304. __exportStar(__webpack_require__(/*! ./Dom */ "./src/Dom.ts"), exports);
  6305. __exportStar(__webpack_require__(/*! ./Svg */ "./src/Svg.ts"), exports);
  6306. __exportStar(__webpack_require__(/*! ./Typography */ "./src/Typography.ts"), exports);
  6307. __exportStar(__webpack_require__(/*! ./Physics */ "./src/Physics.ts"), exports);
  6308. __exportStar(__webpack_require__(/*! ./UI */ "./src/UI.ts"), exports);
  6309. __exportStar(__webpack_require__(/*! ./Play */ "./src/Play.ts"), exports);
  6310. __exportStar(__webpack_require__(/*! ./Image */ "./src/Image.ts"), exports);
  6311. __exportStar(__webpack_require__(/*! ./Types */ "./src/Types.ts"), exports);
  6312. const _Canvas = __webpack_require__(/*! ./Canvas */ "./src/Canvas.ts");
  6313. let namespace = (scope) => {
  6314. let lib = module.exports;
  6315. for (let k in lib) {
  6316. if (k != "namespace") {
  6317. scope[k] = lib[k];
  6318. }
  6319. }
  6320. };
  6321. exports.namespace = namespace;
  6322. let quickStart = (id, bg = "#9ab") => {
  6323. if (!window)
  6324. return;
  6325. let s = window;
  6326. exports.namespace(s);
  6327. s.space = new _Canvas.CanvasSpace(id).setup({ bgcolor: bg, resize: true, retina: true });
  6328. s.form = s.space.getForm();
  6329. return function (animate = null, start = null, action = null, resize = null) {
  6330. s.space.add({
  6331. start: start,
  6332. animate: animate,
  6333. resize: resize,
  6334. action: action,
  6335. });
  6336. s.space.bindMouse().bindTouch().play();
  6337. };
  6338. };
  6339. exports.quickStart = quickStart;
  6340. /***/ })
  6341. /******/ });
  6342. });
  6343. //# sourceMappingURL=pts.js.map