p5_patch.js 655 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743
  1. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.p5 = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. /*!
  3. * Reqwest! A general purpose XHR connection manager
  4. * license MIT (c) Dustin Diaz 2014
  5. * https://github.com/ded/reqwest
  6. */
  7. !function (name, context, definition) {
  8. if (typeof module != 'undefined' && module.exports) module.exports = definition()
  9. else if (typeof define == 'function' && define.amd) define(definition)
  10. else context[name] = definition()
  11. }('reqwest', this, function () {
  12. var win = window
  13. , doc = document
  14. , httpsRe = /^http/
  15. , protocolRe = /(^\w+):\/\//
  16. , twoHundo = /^(20\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
  17. , byTag = 'getElementsByTagName'
  18. , readyState = 'readyState'
  19. , contentType = 'Content-Type'
  20. , requestedWith = 'X-Requested-With'
  21. , head = doc[byTag]('head')[0]
  22. , uniqid = 0
  23. , callbackPrefix = 'reqwest_' + (+new Date())
  24. , lastValue // data stored by the most recent JSONP callback
  25. , xmlHttpRequest = 'XMLHttpRequest'
  26. , xDomainRequest = 'XDomainRequest'
  27. , noop = function () {}
  28. , isArray = typeof Array.isArray == 'function'
  29. ? Array.isArray
  30. : function (a) {
  31. return a instanceof Array
  32. }
  33. , defaultHeaders = {
  34. 'contentType': 'application/x-www-form-urlencoded'
  35. , 'requestedWith': xmlHttpRequest
  36. , 'accept': {
  37. '*': 'text/javascript, text/html, application/xml, text/xml, */*'
  38. , 'xml': 'application/xml, text/xml'
  39. , 'html': 'text/html'
  40. , 'text': 'text/plain'
  41. , 'json': 'application/json, text/javascript'
  42. , 'js': 'application/javascript, text/javascript'
  43. }
  44. }
  45. , xhr = function(o) {
  46. // is it x-domain
  47. if (o['crossOrigin'] === true) {
  48. var xhr = win[xmlHttpRequest] ? new XMLHttpRequest() : null
  49. if (xhr && 'withCredentials' in xhr) {
  50. return xhr
  51. } else if (win[xDomainRequest]) {
  52. return new XDomainRequest()
  53. } else {
  54. throw new Error('Browser does not support cross-origin requests')
  55. }
  56. } else if (win[xmlHttpRequest]) {
  57. return new XMLHttpRequest()
  58. } else {
  59. return new ActiveXObject('Microsoft.XMLHTTP')
  60. }
  61. }
  62. , globalSetupOptions = {
  63. dataFilter: function (data) {
  64. return data
  65. }
  66. }
  67. function succeed(r) {
  68. var protocol = protocolRe.exec(r.url);
  69. protocol = (protocol && protocol[1]) || window.location.protocol;
  70. return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response;
  71. }
  72. function handleReadyState(r, success, error) {
  73. return function () {
  74. // use _aborted to mitigate against IE err c00c023f
  75. // (can't read props on aborted request objects)
  76. if (r._aborted) return error(r.request)
  77. if (r._timedOut) return error(r.request, 'Request is aborted: timeout')
  78. if (r.request && r.request[readyState] == 4) {
  79. r.request.onreadystatechange = noop
  80. if (succeed(r)) success(r.request)
  81. else
  82. error(r.request)
  83. }
  84. }
  85. }
  86. function setHeaders(http, o) {
  87. var headers = o['headers'] || {}
  88. , h
  89. headers['Accept'] = headers['Accept']
  90. || defaultHeaders['accept'][o['type']]
  91. || defaultHeaders['accept']['*']
  92. var isAFormData = typeof FormData === 'function' && (o['data'] instanceof FormData);
  93. // breaks cross-origin requests with legacy browsers
  94. if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']
  95. if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']
  96. for (h in headers)
  97. headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])
  98. }
  99. function setCredentials(http, o) {
  100. if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {
  101. http.withCredentials = !!o['withCredentials']
  102. }
  103. }
  104. function generalCallback(data) {
  105. lastValue = data
  106. }
  107. function urlappend (url, s) {
  108. return url + (/\?/.test(url) ? '&' : '?') + s
  109. }
  110. function handleJsonp(o, fn, err, url) {
  111. var reqId = uniqid++
  112. , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key
  113. , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)
  114. , cbreg = new RegExp('((^|\\?|&)' + cbkey + ')=([^&]+)')
  115. , match = url.match(cbreg)
  116. , script = doc.createElement('script')
  117. , loaded = 0
  118. , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1
  119. if (match) {
  120. if (match[3] === '?') {
  121. url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name
  122. } else {
  123. cbval = match[3] // provided callback func name
  124. }
  125. } else {
  126. url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em
  127. }
  128. win[cbval] = generalCallback
  129. script.type = 'text/javascript'
  130. script.src = url
  131. script.async = true
  132. if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {
  133. // need this for IE due to out-of-order onreadystatechange(), binding script
  134. // execution to an event listener gives us control over when the script
  135. // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
  136. script.htmlFor = script.id = '_reqwest_' + reqId
  137. }
  138. script.onload = script.onreadystatechange = function () {
  139. if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {
  140. return false
  141. }
  142. script.onload = script.onreadystatechange = null
  143. script.onclick && script.onclick()
  144. // Call the user callback with the last value stored and clean up values and scripts.
  145. fn(lastValue)
  146. lastValue = undefined
  147. head.removeChild(script)
  148. loaded = 1
  149. }
  150. // Add the script to the DOM head
  151. head.appendChild(script)
  152. // Enable JSONP timeout
  153. return {
  154. abort: function () {
  155. script.onload = script.onreadystatechange = null
  156. err({}, 'Request is aborted: timeout', {})
  157. lastValue = undefined
  158. head.removeChild(script)
  159. loaded = 1
  160. }
  161. }
  162. }
  163. function getRequest(fn, err) {
  164. var o = this.o
  165. , method = (o['method'] || 'GET').toUpperCase()
  166. , url = typeof o === 'string' ? o : o['url']
  167. // convert non-string objects to query-string form unless o['processData'] is false
  168. , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')
  169. ? reqwest.toQueryString(o['data'])
  170. : (o['data'] || null)
  171. , http
  172. , sendWait = false
  173. // if we're working on a GET request and we have data then we should append
  174. // query string to end of URL and not post data
  175. if ((o['type'] == 'jsonp' || method == 'GET') && data) {
  176. url = urlappend(url, data)
  177. data = null
  178. }
  179. if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)
  180. // get the xhr from the factory if passed
  181. // if the factory returns null, fall-back to ours
  182. http = (o.xhr && o.xhr(o)) || xhr(o)
  183. http.open(method, url, o['async'] === false ? false : true)
  184. setHeaders(http, o)
  185. setCredentials(http, o)
  186. if (win[xDomainRequest] && http instanceof win[xDomainRequest]) {
  187. http.onload = fn
  188. http.onerror = err
  189. // NOTE: see
  190. // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e
  191. http.onprogress = function() {}
  192. sendWait = true
  193. } else {
  194. http.onreadystatechange = handleReadyState(this, fn, err)
  195. }
  196. o['before'] && o['before'](http)
  197. if (sendWait) {
  198. setTimeout(function () {
  199. http.send(data)
  200. }, 200)
  201. } else {
  202. http.send(data)
  203. }
  204. return http
  205. }
  206. function Reqwest(o, fn) {
  207. this.o = o
  208. this.fn = fn
  209. init.apply(this, arguments)
  210. }
  211. function setType(header) {
  212. // json, javascript, text/plain, text/html, xml
  213. if (header.match('json')) return 'json'
  214. if (header.match('javascript')) return 'js'
  215. if (header.match('text')) return 'html'
  216. if (header.match('xml')) return 'xml'
  217. }
  218. function init(o, fn) {
  219. this.url = typeof o == 'string' ? o : o['url']
  220. this.timeout = null
  221. // whether request has been fulfilled for purpose
  222. // of tracking the Promises
  223. this._fulfilled = false
  224. // success handlers
  225. this._successHandler = function(){}
  226. this._fulfillmentHandlers = []
  227. // error handlers
  228. this._errorHandlers = []
  229. // complete (both success and fail) handlers
  230. this._completeHandlers = []
  231. this._erred = false
  232. this._responseArgs = {}
  233. var self = this
  234. fn = fn || function () {}
  235. if (o['timeout']) {
  236. this.timeout = setTimeout(function () {
  237. timedOut()
  238. }, o['timeout'])
  239. }
  240. if (o['success']) {
  241. this._successHandler = function () {
  242. o['success'].apply(o, arguments)
  243. }
  244. }
  245. if (o['error']) {
  246. this._errorHandlers.push(function () {
  247. o['error'].apply(o, arguments)
  248. })
  249. }
  250. if (o['complete']) {
  251. this._completeHandlers.push(function () {
  252. o['complete'].apply(o, arguments)
  253. })
  254. }
  255. function complete (resp) {
  256. o['timeout'] && clearTimeout(self.timeout)
  257. self.timeout = null
  258. while (self._completeHandlers.length > 0) {
  259. self._completeHandlers.shift()(resp)
  260. }
  261. }
  262. function success (resp) {
  263. var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE
  264. resp = (type !== 'jsonp') ? self.request : resp
  265. // use global data filter on response text
  266. var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)
  267. , r = filteredResponse
  268. try {
  269. resp.responseText = r
  270. } catch (e) {
  271. // can't assign this in IE<=8, just ignore
  272. }
  273. if (r) {
  274. switch (type) {
  275. case 'json':
  276. try {
  277. resp = win.JSON ? win.JSON.parse(r) : eval('(' + r + ')')
  278. } catch (err) {
  279. return error(resp, 'Could not parse JSON in response', err)
  280. }
  281. break
  282. case 'js':
  283. resp = eval(r)
  284. break
  285. case 'html':
  286. resp = r
  287. break
  288. case 'xml':
  289. resp = resp.responseXML
  290. && resp.responseXML.parseError // IE trololo
  291. && resp.responseXML.parseError.errorCode
  292. && resp.responseXML.parseError.reason
  293. ? null
  294. : resp.responseXML
  295. break
  296. }
  297. }
  298. self._responseArgs.resp = resp
  299. self._fulfilled = true
  300. fn(resp)
  301. self._successHandler(resp)
  302. while (self._fulfillmentHandlers.length > 0) {
  303. resp = self._fulfillmentHandlers.shift()(resp)
  304. }
  305. complete(resp)
  306. }
  307. function timedOut() {
  308. self._timedOut = true
  309. self.request.abort()
  310. }
  311. function error(resp, msg, t) {
  312. resp = self.request
  313. self._responseArgs.resp = resp
  314. self._responseArgs.msg = msg
  315. self._responseArgs.t = t
  316. self._erred = true
  317. while (self._errorHandlers.length > 0) {
  318. self._errorHandlers.shift()(resp, msg, t)
  319. }
  320. complete(resp)
  321. }
  322. this.request = getRequest.call(this, success, error)
  323. }
  324. Reqwest.prototype = {
  325. abort: function () {
  326. this._aborted = true
  327. this.request.abort()
  328. }
  329. , retry: function () {
  330. init.call(this, this.o, this.fn)
  331. }
  332. /**
  333. * Small deviation from the Promises A CommonJs specification
  334. * http://wiki.commonjs.org/wiki/Promises/A
  335. */
  336. /**
  337. * `then` will execute upon successful requests
  338. */
  339. , then: function (success, fail) {
  340. success = success || function () {}
  341. fail = fail || function () {}
  342. if (this._fulfilled) {
  343. this._responseArgs.resp = success(this._responseArgs.resp)
  344. } else if (this._erred) {
  345. fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)
  346. } else {
  347. this._fulfillmentHandlers.push(success)
  348. this._errorHandlers.push(fail)
  349. }
  350. return this
  351. }
  352. /**
  353. * `always` will execute whether the request succeeds or fails
  354. */
  355. , always: function (fn) {
  356. if (this._fulfilled || this._erred) {
  357. fn(this._responseArgs.resp)
  358. } else {
  359. this._completeHandlers.push(fn)
  360. }
  361. return this
  362. }
  363. /**
  364. * `fail` will execute when the request fails
  365. */
  366. , fail: function (fn) {
  367. if (this._erred) {
  368. fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)
  369. } else {
  370. this._errorHandlers.push(fn)
  371. }
  372. return this
  373. }
  374. , 'catch': function (fn) {
  375. return this.fail(fn)
  376. }
  377. }
  378. function reqwest(o, fn) {
  379. return new Reqwest(o, fn)
  380. }
  381. // normalize newline variants according to spec -> CRLF
  382. function normalize(s) {
  383. return s ? s.replace(/\r?\n/g, '\r\n') : ''
  384. }
  385. function serial(el, cb) {
  386. var n = el.name
  387. , t = el.tagName.toLowerCase()
  388. , optCb = function (o) {
  389. // IE gives value="" even where there is no value attribute
  390. // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273
  391. if (o && !o['disabled'])
  392. cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))
  393. }
  394. , ch, ra, val, i
  395. // don't serialize elements that are disabled or without a name
  396. if (el.disabled || !n) return
  397. switch (t) {
  398. case 'input':
  399. if (!/reset|button|image|file/i.test(el.type)) {
  400. ch = /checkbox/i.test(el.type)
  401. ra = /radio/i.test(el.type)
  402. val = el.value
  403. // WebKit gives us "" instead of "on" if a checkbox has no value, so correct it here
  404. ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))
  405. }
  406. break
  407. case 'textarea':
  408. cb(n, normalize(el.value))
  409. break
  410. case 'select':
  411. if (el.type.toLowerCase() === 'select-one') {
  412. optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)
  413. } else {
  414. for (i = 0; el.length && i < el.length; i++) {
  415. el.options[i].selected && optCb(el.options[i])
  416. }
  417. }
  418. break
  419. }
  420. }
  421. // collect up all form elements found from the passed argument elements all
  422. // the way down to child elements; pass a '<form>' or form fields.
  423. // called with 'this'=callback to use for serial() on each element
  424. function eachFormElement() {
  425. var cb = this
  426. , e, i
  427. , serializeSubtags = function (e, tags) {
  428. var i, j, fa
  429. for (i = 0; i < tags.length; i++) {
  430. fa = e[byTag](tags[i])
  431. for (j = 0; j < fa.length; j++) serial(fa[j], cb)
  432. }
  433. }
  434. for (i = 0; i < arguments.length; i++) {
  435. e = arguments[i]
  436. if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)
  437. serializeSubtags(e, [ 'input', 'select', 'textarea' ])
  438. }
  439. }
  440. // standard query string style serialization
  441. function serializeQueryString() {
  442. return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))
  443. }
  444. // { 'name': 'value', ... } style serialization
  445. function serializeHash() {
  446. var hash = {}
  447. eachFormElement.apply(function (name, value) {
  448. if (name in hash) {
  449. hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])
  450. hash[name].push(value)
  451. } else hash[name] = value
  452. }, arguments)
  453. return hash
  454. }
  455. // [ { name: 'name', value: 'value' }, ... ] style serialization
  456. reqwest.serializeArray = function () {
  457. var arr = []
  458. eachFormElement.apply(function (name, value) {
  459. arr.push({name: name, value: value})
  460. }, arguments)
  461. return arr
  462. }
  463. reqwest.serialize = function () {
  464. if (arguments.length === 0) return ''
  465. var opt, fn
  466. , args = Array.prototype.slice.call(arguments, 0)
  467. opt = args.pop()
  468. opt && opt.nodeType && args.push(opt) && (opt = null)
  469. opt && (opt = opt.type)
  470. if (opt == 'map') fn = serializeHash
  471. else if (opt == 'array') fn = reqwest.serializeArray
  472. else fn = serializeQueryString
  473. return fn.apply(null, args)
  474. }
  475. reqwest.toQueryString = function (o, trad) {
  476. var prefix, i
  477. , traditional = trad || false
  478. , s = []
  479. , enc = encodeURIComponent
  480. , add = function (key, value) {
  481. // If value is a function, invoke it and return its value
  482. value = ('function' === typeof value) ? value() : (value == null ? '' : value)
  483. s[s.length] = enc(key) + '=' + enc(value)
  484. }
  485. // If an array was passed in, assume that it is an array of form elements.
  486. if (isArray(o)) {
  487. for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])
  488. } else {
  489. // If traditional, encode the "old" way (the way 1.3.2 or older
  490. // did it), otherwise encode params recursively.
  491. for (prefix in o) {
  492. if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)
  493. }
  494. }
  495. // spaces should be + according to spec
  496. return s.join('&').replace(/%20/g, '+')
  497. }
  498. function buildParams(prefix, obj, traditional, add) {
  499. var name, i, v
  500. , rbracket = /\[\]$/
  501. if (isArray(obj)) {
  502. // Serialize array item.
  503. for (i = 0; obj && i < obj.length; i++) {
  504. v = obj[i]
  505. if (traditional || rbracket.test(prefix)) {
  506. // Treat each array item as a scalar.
  507. add(prefix, v)
  508. } else {
  509. buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)
  510. }
  511. }
  512. } else if (obj && obj.toString() === '[object Object]') {
  513. // Serialize object item.
  514. for (name in obj) {
  515. buildParams(prefix + '[' + name + ']', obj[name], traditional, add)
  516. }
  517. } else {
  518. // Serialize scalar item.
  519. add(prefix, obj)
  520. }
  521. }
  522. reqwest.getcallbackPrefix = function () {
  523. return callbackPrefix
  524. }
  525. // jQuery and Zepto compatibility, differences can be remapped here so you can call
  526. // .ajax.compat(options, callback)
  527. reqwest.compat = function (o, fn) {
  528. if (o) {
  529. o['type'] && (o['method'] = o['type']) && delete o['type']
  530. o['dataType'] && (o['type'] = o['dataType'])
  531. o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']
  532. o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])
  533. }
  534. return new Reqwest(o, fn)
  535. }
  536. reqwest.ajaxSetup = function (options) {
  537. options = options || {}
  538. for (var k in options) {
  539. globalSetupOptions[k] = options[k]
  540. }
  541. }
  542. return reqwest
  543. });
  544. },{}],2:[function(require,module,exports){
  545. 'use strict';
  546. var p5 = require('../core/core');
  547. require('./p5.Geometry3D');
  548. /**
  549. * draw a plane with given a width and height
  550. * @param {Number} width the width of the plane
  551. * @param {Number} height the height of the plane
  552. * @param {Number} detailX(optional) number of vertices on horizontal surface
  553. * @param {Number} detailY(optional) number of vertices on horizontal surface
  554. * example
  555. * <div class="norender">
  556. * <code>
  557. * function setup(){
  558. * createCanvas(windowWidth, windowHeight, 'webgl');
  559. * }
  560. *
  561. * var theta = 0;
  562. *
  563. * function draw(){
  564. * background(255, 255, 255, 255);
  565. * translate(0, 0, -100);
  566. * push();
  567. * rotateZ(theta);
  568. * rotateX(theta);
  569. * rotateY(theta);
  570. * plane(100, 100);
  571. * pop();
  572. * theta += 0.05;
  573. * </code>
  574. * </div>
  575. */
  576. p5.prototype.plane = function(width, height, detailX, detailY){
  577. width = width || 1;
  578. height = height || 1;
  579. detailX = detailX || 1;
  580. detailY = detailY || 1;
  581. var gId = 'plane|'+width+'|'+height+'|'+detailX+'|'+detailY;
  582. if(!this._graphics.geometryInHash(gId)){
  583. var geometry3d = new p5.Geometry3D();
  584. var createPlane = function(u, v){
  585. var x = 2 * width * u - width;
  586. var y = 2 * height * v - height;
  587. var z = 0;
  588. return new p5.Vector(x, y, z);
  589. };
  590. geometry3d.parametricGeometry(createPlane, detailX, detailY);
  591. var obj = geometry3d.generateObj();
  592. this._graphics.initBuffer(gId, obj);
  593. }
  594. this._graphics.drawBuffer(gId);
  595. };
  596. /**
  597. * draw a sphere with given raduis
  598. * @param {Number} radius radius of the sphere
  599. * @param {Number} detailX(optional) number of vertices on horizontal surface
  600. * @param {Number} detailY(optional) number of vertices on vertical surface
  601. * example
  602. * <div class="norender">
  603. * <code>
  604. * function setup(){
  605. * createCanvas(windowWidth, windowHeight, 'webgl');
  606. * }
  607. *
  608. * var theta = 0;
  609. *
  610. * function draw(){
  611. * background(255, 255, 255, 255);
  612. * translate(0, 0, -100);
  613. * push();
  614. * rotateZ(theta);
  615. * rotateX(theta);
  616. * rotateY(theta);
  617. * sphere(100);
  618. * pop();
  619. * theta += 0.05;
  620. * </code>
  621. * </div>
  622. */
  623. p5.prototype.sphere = function(radius, detailX, detailY){
  624. radius = radius || 50;
  625. detailX = detailX || 10;
  626. detailY = detailY || 6;
  627. var gId = 'sphere|'+radius+'|'+detailX+'|'+detailY;
  628. if(!this._graphics.geometryInHash(gId)){
  629. var geometry3d = new p5.Geometry3D();
  630. var createSphere = function(u, v){
  631. var theta = 2 * Math.PI * u;
  632. var phi = Math.PI * v - Math.PI / 2;
  633. var x = radius * Math.cos(phi) * Math.sin(theta);
  634. var y = radius * Math.sin(phi);
  635. var z = radius * Math.cos(phi) * Math.cos(theta);
  636. return new p5.Vector(x, y, z);
  637. };
  638. geometry3d.parametricGeometry(createSphere, detailX, detailY);
  639. var obj = geometry3d.generateObj();
  640. this._graphics.initBuffer(gId, obj);
  641. }
  642. this._graphics.drawBuffer(gId);
  643. return this;
  644. };
  645. /**
  646. * draw a cylinder with given radius and height
  647. * @param {Number} radius radius of the surface
  648. * @param {Number} height height of the cylinder
  649. * @param {Number} detailX(optional) number of vertices on horizontal surface
  650. * @param {Number} detailY(optional) number of vertices on vertical surface
  651. * example
  652. * <div class="norender">
  653. * <code>
  654. * function setup(){
  655. * createCanvas(windowWidth, windowHeight, 'webgl');
  656. * }
  657. *
  658. * var theta = 0;
  659. *
  660. * function draw(){
  661. * background(255, 255, 255, 255);
  662. * translate(0, 0, -100);
  663. * push();
  664. * rotateZ(theta);
  665. * rotateX(theta);
  666. * rotateY(theta);
  667. * cylinder(100, 200);
  668. * pop();
  669. * theta += 0.05;
  670. * </code>
  671. * </div>
  672. */
  673. p5.prototype.cylinder = function(radius, height, detailX, detailY){
  674. radius = radius || 50;
  675. height = height || 50;
  676. detailX = detailX || 12;
  677. detailY = detailY || 8;
  678. var gId = 'cylinder|'+radius+'|'+height+'|'+detailX+'|'+detailY;
  679. if(!this._graphics.geometryInHash(gId)){
  680. var geometry3d = new p5.Geometry3D();
  681. var createCylinder = function(u, v){
  682. var theta = 2 * Math.PI * u;
  683. var x = radius * Math.sin(theta);
  684. var y = 2 * height * v - height;
  685. var z = radius * Math.cos(theta);
  686. return new p5.Vector(x, y, z);
  687. };
  688. geometry3d.parametricGeometry(createCylinder, detailX, detailY);
  689. geometry3d.mergeVertices();
  690. var createTop = function(u, v){
  691. var theta = 2 * Math.PI * u;
  692. var x = radius * Math.sin(-theta);
  693. var y = height;
  694. var z = radius * Math.cos(theta);
  695. if(v === 0){
  696. return new p5.Vector(0, height, 0);
  697. }
  698. else{
  699. return new p5.Vector(x, y, z);
  700. }
  701. };
  702. geometry3d.parametricGeometry(
  703. createTop, detailX, 1, geometry3d.vertices.length);
  704. var createBottom = function(u, v){
  705. var theta = 2 * Math.PI * u;
  706. var x = radius * Math.sin(theta);
  707. var y = -height;
  708. var z = radius * Math.cos(theta);
  709. if(v === 0){
  710. return new p5.Vector(0, -height, 0);
  711. }else{
  712. return new p5.Vector(x, y, z);
  713. }
  714. };
  715. geometry3d.parametricGeometry(
  716. createBottom, detailX, 1, geometry3d.vertices.length);
  717. var obj = geometry3d.generateObj(true);
  718. this._graphics.initBuffer(gId, obj);
  719. }
  720. this._graphics.drawBuffer(gId);
  721. return this;
  722. };
  723. /**
  724. * draw a cone with given radius and height
  725. * @param {Number} radius radius of the bottom surface
  726. * @param {Number} height height of the cone
  727. * @param {Number} detailX(optional) number of vertices on horizontal surface
  728. * @param {Number} detailY(optional) number of vertices on vertical surface
  729. * example
  730. * <div class="norender">
  731. * <code>
  732. * function setup(){
  733. * createCanvas(windowWidth, windowHeight, 'webgl');
  734. * }
  735. *
  736. * var theta = 0;
  737. *
  738. * function draw(){
  739. * background(255, 255, 255, 255);
  740. * translate(0, 0, -100);
  741. * push();
  742. * rotateZ(theta);
  743. * rotateX(theta);
  744. * rotateY(theta);
  745. * cone(100, 200);
  746. * pop();
  747. * theta += 0.05;
  748. * </code>
  749. * </div>
  750. */
  751. p5.prototype.cone = function(radius, height, detailX, detailY){
  752. radius = radius || 50;
  753. height = height || 50;
  754. detailX = detailX || 10;
  755. detailY = detailY || 6;
  756. var gId = 'cone|'+radius+'|'+height+'|'+detailX+'|'+detailY;
  757. if(!this._graphics.geometryInHash(gId)){
  758. var geometry3d = new p5.Geometry3D();
  759. var createCone = function(u, v){
  760. var theta = 2 * Math.PI * u;
  761. var x = radius * (1 - v) * Math.sin(theta);
  762. var y = 2 * height * v - height;
  763. var z = radius * (1 - v) * Math.cos(theta);
  764. return new p5.Vector(x, y, z);
  765. };
  766. geometry3d.parametricGeometry(createCone, detailX, detailY);
  767. geometry3d.mergeVertices();
  768. var createBottom = function(u, v){
  769. var theta = 2 * Math.PI * u;
  770. var x = radius * (1 - v) * Math.sin(-theta);
  771. var y = -height;
  772. var z = radius * (1 - v) * Math.cos(theta);
  773. return new p5.Vector(x, y, z);
  774. };
  775. geometry3d.parametricGeometry(
  776. createBottom, detailX, 1, geometry3d.vertices.length);
  777. var obj = geometry3d.generateObj(true);
  778. this._graphics.initBuffer(gId, obj);
  779. }
  780. this._graphics.drawBuffer(gId);
  781. return this;
  782. };
  783. /**
  784. * draw a torus with given radius and tube radius
  785. * @param {Number} radius radius of the whole ring
  786. * @param {Number} tubeRadius radius of the tube
  787. * @param {Number} detailX(optional) number of vertices on horizontal surface
  788. * @param {Number} detailY(optional) number of vertices on vertical surface
  789. * example
  790. * <div class="norender">
  791. * <code>
  792. * function setup(){
  793. * createCanvas(windowWidth, windowHeight, 'webgl');
  794. * }
  795. *
  796. * var theta = 0;
  797. *
  798. * function draw(){
  799. * background(255, 255, 255, 255);
  800. * translate(0, 0, -100);
  801. * push();
  802. * rotateZ(theta);
  803. * rotateX(theta);
  804. * rotateY(theta);
  805. * torus(100, 20);
  806. * pop();
  807. * theta += 0.05;
  808. * </code>
  809. * </div>
  810. */
  811. p5.prototype.torus = function(radius, tubeRadius, detailX, detailY){
  812. radius = radius || 50;
  813. tubeRadius = tubeRadius || 20;
  814. detailX = detailX || 12;
  815. detailY = detailY || 6;
  816. var gId = 'torus|'+radius+'|'+tubeRadius+'|'+detailX+'|'+detailY;
  817. if(!this._graphics.geometryInHash(gId)){
  818. var geometry3d = new p5.Geometry3D();
  819. var createTorus = function(u, v){
  820. var theta = 2 * Math.PI * u;
  821. var phi = 2 * Math.PI * v;
  822. var x = (radius + tubeRadius * Math.cos(phi)) * Math.cos(theta);
  823. var y = (radius + tubeRadius * Math.cos(phi)) * Math.sin(theta);
  824. var z = tubeRadius * Math.sin(phi);
  825. return new p5.Vector(x, y, z);
  826. };
  827. geometry3d.parametricGeometry(createTorus, detailX, detailY);
  828. var obj = geometry3d.generateObj();
  829. this._graphics.initBuffer(gId, obj);
  830. }
  831. this._graphics.drawBuffer(gId);
  832. return this;
  833. };
  834. /**
  835. * draw a box with given widht, height and depth
  836. * @param {Number} width width of the box
  837. * @param {Number} height height of the box
  838. * @param {Number} depth depth of the box
  839. * example
  840. * <div class="norender">
  841. * <code>
  842. * function setup(){
  843. * createCanvas(windowWidth, windowHeight, 'webgl');
  844. * }
  845. *
  846. * var theta = 0;
  847. *
  848. * function draw(){
  849. * background(255, 255, 255, 255);
  850. * translate(0, 0, -100);
  851. * push();
  852. * rotateZ(theta);
  853. * rotateX(theta);
  854. * rotateY(theta);
  855. * box(100, 100, 100);
  856. * pop();
  857. * theta += 0.05;
  858. * </code>
  859. * </div>
  860. */
  861. p5.prototype.box = function(width, height, depth){
  862. width = width || 10;
  863. height = height || width;
  864. depth = depth || width;
  865. //detail for box as optional
  866. var detailX = typeof arguments[3] === Number ? arguments[3] : 1;
  867. var detailY = typeof arguments[4] === Number ? arguments[4] : 1;
  868. var gId = 'cube|'+width+'|'+height+'|'+depth+'|'+detailX+'|'+detailY;
  869. if(!this._graphics.geometryInHash(gId)){
  870. var geometry3d = new p5.Geometry3D();
  871. var createPlane1 = function(u, v){
  872. var x = 2 * width * u - width;
  873. var y = 2 * height * v - height;
  874. var z = depth;
  875. return new p5.Vector(x, y, z);
  876. };
  877. var createPlane2 = function(u, v){
  878. var x = 2 * width * ( 1 - u ) - width;
  879. var y = 2 * height * v - height;
  880. var z = -depth;
  881. return new p5.Vector(x, y, z);
  882. };
  883. var createPlane3 = function(u, v){
  884. var x = 2 * width * ( 1 - u ) - width;
  885. var y = height;
  886. var z = 2 * depth * v - depth;
  887. return new p5.Vector(x, y, z);
  888. };
  889. var createPlane4 = function(u, v){
  890. var x = 2 * width * u - width;
  891. var y = -height;
  892. var z = 2 * depth * v - depth;
  893. return new p5.Vector(x, y, z);
  894. };
  895. var createPlane5 = function(u, v){
  896. var x = width;
  897. var y = 2 * height * u - height;
  898. var z = 2 * depth * v - depth;
  899. return new p5.Vector(x, y, z);
  900. };
  901. var createPlane6 = function(u, v){
  902. var x = -width;
  903. var y = 2 * height * ( 1 - u ) - height;
  904. var z = 2 * depth * v - depth;
  905. return new p5.Vector(x, y, z);
  906. };
  907. geometry3d.parametricGeometry(
  908. createPlane1, detailX, detailY, geometry3d.vertices.length);
  909. geometry3d.parametricGeometry(
  910. createPlane2, detailX, detailY, geometry3d.vertices.length);
  911. geometry3d.parametricGeometry(
  912. createPlane3, detailX, detailY, geometry3d.vertices.length);
  913. geometry3d.parametricGeometry(
  914. createPlane4, detailX, detailY, geometry3d.vertices.length);
  915. geometry3d.parametricGeometry(
  916. createPlane5, detailX, detailY, geometry3d.vertices.length);
  917. geometry3d.parametricGeometry(
  918. createPlane6, detailX, detailY, geometry3d.vertices.length);
  919. var obj = geometry3d.generateObj(true);
  920. this._graphics.initBuffer(gId, obj);
  921. }
  922. this._graphics.drawBuffer(gId);
  923. return this;
  924. };
  925. module.exports = p5;
  926. },{"../core/core":17,"./p5.Geometry3D":4}],3:[function(require,module,exports){
  927. 'use strict';
  928. var p5 = require('../core/core');
  929. /**
  930. * [normal description]
  931. * @return {[type]} [description]
  932. */
  933. p5.prototype.normalMaterial = function(){
  934. var mId = 'normalVert|normalFrag';
  935. if(!this._graphics.materialInHash(mId)){
  936. this._graphics.initShaders('normalVert', 'normalFrag');
  937. }
  938. this._graphics.saveShaders(mId);
  939. return this;
  940. };
  941. /**
  942. * [basic description]
  943. * @param {[type]} r [description]
  944. * @param {[type]} g [description]
  945. * @param {[type]} b [description]
  946. * @param {[type]} a [description]
  947. * @return {[type]} [description]
  948. */
  949. p5.prototype.basicMaterial = function(r, g, b, a){
  950. r = r / 255 || 0.5;
  951. g = g / 255 || r;
  952. b = b / 255 || r;
  953. a = a || 1.0;
  954. var mId = 'normalVert|basicFrag';
  955. if(!this._graphics.materialInHash(mId)){
  956. //@TODO: figure out how to do this
  957. // var sp = this._graphics.initShaders(
  958. // shaders.normalVert, shaders.basicFrag, {
  959. // uMaterialColor: [r, g, b, a]
  960. // });
  961. // sp.uMaterialColorLoc = gl.getUniformLocation(
  962. // shaderProgram, 'uMaterialColor' );
  963. // gl.uniform4f( program.uMaterialColorLoc, 1.0, 1.0, 1.0, 1.0 );
  964. this._graphics.initShaders('normalVert', 'basicFrag');
  965. }
  966. this._graphics.saveShaders(mId);
  967. return this;
  968. };
  969. module.exports = p5;
  970. },{"../core/core":17}],4:[function(require,module,exports){
  971. 'use strict';
  972. var p5 = require('../core/core');
  973. /**
  974. * p5 Geometry3D class
  975. */
  976. p5.Geometry3D = function(){
  977. //an array holding every vertice
  978. //each vertex is a p5.Vector
  979. this.vertices = [];
  980. //an array holding each normals for each vertice
  981. //each normal is a p5.Vector
  982. this.vertexNormals = [];
  983. //an array holding each three indecies of vertices that form a face
  984. //[[0, 1, 2], [1, 2, 3], ...]
  985. this.faces = [];
  986. //an array holding every noraml for each face
  987. //each faceNormal is a p5.Vector
  988. //[[p5.Vector, p5.Vector, p5.Vector],[p5.Vector, p5.Vector, p5.Vector],...]
  989. this.faceNormals = [];
  990. //an array of p5.Vector holding uvs
  991. this.uvs = [];
  992. };
  993. /**
  994. * generate geometriy with parametric method
  995. * @param {Function} func callback function for how to generate geometry
  996. * @param {Number} detailX number of vertices on horizontal surface
  997. * @param {Number} detailY number of vertices on horizontal surface
  998. * @param {Number} offset offset of vertices index
  999. */
  1000. p5.Geometry3D.prototype.parametricGeometry = function
  1001. (func, detailX, detailY, offset){
  1002. var i, j, p;
  1003. var u, v;
  1004. offset = offset || 0;
  1005. var sliceCount = detailX + 1;
  1006. for (i = 0; i <= detailY; i++){
  1007. v = i / detailY;
  1008. for (j = 0; j <= detailX; j++){
  1009. u = j / detailX;
  1010. p = func(u, v);
  1011. this.vertices.push(p);
  1012. }
  1013. }
  1014. var a, b, c, d;
  1015. var uva, uvb, uvc, uvd;
  1016. for (i = 0; i < detailY; i++){
  1017. for (j = 0; j < detailX; j++){
  1018. a = i * sliceCount + j + offset;
  1019. b = i * sliceCount + j + 1 + offset;
  1020. c = (i + 1)* sliceCount + j + 1 + offset;
  1021. d = (i + 1)* sliceCount + j + offset;
  1022. uva = [j/detailX, i/detailY];
  1023. uvb = [(j + 1)/ detailX, i/detailY];
  1024. uvc = [(j + 1)/ detailX, (i + 1)/detailY];
  1025. uvd = [j/detailX, (i + 1)/detailY];
  1026. this.faces.push([a, b, d]);
  1027. this.uvs.push([uva, uvb, uvd]);
  1028. this.faces.push([b, c, d]);
  1029. this.uvs.push([uvb, uvc, uvd]);
  1030. }
  1031. }
  1032. };
  1033. /**
  1034. * merge duplicated vertices
  1035. */
  1036. p5.Geometry3D.prototype.mergeVertices= function () {
  1037. var verticesMap = {};
  1038. var unique = [], changes = [];
  1039. var v, key;
  1040. var precisionPoints = 4;
  1041. var precision = Math.pow(10, precisionPoints);
  1042. var i, face;
  1043. var indices;
  1044. for (i = 0; i < this.vertices.length; i ++) {
  1045. v = this.vertices[i];
  1046. key = Math.round(v.x * precision) + '_' +
  1047. Math.round(v.y * precision) + '_' +
  1048. Math.round(v.z * precision);
  1049. if (verticesMap[key] === undefined) {
  1050. verticesMap[key] = i;
  1051. unique.push(this.vertices[i]);
  1052. changes[i] = unique.length - 1;
  1053. } else {
  1054. changes[i] = changes[verticesMap[key]];
  1055. }
  1056. }
  1057. // if faces are completely degenerate after merging vertices, we
  1058. // have to remove them from the geometry.
  1059. var faceIndicesToRemove = [];
  1060. for (i = 0; i < this.faces.length; i ++) {
  1061. face = this.faces[i];
  1062. face[0] = changes[face[0]];
  1063. face[1] = changes[face[1]];
  1064. face[2] = changes[face[2]];
  1065. indices = [face[0], face[1], face[2]];
  1066. var dupIndex = - 1;
  1067. // if any duplicate vertices are found in a Face
  1068. // we have to remove the face as nothing can be saved
  1069. for (var n = 0; n < 3; n ++) {
  1070. if (indices[n] === indices[(n + 1) % 3]) {
  1071. dupIndex = n;
  1072. faceIndicesToRemove.push(i);
  1073. break;
  1074. }
  1075. }
  1076. }
  1077. for (i = faceIndicesToRemove.length - 1; i >= 0; i --) {
  1078. var idx = faceIndicesToRemove[i];
  1079. this.faces.splice(idx, 1);
  1080. }
  1081. // Use unique set of vertices
  1082. var diff = this.vertices.length - unique.length;
  1083. this.vertices = unique;
  1084. return diff;
  1085. };
  1086. /**
  1087. * compute faceNormals for a geometry
  1088. */
  1089. p5.Geometry3D.prototype.computeFaceNormals = function(){
  1090. var cb = new p5.Vector();
  1091. var ab = new p5.Vector();
  1092. for (var f = 0; f < this.faces.length; f++){
  1093. var face = this.faces[f];
  1094. var vA = this.vertices[face[0]];
  1095. var vB = this.vertices[face[1]];
  1096. var vC = this.vertices[face[2]];
  1097. p5.Vector.sub(vC, vB, cb);
  1098. p5.Vector.sub(vA, vB, ab);
  1099. var normal = p5.Vector.cross(ab, cb);
  1100. normal.normalize();
  1101. normal.mult(-1);
  1102. this.faceNormals[f] = normal;
  1103. }
  1104. };
  1105. /**
  1106. * compute vertexNormals for a geometry
  1107. */
  1108. p5.Geometry3D.prototype.computeVertexNormals = function (){
  1109. var v, f, face, faceNormal, vertices;
  1110. var vertexNormals = [];
  1111. vertices = new Array(this.vertices.length);
  1112. for (v = 0; v < this.vertices.length; v++) {
  1113. vertices[v] = new p5.Vector();
  1114. }
  1115. for (f = 0; f < this.faces.length; f++) {
  1116. face = this.faces[f];
  1117. faceNormal = this.faceNormals[f];
  1118. vertices[face[0]].add(faceNormal);
  1119. vertices[face[1]].add(faceNormal);
  1120. vertices[face[2]].add(faceNormal);
  1121. }
  1122. for (v = 0; v < this.vertices.length; v++) {
  1123. vertices[v].normalize();
  1124. }
  1125. for (f = 0; f < this.faces.length; f++) {
  1126. face = this.faces[f];
  1127. vertexNormals[f] = [];
  1128. vertexNormals[f][0]= vertices[face[0]].copy();
  1129. vertexNormals[f][1]= vertices[face[1]].copy();
  1130. vertexNormals[f][2]= vertices[face[2]].copy();
  1131. }
  1132. for (f = 0; f < this.faces.length; f++){
  1133. face = this.faces[f];
  1134. faceNormal = this.faceNormals[f];
  1135. this.vertexNormals[face[0]] = vertexNormals[f][0];
  1136. this.vertexNormals[face[1]] = vertexNormals[f][1];
  1137. this.vertexNormals[face[2]] = vertexNormals[f][2];
  1138. }
  1139. };
  1140. /**
  1141. * generate an object containing information needed to create buffer
  1142. */
  1143. p5.Geometry3D.prototype.generateObj = function(noMerge){
  1144. if(!noMerge){
  1145. this.mergeVertices();
  1146. }
  1147. this.computeFaceNormals();
  1148. this.computeVertexNormals();
  1149. var obj = {
  1150. vertices: turnVectorArrayIntoNumberArray(this.vertices),
  1151. vertexNormals: turnVectorArrayIntoNumberArray(this.vertexNormals),
  1152. faces: flatten(this.faces),
  1153. len: this.faces.length * 3
  1154. };
  1155. return obj;
  1156. };
  1157. /**
  1158. * turn a two dimensional array into one dimensional array
  1159. * @param {Array} arr 2-dimensional array
  1160. * @return {Array} 1-dimensional array
  1161. * [[1, 2, 3],[4, 5, 6]] -> [1, 2, 3, 4, 5, 6]
  1162. */
  1163. function flatten(arr){
  1164. return arr.reduce(function(a, b){
  1165. return a.concat(b);
  1166. });
  1167. }
  1168. /**
  1169. * turn an array of Vector into a one dimensional array of numbers
  1170. * @param {Array} arr an array of p5.Vector
  1171. * @return {Array]} a one dimensional array of numbers
  1172. * [p5.Vector(1, 2, 3), p5.Vector(4, 5, 6)] ->
  1173. * [1, 2, 3, 4, 5, 6]
  1174. */
  1175. function turnVectorArrayIntoNumberArray(arr){
  1176. return flatten(arr.map(function(item){
  1177. return [item.x, item.y, item.z];
  1178. }));
  1179. }
  1180. module.exports = p5.Geometry3D;
  1181. },{"../core/core":17}],5:[function(require,module,exports){
  1182. /**
  1183. * @requires constants
  1184. * @todo see methods below needing further implementation.
  1185. */
  1186. 'use strict';
  1187. var p5 = require('../core/core');
  1188. var polarGeometry = require('../math/polargeometry');
  1189. var constants = require('../core/constants');
  1190. var GLMAT_ARRAY_TYPE = (
  1191. typeof Float32Array !== 'undefined') ?
  1192. Float32Array : Array;
  1193. /**
  1194. * A class to describe a 4x4 matrix
  1195. * for model and view matrix manipulation in the p5js webgl renderer.
  1196. * @class p5.Matrix
  1197. * @constructor
  1198. * @param {Array} [mat4] array literal of our 4x4 matrix
  1199. */
  1200. p5.Matrix = function() {
  1201. // This is how it comes in with createMatrix()
  1202. if(arguments[0] instanceof p5) {
  1203. // save reference to p5 if passed in
  1204. this.p5 = arguments[0];
  1205. this.mat4 = arguments[1] || new GLMAT_ARRAY_TYPE([
  1206. 1, 0, 0, 0,
  1207. 0, 1, 0, 0,
  1208. 0, 0, 1, 0,
  1209. 0, 0, 0, 1
  1210. ]);
  1211. // This is what we'll get with new p5.Matrix()
  1212. // a mat4 identity matrix
  1213. } else {
  1214. this.mat4 = arguments[0] || new GLMAT_ARRAY_TYPE([
  1215. 1, 0, 0, 0,
  1216. 0, 1, 0, 0,
  1217. 0, 0, 1, 0,
  1218. 0, 0, 0, 1
  1219. ]);
  1220. }
  1221. return this;
  1222. };
  1223. /**
  1224. * Sets the x, y, and z component of the vector using two or three separate
  1225. * variables, the data from a p5.Matrix, or the values from a float array.
  1226. *
  1227. * @param {p5.Matrix|Array} [inMatrix] the input p5.Matrix or
  1228. * an Array of length 16
  1229. */
  1230. p5.Matrix.prototype.set = function (inMatrix) {
  1231. if (inMatrix instanceof p5.Matrix) {
  1232. this.mat4 = inMatrix.mat4;
  1233. return this;
  1234. }
  1235. else if (inMatrix instanceof GLMAT_ARRAY_TYPE) {
  1236. this.mat4 = inMatrix;
  1237. return this;
  1238. }
  1239. return this;
  1240. };
  1241. /**
  1242. * Gets a copy of the vector, returns a p5.Matrix object.
  1243. *
  1244. * @return {p5.Matrix} the copy of the p5.Matrix object
  1245. */
  1246. p5.Matrix.prototype.get = function () {
  1247. return new p5.Matrix(this.mat4);
  1248. };
  1249. /**
  1250. * return a copy of a matrix
  1251. * @return {p5.Matrix} the result matrix
  1252. */
  1253. p5.Matrix.prototype.copy = function(){
  1254. var copied = new p5.Matrix();
  1255. copied.mat4[0] = this.mat4[0];
  1256. copied.mat4[1] = this.mat4[1];
  1257. copied.mat4[2] = this.mat4[2];
  1258. copied.mat4[3] = this.mat4[3];
  1259. copied.mat4[4] = this.mat4[4];
  1260. copied.mat4[5] = this.mat4[5];
  1261. copied.mat4[6] = this.mat4[6];
  1262. copied.mat4[7] = this.mat4[7];
  1263. copied.mat4[8] = this.mat4[8];
  1264. copied.mat4[9] = this.mat4[9];
  1265. copied.mat4[10] = this.mat4[10];
  1266. copied.mat4[11] = this.mat4[11];
  1267. copied.mat4[12] = this.mat4[12];
  1268. copied.mat4[13] = this.mat4[13];
  1269. copied.mat4[14] = this.mat4[14];
  1270. copied.mat4[15] = this.mat4[15];
  1271. return copied;
  1272. };
  1273. /**
  1274. * return an identity matrix
  1275. * @return {p5.Matrix} the result matrix
  1276. */
  1277. p5.Matrix.identity = function(){
  1278. return new p5.Matrix();
  1279. };
  1280. /**
  1281. * transpose according to a given matrix
  1282. * @param {p5.Matrix | Typed Array} a the matrix to be based on to transpose
  1283. * @return {p5.Matrix} this
  1284. */
  1285. p5.Matrix.prototype.transpose = function(a){
  1286. var a01, a02, a03, a12, a13, a23;
  1287. if(a instanceof p5.Matrix){
  1288. a01 = a.mat4[1];
  1289. a02 = a.mat4[2];
  1290. a03 = a.mat4[3];
  1291. a12 = a.mat4[6];
  1292. a13 = a.mat4[7];
  1293. a23 = a.mat4[11];
  1294. this.mat4[0] = a.mat4[0];
  1295. this.mat4[1] = a.mat4[4];
  1296. this.mat4[2] = a.mat4[8];
  1297. this.mat4[3] = a.mat4[12];
  1298. this.mat4[4] = a01;
  1299. this.mat4[5] = a.mat4[5];
  1300. this.mat4[6] = a.mat4[9];
  1301. this.mat4[7] = a.mat4[13];
  1302. this.mat4[8] = a02;
  1303. this.mat4[9] = a12;
  1304. this.mat4[10] = a.mat4[10];
  1305. this.mat4[11] = a.mat4[14];
  1306. this.mat4[12] = a03;
  1307. this.mat4[13] = a13;
  1308. this.mat4[14] = a23;
  1309. this.mat4[15] = a.mat4[15];
  1310. }else if(a instanceof GLMAT_ARRAY_TYPE){
  1311. a01 = a[1];
  1312. a02 = a[2];
  1313. a03 = a[3];
  1314. a12 = a[6];
  1315. a13 = a[7];
  1316. a23 = a[11];
  1317. this.mat4[0] = a[0];
  1318. this.mat4[1] = a[4];
  1319. this.mat4[2] = a[8];
  1320. this.mat4[3] = a[12];
  1321. this.mat4[4] = a01;
  1322. this.mat4[5] = a[5];
  1323. this.mat4[6] = a[9];
  1324. this.mat4[7] = a[13];
  1325. this.mat4[8] = a02;
  1326. this.mat4[9] = a12;
  1327. this.mat4[10] = a[10];
  1328. this.mat4[11] = a[14];
  1329. this.mat4[12] = a03;
  1330. this.mat4[13] = a13;
  1331. this.mat4[14] = a23;
  1332. this.mat4[15] = a[15];
  1333. }
  1334. return this;
  1335. };
  1336. /**
  1337. * invert matrix according to a give matrix
  1338. * @param {p5.Matrix or Typed Array} a the matrix to be based on to invert
  1339. * @return {p5.Matrix} this
  1340. */
  1341. p5.Matrix.prototype.invert = function(a){
  1342. var a00, a01, a02, a03, a10, a11, a12, a13,
  1343. a20, a21, a22, a23, a30, a31, a32, a33;
  1344. if(a instanceof p5.Matrix){
  1345. a00 = a.mat4[0];
  1346. a01 = a.mat4[1];
  1347. a02 = a.mat4[2];
  1348. a03 = a.mat4[3];
  1349. a10 = a.mat4[4];
  1350. a11 = a.mat4[5];
  1351. a12 = a.mat4[6];
  1352. a13 = a.mat4[7];
  1353. a20 = a.mat4[8];
  1354. a21 = a.mat4[9];
  1355. a22 = a.mat4[10];
  1356. a23 = a.mat4[11];
  1357. a30 = a.mat4[12];
  1358. a31 = a.mat4[13];
  1359. a32 = a.mat4[14];
  1360. a33 = a.mat4[15];
  1361. }else if(a instanceof GLMAT_ARRAY_TYPE){
  1362. a00 = a[0];
  1363. a01 = a[1];
  1364. a02 = a[2];
  1365. a03 = a[3];
  1366. a10 = a[4];
  1367. a11 = a[5];
  1368. a12 = a[6];
  1369. a13 = a[7];
  1370. a20 = a[8];
  1371. a21 = a[9];
  1372. a22 = a[10];
  1373. a23 = a[11];
  1374. a30 = a[12];
  1375. a31 = a[13];
  1376. a32 = a[14];
  1377. a33 = a[15];
  1378. }
  1379. var b00 = a00 * a11 - a01 * a10,
  1380. b01 = a00 * a12 - a02 * a10,
  1381. b02 = a00 * a13 - a03 * a10,
  1382. b03 = a01 * a12 - a02 * a11,
  1383. b04 = a01 * a13 - a03 * a11,
  1384. b05 = a02 * a13 - a03 * a12,
  1385. b06 = a20 * a31 - a21 * a30,
  1386. b07 = a20 * a32 - a22 * a30,
  1387. b08 = a20 * a33 - a23 * a30,
  1388. b09 = a21 * a32 - a22 * a31,
  1389. b10 = a21 * a33 - a23 * a31,
  1390. b11 = a22 * a33 - a23 * a32,
  1391. // Calculate the determinant
  1392. det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 -
  1393. b04 * b07 + b05 * b06;
  1394. if (!det) {
  1395. return null;
  1396. }
  1397. det = 1.0 / det;
  1398. this.mat4[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  1399. this.mat4[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  1400. this.mat4[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  1401. this.mat4[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  1402. this.mat4[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  1403. this.mat4[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  1404. this.mat4[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  1405. this.mat4[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  1406. this.mat4[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  1407. this.mat4[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  1408. this.mat4[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  1409. this.mat4[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  1410. this.mat4[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  1411. this.mat4[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  1412. this.mat4[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  1413. this.mat4[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  1414. return this;
  1415. };
  1416. /**
  1417. * inspired by Toji's mat4 determinant
  1418. * @return {Number} Determinant of our 4x4 matrix
  1419. */
  1420. p5.Matrix.prototype.determinant = function(){
  1421. var d00 = (this.mat4[0] * this.mat4[5]) - (this.mat4[1] * this.mat4[4]),
  1422. d01 = (this.mat4[0] * this.mat4[6]) - (this.mat4[2] * this.mat4[4]),
  1423. d02 = (this.mat4[0] * this.mat4[7]) - (this.mat4[3] * this.mat4[4]),
  1424. d03 = (this.mat4[1] * this.mat4[6]) - (this.mat4[2] * this.mat4[5]),
  1425. d04 = (this.mat4[1] * this.mat4[7]) - (this.mat4[3] * this.mat4[5]),
  1426. d05 = (this.mat4[2] * this.mat4[7]) - (this.mat4[3] * this.mat4[6]),
  1427. d06 = (this.mat4[8] * this.mat4[13]) - (this.mat4[9] * this.mat4[12]),
  1428. d07 = (this.mat4[8] * this.mat4[14]) - (this.mat4[10] * this.mat4[12]),
  1429. d08 = (this.mat4[8] * this.mat4[15]) - (this.mat4[11] * this.mat4[12]),
  1430. d09 = (this.mat4[9] * this.mat4[14]) - (this.mat4[10] * this.mat4[13]),
  1431. d10 = (this.mat4[9] * this.mat4[15]) - (this.mat4[11] * this.mat4[13]),
  1432. d11 = (this.mat4[10] * this.mat4[15]) - (this.mat4[11] * this.mat4[14]);
  1433. // Calculate the determinant
  1434. return d00 * d11 - d01 * d10 + d02 * d09 +
  1435. d03 * d08 - d04 * d07 + d05 * d06;
  1436. };
  1437. /**
  1438. * multiply two mat4s
  1439. * @param {p5.Matrix | Array} multMatrix The matrix we want to multiply by
  1440. * @return {p5.Matrix} this
  1441. */
  1442. p5.Matrix.prototype.mult = function(multMatrix){
  1443. var _dest = new GLMAT_ARRAY_TYPE(16);
  1444. var _src = new GLMAT_ARRAY_TYPE(16);
  1445. if(multMatrix instanceof p5.Matrix) {
  1446. _src = multMatrix.mat4;
  1447. }
  1448. else if(multMatrix instanceof GLMAT_ARRAY_TYPE){
  1449. _src = multMatrix;
  1450. }
  1451. // each row is used for the multiplier
  1452. var b0 = this.mat4[0], b1 = this.mat4[1],
  1453. b2 = this.mat4[2], b3 = this.mat4[3];
  1454. _dest[0] = b0*_src[0] + b1*_src[4] + b2*_src[8] + b3*_src[12];
  1455. _dest[1] = b0*_src[1] + b1*_src[5] + b2*_src[9] + b3*_src[13];
  1456. _dest[2] = b0*_src[2] + b1*_src[6] + b2*_src[10] + b3*_src[14];
  1457. _dest[3] = b0*_src[3] + b1*_src[7] + b2*_src[11] + b3*_src[15];
  1458. b0 = this.mat4[4];
  1459. b1 = this.mat4[5];
  1460. b2 = this.mat4[6];
  1461. b3 = this.mat4[7];
  1462. _dest[4] = b0*_src[0] + b1*_src[4] + b2*_src[8] + b3*_src[12];
  1463. _dest[5] = b0*_src[1] + b1*_src[5] + b2*_src[9] + b3*_src[13];
  1464. _dest[6] = b0*_src[2] + b1*_src[6] + b2*_src[10] + b3*_src[14];
  1465. _dest[7] = b0*_src[3] + b1*_src[7] + b2*_src[11] + b3*_src[15];
  1466. b0 = this.mat4[8];
  1467. b1 = this.mat4[9];
  1468. b2 = this.mat4[10];
  1469. b3 = this.mat4[11];
  1470. _dest[8] = b0*_src[0] + b1*_src[4] + b2*_src[8] + b3*_src[12];
  1471. _dest[9] = b0*_src[1] + b1*_src[5] + b2*_src[9] + b3*_src[13];
  1472. _dest[10] = b0*_src[2] + b1*_src[6] + b2*_src[10] + b3*_src[14];
  1473. _dest[11] = b0*_src[3] + b1*_src[7] + b2*_src[11] + b3*_src[15];
  1474. b0 = this.mat4[12];
  1475. b1 = this.mat4[13];
  1476. b2 = this.mat4[14];
  1477. b3 = this.mat4[15];
  1478. _dest[12] = b0*_src[0] + b1*_src[4] + b2*_src[8] + b3*_src[12];
  1479. _dest[13] = b0*_src[1] + b1*_src[5] + b2*_src[9] + b3*_src[13];
  1480. _dest[14] = b0*_src[2] + b1*_src[6] + b2*_src[10] + b3*_src[14];
  1481. _dest[15] = b0*_src[3] + b1*_src[7] + b2*_src[11] + b3*_src[15];
  1482. this.mat4 = _dest;
  1483. return this;
  1484. };
  1485. /**
  1486. * scales a p5.Matrix by scalars or a vector
  1487. * @param {p5.Vector | Array | Numbers}
  1488. * vector to scale by
  1489. * @return {p5.Matrix} this
  1490. */
  1491. p5.Matrix.prototype.scale = function() {
  1492. var x,y,z;
  1493. //if our 1st arg is a type p5.Vector
  1494. if (arguments[0] instanceof p5.Vector){
  1495. x = arguments[0].x;
  1496. y = arguments[0].y;
  1497. z = arguments[0].z;
  1498. }
  1499. //otherwise if it's an array
  1500. else if (arguments[0] instanceof Array){
  1501. x = arguments[0][0];
  1502. y = arguments[0][1];
  1503. z = arguments[0][2];
  1504. }
  1505. //otherwise it's probably some numbers
  1506. else {
  1507. //short circuit eval to make sure we maintain
  1508. //component size
  1509. x = arguments[0] || 1;
  1510. y = arguments[1] || 1;
  1511. z = arguments[2] || 1;
  1512. }
  1513. var _dest = new GLMAT_ARRAY_TYPE(16);
  1514. for (var i = 0; i < this.mat4.length; i++) {
  1515. var row = i % 4;
  1516. switch(row){
  1517. case 0:
  1518. _dest[i] = this.mat4[i]*x;
  1519. break;
  1520. case 1:
  1521. _dest[i] = this.mat4[i]*y;
  1522. break;
  1523. case 2:
  1524. _dest[i] = this.mat4[i]*z;
  1525. break;
  1526. case 3:
  1527. _dest[i] = this.mat4[i];
  1528. break;
  1529. }
  1530. }
  1531. this.mat4 = _dest;
  1532. return this;
  1533. };
  1534. /**
  1535. * rotate our Matrix around an axis by the given angle.
  1536. * @param {Number} a The angle of rotation in radians
  1537. * @param {p5.Vector | Array} axis the axis(es) to rotate around
  1538. * @return {p5.Matrix} this
  1539. * inspired by Toji's gl-matrix lib, mat4 rotation
  1540. */
  1541. p5.Matrix.prototype.rotate = function(a, axis){
  1542. var x, y, z, _a, len;
  1543. if (this.p5) {
  1544. if (this.p5._angleMode === constants.DEGREES) {
  1545. _a = polarGeometry.degreesToRadians(a);
  1546. }
  1547. }
  1548. else {
  1549. _a = a;
  1550. }
  1551. if (axis instanceof p5.Vector) {
  1552. x = axis.x;
  1553. y = axis.y;
  1554. z = axis.z;
  1555. }
  1556. else if (axis instanceof Array) {
  1557. x = axis[0];
  1558. y = axis[1];
  1559. z = axis[2];
  1560. }
  1561. len = Math.sqrt(x * x + y * y + z * z);
  1562. x *= (1/len);
  1563. y *= (1/len);
  1564. z *= (1/len);
  1565. var a00 = this.mat4[0];
  1566. var a01 = this.mat4[1];
  1567. var a02 = this.mat4[2];
  1568. var a03 = this.mat4[3];
  1569. var a10 = this.mat4[4];
  1570. var a11 = this.mat4[5];
  1571. var a12 = this.mat4[6];
  1572. var a13 = this.mat4[7];
  1573. var a20 = this.mat4[8];
  1574. var a21 = this.mat4[9];
  1575. var a22 = this.mat4[10];
  1576. var a23 = this.mat4[11];
  1577. //sin,cos, and tan of respective angle
  1578. var sA = Math.sin(_a);
  1579. var cA = Math.cos(_a);
  1580. var tA = 1 - cA;
  1581. // Construct the elements of the rotation matrix
  1582. var b00 = x * x * tA + cA;
  1583. var b01 = y * x * tA + z * sA;
  1584. var b02 = z * x * tA - y * sA;
  1585. var b10 = x * y * tA - z * sA;
  1586. var b11 = y * y * tA + cA;
  1587. var b12 = z * y * tA + x * sA;
  1588. var b20 = x * z * tA + y * sA;
  1589. var b21 = y * z * tA - x * sA;
  1590. var b22 = z * z * tA + cA;
  1591. // rotation-specific matrix multiplication
  1592. this.mat4[0] = a00 * b00 + a10 * b01 + a20 * b02;
  1593. this.mat4[1] = a01 * b00 + a11 * b01 + a21 * b02;
  1594. this.mat4[2] = a02 * b00 + a12 * b01 + a22 * b02;
  1595. this.mat4[3] = a03 * b00 + a13 * b01 + a23 * b02;
  1596. this.mat4[4] = a00 * b10 + a10 * b11 + a20 * b12;
  1597. this.mat4[5] = a01 * b10 + a11 * b11 + a21 * b12;
  1598. this.mat4[6] = a02 * b10 + a12 * b11 + a22 * b12;
  1599. this.mat4[7] = a03 * b10 + a13 * b11 + a23 * b12;
  1600. this.mat4[8] = a00 * b20 + a10 * b21 + a20 * b22;
  1601. this.mat4[9] = a01 * b20 + a11 * b21 + a21 * b22;
  1602. this.mat4[10] = a02 * b20 + a12 * b21 + a22 * b22;
  1603. this.mat4[11] = a03 * b20 + a13 * b21 + a23 * b22;
  1604. return this;
  1605. };
  1606. /**
  1607. * @todo finish implementing this method!
  1608. * translates
  1609. * @param {Array} v vector to translate by
  1610. * @return {p5.Matrix} this
  1611. */
  1612. p5.Matrix.prototype.translate = function(v){
  1613. var x = v[0],
  1614. y = v[1],
  1615. z = v[2];
  1616. this.mat4[12] =
  1617. this.mat4[0] * x +this.mat4[4] * y +this.mat4[8] * z +this.mat4[12];
  1618. this.mat4[13] =
  1619. this.mat4[1] * x +this.mat4[5] * y +this.mat4[9] * z +this.mat4[13];
  1620. this.mat4[14] =
  1621. this.mat4[2] * x +this.mat4[6] * y +this.mat4[10] * z +this.mat4[14];
  1622. this.mat4[15] =
  1623. this.mat4[3] * x +this.mat4[7] * y +this.mat4[11] * z +this.mat4[15];
  1624. };
  1625. p5.Matrix.prototype.rotateX = function(a){
  1626. this.rotate(a, [1,0,0]);
  1627. };
  1628. p5.Matrix.prototype.rotateY = function(a){
  1629. this.rotate(a, [0,1,0]);
  1630. };
  1631. p5.Matrix.prototype.rotateZ = function(a){
  1632. this.rotate(a, [0,0,1]);
  1633. };
  1634. /**
  1635. * sets the perspective matrix
  1636. * @param {Number} fovy [description]
  1637. * @param {Number} aspect [description]
  1638. * @param {Number} near near clipping plane
  1639. * @param {Number} far far clipping plane
  1640. * @return {void}
  1641. */
  1642. p5.Matrix.prototype.perspective = function(fovy,aspect,near,far){
  1643. var f = 1.0 / Math.tan(fovy / 2),
  1644. nf = 1 / (near - far);
  1645. this.mat4[0] = f / aspect;
  1646. this.mat4[1] = 0;
  1647. this.mat4[2] = 0;
  1648. this.mat4[3] = 0;
  1649. this.mat4[4] = 0;
  1650. this.mat4[5] = f;
  1651. this.mat4[6] = 0;
  1652. this.mat4[7] = 0;
  1653. this.mat4[8] = 0;
  1654. this.mat4[9] = 0;
  1655. this.mat4[10] = (far + near) * nf;
  1656. this.mat4[11] = -1;
  1657. this.mat4[12] = 0;
  1658. this.mat4[13] = 0;
  1659. this.mat4[14] = (2 * far * near) * nf;
  1660. this.mat4[15] = 0;
  1661. return this;
  1662. };
  1663. /**
  1664. * sets the ortho matrix
  1665. * @param {Number} left [description]
  1666. * @param {Number} right [description]
  1667. * @param {Number} bottom [description]
  1668. * @param {Number} top [description]
  1669. * @param {Number} near near clipping plane
  1670. * @param {Number} far far clipping plane
  1671. * @return {void}
  1672. */
  1673. p5.Matrix.prototype.ortho = function(left,right,bottom,top,near,far){
  1674. var lr = 1 / (left - right),
  1675. bt = 1 / (bottom - top),
  1676. nf = 1 / (near - far);
  1677. this.mat4[0] = -2 * lr;
  1678. this.mat4[1] = 0;
  1679. this.mat4[2] = 0;
  1680. this.mat4[3] = 0;
  1681. this.mat4[4] = 0;
  1682. this.mat4[5] = -2 * bt;
  1683. this.mat4[6] = 0;
  1684. this.mat4[7] = 0;
  1685. this.mat4[8] = 0;
  1686. this.mat4[9] = 0;
  1687. this.mat4[10] = 2 * nf;
  1688. this.mat4[11] = 0;
  1689. this.mat4[12] = (left + right) * lr;
  1690. this.mat4[13] = (top + bottom) * bt;
  1691. this.mat4[14] = (far + near) * nf;
  1692. this.mat4[15] = 1;
  1693. return this;
  1694. };
  1695. module.exports = p5.Matrix;
  1696. },{"../core/constants":16,"../core/core":17,"../math/polargeometry":46}],6:[function(require,module,exports){
  1697. 'use strict';
  1698. var p5 = require('../core/core');
  1699. var shaders = require('./shaders');
  1700. require('../core/p5.Renderer');
  1701. require('./p5.Matrix');
  1702. var gl;
  1703. var uMVMatrixStack = [];
  1704. var shaderStack = [];
  1705. //@TODO should probably implement an override for these attributes
  1706. var attributes = {
  1707. alpha: false,
  1708. depth: true,
  1709. stencil: true,
  1710. antialias: false,
  1711. premultipliedAlpha: false,
  1712. preserveDrawingBuffer: false
  1713. };
  1714. /**
  1715. * 3D graphics class. Can also be used as an off-screen graphics buffer.
  1716. * A p5.Renderer3D object can be constructed
  1717. *
  1718. */
  1719. p5.Renderer3D = function(elt, pInst, isMainCanvas) {
  1720. p5.Renderer.call(this, elt, pInst, isMainCanvas);
  1721. try {
  1722. this.drawingContext = this.canvas.getContext('webgl', attributes) ||
  1723. this.canvas.getContext('experimental-webgl', attributes);
  1724. if (this.drawingContext === null) {
  1725. throw 'Error creating webgl context';
  1726. } else {
  1727. console.log('p5.Renderer3D: enabled webgl context');
  1728. }
  1729. } catch (er) {
  1730. console.error(er);
  1731. }
  1732. this.isP3D = true; //lets us know we're in 3d mode
  1733. gl = this.drawingContext;
  1734. gl.clearColor(1.0, 1.0, 1.0, 1.0); //background is initialized white
  1735. gl.clearDepth(1);
  1736. gl.enable(gl.DEPTH_TEST);
  1737. gl.depthFunc(gl.LEQUAL);
  1738. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  1739. gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
  1740. //create our default matrices
  1741. this.initHash();
  1742. this.initMatrix();
  1743. return this;
  1744. };
  1745. /**
  1746. * [prototype description]
  1747. * @type {[type]}
  1748. */
  1749. p5.Renderer3D.prototype = Object.create(p5.Renderer.prototype);
  1750. /**
  1751. * [_applyDefaults description]
  1752. * @return {[type]} [description]
  1753. */
  1754. p5.Renderer3D.prototype._applyDefaults = function() {
  1755. return this;
  1756. };
  1757. /**
  1758. * [resize description]
  1759. * @param {[type]} w [description]
  1760. * @param {[type]} h [description]
  1761. * @return {[type]} [description]
  1762. */
  1763. p5.Renderer3D.prototype.resize = function(w,h) {
  1764. p5.Renderer.prototype.resize.call(this, w,h);
  1765. gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
  1766. };
  1767. //////////////////////////////////////////////
  1768. // COLOR | Setting
  1769. //////////////////////////////////////////////
  1770. /**
  1771. * [background description]
  1772. * @return {[type]} [description]
  1773. */
  1774. p5.Renderer3D.prototype.background = function() {
  1775. var _col = this._pInst.color.apply(this._pInst, arguments);
  1776. // gl.clearColor(0.0,0.0,0.0,1.0);
  1777. var _r = (_col.color_array[0]) / 255;
  1778. var _g = (_col.color_array[1]) / 255;
  1779. var _b = (_col.color_array[2]) / 255;
  1780. var _a = (_col.color_array[3]) / 255;
  1781. gl.clearColor(_r, _g, _b, _a);
  1782. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  1783. this.resetMatrix();
  1784. this.emptyShaderStack();
  1785. };
  1786. //@TODO implement this
  1787. // p5.Renderer3D.prototype.clear = function() {
  1788. //@TODO
  1789. // };
  1790. //@TODO implement this
  1791. // p5.Renderer3D.prototype.fill = function() {
  1792. //@TODO
  1793. // };
  1794. //////////////////////////////////////////////
  1795. // SHADER
  1796. //////////////////////////////////////////////
  1797. /**
  1798. * [initShaders description]
  1799. * @param {[type]} vertId [description]
  1800. * @param {[type]} fragId [description]
  1801. * @return {[type]} [description]
  1802. */
  1803. p5.Renderer3D.prototype.initShaders = function(vertId, fragId) {
  1804. //set up our default shaders by:
  1805. // 1. create the shader,
  1806. // 2. load the shader source,
  1807. // 3. compile the shader
  1808. var _vertShader = gl.createShader(gl.VERTEX_SHADER);
  1809. //load in our default vertex shader
  1810. gl.shaderSource(_vertShader, shaders[vertId]);
  1811. gl.compileShader(_vertShader);
  1812. // if our vertex shader failed compilation?
  1813. if (!gl.getShaderParameter(_vertShader, gl.COMPILE_STATUS)) {
  1814. alert('Yikes! An error occurred compiling the shaders:' +
  1815. gl.getShaderInfoLog(_vertShader));
  1816. return null;
  1817. }
  1818. var _fragShader = gl.createShader(gl.FRAGMENT_SHADER);
  1819. //load in our material frag shader
  1820. gl.shaderSource(_fragShader, shaders[fragId]);
  1821. gl.compileShader(_fragShader);
  1822. // if our frag shader failed compilation?
  1823. if (!gl.getShaderParameter(_fragShader, gl.COMPILE_STATUS)) {
  1824. alert('Darn! An error occurred compiling the shaders:' +
  1825. gl.getShaderInfoLog(_fragShader));
  1826. return null;
  1827. }
  1828. var shaderProgram = gl.createProgram();
  1829. gl.attachShader(shaderProgram, _vertShader);
  1830. gl.attachShader(shaderProgram, _fragShader);
  1831. gl.linkProgram(shaderProgram);
  1832. if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
  1833. alert('Snap! Error linking shader program');
  1834. }
  1835. gl.useProgram(shaderProgram);
  1836. //END SHADERS SETUP
  1837. // var vertexResolution =
  1838. // gl.getUniformLocation(shaderProgram, 'u_resolution');
  1839. // @TODO replace 4th argument with far plane once we implement
  1840. // a view frustrum
  1841. //vertex position Attribute
  1842. shaderProgram.vertexPositionAttribute =
  1843. gl.getAttribLocation(shaderProgram, 'position');
  1844. gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
  1845. //vertex normal Attribute
  1846. shaderProgram.vertexNormalAttribute =
  1847. gl.getAttribLocation(shaderProgram, 'normal');
  1848. gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
  1849. //projection Matrix uniform
  1850. shaderProgram.uPMatrixUniform =
  1851. gl.getUniformLocation(shaderProgram, 'transformMatrix');
  1852. //model view Matrix uniform
  1853. shaderProgram.uMVMatrixUniform =
  1854. gl.getUniformLocation(shaderProgram, 'modelviewMatrix');
  1855. //normal Matrix uniform
  1856. shaderProgram.uNMatrixUniform =
  1857. gl.getUniformLocation(shaderProgram, 'normalMatrix');
  1858. this.mHash[vertId + '|' + fragId] = shaderProgram;
  1859. return shaderProgram;
  1860. };
  1861. /**
  1862. * [saveShaders description]
  1863. * @return {[type]} [description]
  1864. */
  1865. p5.Renderer3D.prototype.saveShaders = function(mId){
  1866. shaderStack.push(mId);
  1867. };
  1868. /**
  1869. * [emptyShaderStack description]
  1870. * @return {[type]} [description]
  1871. */
  1872. p5.Renderer3D.prototype.emptyShaderStack = function(){
  1873. shaderStack = [];
  1874. };
  1875. /**
  1876. * [getCurShader description]
  1877. * @return {[type]} [description]
  1878. */
  1879. p5.Renderer3D.prototype.getCurShaderKey = function(){
  1880. var key = shaderStack[shaderStack.length - 1];
  1881. if(key === undefined){
  1882. //@TODO: make a default shader
  1883. key = 'normalVert|normalFrag';
  1884. this.initShaders('normalVert', 'normalFrag');
  1885. this.saveShaders(key);
  1886. }
  1887. return key;
  1888. };
  1889. //////////////////////////////////////////////
  1890. // HASH | Stroing geometriy and materil info
  1891. //////////////////////////////////////////////
  1892. /**
  1893. * [initBuffer description]
  1894. * @return {[type]} [description]
  1895. */
  1896. p5.Renderer3D.prototype.initHash = function(){
  1897. this.gHash = {};
  1898. this.mHash = {};
  1899. };
  1900. /**
  1901. * [geometryInHash description]
  1902. * @param {[type]} gId [description]
  1903. * @return {[type]} [description]
  1904. */
  1905. p5.Renderer3D.prototype.geometryInHash = function(gId){
  1906. return this.gHash[gId] !== undefined;
  1907. };
  1908. /**
  1909. * [materialInHash description]
  1910. * @param {[type]} mId [description]
  1911. * @return {[type]} [description]
  1912. */
  1913. p5.Renderer3D.prototype.materialInHash = function(mId){
  1914. return this.mHash[mId] !== undefined;
  1915. };
  1916. //////////////////////////////////////////////
  1917. // BUFFER | deal with gl buffer
  1918. //////////////////////////////////////////////
  1919. /**
  1920. * [initBuffer description]
  1921. * @param {String} gId key of the geometry object
  1922. * @param {Object} obj an object containing geometry information
  1923. */
  1924. p5.Renderer3D.prototype.initBuffer = function(gId, obj) {
  1925. this.gHash[gId] = {};
  1926. this.gHash[gId].len = obj.len;
  1927. this.gHash[gId].vertexBuffer = gl.createBuffer();
  1928. this.gHash[gId].normalBuffer = gl.createBuffer();
  1929. this.gHash[gId].indexBuffer = gl.createBuffer();
  1930. var shaderProgram = this.mHash[this.getCurShaderKey()];
  1931. gl.bindBuffer(gl.ARRAY_BUFFER, this.gHash[gId].vertexBuffer);
  1932. gl.bufferData(
  1933. gl.ARRAY_BUFFER, new Float32Array(obj.vertices), gl.STATIC_DRAW);
  1934. gl.vertexAttribPointer(
  1935. shaderProgram.vertexPositionAttribute,
  1936. 3, gl.FLOAT, false, 0, 0);
  1937. gl.bindBuffer(gl.ARRAY_BUFFER, this.gHash[gId].normalBuffer);
  1938. gl.bufferData(
  1939. gl.ARRAY_BUFFER, new Float32Array(obj.vertexNormals), gl.STATIC_DRAW);
  1940. gl.vertexAttribPointer(
  1941. shaderProgram.vertexNormalAttribute,
  1942. 3, gl.FLOAT, false, 0, 0);
  1943. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.gHash[gId].indexBuffer);
  1944. gl.bufferData
  1945. (gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(obj.faces), gl.STATIC_DRAW);
  1946. };
  1947. /**
  1948. * [drawBuffer description]
  1949. * @param {String} gId key of the geometery object
  1950. */
  1951. p5.Renderer3D.prototype.drawBuffer = function(gId) {
  1952. var shaderKey = this.getCurShaderKey();
  1953. var shaderProgram = this.mHash[shaderKey];
  1954. gl.bindBuffer(gl.ARRAY_BUFFER, this.gHash[gId].vertexBuffer);
  1955. gl.vertexAttribPointer(
  1956. shaderProgram.vertexPositionAttribute,
  1957. 3, gl.FLOAT, false, 0, 0);
  1958. gl.bindBuffer(gl.ARRAY_BUFFER, this.gHash[gId].normalBuffer);
  1959. gl.vertexAttribPointer(
  1960. shaderProgram.vertexNormalAttribute,
  1961. 3, gl.FLOAT, false, 0, 0);
  1962. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.gHash[gId].indexBuffer);
  1963. this.setMatrixUniforms(shaderKey);
  1964. gl.drawElements(
  1965. gl.TRIANGLES, this.gHash[gId].len,
  1966. gl.UNSIGNED_SHORT, 0);
  1967. };
  1968. /**
  1969. * Sets the Matrix Uniforms inside our default shader.
  1970. * @param {String} shaderKey key of current shader
  1971. */
  1972. p5.Renderer3D.prototype.setMatrixUniforms = function(shaderKey) {
  1973. var shaderProgram = this.mHash[shaderKey];
  1974. gl.useProgram(shaderProgram);
  1975. gl.uniformMatrix4fv(
  1976. shaderProgram.uPMatrixUniform,
  1977. false, this.uPMatrix.mat4);
  1978. gl.uniformMatrix4fv(
  1979. shaderProgram.uMVMatrixUniform,
  1980. false, this.uMVMatrix.mat4);
  1981. this.uNMatrix = new p5.Matrix();
  1982. this.uNMatrix.invert(this.uMVMatrix);
  1983. this.uNMatrix.transpose(this.uNMatrix);
  1984. gl.uniformMatrix4fv(
  1985. shaderProgram.uNMatrixUniform,
  1986. false, this.uNMatrix.mat4);
  1987. };
  1988. //////////////////////////////////////////////
  1989. // MATRIX
  1990. //////////////////////////////////////////////
  1991. /**
  1992. * [initMatrix description]
  1993. * @return {[type]} [description]
  1994. */
  1995. p5.Renderer3D.prototype.initMatrix = function(){
  1996. this.uMVMatrix = new p5.Matrix();
  1997. this.uPMatrix = new p5.Matrix();
  1998. this.uNMatrix = new p5.Matrix();
  1999. var _w = this.width;
  2000. var _h = this.height;
  2001. this.uPMatrix.perspective(60 / 180 * Math.PI, _w / _h, 0.1, 100);
  2002. };
  2003. /**
  2004. * resets the model view matrix to a mat4 identity
  2005. * matrix.
  2006. * @return {void}
  2007. */
  2008. p5.Renderer3D.prototype.resetMatrix = function() {
  2009. this.uMVMatrix = p5.Matrix.identity();
  2010. };
  2011. /**
  2012. * [translate description]
  2013. * @param {[type]} x [description]
  2014. * @param {[type]} y [description]
  2015. * @param {[type]} z [description]
  2016. * @return {[type]} [description]
  2017. * @todo implement handle for components or vector as args
  2018. */
  2019. p5.Renderer3D.prototype.translate = function(x, y, z) {
  2020. //@TODO: figure out how to fit the resolution
  2021. x = x / 100;
  2022. y = -y / 100;
  2023. z = z / 100;
  2024. this.uMVMatrix.translate([x,y,z]);
  2025. return this;
  2026. };
  2027. /**
  2028. * Scales the Model View Matrix by a vector
  2029. * @param {Number} x [description]
  2030. * @param {Number} y [description]
  2031. * @param {Number} z [description]
  2032. * @return {this} [description]
  2033. */
  2034. p5.Renderer3D.prototype.scale = function(x, y, z) {
  2035. this.uMVMatrix.scale([x,y,z]);
  2036. return this;
  2037. };
  2038. /**
  2039. * [rotateX description]
  2040. * @param {[type]} rad [description]
  2041. * @return {[type]} [description]
  2042. */
  2043. p5.Renderer3D.prototype.rotateX = function(rad) {
  2044. this.uMVMatrix.rotateX(rad);
  2045. return this;
  2046. };
  2047. /**
  2048. * [rotateY description]
  2049. * @param {[type]} rad [description]
  2050. * @return {[type]} [description]
  2051. */
  2052. p5.Renderer3D.prototype.rotateY = function(rad) {
  2053. this.uMVMatrix.rotateY(rad);
  2054. return this;
  2055. };
  2056. /**
  2057. * [rotateZ description]
  2058. * @param {[type]} rad [description]
  2059. * @return {[type]} [description]
  2060. */
  2061. p5.Renderer3D.prototype.rotateZ = function(rad) {
  2062. this.uMVMatrix.rotateZ(rad);
  2063. return this;
  2064. };
  2065. /**
  2066. * pushes a copy of the model view matrix onto the
  2067. * MV Matrix stack.
  2068. * NOTE to self: could probably make this more readable
  2069. * @return {[type]} [description]
  2070. */
  2071. p5.Renderer3D.prototype.push = function() {
  2072. uMVMatrixStack.push(this.uMVMatrix.copy());
  2073. };
  2074. /**
  2075. * [pop description]
  2076. * @return {[type]} [description]
  2077. */
  2078. p5.Renderer3D.prototype.pop = function() {
  2079. if (uMVMatrixStack.length === 0) {
  2080. throw 'Invalid popMatrix!';
  2081. }
  2082. this.uMVMatrix = uMVMatrixStack.pop();
  2083. };
  2084. /**
  2085. * [orbitControl description]
  2086. * @return {[type]} [description]
  2087. */
  2088. //@TODO: fix this fake orbitControl
  2089. p5.prototype.orbitControl = function(){
  2090. if(this.mouseIsPressed){
  2091. this.rotateX((this.mouseX - this.width / 2) / (this.width / 2));
  2092. this.rotateY((this.mouseY - this.height / 2) / (this.width / 2));
  2093. }
  2094. return this;
  2095. };
  2096. /**
  2097. * PRIVATE
  2098. */
  2099. // matrix methods adapted from:
  2100. // https://developer.mozilla.org/en-US/docs/Web/WebGL/
  2101. // gluPerspective
  2102. //
  2103. // function _makePerspective(fovy, aspect, znear, zfar){
  2104. // var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
  2105. // var ymin = -ymax;
  2106. // var xmin = ymin * aspect;
  2107. // var xmax = ymax * aspect;
  2108. // return _makeFrustum(xmin, xmax, ymin, ymax, znear, zfar);
  2109. // }
  2110. ////
  2111. //// glFrustum
  2112. ////
  2113. //function _makeFrustum(left, right, bottom, top, znear, zfar){
  2114. // var X = 2*znear/(right-left);
  2115. // var Y = 2*znear/(top-bottom);
  2116. // var A = (right+left)/(right-left);
  2117. // var B = (top+bottom)/(top-bottom);
  2118. // var C = -(zfar+znear)/(zfar-znear);
  2119. // var D = -2*zfar*znear/(zfar-znear);
  2120. // var frustrumMatrix =[
  2121. // X, 0, A, 0,
  2122. // 0, Y, B, 0,
  2123. // 0, 0, C, D,
  2124. // 0, 0, -1, 0
  2125. //];
  2126. //return frustrumMatrix;
  2127. // }
  2128. // function _setMVPMatrices(){
  2129. ////an identity matrix
  2130. ////@TODO use the p5.Matrix class to abstract away our MV matrices and
  2131. ///other math
  2132. //var _mvMatrix =
  2133. //[
  2134. // 1.0,0.0,0.0,0.0,
  2135. // 0.0,1.0,0.0,0.0,
  2136. // 0.0,0.0,1.0,0.0,
  2137. // 0.0,0.0,0.0,1.0
  2138. //];
  2139. module.exports = p5.Renderer3D;
  2140. },{"../core/core":17,"../core/p5.Renderer":23,"./p5.Matrix":5,"./shaders":7}],7:[function(require,module,exports){
  2141. /*
  2142. Part of the Processing project - http://processing.org
  2143. Copyright (c) 2011-13 Ben Fry and Casey Reas
  2144. This library is free software; you can redistribute it and/or
  2145. modify it under the terms of the GNU Lesser General Public
  2146. License version 2.1 as published by the Free Software Foundation.
  2147. This library is distributed in the hope that it will be useful,
  2148. but WITHOUT ANY WARRANTY; without even the implied warranty of
  2149. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  2150. Lesser General Public License for more details.
  2151. You should have received a copy of the GNU Lesser General
  2152. Public License along with this library; if not, write to the
  2153. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  2154. Boston, MA 02111-1307 USA
  2155. */
  2156. /**
  2157. * @description Default full shaders for our WebGL context
  2158. */
  2159. module.exports = {
  2160. texLightVert : [
  2161. 'uniform mat4 modelviewMatrix;',
  2162. 'uniform mat4 transformMatrix;',
  2163. 'uniform mat3 normalMatrix;',
  2164. 'uniform mat4 texMatrix;',
  2165. 'uniform int lightCount;',
  2166. 'uniform vec4 lightPosition[8];',
  2167. 'uniform vec3 lightNormal[8];',
  2168. 'uniform vec3 lightAmbient[8];',
  2169. 'uniform vec3 lightDiffuse[8];',
  2170. 'uniform vec3 lightSpecular[8];',
  2171. 'uniform vec3 lightFalloff[8];',
  2172. 'uniform vec2 lightSpot[8];',
  2173. 'attribute vec4 position;',
  2174. 'attribute vec4 color;',
  2175. 'attribute vec3 normal;',
  2176. 'attribute vec2 texCoord;',
  2177. 'attribute vec4 ambient;',
  2178. 'attribute vec4 specular;',
  2179. 'attribute vec4 emissive;',
  2180. 'attribute float shininess;',
  2181. 'varying vec4 vertColor;',
  2182. 'varying vec4 backVertColor;',
  2183. 'varying vec4 vertTexCoord;',
  2184. 'const float zero_float = 0.0;',
  2185. 'const float one_float = 1.0;',
  2186. 'const vec3 zero_vec3 = vec3(0);',
  2187. 'float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {',
  2188. 'vec3 lpv = lightPos - vertPos;',
  2189. 'vec3 dist = vec3(one_float);',
  2190. 'dist.z = dot(lpv, lpv);',
  2191. 'dist.y = sqrt(dist.z);',
  2192. 'return one_float / dot(dist, coeff);',
  2193. '}',
  2194. 'float spotFactor(vec3 lightPos,vec3 vertPos,',
  2195. 'vec3 lightNorm,float minCos,float spotExp) {',
  2196. 'vec3 lpv = normalize(lightPos - vertPos);',
  2197. 'vec3 nln = -one_float * lightNorm;',
  2198. 'float spotCos = dot(nln, lpv);',
  2199. 'return spotCos <= minCos ? zero_float : pow(spotCos, spotExp);',
  2200. '}',
  2201. 'float lambertFactor(vec3 lightDir, vec3 vecNormal) {',
  2202. 'return max(zero_float, dot(lightDir, vecNormal));',
  2203. '}',
  2204. 'float blinnPhongFactor(vec3 lightDir,',
  2205. 'vec3 vertPos,vec3 vecNormal, float shine) {',
  2206. 'vec3 np = normalize(vertPos);',
  2207. 'vec3 ldp = normalize(lightDir - np);',
  2208. 'return pow(max(zero_float, dot(ldp, vecNormal)), shine);',
  2209. '}',
  2210. 'void main() {',
  2211. // Vertex in clip coordinates
  2212. 'gl_Position = transformMatrix * position;',
  2213. // Vertex in eye coordinates
  2214. 'vec3 ecVertex = vec3(modelviewMatrix * position);',
  2215. // Normal vector in eye coordinates
  2216. 'vec3 ecNormal = normalize(normalMatrix * normal);',
  2217. 'vec3 ecNormalInv = ecNormal * -one_float;',
  2218. // Light calculations
  2219. 'vec3 totalAmbient = vec3(0, 0, 0);',
  2220. 'vec3 totalFrontDiffuse = vec3(0, 0, 0);',
  2221. 'vec3 totalFrontSpecular = vec3(0, 0, 0);',
  2222. 'vec3 totalBackDiffuse = vec3(0, 0, 0);',
  2223. 'vec3 totalBackSpecular = vec3(0, 0, 0);',
  2224. 'for (int i = 0; i < 8; i++) {',
  2225. 'if (lightCount == i) break;',
  2226. 'vec3 lightPos = lightPosition[i].xyz;',
  2227. 'bool isDir = zero_float < lightPosition[i].w;',
  2228. 'float spotCos = lightSpot[i].x;',
  2229. 'float spotExp = lightSpot[i].y;',
  2230. 'vec3 lightDir;',
  2231. 'float falloff;',
  2232. 'float spotf;',
  2233. 'if (isDir) {',
  2234. 'falloff = one_float;',
  2235. 'lightDir = -one_float * lightNormal[i];',
  2236. '} else {',
  2237. 'falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]);',
  2238. 'lightDir = normalize(lightPos - ecVertex);',
  2239. '}',
  2240. 'spotf=spotExp > zero_float ? spotFactor(lightPos,',
  2241. 'ecVertex,',
  2242. 'lightNormal[i],',
  2243. 'spotCos,',
  2244. 'spotExp):one_float;',
  2245. 'if (any(greaterThan(lightAmbient[i], zero_vec3))) {',
  2246. 'totalAmbient+= lightAmbient[i] * falloff;',
  2247. '}',
  2248. 'if (any(greaterThan(lightDiffuse[i], zero_vec3))) {',
  2249. 'totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *',
  2250. 'lambertFactor(lightDir, ecNormal);',
  2251. 'totalBackDiffuse += lightDiffuse[i] * falloff * spotf *',
  2252. 'lambertFactor(lightDir, ecNormalInv);',
  2253. '}',
  2254. 'if (any(greaterThan(lightSpecular[i], zero_vec3))) {',
  2255. 'totalFrontSpecular += lightSpecular[i] * falloff * spotf * ',
  2256. 'blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);',
  2257. 'totalBackSpecular += lightSpecular[i] * falloff * spotf *',
  2258. 'blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);',
  2259. '}',
  2260. '}',
  2261. // Calculating final color as result of all lights (plus emissive term).
  2262. // Transparency is determined exclusively by the diffuse component.
  2263. 'vertColor =vec4(totalAmbient, 0) * ambient + ',
  2264. 'vec4(totalFrontDiffuse, 1) * color +' ,
  2265. 'vec4(totalFrontSpecular, 0) * specular +',
  2266. 'vec4(emissive.rgb, 0);',
  2267. 'backVertColor = vec4(totalAmbient, 0) * ambient + ',
  2268. 'vec4(totalBackDiffuse, 1) * color +',
  2269. 'vec4(totalBackSpecular, 0) * specular +',
  2270. 'vec4(emissive.rgb, 0);',
  2271. // Calculating texture coordinates, with r and q set both to one
  2272. 'vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);',
  2273. '}'
  2274. ].join('\n'),
  2275. texLightFrag : [
  2276. 'precision mediump float;',
  2277. 'precision mediump int;',
  2278. 'uniform sampler2D texture;',
  2279. 'uniform vec2 texOffset;',
  2280. 'varying vec4 vertColor;',
  2281. 'varying vec4 backVertColor;',
  2282. 'varying vec4 vertTexCoord;',
  2283. 'void main() {',
  2284. 'gl_FragColor = texture2D(texture,vertTexCoord.st)*',
  2285. '(gl_FrontFacing ? vertColor : backVertColor);',
  2286. '}'
  2287. ].join('\n'),
  2288. normalVert: [
  2289. 'attribute vec3 position;',
  2290. 'attribute vec3 normal;',
  2291. 'uniform mat4 modelviewMatrix;',
  2292. 'uniform mat4 transformMatrix;',
  2293. 'uniform mat4 normalMatrix;',
  2294. 'varying vec3 vertexNormal;',
  2295. 'void main(void) {',
  2296. 'vec3 zeroToOne = position / 1000.0;',
  2297. 'vec4 positionVec4 = vec4(zeroToOne, 1.);',
  2298. 'gl_Position = transformMatrix * modelviewMatrix * positionVec4;',
  2299. 'vertexNormal = vec3( normalMatrix * vec4( normal, 1.0 ) );',
  2300. '}'
  2301. ].join('\n'),
  2302. normalFrag: [
  2303. 'precision mediump float;',
  2304. 'varying vec3 vertexNormal;',
  2305. 'void main(void) {',
  2306. 'gl_FragColor = vec4(vertexNormal, 1.0);',
  2307. '}'
  2308. ].join('\n'),
  2309. basicFrag: [
  2310. 'precision mediump float;',
  2311. 'varying vec3 vertexNormal;',
  2312. //'uniform vec3 uBasic'
  2313. 'void main(void) {',
  2314. // 'gl_FragColor = vec4(vertexNormal * uBasic, 1.0);',
  2315. 'gl_FragColor = vec4(vertexNormal * vec3(0.5, 0.5, 0.5), 1.0);',
  2316. '}'
  2317. ].join('\n'),
  2318. vertexColorVert:[
  2319. 'attribute vec3 position;',
  2320. 'attribute vec4 aVertexColor;',
  2321. 'uniform mat4 modelviewMatrix;',
  2322. 'uniform mat4 transformMatrix;',
  2323. 'varying vec4 vColor;',
  2324. 'void main(void) {',
  2325. 'vec3 zeroToOne = position / 1000.0;',
  2326. 'vec4 positionVec4 = vec4(zeroToOne, 1.);',
  2327. 'gl_Position = transformMatrix * modelviewMatrix * positionVec4;',
  2328. 'vColor = aVertexColor;',
  2329. '}'
  2330. ].join('\n'),
  2331. vertexColorFrag:[
  2332. 'precision mediump float;',
  2333. 'varying vec4 vColor;',
  2334. 'void main(void) {',
  2335. ' gl_FragColor = vColor;',
  2336. '}'
  2337. ].join('\n')
  2338. };
  2339. },{}],8:[function(require,module,exports){
  2340. 'use strict';
  2341. var p5 = require('./core/core');
  2342. require('./color/p5.Color');
  2343. require('./core/p5.Element');
  2344. require('./typography/p5.Font');
  2345. require('./core/p5.Graphics');
  2346. require('./core/p5.Renderer2D');
  2347. require('./image/p5.Image');
  2348. require('./math/p5.Vector');
  2349. require('./io/p5.TableRow');
  2350. require('./io/p5.Table');
  2351. require('./color/creating_reading');
  2352. require('./color/setting');
  2353. require('./core/constants');
  2354. require('./utilities/conversion');
  2355. require('./utilities/array_functions');
  2356. require('./utilities/string_functions');
  2357. require('./core/environment');
  2358. require('./image/image');
  2359. require('./image/loading_displaying');
  2360. require('./image/pixels');
  2361. require('./io/files');
  2362. require('./events/keyboard');
  2363. require('./events/acceleration'); //john
  2364. require('./events/mouse');
  2365. require('./utilities/time_date');
  2366. require('./events/touch');
  2367. require('./math/math');
  2368. require('./math/calculation');
  2369. require('./math/random');
  2370. require('./math/noise');
  2371. require('./math/trigonometry');
  2372. require('./core/rendering');
  2373. require('./core/2d_primitives');
  2374. require('./core/attributes');
  2375. require('./core/curves');
  2376. require('./core/vertex');
  2377. require('./core/structure');
  2378. require('./core/transform');
  2379. require('./typography/attributes');
  2380. require('./typography/loading_displaying');
  2381. require('./3d/p5.Renderer3D');
  2382. require('./3d/p5.Geometry3D');
  2383. require('./3d/3d_primitives');
  2384. require('./3d/shaders');
  2385. require('./3d/p5.Matrix');
  2386. require('./3d/material');
  2387. /**
  2388. * _globalInit
  2389. *
  2390. * TODO: ???
  2391. * if sketch is on window
  2392. * assume "global" mode
  2393. * and instantiate p5 automatically
  2394. * otherwise do nothing
  2395. *
  2396. * @return {Undefined}
  2397. */
  2398. var _globalInit = function() {
  2399. if (!window.PHANTOMJS && !window.mocha) {
  2400. // If there is a setup or draw function on the window
  2401. // then instantiate p5 in "global" mode
  2402. if((window.setup && typeof window.setup === 'function') ||
  2403. (window.draw && typeof window.draw === 'function')) {
  2404. new p5();
  2405. }
  2406. }
  2407. };
  2408. // TODO: ???
  2409. if (document.readyState === 'complete') {
  2410. _globalInit();
  2411. } else {
  2412. window.addEventListener('load', _globalInit , false);
  2413. }
  2414. module.exports = p5;
  2415. },{"./3d/3d_primitives":2,"./3d/material":3,"./3d/p5.Geometry3D":4,"./3d/p5.Matrix":5,"./3d/p5.Renderer3D":6,"./3d/shaders":7,"./color/creating_reading":10,"./color/p5.Color":11,"./color/setting":12,"./core/2d_primitives":13,"./core/attributes":14,"./core/constants":16,"./core/core":17,"./core/curves":18,"./core/environment":19,"./core/p5.Element":21,"./core/p5.Graphics":22,"./core/p5.Renderer2D":24,"./core/rendering":25,"./core/structure":27,"./core/transform":28,"./core/vertex":29,"./events/acceleration":30,"./events/keyboard":31,"./events/mouse":32,"./events/touch":33,"./image/image":35,"./image/loading_displaying":36,"./image/p5.Image":37,"./image/pixels":38,"./io/files":39,"./io/p5.Table":40,"./io/p5.TableRow":41,"./math/calculation":42,"./math/math":43,"./math/noise":44,"./math/p5.Vector":45,"./math/random":47,"./math/trigonometry":48,"./typography/attributes":49,"./typography/loading_displaying":50,"./typography/p5.Font":51,"./utilities/array_functions":52,"./utilities/conversion":53,"./utilities/string_functions":54,"./utilities/time_date":55}],9:[function(require,module,exports){
  2416. /**
  2417. * module Utils
  2418. * submodule Color Utils
  2419. * @for p5
  2420. */
  2421. var p5 = require('../core/core');
  2422. p5.ColorUtils = {};
  2423. /**
  2424. * For a color expressed as an HSBA array, return the corresponding RGBA value
  2425. * @param {Array} hsba An 'array' object that represents a list of HSB colors
  2426. * @param {Array} maxes An 'array' object that represents the HSB range maxes
  2427. * @return {Array} an array of RGBA values, on a scale of 0-255
  2428. */
  2429. p5.ColorUtils.hsbaToRGBA = function(hsba, maxes) {
  2430. var h = hsba[0];
  2431. var s = hsba[1];
  2432. var v = hsba[2];
  2433. var a = hsba[3] || maxes[3];
  2434. h /= maxes[0];
  2435. s /= maxes[1];
  2436. v /= maxes[2];
  2437. a /= maxes[3];
  2438. // Adapted from http://www.easyrgb.com/math.html
  2439. // hsv values = 0 - 1, rgb values = 0 - 255
  2440. var RGBA = [];
  2441. if(s===0){
  2442. RGBA = [Math.round(v*255), Math.round(v*255), Math.round(v*255), a*255];
  2443. } else {
  2444. // h must be < 1
  2445. var var_h = h * 6;
  2446. if (var_h===6) {
  2447. var_h = 0;
  2448. }
  2449. //Or ... var_i = floor( var_h )
  2450. var var_i = Math.floor( var_h );
  2451. var var_1 = v*(1-s);
  2452. var var_2 = v*(1-s*(var_h-var_i));
  2453. var var_3 = v*(1-s*(1-(var_h-var_i)));
  2454. var r;
  2455. var g;
  2456. var b;
  2457. if(var_i===0){
  2458. r = v;
  2459. g = var_3;
  2460. b = var_1;
  2461. }else if(var_i===1){
  2462. r = var_2;
  2463. g = v;
  2464. b = var_1;
  2465. }else if(var_i===2){
  2466. r = var_1;
  2467. g = v;
  2468. b = var_3;
  2469. }else if(var_i===3){
  2470. r = var_1;
  2471. g = var_2;
  2472. b = v;
  2473. }else if (var_i===4){
  2474. r = var_3;
  2475. g = var_1;
  2476. b = v;
  2477. }else{
  2478. r = v;
  2479. g = var_1;
  2480. b = var_2;
  2481. }
  2482. RGBA = [
  2483. Math.round(r * 255),
  2484. Math.round(g * 255),
  2485. Math.round(b * 255),
  2486. a * 255
  2487. ];
  2488. }
  2489. return RGBA;
  2490. };
  2491. /**
  2492. * For a color expressed as an RGBA array, return the corresponding HSBA value
  2493. *
  2494. * @param {Array} rgba An 'array' object that represents a list of RGB colors
  2495. * @param {Array} maxes An 'array' object that represents the RGB range maxes
  2496. * @return {Array} an array of HSB values, scaled by the HSB-space maxes
  2497. */
  2498. p5.ColorUtils.rgbaToHSBA = function(rgba, maxes) {
  2499. var r = rgba[0]/maxes[0];
  2500. var g = rgba[1]/maxes[1];
  2501. var b = rgba[2]/maxes[2];
  2502. var a = rgba[3]/maxes[3];
  2503. var min = Math.min(r, g, b); //Min. value of RGB
  2504. var max = Math.max(r, g, b); //Max. value of RGB
  2505. var delta_max = max - min; //Delta RGB value
  2506. var h;
  2507. var s;
  2508. var v = max;
  2509. if (delta_max === 0) { //This is a gray, no chroma...
  2510. h = 0; //HSV results from 0 to 1
  2511. s = 0;
  2512. }
  2513. else { //Chromatic data...
  2514. s = delta_max/max;
  2515. var delta_r = ( ( ( max - r ) / 6 ) + ( delta_max / 2 ) ) / delta_max;
  2516. var delta_g = ( ( ( max - g ) / 6 ) + ( delta_max / 2 ) ) / delta_max;
  2517. var delta_b = ( ( ( max - b ) / 6 ) + ( delta_max / 2 ) ) / delta_max;
  2518. if (r === max) {
  2519. h = delta_b - delta_g;
  2520. } else if (g === max) {
  2521. h = 1/3 + delta_r - delta_b;
  2522. } else if (b === max) {
  2523. h = 2/3 + delta_g - delta_r;
  2524. }
  2525. if (h < 0) {
  2526. h += 1;
  2527. }
  2528. if (h > 1) {
  2529. h -= 1;
  2530. }
  2531. }
  2532. return [
  2533. Math.round(h * 360),
  2534. Math.round(s * 100),
  2535. Math.round(v * 100),
  2536. a * 1
  2537. ];
  2538. };
  2539. /**
  2540. * For a color expressed as an HSLA array, return the corresponding RGBA value
  2541. *
  2542. * @param {Array} hsla An 'array' object that represents a list of HSL colors
  2543. * @param {Array} maxes An 'array' object that represents the HSL range maxes
  2544. *
  2545. * @return {Array} an array of RGBA values, on a scale of 0-255
  2546. */
  2547. p5.ColorUtils.hslaToRGBA = function(hsla, maxes){
  2548. var h = hsla[0];
  2549. var s = hsla[1];
  2550. var l = hsla[2];
  2551. var a = hsla[3] || maxes[3];
  2552. h /= maxes[0];
  2553. s /= maxes[1];
  2554. l /= maxes[2];
  2555. a /= maxes[3];
  2556. // Adapted from http://www.easyrgb.com/math.html
  2557. // hsl values = 0 - 1, rgb values = 0 - 255
  2558. var rgba = [];
  2559. if(s === 0){
  2560. rgba = [Math.round(l*255), Math.round(l*255), Math.round(l*255), a];
  2561. } else {
  2562. var m, n, r, g, b;
  2563. n = l < 0.5 ? l * (1 + s) : (l + s) - (s * l);
  2564. m = 2 * l - n;
  2565. var convert = function(x, y, hue){
  2566. if (hue < 0) {
  2567. hue += 1;
  2568. } else if (hue > 1) {
  2569. hue -= 1;
  2570. }
  2571. if ( ( 6 * hue ) < 1 ) {
  2572. return ( x + ( y - x ) * 6 * hue );
  2573. } else if ( ( 2 * hue ) < 1 ) {
  2574. return ( y );
  2575. } else if ( ( 3 * hue ) < 2 ) {
  2576. return ( x + ( y - x ) * ( ( 2 / 3 ) - hue ) * 6 );
  2577. } else {
  2578. return x;
  2579. }
  2580. };
  2581. r = convert( m, n, h + ( 1 / 3 ) );
  2582. g = convert( m, n, h );
  2583. b = convert( m, n, h - ( 1 / 3 ) );
  2584. rgba = [
  2585. Math.round(r * 255),
  2586. Math.round(g * 255),
  2587. Math.round(b * 255),
  2588. Math.round(a * 255)
  2589. ];
  2590. }
  2591. return rgba;
  2592. };
  2593. /**
  2594. * For a color expressed as an RGBA array, return the corresponding HSBA value
  2595. *
  2596. * @param {Array} rgba An 'array' object that represents a list of RGB colors
  2597. * @param {Array} maxes An 'array' object that represents the RGB range maxes
  2598. * @return {Array} an array of HSL values, scaled by the HSL-space maxes
  2599. */
  2600. p5.ColorUtils.rgbaToHSLA = function(rgba, maxes) {
  2601. var r = rgba[0]/maxes[0];
  2602. var g = rgba[1]/maxes[1];
  2603. var b = rgba[2]/maxes[2];
  2604. var a = rgba[3]/maxes[3];
  2605. var min = Math.min(r, g, b); //Min. value of RGB
  2606. var max = Math.max(r, g, b); //Max. value of RGB
  2607. var delta_max = max - min; //Delta RGB value
  2608. var h;
  2609. var s;
  2610. var l = (max + min) / 2;
  2611. var delta_r;
  2612. var delta_g;
  2613. var delta_b;
  2614. if (delta_max === 0) { // This is a gray, no chroma...
  2615. h = 0; // HSL results from 0 to 1
  2616. s = 0;
  2617. } else { // Chromatic data...
  2618. delta_r = ( ( ( max - r ) / 6 ) + ( delta_max / 2 ) ) / delta_max;
  2619. delta_g = ( ( ( max - g ) / 6 ) + ( delta_max / 2 ) ) / delta_max;
  2620. delta_b = ( ( ( max - b ) / 6 ) + ( delta_max / 2 ) ) / delta_max;
  2621. if ( r === max ){
  2622. h = delta_b - delta_g;
  2623. } else if ( g === max ){
  2624. h = ( 1 / 3 ) + delta_r - delta_b;
  2625. } else if ( b === max ) {
  2626. h = ( 2 / 3 ) + delta_g - delta_r;
  2627. }
  2628. if ( h < 0 ) {
  2629. h += 1;
  2630. }
  2631. if ( h > 1 ) {
  2632. h -= 1;
  2633. }
  2634. if ( l < 0.5 ){
  2635. s = delta_max / ( max + min );
  2636. } else {
  2637. s = delta_max / ( 2 - max - min );
  2638. }
  2639. }
  2640. return [
  2641. Math.round(h * 360),
  2642. Math.round(s * 100),
  2643. Math.round(l * 100),
  2644. a * 1
  2645. ];
  2646. };
  2647. module.exports = p5.ColorUtils;
  2648. },{"../core/core":17}],10:[function(require,module,exports){
  2649. /**
  2650. * @module Color
  2651. * @submodule Creating & Reading
  2652. * @for p5
  2653. * @requires core
  2654. */
  2655. 'use strict';
  2656. var p5 = require('../core/core');
  2657. require('./p5.Color');
  2658. /**
  2659. * Extracts the alpha value from a color or pixel array.
  2660. *
  2661. * @method alpha
  2662. * @param {Object} obj p5.Color object or pixel array
  2663. * @example
  2664. * <div>
  2665. * <code>
  2666. * noStroke();
  2667. * c = color(0, 126, 255, 102);
  2668. * fill(c);
  2669. * rect(15, 15, 35, 70);
  2670. * value = alpha(c); // Sets 'value' to 102
  2671. * fill(value);
  2672. * rect(50, 15, 35, 70);
  2673. * </code>
  2674. * </div>
  2675. */
  2676. p5.prototype.alpha = function(c) {
  2677. if (c instanceof p5.Color || c instanceof Array) {
  2678. return this.color(c).getAlpha();
  2679. } else {
  2680. throw new Error('Needs p5.Color or pixel array as argument.');
  2681. }
  2682. };
  2683. /**
  2684. * Extracts the blue value from a color or a pixel array.
  2685. *
  2686. * @method blue
  2687. * @param {Object} obj p5.Color object or pixel array
  2688. * @example
  2689. * <div>
  2690. * <code>
  2691. * c = color(175, 100, 220); // Define color 'c'
  2692. * fill(c); // Use color variable 'c' as fill color
  2693. * rect(15, 20, 35, 60); // Draw left rectangle
  2694. *
  2695. * blueValue = blue(c); // Get blue in 'c'
  2696. * println(blueValue); // Prints "220.0"
  2697. * fill(0, 0, blueValue); // Use 'blueValue' in new fill
  2698. * rect(50, 20, 35, 60); // Draw right rectangle
  2699. * </code>
  2700. * </div>
  2701. */
  2702. p5.prototype.blue = function(c) {
  2703. if (c instanceof p5.Color || c instanceof Array) {
  2704. return this.color(c).getBlue();
  2705. } else {
  2706. throw new Error('Needs p5.Color or pixel array as argument.');
  2707. }
  2708. };
  2709. /**
  2710. * Extracts the brightness value from a color.
  2711. *
  2712. * @method brightness
  2713. * @param {Object} color p5.Color object
  2714. * @example
  2715. * <div>
  2716. * <code>
  2717. * noStroke();
  2718. * colorMode(HSB, 255);
  2719. * c = color(0, 126, 255);
  2720. * fill(c);
  2721. * rect(15, 20, 35, 60);
  2722. * value = brightness(c); // Sets 'value' to 255
  2723. * fill(value);
  2724. * rect(50, 20, 35, 60);
  2725. * </code>
  2726. * </div>
  2727. */
  2728. p5.prototype.brightness = function(c) {
  2729. if (c instanceof p5.Color || c instanceof Array) {
  2730. return this.color(c).getBrightness();
  2731. } else {
  2732. throw new Error('Needs p5.Color or pixel array as argument.');
  2733. }
  2734. };
  2735. /**
  2736. * Creates colors for storing in variables of the color datatype. The
  2737. * parameters are interpreted as RGB or HSB values depending on the
  2738. * current colorMode(). The default mode is RGB values from 0 to 255
  2739. * and, therefore, the function call color(255, 204, 0) will return a
  2740. * bright yellow color.
  2741. *
  2742. * Note that if only one value is provided to color(), it will be interpreted
  2743. * as a grayscale value. Add a second value, and it will be used for alpha
  2744. * transparency. When three values are specified, they are interpreted as
  2745. * either RGB or HSB values. Adding a fourth value applies alpha
  2746. * transparency. If a single string parameter is provided it will be
  2747. * interpreted as a CSS-compatible color string.
  2748. *
  2749. * Colors are stored as Numbers or Arrays.
  2750. *
  2751. * @method color
  2752. * @param {Number|String} v1 gray value or red or hue value relative to
  2753. * the current color range, or a color string
  2754. * @param {Number} [v2] gray value or green or saturation value
  2755. * relative to the current color range (or
  2756. * alpha value if first param is gray value)
  2757. * @param {Number} [v3] gray value or blue or brightness value
  2758. * relative to the current color range
  2759. * @param {Number} [alpha] alpha value relative to current color range
  2760. * @return {Array} resulting color
  2761. *
  2762. * @example
  2763. * <div>
  2764. * <code>
  2765. * c = color(255, 204, 0); // Define color 'c'
  2766. * fill(c); // Use color variable 'c' as fill color
  2767. * noStroke(); // Don't draw a stroke around shapes
  2768. * rect(30, 20, 55, 55); // Draw rectangle
  2769. * </code>
  2770. * </div>
  2771. *
  2772. * <div>
  2773. * <code>
  2774. * c = color(255, 204, 0); // Define color 'c'
  2775. * fill(c); // Use color variable 'c' as fill color
  2776. * noStroke(); // Don't draw a stroke around shapes
  2777. * ellipse(25, 25, 80, 80); // Draw left circle
  2778. *
  2779. * // Using only one value with color()
  2780. * // generates a grayscale value.
  2781. * c = color(65); // Update 'c' with grayscale value
  2782. * fill(c); // Use updated 'c' as fill color
  2783. * ellipse(75, 75, 80, 80); // Draw right circle
  2784. * </code>
  2785. * </div>
  2786. *
  2787. * <div>
  2788. * <code>
  2789. * // Named SVG & CSS colors may be used,
  2790. * c = color('magenta');
  2791. * fill(c); // Use 'c' as fill color
  2792. * noStroke(); // Don't draw a stroke around shapes
  2793. * rect(20, 20, 60, 60); // Draw rectangle
  2794. * </code>
  2795. * </div>
  2796. *
  2797. * <div>
  2798. * <code>
  2799. * // as can hex color codes:
  2800. * c = color('#4F66A1');
  2801. * fill(c); // Use 'c' as fill color
  2802. * noStroke(); // Don't draw a stroke around shapes
  2803. * rect(20, 20, 60, 60); // Draw rectangle
  2804. * </code>
  2805. * </div>
  2806. *
  2807. * <div>
  2808. * <code>
  2809. * // RGB and RGBA color strings are also supported:
  2810. * // these all set 'c' to the same color (solid blue)
  2811. * c = color('rgb(0,0,255)');
  2812. * c = color('rgb(0%, 0%, 100%)');
  2813. * c = color('rgba(0, 0, 255, 1)');
  2814. * c = color('rgba(0%, 0%, 100%, 1)');
  2815. * fill(c); // Use 'c' as fill color
  2816. * noStroke(); // Don't draw a stroke around shapes
  2817. * rect(20, 20, 60, 60); // Draw rectangle
  2818. * </code>
  2819. * </div>
  2820. *
  2821. *
  2822. * <div>
  2823. * <code>
  2824. * // HSL color is also supported and can be specified
  2825. * // by value
  2826. * colorMode(HSL)
  2827. * c = color(156, 100, 50, 1);
  2828. * fill(c); // Use 'c' as fill color
  2829. * noStroke(); // Don't draw a stroke around shapes
  2830. * rect(20, 20, 60, 60); // Draw rectangle
  2831. * </code>
  2832. * </div>
  2833. *
  2834. * <div>
  2835. * <code>
  2836. * // or by string
  2837. * c = color('hsla(156, 100%, 50%, 1)');
  2838. * fill(c); // Use 'c' as fill color
  2839. * noStroke(); // Don't draw a stroke around shapes
  2840. * rect(20, 20, 60, 60); // Draw rectangle
  2841. * </code>
  2842. * </div>
  2843. *
  2844. *
  2845. * // if switching from RGB to HSB or HSL both modes must be declared
  2846. * colorMode(RGB, 255); // Use RGB with scale of 0-255
  2847. * c = color(50, 55, 100); // Create a color for 'c'
  2848. * fill(c); // Use color variable 'c' as fill color
  2849. * rect(0, 10, 45, 80); // Draw left rect
  2850. *
  2851. * colorMode(HSB, 100); // Use HSB with scale of 0-100
  2852. * c = color(50, 55, 100); // Update 'c' with new color
  2853. * fill(c); // Use updated 'c' as fill color
  2854. * rect(55, 10, 45, 80); // Draw right rect
  2855. * </code>
  2856. * </div>
  2857. */
  2858. p5.prototype.color = function () {
  2859. if (arguments[0] instanceof p5.Color) {
  2860. return arguments[0];
  2861. } else if (arguments[0] instanceof Array) {
  2862. return new p5.Color(this, arguments[0]);
  2863. } else {
  2864. var args = Array.prototype.slice.call(arguments);
  2865. return new p5.Color(this, args);
  2866. }
  2867. };
  2868. /**
  2869. * Extracts the green value from a color or pixel array.
  2870. *
  2871. * @method green
  2872. * @param {Object} color p5.Color object
  2873. * @example
  2874. * <div>
  2875. * <code>
  2876. * c = color(20, 75, 200); // Define color 'c'
  2877. * fill(c); // Use color variable 'c' as fill color
  2878. * rect(15, 20, 35, 60); // Draw left rectangle
  2879. *
  2880. * greenValue = green(c); // Get green in 'c'
  2881. * println(greenValue); // Print "75.0"
  2882. * fill(0, greenValue, 0); // Use 'greenValue' in new fill
  2883. * rect(50, 20, 35, 60); // Draw right rectangle
  2884. * </code>
  2885. * </div>
  2886. */
  2887. p5.prototype.green = function(c) {
  2888. if (c instanceof p5.Color || c instanceof Array) {
  2889. return this.color(c).getGreen();
  2890. } else {
  2891. throw new Error('Needs p5.Color or pixel array as argument.');
  2892. }
  2893. };
  2894. /**
  2895. * Extracts the hue value from a color.
  2896. *
  2897. * @method hue
  2898. * @param {Object} color p5.Color object
  2899. * @example
  2900. * <div>
  2901. * <code>
  2902. * noStroke();
  2903. * colorMode(HSB, 255);
  2904. * c = color(0, 126, 255);
  2905. * fill(c);
  2906. * rect(15, 20, 35, 60);
  2907. * value = hue(c); // Sets 'value' to "0"
  2908. * fill(value);
  2909. * rect(50, 20, 35, 60);
  2910. * </code>
  2911. * </div>
  2912. */
  2913. p5.prototype.hue = function(c) {
  2914. if (!(c instanceof p5.Color)) {
  2915. throw new Error('Needs p5.Color as argument.');
  2916. }
  2917. return c.getHue();
  2918. };
  2919. /**
  2920. * Calculates a color or colors between two color at a specific increment,
  2921. * using gamma correction to blend colors in the linear RGB space.
  2922. * The amt parameter is the amount to interpolate between the two values
  2923. * where 0.0 equal to the first point, 0.1 is very near the first point,
  2924. * 0.5 is halfway in between, etc. An amount below 0 will be treated as 0.
  2925. * Likewise, amounts above 1 will be capped at 1. This is different from
  2926. * the behavior of lerp(), but necessary because otherwise numbers outside
  2927. * the range will produce strange and unexpected colors.
  2928. *
  2929. * The regular RGB color representation stores the square root of the
  2930. * displayed color, not the value itself. Your monitor behaves as if it
  2931. * squares the color values before displaying it. lerpColor first transforms
  2932. * colors into the linear color space before blending, to correctly mix the
  2933. * colors as two rays of light.
  2934. *
  2935. * @method lerpColor
  2936. * @param {Array/Number} c1 interpolate from this color
  2937. * @param {Array/Number} c2 interpolate to this color
  2938. * @param {Number} amt number between 0 and 1
  2939. * @return {Array/Number} interpolated color
  2940. * @example
  2941. * <div>
  2942. * <code>
  2943. * stroke(255);
  2944. * background(51);
  2945. * from = color(204, 102, 0);
  2946. * to = color(0, 102, 153);
  2947. * interA = lerpColor(from, to, .33);
  2948. * interB = lerpColor(from, to, .66);
  2949. * fill(from);
  2950. * rect(10, 20, 20, 60);
  2951. * fill(interA);
  2952. * rect(30, 20, 20, 60);
  2953. * fill(interB);
  2954. * rect(50, 20, 20, 60);
  2955. * fill(to);
  2956. * rect(70, 20, 20, 60);
  2957. * </code>
  2958. * </div>
  2959. */
  2960. p5.prototype.lerpColor = function (c1, c2, amt) {
  2961. amt = Math.max(Math.min(amt, 1), 0);
  2962. if (c1 instanceof Array) {
  2963. var c = [];
  2964. for (var i = 0; i < c1.length; i++) {
  2965. c.push(Math.sqrt(p5.prototype.lerp(c1[i]*c1[i], c2[i]*c2[i], amt)));
  2966. }
  2967. return c;
  2968. } else if (c1 instanceof p5.Color) {
  2969. var pc = [];
  2970. for (var j = 0; j < 4; j++) {
  2971. pc.push(Math.sqrt(p5.prototype.lerp(
  2972. c1.rgba[j]*c1.rgba[j],
  2973. c2.rgba[j]*c2.rgba[j],
  2974. amt)));
  2975. }
  2976. return new p5.Color(this, pc);
  2977. } else {
  2978. return Math.sqrt(p5.prototype.lerp(c1*c1, c2*c2, amt));
  2979. }
  2980. };
  2981. /**
  2982. * Extracts the lightness value from a color.
  2983. *
  2984. * @method lightness
  2985. * @param {Object} color p5.Color object
  2986. * @example
  2987. * <div>
  2988. * <code>
  2989. * noStroke();
  2990. * colorMode(HSL);
  2991. * c = color(156, 100, 50, 1);
  2992. * fill(c);
  2993. * rect(15, 20, 35, 60);
  2994. * value = lightness(c); // Sets 'value' to 50
  2995. * fill(value);
  2996. * rect(50, 20, 35, 60);
  2997. * </code>
  2998. * </div>
  2999. */
  3000. p5.prototype.lightness = function(c) {
  3001. if (c instanceof p5.Color || c instanceof Array) {
  3002. return this.color(c).getLightness();
  3003. } else {
  3004. throw new Error('Needs p5.Color or pixel array as argument.');
  3005. }
  3006. };
  3007. /**
  3008. * Extracts the red value from a color or pixel array.
  3009. *
  3010. * @method red
  3011. * @param {Object} obj p5.Color object or pixel array
  3012. * @example
  3013. * <div>
  3014. * <code>
  3015. * c = color(255, 204, 0); // Define color 'c'
  3016. * fill(c); // Use color variable 'c' as fill color
  3017. * rect(15, 20, 35, 60); // Draw left rectangle
  3018. *
  3019. * redValue = red(c); // Get red in 'c'
  3020. * println(redValue); // Print "255.0"
  3021. * fill(redValue, 0, 0); // Use 'redValue' in new fill
  3022. * rect(50, 20, 35, 60); // Draw right rectangle
  3023. * </code>
  3024. * </div>
  3025. */
  3026. p5.prototype.red = function(c) {
  3027. if (c instanceof p5.Color || c instanceof Array) {
  3028. return this.color(c).getRed();
  3029. } else {
  3030. throw new Error('Needs p5.Color or pixel array as argument.');
  3031. }
  3032. };
  3033. /**
  3034. * Extracts the saturation value from a color.
  3035. *
  3036. * @method saturation
  3037. * @param {Object} color p5.Color object
  3038. * @example
  3039. * <div>
  3040. * <code>
  3041. * noStroke();
  3042. * colorMode(HSB, 255);
  3043. * c = color(0, 126, 255);
  3044. * fill(c);
  3045. * rect(15, 20, 35, 60);
  3046. * value = saturation(c); // Sets 'value' to 126
  3047. * fill(value);
  3048. * rect(50, 20, 35, 60);
  3049. * </code>
  3050. * </div>
  3051. */
  3052. p5.prototype.saturation = function(c) {
  3053. if (!(c instanceof p5.Color)) {
  3054. throw new Error('Needs p5.Color as argument.');
  3055. }
  3056. return c.getSaturation();
  3057. };
  3058. module.exports = p5;
  3059. },{"../core/core":17,"./p5.Color":11}],11:[function(require,module,exports){
  3060. /**
  3061. * @module Color
  3062. * @submodule Creating & Reading
  3063. * @for p5
  3064. */
  3065. var p5 = require('../core/core');
  3066. var color_utils = require('./color_utils');
  3067. var constants = require('../core/constants');
  3068. /**
  3069. *
  3070. * @class p5.Color
  3071. * @constructor
  3072. */
  3073. p5.Color = function (pInst, vals) {
  3074. this.maxArr = pInst._colorMaxes[pInst._colorMode];
  3075. this.color_array = p5.Color._getFormattedColor.apply(pInst, vals);
  3076. var isHSB = pInst._colorMode === constants.HSB,
  3077. isRGB = pInst._colorMode === constants.RGB,
  3078. isHSL = pInst._colorMode === constants.HSL;
  3079. if (isRGB) {
  3080. this.rgba = this.color_array;
  3081. } else if (isHSL) {
  3082. this.hsla = this.color_array;
  3083. this.rgba = color_utils.hslaToRGBA(this.color_array, this.maxArr);
  3084. } else if (isHSB) {
  3085. this.hsba = this.color_array;
  3086. this.rgba = color_utils.hsbaToRGBA(this.color_array, this.maxArr);
  3087. } else {
  3088. throw new Error(pInst._colorMode + 'is an invalid colorMode.');
  3089. }
  3090. return this;
  3091. };
  3092. p5.Color.prototype.getHue = function() {
  3093. // Hue is consistent in both HSL & HSB
  3094. if (this.hsla || this.hsba) {
  3095. return this.hsla ? this.hsla[0] : this.hsba[0];
  3096. } else {
  3097. this.hsla = color_utils.rgbaToHSLA(this.color_array, this.maxArr);
  3098. return this.hsla[0];
  3099. }
  3100. };
  3101. p5.Color.prototype.getSaturation = function() {
  3102. // Saturation exists in both HSB and HSL, but returns different values
  3103. // We are preferring HSL here (because it is a web color space)
  3104. // until the global flag issue can be resolved
  3105. if (this.hsla) {
  3106. return this.hsla[1];
  3107. } else if (this.hsba) {
  3108. return this.hsba[1];
  3109. } else {
  3110. this.hsla = color_utils.rgbaToHSLA(this.color_array, this.maxArr);
  3111. return this.hsla[1];
  3112. }
  3113. };
  3114. // Brightness only exists as an HSB value
  3115. p5.Color.prototype.getBrightness = function() {
  3116. if (this.hsba) {
  3117. return this.hsba[2];
  3118. } else {
  3119. this.hsba = color_utils.rgbaToHSBA(this.color_array, this.maxArr);
  3120. return this.hsba[2];
  3121. }
  3122. };
  3123. // Lightness only exists as an HSL value
  3124. p5.Color.prototype.getLightness = function() {
  3125. if (this.hsla) {
  3126. return this.hsla[2];
  3127. } else {
  3128. this.hsla = color_utils.rgbaToHSLA(this.color_array, this.maxArr);
  3129. return this.hsla[2];
  3130. }
  3131. };
  3132. p5.Color.prototype.getRed = function() {
  3133. return this.rgba[0];
  3134. };
  3135. p5.Color.prototype.getGreen = function() {
  3136. return this.rgba[1];
  3137. };
  3138. p5.Color.prototype.getBlue = function() {
  3139. return this.rgba[2];
  3140. };
  3141. p5.Color.prototype.getAlpha = function() {
  3142. // Again this is a little sleight of hand until the global flag
  3143. // issue is resolved. The presumption is that if alpha has been
  3144. // specified in 0-1 space, the user wants that value out
  3145. if (this.hsba || this.hsla) {
  3146. return this.hsla ? this.hsla[3] : this.hsba[3];
  3147. } else {
  3148. return this.rgba[3];
  3149. }
  3150. };
  3151. p5.Color.prototype.toString = function() {
  3152. var a = this.rgba;
  3153. for (var i=0; i<3; i++) {
  3154. a[i] = Math.floor(a[i]);
  3155. }
  3156. var alpha = typeof a[3] !== 'undefined' ? a[3] / 255 : 1;
  3157. return 'rgba('+a[0]+','+a[1]+','+a[2]+','+ alpha +')';
  3158. };
  3159. /**
  3160. * These Regular Expressions are used to build up the patterns for matching
  3161. * viable CSS color strings: fragmenting the regexes in this way increases
  3162. * the legibility and comprehensibility of the code
  3163. */
  3164. // Match any number of whitespace characters (including no whitespace)
  3165. var WHITESPACE = /\s*/;
  3166. // Match whole-number values, e.g `255` or `79`
  3167. var INTEGER = /(\d{1,3})/;
  3168. // Match decimal values, e.g `129.6`, `79`, or `.9`
  3169. // Note: R, G or B values of `.9` are not parsed by IE: however, they are
  3170. // supported here to provide more consistent color string parsing
  3171. var DECIMAL = /((?:\d+(?:\.\d+)?)|(?:\.\d+))/;
  3172. // Match decimal values followed by a percent sign
  3173. var PERCENT = new RegExp(DECIMAL.source + '%');
  3174. var namedColors = {
  3175. aliceblue: '#f0f8ff',
  3176. antiquewhite: '#faebd7',
  3177. aqua: '#00ffff',
  3178. aquamarine: '#7fffd4',
  3179. azure: '#f0ffff',
  3180. beige: '#f5f5dc',
  3181. bisque: '#ffe4c4',
  3182. black: '#000000',
  3183. blanchedalmond: '#ffebcd',
  3184. blue: '#0000ff',
  3185. blueviolet: '#8a2be2',
  3186. brown: '#a52a2a',
  3187. burlywood: '#deb887',
  3188. cadetblue: '#5f9ea0',
  3189. chartreuse: '#7fff00',
  3190. chocolate: '#d2691e',
  3191. coral: '#ff7f50',
  3192. cornflowerblue: '#6495ed',
  3193. cornsilk: '#fff8dc',
  3194. crimson: '#dc143c',
  3195. cyan: '#00ffff',
  3196. darkblue: '#00008b',
  3197. darkcyan: '#008b8b',
  3198. darkgoldenrod: '#b8860b',
  3199. darkgray: '#a9a9a9',
  3200. darkgreen: '#006400',
  3201. darkgrey: '#a9a9a9',
  3202. darkkhaki: '#bdb76b',
  3203. darkmagenta: '#8b008b',
  3204. darkolivegreen: '#556b2f',
  3205. darkorange: '#ff8c00',
  3206. darkorchid: '#9932cc',
  3207. darkred: '#8b0000',
  3208. darksalmon: '#e9967a',
  3209. darkseagreen: '#8fbc8f',
  3210. darkslateblue: '#483d8b',
  3211. darkslategray: '#2f4f4f',
  3212. darkslategrey: '#2f4f4f',
  3213. darkturquoise: '#00ced1',
  3214. darkviolet: '#9400d3',
  3215. deeppink: '#ff1493',
  3216. deepskyblue: '#00bfff',
  3217. dimgray: '#696969',
  3218. dimgrey: '#696969',
  3219. dodgerblue: '#1e90ff',
  3220. firebrick: '#b22222',
  3221. floralwhite: '#fffaf0',
  3222. forestgreen: '#228b22',
  3223. fuchsia: '#ff00ff',
  3224. gainsboro: '#dcdcdc',
  3225. ghostwhite: '#f8f8ff',
  3226. gold: '#ffd700',
  3227. goldenrod: '#daa520',
  3228. gray: '#808080',
  3229. green: '#008000',
  3230. greenyellow: '#adff2f',
  3231. grey: '#808080',
  3232. honeydew: '#f0fff0',
  3233. hotpink: '#ff69b4',
  3234. indianred: '#cd5c5c',
  3235. indigo: '#4b0082',
  3236. ivory: '#fffff0',
  3237. khaki: '#f0e68c',
  3238. lavender: '#e6e6fa',
  3239. lavenderblush: '#fff0f5',
  3240. lawngreen: '#7cfc00',
  3241. lemonchiffon: '#fffacd',
  3242. lightblue: '#add8e6',
  3243. lightcoral: '#f08080',
  3244. lightcyan: '#e0ffff',
  3245. lightgoldenrodyellow: '#fafad2',
  3246. lightgray: '#d3d3d3',
  3247. lightgreen: '#90ee90',
  3248. lightgrey: '#d3d3d3',
  3249. lightpink: '#ffb6c1',
  3250. lightsalmon: '#ffa07a',
  3251. lightseagreen: '#20b2aa',
  3252. lightskyblue: '#87cefa',
  3253. lightslategray: '#778899',
  3254. lightslategrey: '#778899',
  3255. lightsteelblue: '#b0c4de',
  3256. lightyellow: '#ffffe0',
  3257. lime: '#00ff00',
  3258. limegreen: '#32cd32',
  3259. linen: '#faf0e6',
  3260. magenta: '#ff00ff',
  3261. maroon: '#800000',
  3262. mediumaquamarine: '#66cdaa',
  3263. mediumblue: '#0000cd',
  3264. mediumorchid: '#ba55d3',
  3265. mediumpurple: '#9370db',
  3266. mediumseagreen: '#3cb371',
  3267. mediumslateblue: '#7b68ee',
  3268. mediumspringgreen: '#00fa9a',
  3269. mediumturquoise: '#48d1cc',
  3270. mediumvioletred: '#c71585',
  3271. midnightblue: '#191970',
  3272. mintcream: '#f5fffa',
  3273. mistyrose: '#ffe4e1',
  3274. moccasin: '#ffe4b5',
  3275. navajowhite: '#ffdead',
  3276. navy: '#000080',
  3277. oldlace: '#fdf5e6',
  3278. olive: '#808000',
  3279. olivedrab: '#6b8e23',
  3280. orange: '#ffa500',
  3281. orangered: '#ff4500',
  3282. orchid: '#da70d6',
  3283. palegoldenrod: '#eee8aa',
  3284. palegreen: '#98fb98',
  3285. paleturquoise: '#afeeee',
  3286. palevioletred: '#db7093',
  3287. papayawhip: '#ffefd5',
  3288. peachpuff: '#ffdab9',
  3289. peru: '#cd853f',
  3290. pink: '#ffc0cb',
  3291. plum: '#dda0dd',
  3292. powderblue: '#b0e0e6',
  3293. purple: '#800080',
  3294. red: '#ff0000',
  3295. rosybrown: '#bc8f8f',
  3296. royalblue: '#4169e1',
  3297. saddlebrown: '#8b4513',
  3298. salmon: '#fa8072',
  3299. sandybrown: '#f4a460',
  3300. seagreen: '#2e8b57',
  3301. seashell: '#fff5ee',
  3302. sienna: '#a0522d',
  3303. silver: '#c0c0c0',
  3304. skyblue: '#87ceeb',
  3305. slateblue: '#6a5acd',
  3306. slategray: '#708090',
  3307. slategrey: '#708090',
  3308. snow: '#fffafa',
  3309. springgreen: '#00ff7f',
  3310. steelblue: '#4682b4',
  3311. tan: '#d2b48c',
  3312. teal: '#008080',
  3313. thistle: '#d8bfd8',
  3314. tomato: '#ff6347',
  3315. turquoise: '#40e0d0',
  3316. violet: '#ee82ee',
  3317. wheat: '#f5deb3',
  3318. white: '#ffffff',
  3319. whitesmoke: '#f5f5f5',
  3320. yellow: '#ffff00',
  3321. yellowgreen: '#9acd32'
  3322. };
  3323. // Regular Expressions for use identifying color pattern strings
  3324. var colorPatterns = {
  3325. /**
  3326. * Regular expression for matching colors in format #XXX,
  3327. * e.g. #416
  3328. */
  3329. HEX3: /^#([a-f0-9])([a-f0-9])([a-f0-9])$/i,
  3330. /**
  3331. * Regular expression for matching colors in format #XXXXXX,
  3332. * e.g. #b4d455
  3333. */
  3334. HEX6: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i,
  3335. /**
  3336. * Regular expression for matching colors in format rgb(R, G, B),
  3337. * e.g. rgb(255, 0, 128)
  3338. */
  3339. RGB: new RegExp([
  3340. // Defining RegExp this way makes it more obvious where whitespace
  3341. // (`\s*`) is permitted between tokens
  3342. '^rgb\\(',
  3343. INTEGER.source,
  3344. ',',
  3345. INTEGER.source,
  3346. ',',
  3347. INTEGER.source,
  3348. '\\)$'
  3349. ].join(WHITESPACE.source), 'i'),
  3350. /**
  3351. * Regular expression for matching colors in format rgb(R%, G%, B%),
  3352. * e.g. rgb(100%, 0%, 28.9%)
  3353. */
  3354. RGB_PERCENT: new RegExp([
  3355. // Defining RegExp this way makes it more obvious where whitespace
  3356. // (`\s*`) is permitted between tokens
  3357. '^rgb\\(',
  3358. PERCENT.source,
  3359. ',',
  3360. PERCENT.source,
  3361. ',',
  3362. PERCENT.source,
  3363. '\\)$'
  3364. ].join(WHITESPACE.source), 'i'),
  3365. /**
  3366. * Regular expression for matching colors in format rgb(R, G, B, A),
  3367. * e.g. rgb(255, 0, 128, 0.25)
  3368. */
  3369. RGBA: new RegExp([
  3370. '^rgba\\(',
  3371. INTEGER.source,
  3372. ',',
  3373. INTEGER.source,
  3374. ',',
  3375. INTEGER.source,
  3376. ',',
  3377. DECIMAL.source,
  3378. '\\)$'
  3379. ].join(WHITESPACE.source), 'i'),
  3380. /**
  3381. * Regular expression for matching colors in format rgb(R%, G%, B%, A),
  3382. * e.g. rgb(100%, 0%, 28.9%. 0.5)
  3383. */
  3384. RGBA_PERCENT: new RegExp([
  3385. '^rgba\\(',
  3386. PERCENT.source,
  3387. ',',
  3388. PERCENT.source,
  3389. ',',
  3390. PERCENT.source,
  3391. ',',
  3392. DECIMAL.source,
  3393. '\\)$'
  3394. ].join(WHITESPACE.source), 'i'),
  3395. /**
  3396. * Regular expression for matching colors in format hsla(H, S%, L%),
  3397. * e.g. hsl(100, 40%, 28.9%,)
  3398. */
  3399. HSL: new RegExp([
  3400. '^hsl\\(',
  3401. INTEGER.source,
  3402. ',',
  3403. PERCENT.source,
  3404. ',',
  3405. PERCENT.source,
  3406. '\\)$'
  3407. ].join(WHITESPACE.source), 'i'),
  3408. /**
  3409. * Regular expression for matching colors in format hsla(H, S%, L%, A),
  3410. * e.g. hsla(100, 40%, 28.9%, 0.5)
  3411. */
  3412. HSLA: new RegExp([
  3413. '^hsla\\(',
  3414. INTEGER.source,
  3415. ',',
  3416. PERCENT.source,
  3417. ',',
  3418. PERCENT.source,
  3419. ',',
  3420. DECIMAL.source,
  3421. '\\)$'
  3422. ].join(WHITESPACE.source), 'i'),
  3423. };
  3424. /**
  3425. * For a number of different inputs, returns a color formatted as
  3426. * [r, g, b, a].
  3427. *
  3428. * @param {Array-like} args An 'array-like' object that represents a list of
  3429. * arguments
  3430. * @return {Array} a color formatted as [r, g, b, a]
  3431. * Example:
  3432. * input ==> output
  3433. * g ==> [g, g, g, 255]
  3434. * g,a ==> [g, g, g, a]
  3435. * r, g, b ==> [r, g, b, 255]
  3436. * r, g, b, a ==> [r, g, b, a]
  3437. * [g] ==> [g, g, g, 255]
  3438. * [g, a] ==> [g, g, g, a]
  3439. * [r, g, b] ==> [r, g, b, 255]
  3440. * [r, g, b, a] ==> [r, g, b, a]
  3441. * @example
  3442. * <div>
  3443. * <code>
  3444. * // todo
  3445. * </code>
  3446. * </div>
  3447. */
  3448. p5.Color._getFormattedColor = function () {
  3449. var numArgs = arguments.length,
  3450. mode = this._colorMode,
  3451. first, second, third, alpha, str, vals;
  3452. // Handle [r,g,b,a] or [h,s,l,a] color values
  3453. if (numArgs >= 3) {
  3454. first = arguments[0];
  3455. second = arguments[1];
  3456. third = arguments[2];
  3457. alpha = typeof arguments[3] === 'number' ?
  3458. arguments[3] : this._colorMaxes[mode][3];
  3459. // Handle strings: named colors, hex values, css strings
  3460. } else if (numArgs === 1 && typeof arguments[0] === 'string') {
  3461. str = arguments[0].trim().toLowerCase();
  3462. if (namedColors[str]) {
  3463. // Handle named color values
  3464. return p5.Color._getFormattedColor.apply(this, [namedColors[str]]);
  3465. }
  3466. // Work through available string patterns to determine how to proceed
  3467. if (colorPatterns.HEX3.test(str)) {
  3468. vals = colorPatterns.HEX3.exec(str).slice(1).map(function(color) {
  3469. // Expand #RGB to #RRGGBB
  3470. return parseInt(color + color, 16);
  3471. });
  3472. } else if (colorPatterns.HEX6.test(str)) {
  3473. vals = colorPatterns.HEX6.exec(str).slice(1).map(function(color) {
  3474. return parseInt(color, 16);
  3475. });
  3476. } else if (colorPatterns.RGB.test(str)) {
  3477. vals = colorPatterns.RGB.exec(str).slice(1).map(function(color) {
  3478. return parseInt(color, 10);
  3479. });
  3480. } else if (colorPatterns.RGB_PERCENT.test(str)) {
  3481. vals = colorPatterns.RGB_PERCENT.exec(str).slice(1)
  3482. .map(function(color) {
  3483. return parseInt(parseFloat(color) / 100 * 255, 10);
  3484. });
  3485. } else if (colorPatterns.RGBA.test(str)) {
  3486. vals = colorPatterns.RGBA.exec(str).slice(1)
  3487. .map(function(color, idx) {
  3488. if (idx === 3) {
  3489. // Alpha value is a decimal: multiply by 255
  3490. return parseInt(parseFloat(color) * 255, 10);
  3491. }
  3492. return parseInt(color, 10);
  3493. });
  3494. } else if (colorPatterns.RGBA_PERCENT.test(str)) {
  3495. vals = colorPatterns.RGBA_PERCENT.exec(str).slice(1)
  3496. .map(function(color, idx) {
  3497. if (idx === 3) {
  3498. // Alpha value is a decimal: multiply by 255
  3499. return parseInt(parseFloat(color) * 255, 10);
  3500. }
  3501. return parseInt(parseFloat(color) / 100 * 255, 10);
  3502. });
  3503. } else if (colorPatterns.HSL.test(str)) {
  3504. vals = colorPatterns.HSL.exec(str).slice(1).map(function(color) {
  3505. return parseInt(color, 10);
  3506. });
  3507. } else if (colorPatterns.HSLA.test(str)) {
  3508. vals = colorPatterns.HSLA.exec(str).slice(1).map(function(color) {
  3509. return parseFloat(color, 10);
  3510. });
  3511. } else {
  3512. // Input did not match any CSS Color pattern: Default to white
  3513. vals = [255];
  3514. }
  3515. // Re-run _getFormattedColor with the values parsed out of the string
  3516. return p5.Color._getFormattedColor.apply(this, vals);
  3517. // Handle greyscale color mode
  3518. } else if (numArgs === 1 && typeof arguments[0] === 'number') {
  3519. // When users pass only one argument, they are presumed to be
  3520. // working in grayscale mode.
  3521. if (mode === constants.RGB) {
  3522. first = second = third = arguments[0];
  3523. } else if (mode === constants.HSB || mode === constants.HSL) {
  3524. // In order for grayscale to work with HSB & HSL, the saturation
  3525. // (the second argument) must be 0.
  3526. first = third = arguments[0];
  3527. second = 0;
  3528. }
  3529. alpha = typeof arguments[1] === 'number' ?
  3530. arguments[1] : this._colorMaxes[mode][3];
  3531. // Handle brightness and alpha (grayscale)
  3532. } else if (numArgs === 2 &&
  3533. typeof arguments[0] === 'number' &&
  3534. typeof arguments[1] === 'number') {
  3535. // When users pass only one argument, they are presumed to be
  3536. // working in grayscale mode.
  3537. if (mode === constants.RGB) {
  3538. first = second = third = arguments[0];
  3539. } else if (mode === constants.HSB || mode === constants.HSL) {
  3540. // In order for grayscale to work with HSB & HSL, the saturation
  3541. // (the second argument) must be 0.
  3542. first = third = arguments[0];
  3543. second = 0;
  3544. }
  3545. alpha = arguments[1];
  3546. } else {
  3547. throw new Error (arguments + 'is not a valid color representation.');
  3548. }
  3549. return [
  3550. first,
  3551. second,
  3552. third,
  3553. alpha
  3554. ];
  3555. };
  3556. module.exports = p5.Color;
  3557. },{"../core/constants":16,"../core/core":17,"./color_utils":9}],12:[function(require,module,exports){
  3558. /**
  3559. * @module Color
  3560. * @submodule Setting
  3561. * @for p5
  3562. * @requires core
  3563. * @requires constants
  3564. */
  3565. 'use strict';
  3566. var p5 = require('../core/core');
  3567. var constants = require('../core/constants');
  3568. require('./p5.Color');
  3569. p5.prototype._doStroke = true;
  3570. p5.prototype._doFill = true;
  3571. p5.prototype._strokeSet = false;
  3572. p5.prototype._fillSet = false;
  3573. p5.prototype._colorMode = constants.RGB;
  3574. p5.prototype._colorMaxes = {
  3575. rgb: [255, 255, 255, 255],
  3576. hsb: [360, 100, 100, 1],
  3577. hsl: [360, 100, 100, 1]
  3578. };
  3579. /**
  3580. * The background() function sets the color used for the background of the
  3581. * p5.js canvas. The default background is light gray. This function is
  3582. * typically used within draw() to clear the display window at the beginning
  3583. * of each frame, but it can be used inside setup() to set the background on
  3584. * the first frame of animation or if the background need only be set once.
  3585. *
  3586. * @method background
  3587. * @param {Number|String|p5.Color|p5.Image} v1 gray value, red or hue value
  3588. * (depending on the current
  3589. * color mode), color string,
  3590. * p5.Color, or p5.Image
  3591. * @param {Number} [v2] green or saturation value
  3592. * (depending on the current
  3593. * color mode)
  3594. * @param {Number} [v3] blue or brightness value
  3595. * (depending on the current
  3596. * color mode)
  3597. * @param {Number} [a] opacity of the background
  3598. *
  3599. * @example
  3600. * <div>
  3601. * <code>
  3602. * // Grayscale integer value
  3603. * background(51);
  3604. * </code>
  3605. * </div>
  3606. *
  3607. * <div>
  3608. * <code>
  3609. * // R, G & B integer values
  3610. * background(255, 204, 0);
  3611. * </code>
  3612. * </div>
  3613. *
  3614. * <div>
  3615. * <code>
  3616. * // H, S & B integer values
  3617. * colorMode(HSB);
  3618. * background(255, 204, 100);
  3619. * </code>
  3620. * </div>
  3621. *
  3622. * <div>
  3623. * <code>
  3624. * // Named SVG/CSS color string
  3625. * background('red');
  3626. * </code>
  3627. * </div>
  3628. *
  3629. * <div>
  3630. * <code>
  3631. * // three-digit hexadecimal RGB notation
  3632. * background('#fae');
  3633. * </code>
  3634. * </div>
  3635. *
  3636. * <div>
  3637. * <code>
  3638. * // six-digit hexadecimal RGB notation
  3639. * background('#222222');
  3640. * </code>
  3641. * </div>
  3642. *
  3643. * <div>
  3644. * <code>
  3645. * // integer RGB notation
  3646. * background('rgb(0,255,0)');
  3647. * </code>
  3648. * </div>
  3649. *
  3650. * <div>
  3651. * <code>
  3652. * // integer RGBA notation
  3653. * background('rgba(0,255,0, 0.25)');
  3654. * </code>
  3655. * </div>
  3656. *
  3657. * <div>
  3658. * <code>
  3659. * // percentage RGB notation
  3660. * background('rgb(100%,0%,10%)');
  3661. * </code>
  3662. * </div>
  3663. *
  3664. * <div>
  3665. * <code>
  3666. * // percentage RGBA notation
  3667. * background('rgba(100%,0%,100%,0.5)');
  3668. * </code>
  3669. * </div>
  3670. *
  3671. * <div>
  3672. * <code>
  3673. * // p5 Color object
  3674. * background(color(0, 0, 255));
  3675. * </code>
  3676. * </div>
  3677. */
  3678. p5.prototype.background = function() {
  3679. if (arguments[0] instanceof p5.Image) {
  3680. this.image(arguments[0], 0, 0, this.width, this.height);
  3681. } else {
  3682. this._graphics.background.apply(this._graphics, arguments);
  3683. }
  3684. return this;
  3685. };
  3686. /**
  3687. * Clears the pixels within a buffer. This function only works on p5.Canvas
  3688. * objects created with the createCanvas() function; it won't work with the
  3689. * main display window. Unlike the main graphics context, pixels in
  3690. * additional graphics areas created with createGraphics() can be entirely
  3691. * or partially transparent. This function clears everything to make all of
  3692. * the pixels 100% transparent.
  3693. *
  3694. * @method clear
  3695. * @example
  3696. * <div>
  3697. * <code>
  3698. * </code>
  3699. * </div>
  3700. */
  3701. p5.prototype.clear = function() {
  3702. this._graphics.clear();
  3703. return this;
  3704. };
  3705. /**
  3706. * Changes the way p5.js interprets color data. By default, the parameters
  3707. * for fill(), stroke(), background(), and color() are defined by values
  3708. * between 0 and 255 using the RGB color model. The colorMode() function is
  3709. * used to switch color systems. Regardless of color system, all value ranges
  3710. * are presumed to be 0–255 unless explicitly set otherwise. That is,
  3711. * for a standard HSB range, one would pass colorMode(HSB, 360, 100, 100, 1).
  3712. *
  3713. * @method colorMode
  3714. * @param {Number|Constant} mode either RGB or HSB, corresponding to
  3715. * Red/Green/Blue and Hue/Saturation/Brightness
  3716. * @param {Number|Constant} max1 range for the red or hue depending on the
  3717. * current color mode, or range for all values
  3718. * @param {Number|Constant} max2 range for the green or saturation depending
  3719. * on the current color mode
  3720. * @param {Number|Constant} max3 range for the blue or brightness depending
  3721. * on the current color mode
  3722. * @param {Number|Constant} maxA range for the alpha
  3723. * @example
  3724. * <div>
  3725. * <code>
  3726. * noStroke();
  3727. * colorMode(RGB, 100);
  3728. * for (i = 0; i < 100; i++) {
  3729. * for (j = 0; j < 100; j++) {
  3730. * stroke(i, j, 0);
  3731. * point(i, j);
  3732. * }
  3733. * }
  3734. * </code>
  3735. * </div>
  3736. *
  3737. * <div>
  3738. * <code>
  3739. * noStroke();
  3740. * colorMode(HSB, 100);
  3741. * for (i = 0; i < 100; i++) {
  3742. * for (j = 0; j < 100; j++) {
  3743. * stroke(i, j, 100);
  3744. * point(i, j);
  3745. * }
  3746. * }
  3747. * </code>
  3748. * </div>
  3749. */
  3750. p5.prototype.colorMode = function() {
  3751. if (arguments[0] === constants.RGB ||
  3752. arguments[0] === constants.HSB ||
  3753. arguments[0] === constants.HSL) {
  3754. this._colorMode = arguments[0];
  3755. var maxArr = this._colorMaxes[this._colorMode];
  3756. if (arguments.length === 2) {
  3757. maxArr[0] = arguments[1];
  3758. maxArr[1] = arguments[1];
  3759. maxArr[2] = arguments[1];
  3760. maxArr[3] = arguments[1];
  3761. } else if (arguments.length > 2) {
  3762. maxArr[0] = arguments[1];
  3763. maxArr[1] = arguments[2];
  3764. maxArr[2] = arguments[3];
  3765. }
  3766. if (arguments.length === 5) {
  3767. maxArr[3] = arguments[4];
  3768. }
  3769. }
  3770. return this;
  3771. };
  3772. /**
  3773. * Sets the color used to fill shapes. For example, if you run
  3774. * fill(204, 102, 0), all subsequent shapes will be filled with orange. This
  3775. * color is either specified in terms of the RGB or HSB color depending on
  3776. * the current colorMode(). (The default color space is RGB, with each value
  3777. * in the range from 0 to 255.) If a single string argument is provided, RGB,
  3778. * RGBA and Hex CSS color strings and all named color strings are supported.
  3779. * A p5 Color object can also be provided to set the fill color.
  3780. *
  3781. * @method fill
  3782. * @param {Number|Array|String|p5.Color} v1 gray value, red or hue value
  3783. * (depending on the current color
  3784. * mode), or color Array, or CSS
  3785. * color string
  3786. * @param {Number} [v2] green or saturation value
  3787. * (depending on the current
  3788. * color mode)
  3789. * @param {Number} [v3] blue or brightness value
  3790. * (depending on the current
  3791. * color mode)
  3792. * @param {Number} [a] opacity of the background
  3793. *
  3794. * @example
  3795. * <div>
  3796. * <code>
  3797. * // Grayscale integer value
  3798. * fill(51);
  3799. * rect(20, 20, 60, 60);
  3800. * </code>
  3801. * </div>
  3802. *
  3803. * <div>
  3804. * <code>
  3805. * // R, G & B integer values
  3806. * fill(255, 204, 0);
  3807. * rect(20, 20, 60, 60);
  3808. * </code>
  3809. * </div>
  3810. *
  3811. * <div>
  3812. * <code>
  3813. * // H, S & B integer values
  3814. * colorMode(HSB);
  3815. * fill(255, 204, 100);
  3816. * rect(20, 20, 60, 60);
  3817. * </code>
  3818. * </div>
  3819. *
  3820. * <div>
  3821. * <code>
  3822. * // Named SVG/CSS color string
  3823. * fill('red');
  3824. * rect(20, 20, 60, 60);
  3825. * </code>
  3826. * </div>
  3827. *
  3828. * <div>
  3829. * <code>
  3830. * // three-digit hexadecimal RGB notation
  3831. * fill('#fae');
  3832. * rect(20, 20, 60, 60);
  3833. * </code>
  3834. * </div>
  3835. *
  3836. * <div>
  3837. * <code>
  3838. * // six-digit hexadecimal RGB notation
  3839. * fill('#222222');
  3840. * rect(20, 20, 60, 60);
  3841. * </code>
  3842. * </div>
  3843. *
  3844. * <div>
  3845. * <code>
  3846. * // integer RGB notation
  3847. * fill('rgb(0,255,0)');
  3848. * rect(20, 20, 60, 60);
  3849. * </code>
  3850. * </div>
  3851. *
  3852. * <div>
  3853. * <code>
  3854. * // integer RGBA notation
  3855. * fill('rgba(0,255,0, 0.25)');
  3856. * rect(20, 20, 60, 60);
  3857. * </code>
  3858. * </div>
  3859. *
  3860. * <div>
  3861. * <code>
  3862. * // percentage RGB notation
  3863. * fill('rgb(100%,0%,10%)');
  3864. * rect(20, 20, 60, 60);
  3865. * </code>
  3866. * </div>
  3867. *
  3868. * <div>
  3869. * <code>
  3870. * // percentage RGBA notation
  3871. * fill('rgba(100%,0%,100%,0.5)');
  3872. * rect(20, 20, 60, 60);
  3873. * </code>
  3874. * </div>
  3875. *
  3876. * <div>
  3877. * <code>
  3878. * // p5 Color object
  3879. * fill(color(0, 0, 255));
  3880. * rect(20, 20, 60, 60);
  3881. * </code>
  3882. * </div>
  3883. */
  3884. p5.prototype.fill = function() {
  3885. this._setProperty('_fillSet', true);
  3886. this._setProperty('_doFill', true);
  3887. this._graphics.fill.apply(this._graphics, arguments);
  3888. return this;
  3889. };
  3890. /**
  3891. * Disables filling geometry. If both noStroke() and noFill() are called,
  3892. * nothing will be drawn to the screen.
  3893. *
  3894. * @method noFill
  3895. * @example
  3896. * <div>
  3897. * <code>
  3898. * rect(15, 10, 55, 55);
  3899. * noFill();
  3900. * rect(20, 20, 60, 60);
  3901. * </code>
  3902. * </div>
  3903. */
  3904. p5.prototype.noFill = function() {
  3905. this._setProperty('_doFill', false);
  3906. return this;
  3907. };
  3908. /**
  3909. * Disables drawing the stroke (outline). If both noStroke() and noFill()
  3910. * are called, nothing will be drawn to the screen.
  3911. *
  3912. * @method noStroke
  3913. * @example
  3914. * <div>
  3915. * <code>
  3916. * noStroke();
  3917. * rect(20, 20, 60, 60);
  3918. * </code>
  3919. * </div>
  3920. */
  3921. p5.prototype.noStroke = function() {
  3922. this._setProperty('_doStroke', false);
  3923. return this;
  3924. };
  3925. /**
  3926. * Sets the color used to draw lines and borders around shapes. This color
  3927. * is either specified in terms of the RGB or HSB color depending on the
  3928. * current colorMode() (the default color space is RGB, with each value in
  3929. * the range from 0 to 255). If a single string argument is provided, RGB,
  3930. * RGBA and Hex CSS color strings and all named color strings are supported.
  3931. * A p5 Color object can also be provided to set the stroke color.
  3932. *
  3933. * @method stroke
  3934. * @param {Number|Array|String|p5.Color} v1 gray value, red or hue value
  3935. * (depending on the current color
  3936. * mode), or color Array, or CSS
  3937. * color string
  3938. * @param {Number} [v2] green or saturation value
  3939. * (depending on the current
  3940. * color mode)
  3941. * @param {Number} [v3] blue or brightness value
  3942. * (depending on the current
  3943. * color mode)
  3944. * @param {Number} [a] opacity of the background
  3945. *
  3946. * @example
  3947. * <div>
  3948. * <code>
  3949. * // Grayscale integer value
  3950. * strokeWeight(4);
  3951. * stroke(51);
  3952. * rect(20, 20, 60, 60);
  3953. * </code>
  3954. * </div>
  3955. *
  3956. * <div>
  3957. * <code>
  3958. * // R, G & B integer values
  3959. * stroke(255, 204, 0);
  3960. * strokeWeight(4);
  3961. * rect(20, 20, 60, 60);
  3962. * </code>
  3963. * </div>
  3964. *
  3965. * <div>
  3966. * <code>
  3967. * // H, S & B integer values
  3968. * colorMode(HSB);
  3969. * strokeWeight(4);
  3970. * stroke(255, 204, 100);
  3971. * rect(20, 20, 60, 60);
  3972. * </code>
  3973. * </div>
  3974. *
  3975. * <div>
  3976. * <code>
  3977. * // Named SVG/CSS color string
  3978. * stroke('red');
  3979. * strokeWeight(4);
  3980. * rect(20, 20, 60, 60);
  3981. * </code>
  3982. * </div>
  3983. *
  3984. * <div>
  3985. * <code>
  3986. * // three-digit hexadecimal RGB notation
  3987. * stroke('#fae');
  3988. * strokeWeight(4);
  3989. * rect(20, 20, 60, 60);
  3990. * </code>
  3991. * </div>
  3992. *
  3993. * <div>
  3994. * <code>
  3995. * // six-digit hexadecimal RGB notation
  3996. * stroke('#222222');
  3997. * strokeWeight(4);
  3998. * rect(20, 20, 60, 60);
  3999. * </code>
  4000. * </div>
  4001. *
  4002. * <div>
  4003. * <code>
  4004. * // integer RGB notation
  4005. * stroke('rgb(0,255,0)');
  4006. * strokeWeight(4);
  4007. * rect(20, 20, 60, 60);
  4008. * </code>
  4009. * </div>
  4010. *
  4011. * <div>
  4012. * <code>
  4013. * // integer RGBA notation
  4014. * stroke('rgba(0,255,0,0.25)');
  4015. * strokeWeight(4);
  4016. * rect(20, 20, 60, 60);
  4017. * </code>
  4018. * </div>
  4019. *
  4020. * <div>
  4021. * <code>
  4022. * // percentage RGB notation
  4023. * stroke('rgb(100%,0%,10%)');
  4024. * strokeWeight(4);
  4025. * rect(20, 20, 60, 60);
  4026. * </code>
  4027. * </div>
  4028. *
  4029. * <div>
  4030. * <code>
  4031. * // percentage RGBA notation
  4032. * stroke('rgba(100%,0%,100%,0.5)');
  4033. * strokeWeight(4);
  4034. * rect(20, 20, 60, 60);
  4035. * </code>
  4036. * </div>
  4037. *
  4038. * <div>
  4039. * <code>
  4040. * // p5 Color object
  4041. * stroke(color(0, 0, 255));
  4042. * strokeWeight(4);
  4043. * rect(20, 20, 60, 60);
  4044. * </code>
  4045. * </div>
  4046. */
  4047. p5.prototype.stroke = function() {
  4048. this._setProperty('_strokeSet', true);
  4049. this._setProperty('_doStroke', true);
  4050. this._graphics.stroke.apply(this._graphics, arguments);
  4051. return this;
  4052. };
  4053. module.exports = p5;
  4054. },{"../core/constants":16,"../core/core":17,"./p5.Color":11}],13:[function(require,module,exports){
  4055. /**
  4056. * @module Shape
  4057. * @submodule 2D Primitives
  4058. * @for p5
  4059. * @requires core
  4060. * @requires constants
  4061. */
  4062. 'use strict';
  4063. var p5 = require('./core');
  4064. var constants = require('./constants');
  4065. require('./error_helpers');
  4066. /**
  4067. * Draw an arc to the screen. If called with only a, b, c, d, start, and
  4068. * stop, the arc will pe drawn as an open pie. If mode is provided, the arc
  4069. * will be drawn either open, as a chord, or as a pie as specified. The
  4070. * origin may be changed with the ellipseMode() function.
  4071. *
  4072. * @method arc
  4073. * @param {Number} a x-coordinate of the arc's ellipse
  4074. * @param {Number} b y-coordinate of the arc's ellipse
  4075. * @param {Number} c width of the arc's ellipse by default
  4076. * @param {Number} d height of the arc's ellipse by default
  4077. * @param {Number} start angle to start the arc, specified in radians
  4078. * @param {Number} stop angle to stop the arc, specified in radians
  4079. * @param {String} [mode] optional parameter to determine the way of drawing
  4080. * the arc
  4081. * @return {Object} the p5 object
  4082. * @example
  4083. * <div>
  4084. * <code>
  4085. * arc(50, 55, 50, 50, 0, HALF_PI);
  4086. * noFill();
  4087. * arc(50, 55, 60, 60, HALF_PI, PI);
  4088. * arc(50, 55, 70, 70, PI, PI+QUARTER_PI);
  4089. * arc(50, 55, 80, 80, PI+QUARTER_PI, TWO_PI);
  4090. * </code>
  4091. * </div>
  4092. *
  4093. * <div>
  4094. * <code>
  4095. * arc(50, 50, 80, 80, 0, PI+QUARTER_PI, OPEN);
  4096. * </code>
  4097. * </div>
  4098. *
  4099. * <div>
  4100. * <code>
  4101. * arc(50, 50, 80, 80, 0, PI+QUARTER_PI, CHORD);
  4102. * </code>
  4103. * </div>
  4104. *
  4105. * <div>
  4106. * <code>
  4107. * arc(50, 50, 80, 80, 0, PI+QUARTER_PI, PIE);
  4108. * </code>
  4109. * </div>
  4110. */
  4111. p5.prototype.arc = function(x, y, w, h, start, stop, mode) {
  4112. this._validateParameters(
  4113. 'arc',
  4114. arguments,
  4115. [
  4116. ['Number', 'Number', 'Number', 'Number', 'Number', 'Number'],
  4117. [ 'Number', 'Number', 'Number', 'Number',
  4118. 'Number', 'Number', 'String' ]
  4119. ]
  4120. );
  4121. if (!this._doStroke && !this._doFill) {
  4122. return this;
  4123. }
  4124. if (this._angleMode === constants.DEGREES) {
  4125. start = this.radians(start);
  4126. stop = this.radians(stop);
  4127. }
  4128. // Make all angles positive...
  4129. while (start < 0) {
  4130. start += constants.TWO_PI;
  4131. }
  4132. while (stop < 0) {
  4133. stop += constants.TWO_PI;
  4134. }
  4135. // ...and confine them to the interval [0,TWO_PI).
  4136. start %= constants.TWO_PI;
  4137. stop %= constants.TWO_PI;
  4138. // Adjust angles to counter linear scaling.
  4139. if (start <= constants.HALF_PI) {
  4140. start = Math.atan(w / h * Math.tan(start));
  4141. } else if (start > constants.HALF_PI && start <= 3 * constants.HALF_PI) {
  4142. start = Math.atan(w / h * Math.tan(start)) + constants.PI;
  4143. } else {
  4144. start = Math.atan(w / h * Math.tan(start)) + constants.TWO_PI;
  4145. }
  4146. if (stop <= constants.HALF_PI) {
  4147. stop = Math.atan(w / h * Math.tan(stop));
  4148. } else if (stop > constants.HALF_PI && stop <= 3 * constants.HALF_PI) {
  4149. stop = Math.atan(w / h * Math.tan(stop)) + constants.PI;
  4150. } else {
  4151. stop = Math.atan(w / h * Math.tan(stop)) + constants.TWO_PI;
  4152. }
  4153. // Exceed the interval if necessary in order to preserve the size and
  4154. // orientation of the arc.
  4155. if (start > stop) {
  4156. stop += constants.TWO_PI;
  4157. }
  4158. // p5 supports negative width and heights for ellipses
  4159. w = Math.abs(w);
  4160. h = Math.abs(h);
  4161. this._graphics.arc(x, y, w, h, start, stop, mode);
  4162. return this;
  4163. };
  4164. /**
  4165. * Draws an ellipse (oval) to the screen. An ellipse with equal width and
  4166. * height is a circle. By default, the first two parameters set the location,
  4167. * and the third and fourth parameters set the shape's width and height. The
  4168. * origin may be changed with the ellipseMode() function.
  4169. *
  4170. * @method ellipse
  4171. * @param {Number} a x-coordinate of the ellipse.
  4172. * @param {Number} b y-coordinate of the ellipse.
  4173. * @param {Number} c width of the ellipse.
  4174. * @param {Number} d height of the ellipse.
  4175. * @return {p5} the p5 object
  4176. * @example
  4177. * <div>
  4178. * <code>
  4179. * ellipse(56, 46, 55, 55);
  4180. * </code>
  4181. * </div>
  4182. */
  4183. p5.prototype.ellipse = function(x, y, w, h) {
  4184. this._validateParameters(
  4185. 'ellipse',
  4186. arguments,
  4187. ['Number', 'Number', 'Number', 'Number']
  4188. );
  4189. if (!this._doStroke && !this._doFill) {
  4190. return this;
  4191. }
  4192. // p5 supports negative width and heights for ellipses
  4193. w = Math.abs(w);
  4194. h = Math.abs(h);
  4195. //@TODO add catch block here if this._graphics
  4196. //doesn't have the method implemented yet
  4197. this._graphics.ellipse(x, y, w, h);
  4198. return this;
  4199. };
  4200. /**
  4201. * Draws a line (a direct path between two points) to the screen. The version
  4202. * of line() with four parameters draws the line in 2D. To color a line, use
  4203. * the stroke() function. A line cannot be filled, therefore the fill()
  4204. * function will not affect the color of a line. 2D lines are drawn with a
  4205. * width of one pixel by default, but this can be changed with the
  4206. * strokeWeight() function.
  4207. *
  4208. * @method line
  4209. * @param {Number} x1 the x-coordinate of the first point
  4210. * @param {Number} y1 the y-coordinate of the first point
  4211. * @param {Number} x2 the x-coordinate of the second point
  4212. * @param {Number} y2 the y-coordinate of the second point
  4213. * @return {p5} the p5 object
  4214. * @example
  4215. * <div>
  4216. * <code>
  4217. * line(30, 20, 85, 75);
  4218. * </code>
  4219. * </div>
  4220. *
  4221. * <div>
  4222. * <code>
  4223. * line(30, 20, 85, 20);
  4224. * stroke(126);
  4225. * line(85, 20, 85, 75);
  4226. * stroke(255);
  4227. * line(85, 75, 30, 75);
  4228. * </code>
  4229. * </div>
  4230. */
  4231. ////commented out original
  4232. // p5.prototype.line = function(x1, y1, x2, y2) {
  4233. // if (!this._doStroke) {
  4234. // return this;
  4235. // }
  4236. // if(this._graphics.isP3D){
  4237. // } else {
  4238. // this._graphics.line(x1, y1, x2, y2);
  4239. // }
  4240. // };
  4241. p5.prototype.line = function() {
  4242. this._validateParameters(
  4243. 'line',
  4244. arguments,
  4245. [
  4246. ['Number', 'Number', 'Number', 'Number'],
  4247. ['Number', 'Number', 'Number', 'Number', 'Number', 'Number']
  4248. ]
  4249. );
  4250. if (!this._doStroke) {
  4251. return this;
  4252. }
  4253. //check whether we should draw a 3d line or 2d
  4254. if(this._graphics.isP3D){
  4255. this._graphics.line(arguments[0],
  4256. arguments[1],
  4257. arguments[2],
  4258. arguments[3],
  4259. arguments[4],
  4260. arguments[5]);
  4261. } else {
  4262. this._graphics.line(arguments[0],
  4263. arguments[1],
  4264. arguments[2],
  4265. arguments[3]);
  4266. }
  4267. };
  4268. /**
  4269. * Draws a point, a coordinate in space at the dimension of one pixel.
  4270. * The first parameter is the horizontal value for the point, the second
  4271. * value is the vertical value for the point.
  4272. *
  4273. * @method point
  4274. * @param {Number} x the x-coordinate
  4275. * @param {Number} y the y-coordinate
  4276. * @return {p5} the p5 object
  4277. * @example
  4278. * <div>
  4279. * <code>
  4280. * point(30, 20);
  4281. * point(85, 20);
  4282. * point(85, 75);
  4283. * point(30, 75);
  4284. * </code>
  4285. * </div>
  4286. */
  4287. p5.prototype.point = function(x, y) {
  4288. this._validateParameters(
  4289. 'point',
  4290. arguments,
  4291. ['Number', 'Number']
  4292. );
  4293. if (!this._doStroke) {
  4294. return this;
  4295. }
  4296. this._graphics.point(x, y);
  4297. return this;
  4298. };
  4299. /**
  4300. * Draw a quad. A quad is a quadrilateral, a four sided polygon. It is
  4301. * similar to a rectangle, but the angles between its edges are not
  4302. * constrained to ninety degrees. The first pair of parameters (x1,y1)
  4303. * sets the first vertex and the subsequent pairs should proceed
  4304. * clockwise or counter-clockwise around the defined shape.
  4305. *
  4306. * @method quad
  4307. * @param {type} x1 the x-coordinate of the first point
  4308. * @param {type} y1 the y-coordinate of the first point
  4309. * @param {type} x2 the x-coordinate of the second point
  4310. * @param {type} y2 the y-coordinate of the second point
  4311. * @param {type} x3 the x-coordinate of the third point
  4312. * @param {type} y3 the y-coordinate of the third point
  4313. * @param {type} x4 the x-coordinate of the fourth point
  4314. * @param {type} y4 the y-coordinate of the fourth point
  4315. * @return {p5} the p5 object
  4316. * @example
  4317. * <div>
  4318. * <code>
  4319. * quad(38, 31, 86, 20, 69, 63, 30, 76);
  4320. * </code>
  4321. * </div>
  4322. */
  4323. p5.prototype.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) {
  4324. this._validateParameters(
  4325. 'quad',
  4326. arguments,
  4327. [ 'Number', 'Number', 'Number', 'Number',
  4328. 'Number', 'Number', 'Number', 'Number' ]
  4329. );
  4330. if (!this._doStroke && !this._doFill) {
  4331. return this;
  4332. }
  4333. this._graphics.quad(x1, y1, x2, y2, x3, y3, x4, y4);
  4334. return this;
  4335. };
  4336. /**
  4337. * Draws a rectangle to the screen. A rectangle is a four-sided shape with
  4338. * every angle at ninety degrees. By default, the first two parameters set
  4339. * the location of the upper-left corner, the third sets the width, and the
  4340. * fourth sets the height. The way these parameters are interpreted, however,
  4341. * may be changed with the rectMode() function. If provided, the fifth, sixth
  4342. * seventh and eighth parameters, if specified, determine corner radius for
  4343. * the top-right, top-left, lower-right and lower-left corners, respectively.
  4344. * An omitted corner radius parameter is set to the value of the previously
  4345. * specified radius value in the parameter list.
  4346. *
  4347. * @method rect
  4348. * @param {Number} x x-coordinate of the rectangle.
  4349. * @param {Number} y y-coordinate of the rectangle.
  4350. * @param {Number} w width of the rectangle.
  4351. * @param {Number} h height of the rectangle.
  4352. * @param {Number} [tl] optional radius of top-left corner.
  4353. * @param {Number} [tr] optional radius of top-right corner.
  4354. * @param {Number} [br] optional radius of bottom-right corner.
  4355. * @param {Number} [bl] optional radius of bottom-left corner.
  4356. * @return {p5} the p5 object.
  4357. * @example
  4358. * <div>
  4359. * <code>
  4360. * // Draw a rectangle at location (30, 25) with a width and height of 55.
  4361. * rect(30, 20, 55, 55);
  4362. * </code>
  4363. * </div>
  4364. *
  4365. * <div>
  4366. * <code>
  4367. * // Draw a rectangle with rounded corners, each having a radius of 20.
  4368. * rect(30, 20, 55, 55, 20);
  4369. * </code>
  4370. * </div>
  4371. *
  4372. * <div>
  4373. * <code>
  4374. * // Draw a rectangle with rounded corners having the following radii:
  4375. * // top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.
  4376. * rect(30, 20, 55, 55, 20, 15, 10, 5)
  4377. * </code>
  4378. * </div>
  4379. */
  4380. p5.prototype.rect = function (x, y, w, h, tl, tr, br, bl) {
  4381. this._validateParameters(
  4382. 'rect',
  4383. arguments,
  4384. [
  4385. ['Number', 'Number', 'Number', 'Number'],
  4386. ['Number', 'Number', 'Number', 'Number', 'Number'],
  4387. [ 'Number', 'Number', 'Number', 'Number',
  4388. 'Number', 'Number', 'Number', 'Number', 'Number' ]
  4389. ]
  4390. );
  4391. if (!this._doStroke && !this._doFill) {
  4392. return;
  4393. }
  4394. this._graphics.rect(x, y, w, h, tl, tr, br, bl);
  4395. return this;
  4396. };
  4397. /**
  4398. * A triangle is a plane created by connecting three points. The first two
  4399. * arguments specify the first point, the middle two arguments specify the
  4400. * second point, and the last two arguments specify the third point.
  4401. *
  4402. * @method triangle
  4403. * @param {Number} x1 x-coordinate of the first point
  4404. * @param {Number} y1 y-coordinate of the first point
  4405. * @param {Number} x2 x-coordinate of the second point
  4406. * @param {Number} y2 y-coordinate of the second point
  4407. * @param {Number} x3 x-coordinate of the third point
  4408. * @param {Number} y3 y-coordinate of the third point
  4409. * @return {p5} the p5 object
  4410. * @example
  4411. * <div>
  4412. * <code>
  4413. * triangle(30, 75, 58, 20, 86, 75);
  4414. * </code>
  4415. * </div>
  4416. */
  4417. p5.prototype.triangle = function(x1, y1, x2, y2, x3, y3) {
  4418. this._validateParameters(
  4419. 'triangle',
  4420. arguments,
  4421. ['Number', 'Number', 'Number', 'Number', 'Number', 'Number']
  4422. );
  4423. if (!this._doStroke && !this._doFill) {
  4424. return this;
  4425. }
  4426. this._graphics.triangle(x1, y1, x2, y2, x3, y3);
  4427. return this;
  4428. };
  4429. module.exports = p5;
  4430. },{"./constants":16,"./core":17,"./error_helpers":20}],14:[function(require,module,exports){
  4431. /**
  4432. * @module Shape
  4433. * @submodule Attributes
  4434. * @for p5
  4435. * @requires core
  4436. * @requires constants
  4437. */
  4438. 'use strict';
  4439. var p5 = require('./core');
  4440. var constants = require('./constants');
  4441. p5.prototype._rectMode = constants.CORNER;
  4442. p5.prototype._ellipseMode = constants.CENTER;
  4443. /**
  4444. * Modifies the location from which ellipses are drawn by changing the way
  4445. * in which parameters given to ellipse() are interpreted.
  4446. *
  4447. * The default mode is ellipseMode(CENTER), which interprets the first two
  4448. * parameters of ellipse() as the shape's center point, while the third and
  4449. * fourth parameters are its width and height.
  4450. *
  4451. * ellipseMode(RADIUS) also uses the first two parameters of ellipse() as
  4452. * the shape's center point, but uses the third and fourth parameters to
  4453. * specify half of the shapes's width and height.
  4454. *
  4455. * ellipseMode(CORNER) interprets the first two parameters of ellipse() as
  4456. * the upper-left corner of the shape, while the third and fourth parameters
  4457. * are its width and height.
  4458. *
  4459. * ellipseMode(CORNERS) interprets the first two parameters of ellipse() as
  4460. * the location of one corner of the ellipse's bounding box, and the third
  4461. * and fourth parameters as the location of the opposite corner.
  4462. *
  4463. * The parameter must be written in ALL CAPS because Processing is a
  4464. * case-sensitive language.
  4465. *
  4466. * @method ellipseMode
  4467. * @param {Number/Constant} mode either CENTER, RADIUS, CORNER, or CORNERS
  4468. * @return {p5} the p5 object
  4469. * @example
  4470. * <div>
  4471. * <code>
  4472. * ellipseMode(RADIUS); // Set ellipseMode to RADIUS
  4473. * fill(255); // Set fill to white
  4474. * ellipse(50, 50, 30, 30); // Draw white ellipse using RADIUS mode
  4475. *
  4476. * ellipseMode(CENTER); // Set ellipseMode to CENTER
  4477. * fill(100); // Set fill to gray
  4478. * ellipse(50, 50, 30, 30); // Draw gray ellipse using CENTER mode
  4479. * </code>
  4480. * </div>
  4481. *
  4482. * <div>
  4483. * <code>
  4484. * ellipseMode(CORNER); // Set ellipseMode is CORNER
  4485. * fill(255); // Set fill to white
  4486. * ellipse(25, 25, 50, 50); // Draw white ellipse using CORNER mode
  4487. *
  4488. * ellipseMode(CORNERS); // Set ellipseMode to CORNERS
  4489. * fill(100); // Set fill to gray
  4490. * ellipse(25, 25, 50, 50); // Draw gray ellipse using CORNERS mode
  4491. * </code>
  4492. * </div>
  4493. */
  4494. p5.prototype.ellipseMode = function(m) {
  4495. if (m === constants.CORNER ||
  4496. m === constants.CORNERS ||
  4497. m === constants.RADIUS ||
  4498. m === constants.CENTER) {
  4499. this._ellipseMode = m;
  4500. }
  4501. return this;
  4502. };
  4503. /**
  4504. * Draws all geometry with jagged (aliased) edges. Note that smooth() is
  4505. * active by default, so it is necessary to call noSmooth() to disable
  4506. * smoothing of geometry, images, and fonts.
  4507. *
  4508. * @method noSmooth
  4509. * @return {p5} the p5 object
  4510. * @example
  4511. * <div>
  4512. * <code>
  4513. * background(0);
  4514. * noStroke();
  4515. * smooth();
  4516. * ellipse(30, 48, 36, 36);
  4517. * noSmooth();
  4518. * ellipse(70, 48, 36, 36);
  4519. * </code>
  4520. * </div>
  4521. */
  4522. p5.prototype.noSmooth = function() {
  4523. this._graphics.noSmooth();
  4524. return this;
  4525. };
  4526. /**
  4527. * Modifies the location from which rectangles are drawn by changing the way
  4528. * in which parameters given to rect() are interpreted.
  4529. *
  4530. * The default mode is rectMode(CORNER), which interprets the first two
  4531. * parameters of rect() as the upper-left corner of the shape, while the
  4532. * third and fourth parameters are its width and height.
  4533. *
  4534. * rectMode(CORNERS) interprets the first two parameters of rect() as the
  4535. * location of one corner, and the third and fourth parameters as the
  4536. * location of the opposite corner.
  4537. *
  4538. * rectMode(CENTER) interprets the first two parameters of rect() as the
  4539. * shape's center point, while the third and fourth parameters are its
  4540. * width and height.
  4541. *
  4542. * rectMode(RADIUS) also uses the first two parameters of rect() as the
  4543. * shape's center point, but uses the third and fourth parameters to specify
  4544. * half of the shapes's width and height.
  4545. *
  4546. * The parameter must be written in ALL CAPS because Processing is a
  4547. * case-sensitive language.
  4548. *
  4549. * @method rectMode
  4550. * @param {Number/Constant} mode either CORNER, CORNERS, CENTER, or RADIUS
  4551. * @return {p5} the p5 object
  4552. * @example
  4553. * <div>
  4554. * <code>
  4555. * rectMode(CORNER); // Default rectMode is CORNER
  4556. * fill(255); // Set fill to white
  4557. * rect(25, 25, 50, 50); // Draw white rect using CORNER mode
  4558. *
  4559. * rectMode(CORNERS); // Set rectMode to CORNERS
  4560. * fill(100); // Set fill to gray
  4561. * rect(25, 25, 50, 50); // Draw gray rect using CORNERS mode
  4562. * </code>
  4563. * </div>
  4564. *
  4565. * <div>
  4566. * <code>
  4567. * rectMode(RADIUS); // Set rectMode to RADIUS
  4568. * fill(255); // Set fill to white
  4569. * rect(50, 50, 30, 30); // Draw white rect using RADIUS mode
  4570. *
  4571. * rectMode(CENTER); // Set rectMode to CENTER
  4572. * fill(100); // Set fill to gray
  4573. * rect(50, 50, 30, 30); // Draw gray rect using CENTER mode
  4574. * </code>
  4575. * </div>
  4576. */
  4577. p5.prototype.rectMode = function(m) {
  4578. if (m === constants.CORNER ||
  4579. m === constants.CORNERS ||
  4580. m === constants.RADIUS ||
  4581. m === constants.CENTER) {
  4582. this._rectMode = m;
  4583. }
  4584. return this;
  4585. };
  4586. /**
  4587. * Draws all geometry with smooth (anti-aliased) edges. smooth() will also
  4588. * improve image quality of resized images. Note that smooth() is active by
  4589. * default; noSmooth() can be used to disable smoothing of geometry,
  4590. * images, and fonts.
  4591. *
  4592. * @method smooth
  4593. * @return {p5} the p5 object
  4594. * @example
  4595. * <div>
  4596. * <code>
  4597. * background(0);
  4598. * noStroke();
  4599. * smooth();
  4600. * ellipse(30, 48, 36, 36);
  4601. * noSmooth();
  4602. * ellipse(70, 48, 36, 36);
  4603. * </code>
  4604. * </div>
  4605. */
  4606. p5.prototype.smooth = function() {
  4607. this._graphics.smooth();
  4608. return this;
  4609. };
  4610. /**
  4611. * Sets the style for rendering line endings. These ends are either squared,
  4612. * extended, or rounded, each of which specified with the corresponding
  4613. * parameters: SQUARE, PROJECT, and ROUND. The default cap is ROUND.
  4614. *
  4615. * @method strokeCap
  4616. * @param {Number/Constant} cap either SQUARE, PROJECT, or ROUND
  4617. * @return {p5} the p5 object
  4618. * @example
  4619. * <div>
  4620. * <code>
  4621. * strokeWeight(12.0);
  4622. * strokeCap(ROUND);
  4623. * line(20, 30, 80, 30);
  4624. * strokeCap(SQUARE);
  4625. * line(20, 50, 80, 50);
  4626. * strokeCap(PROJECT);
  4627. * line(20, 70, 80, 70);
  4628. * </code>
  4629. * </div>
  4630. */
  4631. p5.prototype.strokeCap = function(cap) {
  4632. if (cap === constants.ROUND ||
  4633. cap === constants.SQUARE ||
  4634. cap === constants.PROJECT) {
  4635. this._graphics.strokeCap(cap);
  4636. }
  4637. return this;
  4638. };
  4639. /**
  4640. * Sets the style of the joints which connect line segments. These joints
  4641. * are either mitered, beveled, or rounded and specified with the
  4642. * corresponding parameters MITER, BEVEL, and ROUND. The default joint is
  4643. * MITER.
  4644. *
  4645. * @method strokeJoin
  4646. * @param {Number/Constant} join either MITER, BEVEL, ROUND
  4647. * @return {p5} the p5 object
  4648. * @example
  4649. * <div>
  4650. * <code>
  4651. * noFill();
  4652. * strokeWeight(10.0);
  4653. * strokeJoin(MITER);
  4654. * beginShape();
  4655. * vertex(35, 20);
  4656. * vertex(65, 50);
  4657. * vertex(35, 80);
  4658. * endShape();
  4659. * </code>
  4660. * </div>
  4661. *
  4662. * <div>
  4663. * <code>
  4664. * noFill();
  4665. * strokeWeight(10.0);
  4666. * strokeJoin(BEVEL);
  4667. * beginShape();
  4668. * vertex(35, 20);
  4669. * vertex(65, 50);
  4670. * vertex(35, 80);
  4671. * endShape();
  4672. * </code>
  4673. * </div>
  4674. *
  4675. * <div>
  4676. * <code>
  4677. * noFill();
  4678. * strokeWeight(10.0);
  4679. * strokeJoin(ROUND);
  4680. * beginShape();
  4681. * vertex(35, 20);
  4682. * vertex(65, 50);
  4683. * vertex(35, 80);
  4684. * endShape();
  4685. * </code>
  4686. * </div>
  4687. */
  4688. p5.prototype.strokeJoin = function(join) {
  4689. if (join === constants.ROUND ||
  4690. join === constants.BEVEL ||
  4691. join === constants.MITER) {
  4692. this._graphics.strokeJoin(join);
  4693. }
  4694. return this;
  4695. };
  4696. /**
  4697. * Sets the width of the stroke used for lines, points, and the border
  4698. * around shapes. All widths are set in units of pixels.
  4699. *
  4700. * @method strokeWeight
  4701. * @param {Number} weight the weight (in pixels) of the stroke
  4702. * @return {p5} the p5 object
  4703. * @example
  4704. * <div>
  4705. * <code>
  4706. * strokeWeight(1); // Default
  4707. * line(20, 20, 80, 20);
  4708. * strokeWeight(4); // Thicker
  4709. * line(20, 40, 80, 40);
  4710. * strokeWeight(10); // Beastly
  4711. * line(20, 70, 80, 70);
  4712. * </code>
  4713. * </div>
  4714. */
  4715. p5.prototype.strokeWeight = function(w) {
  4716. this._graphics.strokeWeight(w);
  4717. return this;
  4718. };
  4719. module.exports = p5;
  4720. },{"./constants":16,"./core":17}],15:[function(require,module,exports){
  4721. /**
  4722. * @requires constants
  4723. */
  4724. var constants = require('./constants');
  4725. module.exports = {
  4726. modeAdjust: function(a, b, c, d, mode) {
  4727. if (mode === constants.CORNER) {
  4728. return { x: a, y: b, w: c, h: d };
  4729. } else if (mode === constants.CORNERS) {
  4730. return { x: a, y: b, w: c-a, h: d-b };
  4731. } else if (mode === constants.RADIUS) {
  4732. return { x: a-c, y: b-d, w: 2*c, h: 2*d };
  4733. } else if (mode === constants.CENTER) {
  4734. return { x: a-c*0.5, y: b-d*0.5, w: c, h: d };
  4735. }
  4736. },
  4737. arcModeAdjust: function(a, b, c, d, mode) {
  4738. if (mode === constants.CORNER) {
  4739. return { x: a+c*0.5, y: b+d*0.5, w: c, h: d };
  4740. } else if (mode === constants.CORNERS) {
  4741. return { x: a, y: b, w: c+a, h: d+b };
  4742. } else if (mode === constants.RADIUS) {
  4743. return { x: a, y: b, w: 2*c, h: 2*d };
  4744. } else if (mode === constants.CENTER) {
  4745. return { x: a, y: b, w: c, h: d };
  4746. }
  4747. }
  4748. };
  4749. },{"./constants":16}],16:[function(require,module,exports){
  4750. /**
  4751. * @module Constants
  4752. * @submodule Constants
  4753. * @for p5
  4754. */
  4755. var PI = Math.PI;
  4756. module.exports = {
  4757. // GRAPHICS RENDERER
  4758. P2D: 'p2d',
  4759. WEBGL: 'webgl',
  4760. // ENVIRONMENT
  4761. ARROW: 'default',
  4762. CROSS: 'crosshair',
  4763. HAND: 'pointer',
  4764. MOVE: 'move',
  4765. TEXT: 'text',
  4766. WAIT: 'wait',
  4767. // TRIGONOMETRY
  4768. /**
  4769. * HALF_PI is a mathematical constant with the value
  4770. * 1.57079632679489661923. It is half the ratio of the
  4771. * circumference of a circle to its diameter. It is useful in
  4772. * combination with the trigonometric functions sin() and cos().
  4773. *
  4774. * @property HALF_PI
  4775. *
  4776. * @example
  4777. * <div><code>
  4778. * arc(50, 50, 80, 80, 0, HALF_PI);
  4779. * </code></div>
  4780. *
  4781. */
  4782. HALF_PI: PI / 2,
  4783. /**
  4784. * PI is a mathematical constant with the value
  4785. * 3.14159265358979323846. It is the ratio of the circumference
  4786. * of a circle to its diameter. It is useful in combination with
  4787. * the trigonometric functions sin() and cos().
  4788. *
  4789. * @property PI
  4790. *
  4791. * @example
  4792. * <div><code>
  4793. * arc(50, 50, 80, 80, 0, PI);
  4794. * </code></div>
  4795. */
  4796. PI: PI,
  4797. /**
  4798. * QUARTER_PI is a mathematical constant with the value 0.7853982.
  4799. * It is one quarter the ratio of the circumference of a circle to
  4800. * its diameter. It is useful in combination with the trigonometric
  4801. * functions sin() and cos().
  4802. *
  4803. * @property QUARTER_PI
  4804. *
  4805. * @example
  4806. * <div><code>
  4807. * arc(50, 50, 80, 80, 0, QUARTER_PI);
  4808. * </code></div>
  4809. *
  4810. */
  4811. QUARTER_PI: PI / 4,
  4812. /**
  4813. * TAU is an alias for TWO_PI, a mathematical constant with the
  4814. * value 6.28318530717958647693. It is twice the ratio of the
  4815. * circumference of a circle to its diameter. It is useful in
  4816. * combination with the trigonometric functions sin() and cos().
  4817. *
  4818. * @property TAU
  4819. *
  4820. * @example
  4821. * <div><code>
  4822. * arc(50, 50, 80, 80, 0, TAU);
  4823. * </code></div>
  4824. *
  4825. */
  4826. TAU: PI * 2,
  4827. /**
  4828. * TWO_PI is a mathematical constant with the value
  4829. * 6.28318530717958647693. It is twice the ratio of the
  4830. * circumference of a circle to its diameter. It is useful in
  4831. * combination with the trigonometric functions sin() and cos().
  4832. *
  4833. * @property TWO_PI
  4834. *
  4835. * @example
  4836. * <div><code>
  4837. * arc(50, 50, 80, 80, 0, TWO_PI);
  4838. * </code></div>
  4839. *
  4840. */
  4841. TWO_PI: PI * 2,
  4842. DEGREES: 'degrees',
  4843. RADIANS: 'radians',
  4844. // SHAPE
  4845. CORNER: 'corner',
  4846. CORNERS: 'corners',
  4847. RADIUS: 'radius',
  4848. RIGHT: 'right',
  4849. LEFT: 'left',
  4850. CENTER: 'center',
  4851. TOP: 'top',
  4852. BOTTOM: 'bottom',
  4853. BASELINE: 'alphabetic',
  4854. POINTS: 'points',
  4855. LINES: 'lines',
  4856. TRIANGLES: 'triangles',
  4857. TRIANGLE_FAN: 'triangles_fan',
  4858. TRIANGLE_STRIP: 'triangles_strip',
  4859. QUADS: 'quads',
  4860. QUAD_STRIP: 'quad_strip',
  4861. CLOSE: 'close',
  4862. OPEN: 'open',
  4863. CHORD: 'chord',
  4864. PIE: 'pie',
  4865. PROJECT: 'square', // PEND: careful this is counterintuitive
  4866. SQUARE: 'butt',
  4867. ROUND: 'round',
  4868. BEVEL: 'bevel',
  4869. MITER: 'miter',
  4870. // COLOR
  4871. RGB: 'rgb',
  4872. HSB: 'hsb',
  4873. HSL: 'hsl',
  4874. // DOM EXTENSION
  4875. AUTO: 'auto',
  4876. // INPUT
  4877. ALT: 18,
  4878. BACKSPACE: 8,
  4879. CONTROL: 17,
  4880. DELETE: 46,
  4881. DOWN_ARROW: 40,
  4882. ENTER: 13,
  4883. ESCAPE: 27,
  4884. LEFT_ARROW: 37,
  4885. OPTION: 18,
  4886. RETURN: 13,
  4887. RIGHT_ARROW: 39,
  4888. SHIFT: 16,
  4889. TAB: 9,
  4890. UP_ARROW: 38,
  4891. // RENDERING
  4892. BLEND: 'normal',
  4893. ADD: 'lighter',
  4894. //ADD: 'add', //
  4895. //SUBTRACT: 'subtract', //
  4896. DARKEST: 'darken',
  4897. LIGHTEST: 'lighten',
  4898. DIFFERENCE: 'difference',
  4899. EXCLUSION: 'exclusion',
  4900. MULTIPLY: 'multiply',
  4901. SCREEN: 'screen',
  4902. REPLACE: 'source-over',
  4903. OVERLAY: 'overlay',
  4904. HARD_LIGHT: 'hard-light',
  4905. SOFT_LIGHT: 'soft-light',
  4906. DODGE: 'color-dodge',
  4907. BURN: 'color-burn',
  4908. // FILTERS
  4909. THRESHOLD: 'threshold',
  4910. GRAY: 'gray',
  4911. OPAQUE: 'opaque',
  4912. INVERT: 'invert',
  4913. POSTERIZE: 'posterize',
  4914. DILATE: 'dilate',
  4915. ERODE: 'erode',
  4916. BLUR: 'blur',
  4917. // TYPOGRAPHY
  4918. NORMAL: 'normal',
  4919. ITALIC: 'italic',
  4920. BOLD: 'bold',
  4921. // TYPOGRAPHY-INTERNAL
  4922. _DEFAULT_TEXT_FILL: '#000000',
  4923. _DEFAULT_LEADMULT: 1.25,
  4924. _CTX_MIDDLE: 'middle',
  4925. // VERTICES
  4926. LINEAR: 'linear',
  4927. QUADRATIC: 'quadratic',
  4928. BEZIER: 'bezier',
  4929. CURVE: 'curve',
  4930. // DEFAULTS
  4931. _DEFAULT_STROKE: '#000000',
  4932. _DEFAULT_FILL: '#FFFFFF'
  4933. };
  4934. },{}],17:[function(require,module,exports){
  4935. /**
  4936. * @module Structure
  4937. * @submodule Structure
  4938. * @for p5
  4939. * @requires constants
  4940. */
  4941. 'use strict';
  4942. require('./shim');
  4943. // Core needs the PVariables object
  4944. var constants = require('./constants');
  4945. /**
  4946. * This is the p5 instance constructor.
  4947. *
  4948. * A p5 instance holds all the properties and methods related to
  4949. * a p5 sketch. It expects an incoming sketch closure and it can also
  4950. * take an optional node parameter for attaching the generated p5 canvas
  4951. * to a node. The sketch closure takes the newly created p5 instance as
  4952. * its sole argument and may optionally set preload(), setup(), and/or
  4953. * draw() properties on it for running a sketch.
  4954. *
  4955. * A p5 sketch can run in "global" or "instance" mode:
  4956. * "global" - all properties and methods are attached to the window
  4957. * "instance" - all properties and methods are bound to this p5 object
  4958. *
  4959. * @param {Function} sketch a closure that can set optional preload(),
  4960. * setup(), and/or draw() properties on the
  4961. * given p5 instance
  4962. * @param {HTMLElement|boolean} node element to attach canvas to, if a
  4963. * boolean is passed in use it as sync
  4964. * @param {boolean} [sync] start synchronously (optional)
  4965. * @return {p5} a p5 instance
  4966. */
  4967. var p5 = function(sketch, node, sync) {
  4968. if (arguments.length === 2 && typeof node === 'boolean') {
  4969. sync = node;
  4970. node = undefined;
  4971. }
  4972. //////////////////////////////////////////////
  4973. // PUBLIC p5 PROPERTIES AND METHODS
  4974. //////////////////////////////////////////////
  4975. /**
  4976. * Called directly before setup(), the preload() function is used to handle
  4977. * asynchronous loading of external files. If a preload function is
  4978. * defined, setup() will wait until any load calls within have finished.
  4979. * Nothing besides load calls should be inside preload (loadImage,
  4980. * loadJSON, loadFont, loadStrings, etc).
  4981. *
  4982. * @method preload
  4983. * @example
  4984. * <div><code>
  4985. * var img;
  4986. * var c;
  4987. * function preload() { // preload() runs once
  4988. * img = loadImage('assets/laDefense.jpg');
  4989. * }
  4990. *
  4991. * function setup() { // setup() waits until preload() is done
  4992. * img.loadPixels();
  4993. * // get color of middle pixel
  4994. * c = img.get(img.width/2, img.height/2);
  4995. * }
  4996. *
  4997. * function draw() {
  4998. * background(c);
  4999. * image(img, 25, 25, 50, 50);
  5000. * }
  5001. * </code></div>
  5002. */
  5003. /**
  5004. * The setup() function is called once when the program starts. It's used to
  5005. * define initial environment properties such as screen size and background
  5006. * color and to load media such as images and fonts as the program starts.
  5007. * There can only be one setup() function for each program and it shouldn't
  5008. * be called again after its initial execution. Note: Variables declared
  5009. * within setup() are not accessible within other functions, including
  5010. * draw().
  5011. *
  5012. * @method setup
  5013. * @example
  5014. * <div><code>
  5015. * var a = 0;
  5016. *
  5017. * function setup() {
  5018. * background(0);
  5019. * noStroke();
  5020. * fill(102);
  5021. * }
  5022. *
  5023. * function draw() {
  5024. * rect(a++%width, 10, 2, 80);
  5025. * }
  5026. * </code></div>
  5027. */
  5028. /**
  5029. * Called directly after setup(), the draw() function continuously executes
  5030. * the lines of code contained inside its block until the program is stopped
  5031. * or noLoop() is called. draw() is called automatically and should never be
  5032. * called explicitly.
  5033. *
  5034. * It should always be controlled with noLoop(), redraw() and loop(). After
  5035. * noLoop() stops the code in draw() from executing, redraw() causes the
  5036. * code inside draw() to execute once, and loop() will cause the code
  5037. * inside draw() to resume executing continuously.
  5038. *
  5039. * The number of times draw() executes in each second may be controlled with
  5040. * the frameRate() function.
  5041. *
  5042. * There can only be one draw() function for each sketch, and draw() must
  5043. * exist if you want the code to run continuously, or to process events such
  5044. * as mousePressed(). Sometimes, you might have an empty call to draw() in
  5045. * your program, as shown in the above example.
  5046. *
  5047. * @method draw
  5048. * @example
  5049. * <div><code>
  5050. * var yPos = 0;
  5051. * function setup() { // setup() runs once
  5052. * frameRate(30);
  5053. * }
  5054. * function draw() { // draw() loops forever, until stopped
  5055. * background(204);
  5056. * yPos = yPos - 1;
  5057. * if (yPos < 0) {
  5058. * yPos = height;
  5059. * }
  5060. * line(0, yPos, width, yPos);
  5061. * }
  5062. * </code></div>
  5063. */
  5064. //////////////////////////////////////////////
  5065. // PRIVATE p5 PROPERTIES AND METHODS
  5066. //////////////////////////////////////////////
  5067. this._setupDone = false;
  5068. this.pixelDensity = window.devicePixelRatio || 1; // for handling hidpi
  5069. this._userNode = node;
  5070. this._curElement = null;
  5071. this._elements = [];
  5072. this._preloadCount = 0;
  5073. this._updateInterval = 0;
  5074. this._isGlobal = false;
  5075. this._loop = true;
  5076. this._styles = [];
  5077. this._defaultCanvasSize = {
  5078. width: 100,
  5079. height: 100
  5080. };
  5081. this._events = { // keep track of user-events for unregistering later
  5082. 'mousemove': null,
  5083. 'mousedown': null,
  5084. 'mouseup': null,
  5085. 'click': null,
  5086. 'mouseover': null,
  5087. 'mouseout': null,
  5088. 'keydown': null,
  5089. 'keyup': null,
  5090. 'keypress': null,
  5091. 'touchstart': null,
  5092. 'touchmove': null,
  5093. 'touchend': null,
  5094. 'resize': null,
  5095. 'blur': null
  5096. };
  5097. if (window.DeviceOrientationEvent) {
  5098. this._events.deviceorientation = null;
  5099. } else if (window.DeviceMotionEvent) {
  5100. this._events.devicemotion = null;
  5101. } else {
  5102. this._events.MozOrientation = null;
  5103. }
  5104. //FF doesn't recognize mousewheel as of FF3.x
  5105. if (/Firefox/i.test(navigator.userAgent)) {
  5106. this._events.DOMMouseScroll = null;
  5107. } else {
  5108. this._events.mousewheel = null;
  5109. }
  5110. this._loadingScreenId = 'p5_loading';
  5111. this._start = function () {
  5112. // Find node if id given
  5113. if (this._userNode) {
  5114. if (typeof this._userNode === 'string') {
  5115. this._userNode = document.getElementById(this._userNode);
  5116. }
  5117. }
  5118. // Setup loading screen
  5119. // Set loading scfeen into dom if not present
  5120. // Otherwise displays and removes user provided loading screen
  5121. this._loadingScreen = document.getElementById(this._loadingScreenId);
  5122. if(!this._loadingScreen){
  5123. this._loadingScreen = document.createElement('div');
  5124. this._loadingScreen.innerHTML = 'loading...';
  5125. this._loadingScreen.style.position = 'absolute';
  5126. var node = this._userNode || document.body;
  5127. node.appendChild(this._loadingScreen);
  5128. }
  5129. // Always create a default canvas.
  5130. // Later on if the user calls createCanvas, this default one
  5131. // will be replaced
  5132. this.createCanvas(
  5133. this._defaultCanvasSize.width,
  5134. this._defaultCanvasSize.height,
  5135. 'p2d',
  5136. true
  5137. );
  5138. var userPreload = this.preload || window.preload; // look for "preload"
  5139. var context = this._isGlobal ? window : this;
  5140. if (userPreload) {
  5141. var methods = this._preloadMethods;
  5142. Object.keys(methods).forEach(function(f) {
  5143. context[f] = function() {
  5144. var argsArray = Array.prototype.slice.call(arguments);
  5145. return context._preload(f, methods[f], argsArray);
  5146. };
  5147. });
  5148. userPreload();
  5149. if (this._preloadCount === 0) {
  5150. this._setup();
  5151. this._runFrames();
  5152. this._draw();
  5153. }
  5154. } else {
  5155. this._setup();
  5156. this._runFrames();
  5157. this._draw();
  5158. }
  5159. }.bind(this);
  5160. this._preload = function (func, obj, args) {
  5161. var context = this._isGlobal ? window : this;
  5162. context._setProperty('_preloadCount', context._preloadCount + 1);
  5163. var preloadCallback = function (resp) {
  5164. context._setProperty('_preloadCount', context._preloadCount - 1);
  5165. if (context._preloadCount === 0) {
  5166. context._setup();
  5167. context._runFrames();
  5168. context._draw();
  5169. }
  5170. };
  5171. args.push(preloadCallback);
  5172. return window[obj].prototype[func].apply(context, args);
  5173. }.bind(this);
  5174. this._setup = function() {
  5175. // return preload functions to their normal vals if switched by preload
  5176. var context = this._isGlobal ? window : this;
  5177. if (typeof context.preload === 'function') {
  5178. for (var f in this._preloadMethods) {
  5179. var o = this._preloadMethods[f];
  5180. context[f] = window[o].prototype[f];
  5181. }
  5182. }
  5183. // Short-circuit on this, in case someone used the library in "global"
  5184. // mode earlier
  5185. if (typeof context.setup === 'function') {
  5186. context.setup();
  5187. }
  5188. // // unhide hidden canvas that was created
  5189. // this.canvas.style.visibility = '';
  5190. // this.canvas.className = this.canvas.className.replace('p5_hidden', '');
  5191. // unhide any hidden canvases that were created
  5192. var reg = new RegExp(/(^|\s)p5_hidden(?!\S)/g);
  5193. var canvases = document.getElementsByClassName('p5_hidden');
  5194. for (var i = 0; i < canvases.length; i++) {
  5195. var k = canvases[i];
  5196. k.style.visibility = '';
  5197. k.className = k.className.replace(reg, '');
  5198. }
  5199. this._setupDone = true;
  5200. // Removes the loading screen if it's in the DOM
  5201. this._loadingScreen.parentNode.removeChild(this._loadingScreen);
  5202. }.bind(this);
  5203. this._draw = function () {
  5204. var now = window.performance.now();
  5205. var time_since_last = now - this._lastFrameTime;
  5206. var target_time_between_frames = 1000 / this._targetFrameRate;
  5207. // only draw if we really need to; don't overextend the browser.
  5208. // draw if we're within 5ms of when our next frame should paint
  5209. // (this will prevent us from giving up opportunities to draw
  5210. // again when it's really about time for us to do so). fixes an
  5211. // issue where the frameRate is too low if our refresh loop isn't
  5212. // in sync with the browser. note that we have to draw once even
  5213. // if looping is off, so we bypass the time delay if that
  5214. // is the case.
  5215. var epsilon = 5;
  5216. if (!this.loop ||
  5217. time_since_last >= target_time_between_frames - epsilon) {
  5218. this._setProperty('frameCount', this.frameCount + 1);
  5219. this.redraw();
  5220. this._updatePAccelerations();
  5221. this._updatePMouseCoords();
  5222. this._updatePTouchCoords();
  5223. this._frameRate = 1000.0/(now - this._lastFrameTime);
  5224. this._lastFrameTime = now;
  5225. }
  5226. // get notified the next time the browser gives us
  5227. // an opportunity to draw.
  5228. if (this._loop) {
  5229. window.requestAnimationFrame(this._draw);
  5230. }
  5231. }.bind(this);
  5232. this._runFrames = function() {
  5233. if (this._updateInterval) {
  5234. clearInterval(this._updateInterval);
  5235. }
  5236. }.bind(this);
  5237. this._setProperty = function(prop, value) {
  5238. this[prop] = value;
  5239. if (this._isGlobal) {
  5240. window[prop] = value;
  5241. }
  5242. }.bind(this);
  5243. /**
  5244. * Removes the entire p5 sketch. This will remove the canvas and any
  5245. * elements created by p5.js. It will also stop the draw loop and unbind
  5246. * any properties or methods from the window global scope. It will
  5247. * leave a variable p5 in case you wanted to create a new p5 sketch.
  5248. * If you like, you can set p5 = null to erase it.
  5249. * @method remove
  5250. * @example
  5251. * <div class='norender'><code>
  5252. * function draw() {
  5253. * ellipse(50, 50, 10, 10);
  5254. * }
  5255. *
  5256. * function mousePressed() {
  5257. * remove(); // remove whole sketch on mouse press
  5258. * }
  5259. * </code></div>
  5260. */
  5261. this.remove = function() {
  5262. if (this._curElement) {
  5263. // stop draw
  5264. this._loop = false;
  5265. if (this._updateInterval) {
  5266. clearTimeout(this._updateInterval);
  5267. }
  5268. // unregister events sketch-wide
  5269. for (var ev in this._events) {
  5270. window.removeEventListener(ev, this._events[ev]);
  5271. }
  5272. // remove DOM elements created by p5, and listeners
  5273. for (var i=0; i<this._elements.length; i++) {
  5274. var e = this._elements[i];
  5275. if (e.elt.parentNode) {
  5276. e.elt.parentNode.removeChild(e.elt);
  5277. }
  5278. for (var elt_ev in e._events) {
  5279. e.elt.removeEventListener(elt_ev, e._events[elt_ev]);
  5280. }
  5281. }
  5282. // call any registered remove functions
  5283. var self = this;
  5284. this._registeredMethods.remove.forEach(function (f) {
  5285. if (typeof(f) !== 'undefined') {
  5286. f.call(self);
  5287. }
  5288. });
  5289. // remove window bound properties and methods
  5290. if (this._isGlobal) {
  5291. for (var p in p5.prototype) {
  5292. try {
  5293. delete window[p];
  5294. } catch (x) {
  5295. window[p] = undefined;
  5296. }
  5297. }
  5298. for (var p2 in this) {
  5299. if (this.hasOwnProperty(p2)) {
  5300. try {
  5301. delete window[p2];
  5302. } catch (x) {
  5303. window[p2] = undefined;
  5304. }
  5305. }
  5306. }
  5307. }
  5308. }
  5309. // window.p5 = undefined;
  5310. }.bind(this);
  5311. // attach constants to p5 instance
  5312. for (var k in constants) {
  5313. p5.prototype[k] = constants[k];
  5314. }
  5315. // If the user has created a global setup or draw function,
  5316. // assume "global" mode and make everything global (i.e. on the window)
  5317. if (!sketch) {
  5318. this._isGlobal = true;
  5319. // Loop through methods on the prototype and attach them to the window
  5320. for (var p in p5.prototype) {
  5321. if(typeof p5.prototype[p] === 'function') {
  5322. var ev = p.substring(2);
  5323. if (!this._events.hasOwnProperty(ev)) {
  5324. window[p] = p5.prototype[p].bind(this);
  5325. }
  5326. } else {
  5327. window[p] = p5.prototype[p];
  5328. }
  5329. }
  5330. // Attach its properties to the window
  5331. for (var p2 in this) {
  5332. if (this.hasOwnProperty(p2)) {
  5333. window[p2] = this[p2];
  5334. }
  5335. }
  5336. } else {
  5337. // Else, the user has passed in a sketch closure that may set
  5338. // user-provided 'setup', 'draw', etc. properties on this instance of p5
  5339. sketch(this);
  5340. }
  5341. // Bind events to window (not using container div bc key events don't work)
  5342. for (var e in this._events) {
  5343. var f = this['_on'+e];
  5344. if (f) {
  5345. var m = f.bind(this);
  5346. window.addEventListener(e, m);
  5347. this._events[e] = m;
  5348. }
  5349. }
  5350. var self = this;
  5351. window.addEventListener('focus', function() {
  5352. self._setProperty('focused', true);
  5353. });
  5354. window.addEventListener('blur', function() {
  5355. self._setProperty('focused', false);
  5356. });
  5357. // TODO: ???
  5358. if (sync) {
  5359. this._start();
  5360. } else {
  5361. if (document.readyState === 'complete') {
  5362. this._start();
  5363. } else {
  5364. window.addEventListener('load', this._start.bind(this), false);
  5365. }
  5366. }
  5367. };
  5368. // functions that cause preload to wait
  5369. // more can be added by using registerPreloadMethod(func)
  5370. p5.prototype._preloadMethods = {
  5371. loadJSON: 'p5',
  5372. loadImage: 'p5',
  5373. loadStrings: 'p5',
  5374. loadXML: 'p5',
  5375. loadShape: 'p5',
  5376. loadTable: 'p5',
  5377. loadFont: 'p5'
  5378. };
  5379. p5.prototype._registeredMethods = { pre: [], post: [], remove: [] };
  5380. p5.prototype.registerPreloadMethod = function(f, o) {
  5381. o = o || 'p5';
  5382. if (!p5.prototype._preloadMethods.hasOwnProperty(f)) {
  5383. p5.prototype._preloadMethods[f] = o;
  5384. }
  5385. };
  5386. p5.prototype.registerMethod = function(name, m) {
  5387. if (!p5.prototype._registeredMethods.hasOwnProperty(name)) {
  5388. p5.prototype._registeredMethods[name] = [];
  5389. }
  5390. p5.prototype._registeredMethods[name].push(m);
  5391. };
  5392. module.exports = p5;
  5393. },{"./constants":16,"./shim":26}],18:[function(require,module,exports){
  5394. /**
  5395. * @module Shape
  5396. * @submodule Curves
  5397. * @for p5
  5398. * @requires core
  5399. */
  5400. 'use strict';
  5401. var p5 = require('./core');
  5402. require('./error_helpers');
  5403. var bezierDetail = 20;
  5404. var curveDetail = 20;
  5405. p5.prototype._curveTightness = 0;
  5406. /**
  5407. * Draws a Bezier curve on the screen. These curves are defined by a series
  5408. * of anchor and control points. The first two parameters specify the first
  5409. * anchor point and the last two parameters specify the other anchor point.
  5410. * The middle parameters specify the control points which define the shape
  5411. * of the curve. Bezier curves were developed by French engineer Pierre
  5412. * Bezier.
  5413. *
  5414. * @method bezier
  5415. * @param {Number} x1 x-coordinate for the first anchor point
  5416. * @param {Number} y1 y-coordinate for the first anchor point
  5417. * @param {Number} x2 x-coordinate for the first control point
  5418. * @param {Number} y2 y-coordinate for the first control point
  5419. * @param {Number} x3 x-coordinate for the second control point
  5420. * @param {Number} y3 y-coordinate for the second control point
  5421. * @param {Number} x4 x-coordinate for the second anchor point
  5422. * @param {Number} y4 y-coordinate for the second anchor point
  5423. * @return {Object} the p5 object
  5424. * @example
  5425. * <div>
  5426. * <code>
  5427. * noFill();
  5428. * stroke(255, 102, 0);
  5429. * line(85, 20, 10, 10);
  5430. * line(90, 90, 15, 80);
  5431. * stroke(0, 0, 0);
  5432. * bezier(85, 20, 10, 10, 90, 90, 15, 80);
  5433. * </code>
  5434. * </div>
  5435. */
  5436. p5.prototype.bezier = function(x1, y1, x2, y2, x3, y3, x4, y4) {
  5437. this._validateParameters(
  5438. 'bezier',
  5439. arguments,
  5440. [ 'Number', 'Number', 'Number', 'Number',
  5441. 'Number', 'Number', 'Number', 'Number' ]
  5442. );
  5443. if (!this._doStroke) {
  5444. return this;
  5445. }
  5446. this._graphics.bezier(x1, y1, x2, y2, x3, y3, x4, y4);
  5447. return this;
  5448. };
  5449. /**
  5450. * Sets the resolution at which Beziers display.
  5451. *
  5452. * The default value is 20.
  5453. *
  5454. * @param {Number} detail resolution of the curves
  5455. * @return {Object} the p5 object
  5456. * @example
  5457. * <div>
  5458. * <code>
  5459. * background(204);
  5460. * bezierDetail(50);
  5461. * bezier(85, 20, 10, 10, 90, 90, 15, 80);
  5462. * </code>
  5463. * </div>
  5464. */
  5465. p5.prototype.bezierDetail = function(d) {
  5466. bezierDetail = d;
  5467. return this;
  5468. };
  5469. /**
  5470. * Calculate a point on the Bezier Curve
  5471. *
  5472. * Evaluates the Bezier at point t for points a, b, c, d.
  5473. * The parameter t varies between 0 and 1, a and d are points
  5474. * on the curve, and b and c are the control points.
  5475. * This can be done once with the x coordinates and a second time
  5476. * with the y coordinates to get the location of a bezier curve at t.
  5477. *
  5478. * @method bezierPoint
  5479. * @param {Number} a coordinate of first point on the curve
  5480. * @param {Number} b coordinate of first control point
  5481. * @param {Number} c coordinate of second control point
  5482. * @param {Number} d coordinate of second point on the curve
  5483. * @param {Number} t value between 0 and 1
  5484. * @return {Number} the value of the Bezier at point t
  5485. * @example
  5486. * <div>
  5487. * <code>
  5488. * noFill();
  5489. * bezier(85, 20, 10, 10, 90, 90, 15, 80);
  5490. * fill(255);
  5491. * steps = 10;
  5492. * for (i = 0; i <= steps; i++) {
  5493. * t = i / steps;
  5494. * x = bezierPoint(85, 10, 90, 15, t);
  5495. * y = bezierPoint(20, 10, 90, 80, t);
  5496. * ellipse(x, y, 5, 5);
  5497. * }
  5498. * </code>
  5499. * </div>
  5500. */
  5501. p5.prototype.bezierPoint = function(a, b, c, d, t) {
  5502. var adjustedT = 1-t;
  5503. return Math.pow(adjustedT,3)*a +
  5504. 3*(Math.pow(adjustedT,2))*t*b +
  5505. 3*adjustedT*Math.pow(t,2)*c +
  5506. Math.pow(t,3)*d;
  5507. };
  5508. /**
  5509. * Calculates the tangent of a point on a Bezier curve
  5510. *
  5511. * Evaluates the tangent at point t for points a, b, c, d.
  5512. * The parameter t varies between 0 and 1, a and d are points
  5513. * on the curve, and b and c are the control points
  5514. *
  5515. * @method bezierTangent
  5516. * @param {Number} a coordinate of first point on the curve
  5517. * @param {Number} b coordinate of first control point
  5518. * @param {Number} c coordinate of second control point
  5519. * @param {Number} d coordinate of second point on the curve
  5520. * @param {Number} t value between 0 and 1
  5521. * @return {Number} the tangent at point t
  5522. * @example
  5523. * <div>
  5524. * <code>
  5525. * noFill();
  5526. * bezier(85, 20, 10, 10, 90, 90, 15, 80);
  5527. * steps = 6;
  5528. * fill(255);
  5529. * for (i = 0; i <= steps; i++) {
  5530. * t = i / steps;
  5531. * // Get the location of the point
  5532. * x = bezierPoint(85, 10, 90, 15, t);
  5533. * y = bezierPoint(20, 10, 90, 80, t);
  5534. * // Get the tangent points
  5535. * tx = bezierTangent(85, 10, 90, 15, t);
  5536. * ty = bezierTangent(20, 10, 90, 80, t);
  5537. * // Calculate an angle from the tangent points
  5538. * a = atan2(ty, tx);
  5539. * a += PI;
  5540. * stroke(255, 102, 0);
  5541. * line(x, y, cos(a)*30 + x, sin(a)*30 + y);
  5542. * // The following line of code makes a line
  5543. * // inverse of the above line
  5544. * //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);
  5545. * stroke(0);
  5546. * ellipse(x, y, 5, 5);
  5547. * }
  5548. * </code>
  5549. * </div>
  5550. *
  5551. * <div>
  5552. * <code>
  5553. * noFill();
  5554. * bezier(85, 20, 10, 10, 90, 90, 15, 80);
  5555. * stroke(255, 102, 0);
  5556. * steps = 16;
  5557. * for (i = 0; i <= steps; i++) {
  5558. * t = i / steps;
  5559. * x = bezierPoint(85, 10, 90, 15, t);
  5560. * y = bezierPoint(20, 10, 90, 80, t);
  5561. * tx = bezierTangent(85, 10, 90, 15, t);
  5562. * ty = bezierTangent(20, 10, 90, 80, t);
  5563. * a = atan2(ty, tx);
  5564. * a -= HALF_PI;
  5565. * line(x, y, cos(a)*8 + x, sin(a)*8 + y);
  5566. * }
  5567. * </code>
  5568. * </div>
  5569. */
  5570. p5.prototype.bezierTangent = function(a, b, c, d, t) {
  5571. var adjustedT = 1-t;
  5572. return 3*d*Math.pow(t,2) -
  5573. 3*c*Math.pow(t,2) +
  5574. 6*c*adjustedT*t -
  5575. 6*b*adjustedT*t +
  5576. 3*b*Math.pow(adjustedT,2) -
  5577. 3*a*Math.pow(adjustedT,2);
  5578. };
  5579. /**
  5580. * Draws a curved line on the screen. The first and second parameters specify
  5581. * the beginning control point and the last two parameters specify the ending
  5582. * control point. The middle parameters specify the start and stop of the
  5583. * curve. Longer curves can be created by putting a series of curve()
  5584. * functions together or using curveVertex(). An additional function called
  5585. * curveTightness() provides control for the visual quality of the curve.
  5586. * The curve() function is an implementation of Catmull-Rom splines.
  5587. *
  5588. * @method curve
  5589. * @param {Number} x1 x-coordinate for the beginning control point
  5590. * @param {Number} y1 y-coordinate for the beginning control point
  5591. * @param {Number} x2 x-coordinate for the first point
  5592. * @param {Number} y2 y-coordinate for the first point
  5593. * @param {Number} x3 x-coordinate for the second point
  5594. * @param {Number} y3 y-coordinate for the second point
  5595. * @param {Number} x4 x-coordinate for the ending control point
  5596. * @param {Number} y4 y-coordinate for the ending control point
  5597. * @return {Object} the p5 object
  5598. * @example
  5599. * <div>
  5600. * <code>
  5601. * noFill();
  5602. * stroke(255, 102, 0);
  5603. * curve(5, 26, 5, 26, 73, 24, 73, 61);
  5604. * stroke(0);
  5605. * curve(5, 26, 73, 24, 73, 61, 15, 65);
  5606. * stroke(255, 102, 0);
  5607. * curve(73, 24, 73, 61, 15, 65, 15, 65);
  5608. * </code>
  5609. * </div>
  5610. */
  5611. p5.prototype.curve = function(x1, y1, x2, y2, x3, y3, x4, y4) {
  5612. this._validateParameters(
  5613. 'curve',
  5614. arguments,
  5615. [ 'Number', 'Number', 'Number', 'Number',
  5616. 'Number', 'Number', 'Number', 'Number' ]
  5617. );
  5618. if (!this._doStroke) {
  5619. return;
  5620. }
  5621. this._graphics.curve(x1, y1, x2, y2, x3, y3, x4, y4);
  5622. return this;
  5623. };
  5624. /**
  5625. * Sets the resolution at which curves display.
  5626. *
  5627. * The default value is 20.
  5628. *
  5629. * @param {Number} resolution of the curves
  5630. * @return {Object} the p5 object
  5631. * @example
  5632. * <div>
  5633. * <code>
  5634. * background(204);
  5635. * curveDetail(20);
  5636. * curve(5, 26, 5, 26, 73, 24, 73, 61);
  5637. * </code>
  5638. * </div>
  5639. */
  5640. p5.prototype.curveDetail = function(d) {
  5641. curveDetail = d;
  5642. return this;
  5643. };
  5644. /**
  5645. * Modifies the quality of forms created with curve() and curveVertex().
  5646. * The parameter tightness determines how the curve fits to the vertex
  5647. * points. The value 0.0 is the default value for tightness (this value
  5648. * defines the curves to be Catmull-Rom splines) and the value 1.0 connects
  5649. * all the points with straight lines. Values within the range -5.0 and 5.0
  5650. * will deform the curves but will leave them recognizable and as values
  5651. * increase in magnitude, they will continue to deform.
  5652. *
  5653. * @method curveTightness
  5654. * @param {Number} amount of deformation from the original vertices
  5655. * @return {Object} the p5 object
  5656. * @example
  5657. * <div>
  5658. * <code>
  5659. * // Move the mouse left and right to see the curve change
  5660. *
  5661. * function setup() {
  5662. * createCanvas(100, 100);
  5663. * noFill();
  5664. * }
  5665. *
  5666. * function draw() {
  5667. * background(204);
  5668. * var t = map(mouseX, 0, width, -5, 5);
  5669. * curveTightness(t);
  5670. * beginShape();
  5671. * curveVertex(10, 26);
  5672. * curveVertex(10, 26);
  5673. * curveVertex(83, 24);
  5674. * curveVertex(83, 61);
  5675. * curveVertex(25, 65);
  5676. * curveVertex(25, 65);
  5677. * endShape();
  5678. * }
  5679. * </code>
  5680. * </div>
  5681. */
  5682. p5.prototype.curveTightness = function (t) {
  5683. this._setProperty('_curveTightness', t);
  5684. };
  5685. /**
  5686. * Calculate a point on the Curve
  5687. *
  5688. * Evaluates the Bezier at point t for points a, b, c, d.
  5689. * The parameter t varies between 0 and 1, a and d are points
  5690. * on the curve, and b and c are the control points.
  5691. * This can be done once with the x coordinates and a second time
  5692. * with the y coordinates to get the location of a curve at t.
  5693. *
  5694. * @method curvePoint
  5695. * @param {Number} a coordinate of first point on the curve
  5696. * @param {Number} b coordinate of first control point
  5697. * @param {Number} c coordinate of second control point
  5698. * @param {Number} d coordinate of second point on the curve
  5699. * @param {Number} t value between 0 and 1
  5700. * @return {Number} bezier value at point t
  5701. * @example
  5702. * <div>
  5703. * <code>
  5704. * noFill();
  5705. * curve(5, 26, 5, 26, 73, 24, 73, 61);
  5706. * curve(5, 26, 73, 24, 73, 61, 15, 65);
  5707. * fill(255);
  5708. * ellipseMode(CENTER);
  5709. * steps = 6;
  5710. * for (i = 0; i <= steps; i++) {
  5711. * t = i / steps;
  5712. * x = curvePoint(5, 5, 73, 73, t);
  5713. * y = curvePoint(26, 26, 24, 61, t);
  5714. * ellipse(x, y, 5, 5);
  5715. * x = curvePoint(5, 73, 73, 15, t);
  5716. * y = curvePoint(26, 24, 61, 65, t);
  5717. * ellipse(x, y, 5, 5);
  5718. * }
  5719. * </code>
  5720. * </div>
  5721. */
  5722. p5.prototype.curvePoint = function(a, b,c, d, t) {
  5723. var t3 = t*t*t,
  5724. t2 = t*t,
  5725. f1 = -0.5 * t3 + t2 - 0.5 * t,
  5726. f2 = 1.5 * t3 - 2.5 * t2 + 1.0,
  5727. f3 = -1.5 * t3 + 2.0 * t2 + 0.5 * t,
  5728. f4 = 0.5 * t3 - 0.5 * t2;
  5729. return a*f1 + b*f2 + c*f3 + d*f4;
  5730. };
  5731. /**
  5732. * Calculates the tangent of a point on a curve
  5733. *
  5734. * Evaluates the tangent at point t for points a, b, c, d.
  5735. * The parameter t varies between 0 and 1, a and d are points
  5736. * on the curve, and b and c are the control points
  5737. *
  5738. * @method curveTangent
  5739. * @param {Number} a coordinate of first point on the curve
  5740. * @param {Number} b coordinate of first control point
  5741. * @param {Number} c coordinate of second control point
  5742. * @param {Number} d coordinate of second point on the curve
  5743. * @param {Number} t value between 0 and 1
  5744. * @return {Number} the tangent at point t
  5745. * @example
  5746. * <div>
  5747. * <code>
  5748. * noFill();
  5749. * curve(5, 26, 73, 24, 73, 61, 15, 65);
  5750. * steps = 6;
  5751. * for (i = 0; i <= steps; i++) {
  5752. * t = i / steps;
  5753. * x = curvePoint(5, 73, 73, 15, t);
  5754. * y = curvePoint(26, 24, 61, 65, t);
  5755. * //ellipse(x, y, 5, 5);
  5756. * tx = curveTangent(5, 73, 73, 15, t);
  5757. * ty = curveTangent(26, 24, 61, 65, t);
  5758. * a = atan2(ty, tx);
  5759. * a -= PI/2.0;
  5760. * line(x, y, cos(a)*8 + x, sin(a)*8 + y);
  5761. * }
  5762. * </code>
  5763. * </div>
  5764. */
  5765. p5.prototype.curveTangent = function(a, b,c, d, t) {
  5766. var t2 = t*t,
  5767. f1 = (-3*t2)/2 + 2*t - 0.5,
  5768. f2 = (9*t2)/2 - 5*t,
  5769. f3 = (-9*t2)/2 + 4*t + 0.5,
  5770. f4 = (3*t2)/2 - t;
  5771. return a*f1 + b*f2 + c*f3 + d*f4;
  5772. };
  5773. module.exports = p5;
  5774. },{"./core":17,"./error_helpers":20}],19:[function(require,module,exports){
  5775. /**
  5776. * @module Environment
  5777. * @submodule Environment
  5778. * @for p5
  5779. * @requires core
  5780. * @requires constants
  5781. */
  5782. 'use strict';
  5783. var p5 = require('./core');
  5784. var C = require('./constants');
  5785. var standardCursors = [C.ARROW, C.CROSS, C.HAND, C.MOVE, C.TEXT, C.WAIT];
  5786. p5.prototype._frameRate = 0;
  5787. p5.prototype._lastFrameTime = window.performance.now();
  5788. p5.prototype._targetFrameRate = 60;
  5789. if (window.console && console.log) {
  5790. /**
  5791. * The print() function writes to the console area of your browser.
  5792. * This function is often helpful for looking at the data a program is
  5793. * producing. This function creates a new line of text for each call to
  5794. * the function. More than one parameter can be passed into the function by
  5795. * separating them with commas. Alternatively, individual elements can be
  5796. * separated with quotes ("") and joined with the addition operator (+).
  5797. *
  5798. * While print() is similar to console.log(), it does not directly map to
  5799. * it in order to simulate easier to understand behavior than
  5800. * console.log(). Due to this, it is slower. For fastest results, use
  5801. * console.log().
  5802. *
  5803. * @method print
  5804. * @param {Any} contents any combination of Number, String, Object, Boolean,
  5805. * Array to print
  5806. */
  5807. // Converts passed args into a string and then parses that string to
  5808. // simulate synchronous behavior. This is a hack and is gross.
  5809. // Since this will not work on all objects, particularly circular
  5810. // structures, simply console.log() on error.
  5811. p5.prototype.print = function(args) {
  5812. try {
  5813. var newArgs = JSON.parse(JSON.stringify(args));
  5814. console.log(newArgs);
  5815. } catch(err) {
  5816. console.log(args);
  5817. }
  5818. };
  5819. } else {
  5820. p5.prototype.print = function() {};
  5821. }
  5822. p5.prototype.println = p5.prototype.print;
  5823. /**
  5824. * The system variable frameCount contains the number of frames that have
  5825. * been displayed since the program started. Inside setup() the value is 0,
  5826. * after the first iteration of draw it is 1, etc.
  5827. *
  5828. * @property frameCount
  5829. * @example
  5830. * <div><code>
  5831. * function setup() {
  5832. * frameRate(30);
  5833. * textSize(20);
  5834. * textSize(30);
  5835. * textAlign(CENTER);
  5836. * }
  5837. *
  5838. * function draw() {
  5839. * background(200);
  5840. * text(frameCount, width/2, height/2);
  5841. * }
  5842. * </code></div>
  5843. */
  5844. p5.prototype.frameCount = 0;
  5845. /**
  5846. * Confirms if the window a p5.js program is in is "focused," meaning that
  5847. * the sketch will accept mouse or keyboard input. This variable is
  5848. * "true" if the window is focused and "false" if not.
  5849. *
  5850. * @property focused
  5851. * @example
  5852. * <div><code>
  5853. * // To demonstrate, put two windows side by side.
  5854. * // Click on the window that the p5 sketch isn't in!
  5855. * function draw() {
  5856. * if (focused) { // or "if (focused === true)"
  5857. * noStroke();
  5858. * fill(0, 200, 0);
  5859. * ellipse(25, 25, 50, 50);
  5860. * } else {
  5861. * stroke(200,0,0);
  5862. * line(0, 0, 100, 100);
  5863. * line(100, 0, 0, 100);
  5864. * }
  5865. * }
  5866. *
  5867. * </code></div>
  5868. */
  5869. p5.prototype.focused = (document.hasFocus());
  5870. /**
  5871. * Sets the cursor to a predefined symbol or an image, or makes it visible
  5872. * if already hidden. If you are trying to set an image as the cursor, the
  5873. * recommended size is 16x16 or 32x32 pixels. It is not possible to load an
  5874. * image as the cursor if you are exporting your program for the Web, and not
  5875. * all MODES work with all browsers. The values for parameters x and y must
  5876. * be less than the dimensions of the image.
  5877. *
  5878. * @method cursor
  5879. * @param {Number/Constant} type either ARROW, CROSS, HAND, MOVE, TEXT, or
  5880. * WAIT, or path for image
  5881. * @param {Number} [x] the horizontal active spot of the cursor
  5882. * @param {Number} [y] the vertical active spot of the cursor
  5883. * @example
  5884. * <div><code>
  5885. * // Move the mouse left and right across the image
  5886. * // to see the cursor change from a cross to a hand
  5887. * function draw() {
  5888. * line(width/2, 0, width/2, height);
  5889. * if (mouseX < 50) {
  5890. * cursor(CROSS);
  5891. * } else {
  5892. * cursor(HAND);
  5893. * }
  5894. * }
  5895. * </code></div>
  5896. */
  5897. p5.prototype.cursor = function(type, x, y) {
  5898. var cursor = 'auto';
  5899. var canvas = this._curElement.elt;
  5900. if (standardCursors.indexOf(type) > -1) {
  5901. // Standard css cursor
  5902. cursor = type;
  5903. } else if (typeof type === 'string') {
  5904. var coords = '';
  5905. if (x && y && (typeof x === 'number' && typeof y === 'number')) {
  5906. // Note that x and y values must be unit-less positive integers < 32
  5907. // https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
  5908. coords = x + ' ' + y;
  5909. }
  5910. if (type.substring(0, 6) !== 'http://') {
  5911. // Image (absolute url)
  5912. cursor = 'url(' + type + ') ' + coords + ', auto';
  5913. } else if (/\.(cur|jpg|jpeg|gif|png|CUR|JPG|JPEG|GIF|PNG)$/.test(type)) {
  5914. // Image file (relative path) - Separated for performance reasons
  5915. cursor = 'url(' + type + ') ' + coords + ', auto';
  5916. } else {
  5917. // Any valid string for the css cursor property
  5918. cursor = type;
  5919. }
  5920. }
  5921. canvas.style.cursor = cursor;
  5922. };
  5923. /**
  5924. * Specifies the number of frames to be displayed every second. For example,
  5925. * the function call frameRate(30) will attempt to refresh 30 times a second.
  5926. * If the processor is not fast enough to maintain the specified rate, the
  5927. * frame rate will not be achieved. Setting the frame rate within setup() is
  5928. * recommended. The default rate is 60 frames per second. This is the same as
  5929. * setFrameRate(val).
  5930. *
  5931. * Calling frameRate() with no arguments returns the current framerate. This
  5932. * is the same as getFrameRate().
  5933. *
  5934. * @method frameRate
  5935. * @param {Number} [fps] number of frames to be displayed every second
  5936. * @return {Number} current frameRate
  5937. * @example
  5938. *
  5939. * <div><code>
  5940. * var rectX = 0;
  5941. * var fr = 30; //starting FPS
  5942. * var clr = color(255,0,0);
  5943. *
  5944. * function setup() {
  5945. * background(200);
  5946. * frameRate(fr); // Attempt to refresh at starting FPS
  5947. * }
  5948. *
  5949. * function draw() {
  5950. * background(200);
  5951. * rectX = rectX += 1; // Move Rectangle
  5952. *
  5953. * if (rectX >= width) { // If you go off screen.
  5954. * if (fr == 30) {
  5955. * clr = color(0,0,255);
  5956. * fr = 10;
  5957. * frameRate(fr); // make frameRate 10 FPS
  5958. * } else {
  5959. * clr = color(255,0,0);
  5960. * fr = 30;
  5961. * frameRate(fr); // make frameRate 30 FPS
  5962. * }
  5963. * rectX = 0;
  5964. * }
  5965. * fill(clr);
  5966. * rect(rectX, 40, 20,20);
  5967. * }
  5968. * </div></code>
  5969. *
  5970. */
  5971. p5.prototype.frameRate = function(fps) {
  5972. if (typeof fps === 'undefined') {
  5973. return this._frameRate;
  5974. } else {
  5975. this._setProperty('_targetFrameRate', fps);
  5976. this._runFrames();
  5977. return this;
  5978. }
  5979. };
  5980. /**
  5981. * Returns the current framerate.
  5982. *
  5983. * @return {Number} current frameRate
  5984. */
  5985. p5.prototype.getFrameRate = function() {
  5986. return this.frameRate();
  5987. };
  5988. /**
  5989. * Specifies the number of frames to be displayed every second. For example,
  5990. * the function call frameRate(30) will attempt to refresh 30 times a second.
  5991. * If the processor is not fast enough to maintain the specified rate, the
  5992. * frame rate will not be achieved. Setting the frame rate within setup() is
  5993. * recommended. The default rate is 60 frames per second.
  5994. *
  5995. * Calling frameRate() with no arguments returns the current framerate.
  5996. *
  5997. * @param {Number} [fps] number of frames to be displayed every second
  5998. */
  5999. p5.prototype.setFrameRate = function(fps) {
  6000. return this.frameRate(fps);
  6001. };
  6002. /**
  6003. * Hides the cursor from view.
  6004. *
  6005. * @method noCursor
  6006. * @example
  6007. * <div><code>
  6008. * function setup() {
  6009. * noCursor();
  6010. * }
  6011. *
  6012. * function draw() {
  6013. * background(200);
  6014. * ellipse(mouseX, mouseY, 10, 10);
  6015. * }
  6016. * </code></div>
  6017. */
  6018. p5.prototype.noCursor = function() {
  6019. this._curElement.elt.style.cursor = 'none';
  6020. };
  6021. /**
  6022. * System variable that stores the width of the entire screen display. This
  6023. * is used to run a full-screen program on any display size.
  6024. *
  6025. * @property displayWidth
  6026. * @example
  6027. * <div class="norender"><code>
  6028. * createCanvas(displayWidth, displayHeight);
  6029. * </code></div>
  6030. */
  6031. p5.prototype.displayWidth = screen.width;
  6032. /**
  6033. * System variable that stores the height of the entire screen display. This
  6034. * is used to run a full-screen program on any display size.
  6035. *
  6036. * @property displayHeight
  6037. * @example
  6038. * <div class="norender"><code>
  6039. * createCanvas(displayWidth, displayHeight);
  6040. * </code></div>
  6041. */
  6042. p5.prototype.displayHeight = screen.height;
  6043. /**
  6044. * System variable that stores the width of the inner window, it maps to
  6045. * window.innerWidth.
  6046. *
  6047. * @property windowWidth
  6048. * @example
  6049. * <div class="norender"><code>
  6050. * createCanvas(windowWidth, windowHeight);
  6051. * </code></div>
  6052. */
  6053. p5.prototype.windowWidth = window.innerWidth;
  6054. /**
  6055. * System variable that stores the height of the inner window, it maps to
  6056. * window.innerHeight.
  6057. *
  6058. * @property windowHeight
  6059. * @example
  6060. * <div class="norender"><code>
  6061. * createCanvas(windowWidth, windowHeight);
  6062. * </code></div>
  6063. */
  6064. p5.prototype.windowHeight = window.innerHeight;
  6065. /**
  6066. * The windowResized() function is called once every time the browser window
  6067. * is resized. This is a good place to resize the canvas or do any other
  6068. * adjustements to accomodate the new window size.
  6069. *
  6070. * @property windowResized
  6071. * @example
  6072. * <div class="norender"><code>
  6073. * function setup() {
  6074. * createCanvas(windowWidth, windowHeight);
  6075. * }
  6076. *
  6077. * function draw() {
  6078. * background(0, 100, 200);
  6079. * }
  6080. *
  6081. * function windowResized() {
  6082. * resizeCanvas(windowWidth, windowHeight);
  6083. * }
  6084. * </code></div>
  6085. */
  6086. p5.prototype._onresize = function(e){
  6087. this._setProperty('windowWidth', window.innerWidth);
  6088. this._setProperty('windowHeight', window.innerHeight);
  6089. var context = this._isGlobal ? window : this;
  6090. var executeDefault;
  6091. if (typeof context.windowResized === 'function') {
  6092. executeDefault = context.windowResized(e);
  6093. if (executeDefault !== undefined && !executeDefault) {
  6094. e.preventDefault();
  6095. }
  6096. }
  6097. };
  6098. /**
  6099. * System variable that stores the width of the drawing canvas. This value
  6100. * is set by the first parameter of the createCanvas() function.
  6101. * For example, the function call createCanvas(320, 240) sets the width
  6102. * variable to the value 320. The value of width defaults to 100 if
  6103. * createCanvas() is not used in a program.
  6104. *
  6105. * @property width
  6106. */
  6107. p5.prototype.width = 0;
  6108. /**
  6109. * System variable that stores the height of the drawing canvas. This value
  6110. * is set by the second parameter of the createCanvas() function. For
  6111. * example, the function call createCanvas(320, 240) sets the height
  6112. * variable to the value 240. The value of height defaults to 100 if
  6113. * createCanvas() is not used in a program.
  6114. *
  6115. * @property height
  6116. */
  6117. p5.prototype.height = 0;
  6118. /**
  6119. * If argument is given, sets the sketch to fullscreen or not based on the
  6120. * value of the argument. If no argument is given, returns the current
  6121. * fullscreen state. Note that due to browser restrictions this can only
  6122. * be called on user input, for example, on mouse press like the example
  6123. * below.
  6124. *
  6125. * @method fullscreen
  6126. * @param {Boolean} [val] whether the sketch should be fullscreened or not
  6127. * @return {Boolean} current fullscreen state
  6128. * @example
  6129. * <div>
  6130. * <code>
  6131. * // Clicking in the box toggles fullscreen on and off.
  6132. * function setup() {
  6133. * background(200);
  6134. * }
  6135. * function mousePressed() {
  6136. * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
  6137. * var fs = fullscreen();
  6138. * fullscreen(!fs);
  6139. * }
  6140. * }
  6141. * </code>
  6142. * </div>
  6143. */
  6144. p5.prototype.fullscreen = function(val) {
  6145. // no arguments, return fullscreen or not
  6146. if (typeof val === 'undefined') {
  6147. return document.fullscreenElement ||
  6148. document.webkitFullscreenElement ||
  6149. document.mozFullScreenElement ||
  6150. document.msFullscreenElement;
  6151. } else { // otherwise set to fullscreen or not
  6152. if (val) {
  6153. launchFullscreen(document.documentElement);
  6154. } else {
  6155. exitFullscreen();
  6156. }
  6157. }
  6158. };
  6159. /**
  6160. * Toggles pixel scaling for high pixel density displays. By default
  6161. * pixel scaling is on, call devicePixelScaling(false) to turn it off.
  6162. * This devicePixelScaling() function must be the first line of code
  6163. * inside setup().
  6164. *
  6165. * @method devicePixelScaling
  6166. * @param {Boolean|Number} [val] whether or how much the sketch should scale
  6167. * @example
  6168. * <div>
  6169. * <code>
  6170. * function setup() {
  6171. * devicePixelScaling(false);
  6172. * createCanvas(100, 100);
  6173. * background(200);
  6174. * ellipse(width/2, height/2, 50, 50);
  6175. * }
  6176. * </code>
  6177. * </div>
  6178. * <div>
  6179. * <code>
  6180. * function setup() {
  6181. * devicePixelScaling(3.0);
  6182. * createCanvas(100, 100);
  6183. * background(200);
  6184. * ellipse(width/2, height/2, 50, 50);
  6185. * }
  6186. * </code>
  6187. * </div>
  6188. */
  6189. p5.prototype.devicePixelScaling = function(val) {
  6190. if (val) {
  6191. if (typeof val === 'number') {
  6192. this.pixelDensity = val;
  6193. }
  6194. else {
  6195. this.pixelDensity = window.devicePixelRatio || 1;
  6196. }
  6197. } else {
  6198. this.pixelDensity = 1;
  6199. }
  6200. this.resizeCanvas(this.width, this.height, true);
  6201. };
  6202. function launchFullscreen(element) {
  6203. var enabled = document.fullscreenEnabled ||
  6204. document.webkitFullscreenEnabled ||
  6205. document.mozFullScreenEnabled ||
  6206. document.msFullscreenEnabled;
  6207. if (!enabled) {
  6208. throw new Error('Fullscreen not enabled in this browser.');
  6209. }
  6210. if(element.requestFullscreen) {
  6211. element.requestFullscreen();
  6212. } else if(element.mozRequestFullScreen) {
  6213. element.mozRequestFullScreen();
  6214. } else if(element.webkitRequestFullscreen) {
  6215. element.webkitRequestFullscreen();
  6216. } else if(element.msRequestFullscreen) {
  6217. element.msRequestFullscreen();
  6218. }
  6219. }
  6220. function exitFullscreen() {
  6221. if(document.exitFullscreen) {
  6222. document.exitFullscreen();
  6223. } else if(document.mozCancelFullScreen) {
  6224. document.mozCancelFullScreen();
  6225. } else if(document.webkitExitFullscreen) {
  6226. document.webkitExitFullscreen();
  6227. } else if (document.msExitFullscreen) {
  6228. document.msExitFullscreen();
  6229. }
  6230. }
  6231. /**
  6232. * Gets the current URL.
  6233. * @method getURL
  6234. * @return {String} url
  6235. * @example
  6236. * <div>
  6237. * <code>
  6238. * var url;
  6239. * var x = 100;
  6240. *
  6241. * function setup() {
  6242. * fill(0);
  6243. * noStroke();
  6244. * url = getURL();
  6245. * }
  6246. *
  6247. * function draw() {
  6248. * background(200);
  6249. * text(url, x, height/2);
  6250. * x--;
  6251. * }
  6252. * </code>
  6253. * </div>
  6254. */
  6255. p5.prototype.getURL = function() {
  6256. return location.href;
  6257. };
  6258. /**
  6259. * Gets the current URL path as an array.
  6260. * @method getURLPath
  6261. * @return {Array} path components
  6262. * @example
  6263. * <div class='norender'><code>
  6264. * function setup() {
  6265. * var urlPath = getURLPath();
  6266. * for (var i=0; i&lt;urlPath.length; i++) {
  6267. * text(urlPath[i], 10, i*20+20);
  6268. * }
  6269. * }
  6270. * </code></div>
  6271. */
  6272. p5.prototype.getURLPath = function() {
  6273. return location.pathname.split('/').filter(function(v){return v!=='';});
  6274. };
  6275. /**
  6276. * Gets the current URL params as an Object.
  6277. * @method getURLParams
  6278. * @return {Object} URL params
  6279. * @example
  6280. * <div class='norender'>
  6281. * <code>
  6282. * // Example: http://p5js.org?year=2014&month=May&day=15
  6283. *
  6284. * function setup() {
  6285. * var params = getURLParams();
  6286. * text(params.day, 10, 20);
  6287. * text(params.month, 10, 40);
  6288. * text(params.year, 10, 60);
  6289. * }
  6290. * </code>
  6291. * </div>
  6292. */
  6293. p5.prototype.getURLParams = function() {
  6294. var re = /[?&]([^&=]+)(?:[&=])([^&=]+)/gim;
  6295. var m;
  6296. var v={};
  6297. while ((m = re.exec(location.search)) != null) {
  6298. if (m.index === re.lastIndex) {
  6299. re.lastIndex++;
  6300. }
  6301. v[m[1]]=m[2];
  6302. }
  6303. return v;
  6304. };
  6305. module.exports = p5;
  6306. },{"./constants":16,"./core":17}],20:[function(require,module,exports){
  6307. /**
  6308. * @for p5
  6309. * @requires core
  6310. */
  6311. 'use strict';
  6312. var p5 = require('./core');
  6313. var doFriendlyWelcome = true;
  6314. // -- Borrowed from jQuery 1.11.3 --
  6315. var class2type = {};
  6316. var toString = class2type.toString;
  6317. var names = ['Boolean', 'Number', 'String', 'Function',
  6318. 'Array', 'Date', 'RegExp', 'Object', 'Error'];
  6319. for (var n=0; n<names.length; n++) {
  6320. class2type[ '[object ' + names[n] + ']' ] = names[n].toLowerCase();
  6321. }
  6322. var getType = function( obj ) {
  6323. if ( obj == null ) {
  6324. return obj + '';
  6325. }
  6326. return typeof obj === 'object' || typeof obj === 'function' ?
  6327. class2type[ toString.call(obj) ] || 'object' :
  6328. typeof obj;
  6329. };
  6330. var isArray = Array.isArray || function( obj ) {
  6331. return getType(obj) === 'array';
  6332. };
  6333. var isNumeric =function( obj ) {
  6334. // parseFloat NaNs numeric-cast false positives (null|true|false|"")
  6335. // ...but misinterprets leading-number strings, particularly hex literals
  6336. // subtraction forces infinities to NaN
  6337. // adding 1 corrects loss of precision from parseFloat (#15100)
  6338. return !isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
  6339. };
  6340. // -- End borrow --
  6341. /**
  6342. * Checks the definition type against the argument type
  6343. * If any of these passes (in order), it matches:
  6344. *
  6345. * - p5.* definitions are checked with instanceof
  6346. * - Booleans are let through (everything is truthy or falsey)
  6347. * - Lowercase of the definition is checked against the js type
  6348. * - Number types are checked to see if they are numerically castable
  6349. */
  6350. var numberTypes = ['Number', 'Integer', 'Number/Constant'];
  6351. function typeMatches(defType, argType, arg) {
  6352. if(defType.match(/^p5\./)) {
  6353. var parts = defType.split('.');
  6354. return arg instanceof p5[parts[1]];
  6355. }
  6356. return defType === 'Boolean' || // Anything is truthy, cover in Debug Guide
  6357. (defType.toLowerCase() === argType) ||
  6358. (numberTypes.indexOf(defType) > -1 && isNumeric(arg));
  6359. }
  6360. /**
  6361. * Prints out a fancy, colorful message to the console log
  6362. *
  6363. * @param {String} message the words to be said
  6364. * @param {String} func the name of the function to link
  6365. * @param {Integer/Color String} color CSS color string or error type
  6366. *
  6367. * @return console logs
  6368. */
  6369. // Wrong number of params, undefined param, wrong type
  6370. var PARAM_COUNT = 0;
  6371. var EMPTY_VAR = 1;
  6372. var WRONG_TYPE = 2;
  6373. var FILE_LOAD = 3;
  6374. // p5.js blue, p5.js orange, auto dark green; fallback p5.js darkened magenta
  6375. // See testColors below for all the color codes and names
  6376. var typeColors = ['#2D7BB6', '#EE9900', '#4DB200', '#C83C00'];
  6377. function report(message, func, color) {
  6378. if(doFriendlyWelcome){
  6379. friendlyWelcome();
  6380. doFriendlyWelcome =false;
  6381. }
  6382. if ('undefined' === getType(color)) {
  6383. color = '#B40033'; // dark magenta
  6384. } else if (getType(color) === 'number') { // Type to color
  6385. color = typeColors[color];
  6386. }
  6387. if (func.substring(0,4) === 'load'){
  6388. console.log(
  6389. '%c> p5.js says: '+message+'%c'+
  6390. '[https://github.com/processing/p5.js/wiki/Local-server]',
  6391. 'background-color:' + color + ';color:#FFF;',
  6392. 'background-color:transparent;color:' + color +';',
  6393. 'background-color:' + color + ';color:#FFF;',
  6394. 'background-color:transparent;color:' + color +';'
  6395. );
  6396. }
  6397. else{
  6398. console.log(
  6399. '%c> p5.js says: '+message+'%c [http://p5js.org/reference/#p5/'+func+
  6400. ']', 'background-color:' + color + ';color:#FFF;',
  6401. 'background-color:transparent;color:' + color +';'
  6402. );
  6403. }
  6404. }
  6405. /**
  6406. * Validate all the parameters of a function for number and type
  6407. *
  6408. * @param {String} func name of function we're checking
  6409. * @param {Array} args pass of the JS default arguments array
  6410. * @param {Array} types List of types accepted ['Number', 'String, ...] OR
  6411. * a list of lists for each format: [
  6412. * ['String', 'Number', 'Number'],
  6413. * ['String', 'Number', 'Number', 'Number', 'Number'
  6414. * ]
  6415. *
  6416. * @return console logs
  6417. */
  6418. p5.prototype._validateParameters = function(func, args, types) {
  6419. if (!isArray(types[0])) {
  6420. types = [types];
  6421. }
  6422. /**
  6423. * Check number of parameters
  6424. *
  6425. * Example: "You wrote ellipse(X,X,X). ellipse was expecting 4
  6426. * parameters. Try ellipse(X,X,X,X)."
  6427. */
  6428. var diff = Math.abs(args.length-types[0].length);
  6429. var message, tindex = 0;
  6430. for (var i=1, len=types.length; i<len; i++) {
  6431. var d = Math.abs(args.length-types[i].length);
  6432. if (d <= diff) {
  6433. tindex = i;
  6434. diff = d;
  6435. }
  6436. }
  6437. var symbol = 'X'; // Parameter placeholder
  6438. if(diff > 0) {
  6439. message = 'You wrote ' + func + '(';
  6440. // Concat an appropriate number of placeholders for call
  6441. if (args.length > 0) {
  6442. message += symbol + (','+symbol).repeat(args.length-1);
  6443. }
  6444. message += '). ' + func + ' was expecting ' + types[tindex].length +
  6445. ' parameters. Try ' + func + '(';
  6446. // Concat an appropriate number of placeholders for definition
  6447. if (types[tindex].length > 0) {
  6448. message += symbol + (','+symbol).repeat(types[tindex].length-1);
  6449. }
  6450. message += ').';
  6451. // If multiple definitions
  6452. if (types.length > 1) {
  6453. message += ' ' + func + ' takes different numbers of parameters ' +
  6454. 'depending on what you want to do. Click this link to learn more: ';
  6455. }
  6456. report(message, func, PARAM_COUNT);
  6457. }
  6458. /**
  6459. * Type checking
  6460. *
  6461. * Example: "It looks like ellipse received an empty variable in spot #2."
  6462. * Example: "ellipse was expecting a number for parameter #1,
  6463. * received "foo" instead."
  6464. */
  6465. for (var format=0; format<types.length; format++) {
  6466. for (var p=0; p < types[format].length && p < args.length; p++) {
  6467. var defType = types[format][p];
  6468. var argType = getType(args[p]);
  6469. if ('undefined' === argType || null === argType) {
  6470. report('It looks like ' + func +
  6471. ' received an empty variable in spot #' + (p+1) +
  6472. '. If not intentional, this is often a problem with scope: ' +
  6473. '[link to scope].', func, EMPTY_VAR);
  6474. } else if (defType !== '*' && !typeMatches(defType, argType, args[p])) {
  6475. message = func + ' was expecting a ' + defType.toLowerCase() +
  6476. ' for parameter #' + (p+1) + ', received ';
  6477. // Wrap strings in quotes
  6478. message += 'string' === argType ? '"' + args[p] + '"' : args[p];
  6479. message += ' instead.';
  6480. // If multiple definitions
  6481. if (types.length > 1) {
  6482. message += ' ' + func + ' takes different numbers of parameters ' +
  6483. 'depending on what you want to do. ' +
  6484. 'Click this link to learn more:';
  6485. }
  6486. report(message, func, WRONG_TYPE);
  6487. }
  6488. }
  6489. }
  6490. };
  6491. var errorCases = {
  6492. '0': {
  6493. fileType: 'image',
  6494. method: 'loadImage',
  6495. message: ' hosting the image online,'
  6496. },
  6497. '1': {
  6498. fileType: 'XML file',
  6499. method: 'loadXML'
  6500. },
  6501. '2': {
  6502. fileType: 'table file',
  6503. method: 'loadTable'
  6504. },
  6505. '3': {
  6506. fileType: 'text file',
  6507. method: 'loadStrings'
  6508. }
  6509. };
  6510. p5._friendlyFileLoadError = function (errorType, filePath) {
  6511. var errorInfo = errorCases[ errorType ];
  6512. var message = 'It looks like there was a problem' +
  6513. ' loading your ' + errorInfo.fileType + '.' +
  6514. ' Try checking if the file path%c [' + filePath + '] %cis correct,' +
  6515. (errorInfo.message || '') + ' or running a local server.';
  6516. report(message, errorInfo.method, FILE_LOAD);
  6517. };
  6518. function friendlyWelcome() {
  6519. // p5.js brand - magenta: #ED225D
  6520. var astrixBgColor = 'transparent';
  6521. var astrixTxtColor = '#ED225D';
  6522. var welcomeBgColor = '#ED225D';
  6523. var welcomeTextColor = 'white';
  6524. console.log(
  6525. '%c _ \n'+
  6526. ' /\\| |/\\ \n'+
  6527. ' \\ ` \' / \n'+
  6528. ' / , . \\ \n'+
  6529. ' \\/|_|\\/ '+
  6530. '\n\n%c> p5.js says: Welcome! '+
  6531. 'This is your friendly debugger. ' +
  6532. 'To turn me off switch to using “p5.min.js”.',
  6533. 'background-color:'+astrixBgColor+';color:' + astrixTxtColor +';',
  6534. 'background-color:'+welcomeBgColor+';color:' + welcomeTextColor +';'
  6535. );
  6536. }
  6537. /**
  6538. * Prints out all the colors in the color pallete with white text.
  6539. * For color blindness testing.
  6540. */
  6541. /* function testColors() {
  6542. var str = 'A box of biscuits, a box of mixed biscuits and a biscuit mixer';
  6543. report(str, 'println', '#ED225D'); // p5.js magenta
  6544. report(str, 'println', '#2D7BB6'); // p5.js blue
  6545. report(str, 'println', '#EE9900'); // p5.js orange
  6546. report(str, 'println', '#A67F59'); // p5.js light brown
  6547. report(str, 'println', '#704F21'); // p5.js gold
  6548. report(str, 'println', '#1CC581'); // auto cyan
  6549. report(str, 'println', '#FF6625'); // auto orange
  6550. report(str, 'println', '#79EB22'); // auto green
  6551. report(str, 'println', '#B40033'); // p5.js darkened magenta
  6552. report(str, 'println', '#084B7F'); // p5.js darkened blue
  6553. report(str, 'println', '#945F00'); // p5.js darkened orange
  6554. report(str, 'println', '#6B441D'); // p5.js darkened brown
  6555. report(str, 'println', '#2E1B00'); // p5.js darkened gold
  6556. report(str, 'println', '#008851'); // auto dark cyan
  6557. report(str, 'println', '#C83C00'); // auto dark orange
  6558. report(str, 'println', '#4DB200'); // auto dark green
  6559. } */
  6560. module.exports = p5;
  6561. },{"./core":17}],21:[function(require,module,exports){
  6562. /**
  6563. * @module DOM
  6564. * @submodule DOM
  6565. * @for p5.Element
  6566. */
  6567. var p5 = require('./core');
  6568. /**
  6569. * Base class for all elements added to a sketch, including canvas,
  6570. * graphics buffers, and other HTML elements. Methods in blue are
  6571. * included in the core functionality, methods in brown are added
  6572. * with the <a href="http://p5js.org/libraries/">p5.dom library</a>.
  6573. * It is not called directly, but p5.Element
  6574. * objects are created by calling createCanvas, createGraphics,
  6575. * or in the p5.dom library, createDiv, createImg, createInput, etc.
  6576. *
  6577. * @class p5.Element
  6578. * @constructor
  6579. * @param {String} elt DOM node that is wrapped
  6580. * @param {Object} [pInst] pointer to p5 instance
  6581. */
  6582. p5.Element = function(elt, pInst) {
  6583. /**
  6584. * Underlying HTML element. All normal HTML methods can be called on this.
  6585. *
  6586. * @property elt
  6587. */
  6588. this.elt = elt;
  6589. this._pInst = pInst;
  6590. this._events = {};
  6591. this.width = this.elt.offsetWidth;
  6592. this.height = this.elt.offsetHeight;
  6593. };
  6594. /**
  6595. *
  6596. * Attaches the element to the parent specified. A way of setting
  6597. * the container for the element. Accepts either a string ID, DOM
  6598. * node, or p5.Element.
  6599. *
  6600. * @method parent
  6601. * @param {String|Object} parent the ID, DOM node, or p5.Element
  6602. * of desired parent element
  6603. * @return {p5.Element}
  6604. * @example
  6605. * <div class="norender"><code>
  6606. * // in the html file:
  6607. * &lt;div id="myContainer">&lt;/div>
  6608. * // in the js file:
  6609. * var cnv = createCanvas(100, 100);
  6610. * cnv.parent("myContainer");
  6611. * </code></div>
  6612. * <div class='norender'><code>
  6613. * var div0 = createDiv('this is the parent');
  6614. * var div1 = createDiv('this is the child');
  6615. * div1.parent(div0); // use p5.Element
  6616. * </code></div>
  6617. * <div class='norender'><code>
  6618. * var div0 = createDiv('this is the parent');
  6619. * div0.id('apples');
  6620. * var div1 = createDiv('this is the child');
  6621. * div1.parent('apples'); // use id
  6622. * </code></div>
  6623. * <div class='norender'><code>
  6624. * var elt = document.getElementById('myParentDiv');
  6625. * var div1 = createDiv('this is the child');
  6626. * div1.parent(elt); // use element from page
  6627. * </code></div>
  6628. */
  6629. p5.Element.prototype.parent = function(p) {
  6630. if (typeof p === 'string') {
  6631. p = document.getElementById(p);
  6632. } else if (p instanceof p5.Element) {
  6633. p = p.elt;
  6634. }
  6635. p.appendChild(this.elt);
  6636. return this;
  6637. };
  6638. /**
  6639. *
  6640. * Sets the ID of the element
  6641. *
  6642. * @method id
  6643. * @param {String} id ID of the element
  6644. * @return {p5.Element}
  6645. */
  6646. p5.Element.prototype.id = function(id) {
  6647. this.elt.id = id;
  6648. return this;
  6649. };
  6650. /**
  6651. *
  6652. * Adds given class to the element
  6653. *
  6654. * @method class
  6655. * @param {String} class class to add
  6656. * @return {p5.Element}
  6657. */
  6658. p5.Element.prototype.class = function(c) {
  6659. this.elt.className += ' '+c;
  6660. return this;
  6661. };
  6662. /**
  6663. * The .mousePressed() function is called once after every time a
  6664. * mouse button is pressed over the element. This can be used to
  6665. * attach element specific event listeners.
  6666. *
  6667. * @method mousePressed
  6668. * @param {Function} fxn function to be fired when mouse is
  6669. * pressed over the element.
  6670. * @return {p5.Element}
  6671. * @example
  6672. * <div class='norender'><code>
  6673. * var cnv;
  6674. * var d;
  6675. * var g;
  6676. * function setup() {
  6677. * cnv = createCanvas(100, 100);
  6678. * cnv.mousePressed(changeGray); // attach listener for
  6679. * // canvas click only
  6680. * d = 10;
  6681. * g = 100;
  6682. * }
  6683. *
  6684. * function draw() {
  6685. * background(g);
  6686. * ellipse(width/2, height/2, d, d);
  6687. * }
  6688. *
  6689. * // this function fires with any click anywhere
  6690. * function mousePressed() {
  6691. * d = d + 10;
  6692. * }
  6693. *
  6694. * // this function fires only when cnv is clicked
  6695. * function changeGray() {
  6696. * g = random(0, 255);
  6697. * }
  6698. * </code></div>
  6699. *
  6700. */
  6701. p5.Element.prototype.mousePressed = function (fxn) {
  6702. attachListener('mousedown', fxn, this);
  6703. attachListener('touchstart', fxn, this);
  6704. return this;
  6705. };
  6706. /**
  6707. * The .mouseWheel() function is called once after every time a
  6708. * mouse wheel is scrolled over the element. This can be used to
  6709. * attach element specific event listeners.<br><br>
  6710. * The event.wheelDelta or event.detail property returns negative values if
  6711. * the mouse wheel if rotated up or away from the user and positive in the
  6712. * other direction. On OS X with "natural" scrolling enabled, the values are
  6713. * opposite.
  6714. *
  6715. * @method mouseWheel
  6716. * @param {Function} fxn function to be fired when mouse wheel is
  6717. * scrolled over the element.
  6718. * @return {p5.Element}
  6719. */
  6720. p5.Element.prototype.mouseWheel = function (fxn) {
  6721. attachListener('mousewheel', fxn, this);
  6722. return this;
  6723. };
  6724. /**
  6725. * The .mouseReleased() function is called once after every time a
  6726. * mouse button is released over the element. This can be used to
  6727. * attach element specific event listeners.
  6728. *
  6729. * @method mouseReleased
  6730. * @param {Function} fxn function to be fired when mouse is
  6731. * released over the element.
  6732. * @return {p5.Element}
  6733. */
  6734. p5.Element.prototype.mouseReleased = function (fxn) {
  6735. attachListener('mouseup', fxn, this);
  6736. attachListener('touchend', fxn, this);
  6737. return this;
  6738. };
  6739. /**
  6740. * The .mouseClicked() function is called once after a mouse button is
  6741. * pressed and released over the element. This can be used to
  6742. * attach element specific event listeners.
  6743. *
  6744. * @method mouseClicked
  6745. * @param {Function} fxn function to be fired when mouse is
  6746. * clicked over the element.
  6747. * @return {p5.Element}
  6748. */
  6749. p5.Element.prototype.mouseClicked = function (fxn) {
  6750. attachListener('click', fxn, this);
  6751. return this;
  6752. };
  6753. /**
  6754. * The .mouseMoved() function is called once every time a
  6755. * mouse moves over the element. This can be used to attach an
  6756. * element specific event listener.
  6757. *
  6758. * @method mouseMoved
  6759. * @param {Function} fxn function to be fired when mouse is
  6760. * moved over the element.
  6761. * @return {p5.Element}
  6762. */
  6763. p5.Element.prototype.mouseMoved = function (fxn) {
  6764. attachListener('mousemove', fxn, this);
  6765. attachListener('touchmove', fxn, this);
  6766. return this;
  6767. };
  6768. /**
  6769. * The .mouseOver() function is called once after every time a
  6770. * mouse moves onto the element. This can be used to attach an
  6771. * element specific event listener.
  6772. *
  6773. * @method mouseOver
  6774. * @param {Function} fxn function to be fired when mouse is
  6775. * moved over the element.
  6776. * @return {p5.Element}
  6777. */
  6778. p5.Element.prototype.mouseOver = function (fxn) {
  6779. attachListener('mouseover', fxn, this);
  6780. return this;
  6781. };
  6782. /**
  6783. * The .mouseOut() function is called once after every time a
  6784. * mouse moves off the element. This can be used to attach an
  6785. * element specific event listener.
  6786. *
  6787. * @method mouseOut
  6788. * @param {Function} fxn function to be fired when mouse is
  6789. * moved off the element.
  6790. * @return {p5.Element}
  6791. */
  6792. p5.Element.prototype.mouseOut = function (fxn) {
  6793. attachListener('mouseout', fxn, this);
  6794. return this;
  6795. };
  6796. /**
  6797. * The .touchStarted() function is called once after every time a touch is
  6798. * registered. This can be used to attach element specific event listeners.
  6799. *
  6800. * @method touchStarted
  6801. * @param {Function} fxn function to be fired when touch is
  6802. * started over the element.
  6803. * @return {p5.Element}
  6804. * @example
  6805. * <div class='norender'><code>
  6806. * var cnv;
  6807. * var d;
  6808. * var g;
  6809. * function setup() {
  6810. * cnv = createCanvas(100, 100);
  6811. * cnv.touchStarted(changeGray); // attach listener for
  6812. * // canvas click only
  6813. * d = 10;
  6814. * g = 100;
  6815. * }
  6816. *
  6817. * function draw() {
  6818. * background(g);
  6819. * ellipse(width/2, height/2, d, d);
  6820. * }
  6821. *
  6822. * // this function fires with any touch anywhere
  6823. * function touchStarted() {
  6824. * d = d + 10;
  6825. * }
  6826. *
  6827. * // this function fires only when cnv is clicked
  6828. * function changeGray() {
  6829. * g = random(0, 255);
  6830. * }
  6831. * </code></div>
  6832. *
  6833. */
  6834. p5.Element.prototype.touchStarted = function (fxn) {
  6835. attachListener('touchstart', fxn, this);
  6836. attachListener('mousedown', fxn, this);
  6837. return this;
  6838. };
  6839. /**
  6840. * The .touchMoved() function is called once after every time a touch move is
  6841. * registered. This can be used to attach element specific event listeners.
  6842. *
  6843. * @method touchMoved
  6844. * @param {Function} fxn function to be fired when touch is moved
  6845. * over the element.
  6846. * @return {p5.Element}
  6847. * @example
  6848. * <div class='norender'><code>
  6849. * var cnv;
  6850. * var g;
  6851. * function setup() {
  6852. * cnv = createCanvas(100, 100);
  6853. * cnv.touchMoved(changeGray); // attach listener for
  6854. * // canvas click only
  6855. * g = 100;
  6856. * }
  6857. *
  6858. * function draw() {
  6859. * background(g);
  6860. * }
  6861. *
  6862. * // this function fires only when cnv is clicked
  6863. * function changeGray() {
  6864. * g = random(0, 255);
  6865. * }
  6866. * </code></div>
  6867. *
  6868. */
  6869. p5.Element.prototype.touchMoved = function (fxn) {
  6870. attachListener('touchmove', fxn, this);
  6871. attachListener('mousemove', fxn, this);
  6872. return this;
  6873. };
  6874. /**
  6875. * The .touchEnded() function is called once after every time a touch is
  6876. * registered. This can be used to attach element specific event listeners.
  6877. *
  6878. * @method touchEnded
  6879. * @param {Function} fxn function to be fired when touch is
  6880. * ended over the element.
  6881. * @return {p5.Element}
  6882. * @example
  6883. * <div class='norender'><code>
  6884. * var cnv;
  6885. * var d;
  6886. * var g;
  6887. * function setup() {
  6888. * cnv = createCanvas(100, 100);
  6889. * cnv.touchEnded(changeGray); // attach listener for
  6890. * // canvas click only
  6891. * d = 10;
  6892. * g = 100;
  6893. * }
  6894. *
  6895. * function draw() {
  6896. * background(g);
  6897. * ellipse(width/2, height/2, d, d);
  6898. * }
  6899. *
  6900. * // this function fires with any touch anywhere
  6901. * function touchEnded() {
  6902. * d = d + 10;
  6903. * }
  6904. *
  6905. * // this function fires only when cnv is clicked
  6906. * function changeGray() {
  6907. * g = random(0, 255);
  6908. * }
  6909. * </code></div>
  6910. *
  6911. */
  6912. p5.Element.prototype.touchEnded = function (fxn) {
  6913. attachListener('touchend', fxn, this);
  6914. attachListener('mouseup', fxn, this);
  6915. return this;
  6916. };
  6917. /**
  6918. * The .dragOver() function is called once after every time a
  6919. * file is dragged over the element. This can be used to attach an
  6920. * element specific event listener.
  6921. *
  6922. * @method dragOver
  6923. * @param {Function} fxn function to be fired when mouse is
  6924. * dragged over the element.
  6925. * @return {p5.Element}
  6926. */
  6927. p5.Element.prototype.dragOver = function (fxn) {
  6928. attachListener('dragover', fxn, this);
  6929. return this;
  6930. };
  6931. /**
  6932. * The .dragLeave() function is called once after every time a
  6933. * dragged file leaves the element area. This can be used to attach an
  6934. * element specific event listener.
  6935. *
  6936. * @method dragLeave
  6937. * @param {Function} fxn function to be fired when mouse is
  6938. * dragged over the element.
  6939. * @return {p5.Element}
  6940. */
  6941. p5.Element.prototype.dragLeave = function (fxn) {
  6942. attachListener('dragleave', fxn, this);
  6943. return this;
  6944. };
  6945. /**
  6946. * The .drop() function is called for each file dropped on the element.
  6947. * It requires a callback that is passed a p5.File object. You can
  6948. * optionally pass two callbacks, the first one (required) is triggered
  6949. * for each file dropped when the file is loaded. The second (optional)
  6950. * is triggered just once when a file (or files) are dropped.
  6951. *
  6952. * @method drop
  6953. * @param {Function} callback triggered when files are dropped.
  6954. * @param {Function} callback to receive loaded file.
  6955. * @return {p5.Element}
  6956. */
  6957. p5.Element.prototype.drop = function (callback, fxn) {
  6958. // Make a file loader callback and trigger user's callback
  6959. function makeLoader(theFile) {
  6960. // Making a p5.File object
  6961. var p5file = new p5.File(theFile);
  6962. return function(e) {
  6963. p5file.data = e.target.result;
  6964. callback(p5file);
  6965. };
  6966. }
  6967. // Is the file stuff supported?
  6968. if (window.File && window.FileReader && window.FileList && window.Blob) {
  6969. // If you want to be able to drop you've got to turn off
  6970. // a lot of default behavior
  6971. attachListener('dragover',function(evt) {
  6972. evt.stopPropagation();
  6973. evt.preventDefault();
  6974. },this);
  6975. // If this is a drag area we need to turn off the default behavior
  6976. attachListener('dragleave',function(evt) {
  6977. evt.stopPropagation();
  6978. evt.preventDefault();
  6979. },this);
  6980. // If just one argument it's the callback for the files
  6981. if (arguments.length > 1) {
  6982. attachListener('drop', fxn, this);
  6983. }
  6984. // Deal with the files
  6985. attachListener('drop', function(evt) {
  6986. evt.stopPropagation();
  6987. evt.preventDefault();
  6988. // A FileList
  6989. var files = evt.dataTransfer.files;
  6990. // Load each one and trigger the callback
  6991. for (var i = 0; i < files.length; i++) {
  6992. var f = files[i];
  6993. var reader = new FileReader();
  6994. reader.onload = makeLoader(f);
  6995. // Text of data?
  6996. // This should likely be improved
  6997. if (f.type === 'text') {
  6998. reader.readAsText(f);
  6999. } else {
  7000. reader.readAsDataURL(f);
  7001. }
  7002. }
  7003. }, this);
  7004. } else {
  7005. console.log('The File APIs are not fully supported in this browser.');
  7006. }
  7007. return this;
  7008. };
  7009. function attachListener(ev, fxn, ctx) {
  7010. // LM removing, not sure why we had this?
  7011. // var _this = ctx;
  7012. // var f = function (e) { fxn(e, _this); };
  7013. var f = fxn.bind(ctx);
  7014. ctx.elt.addEventListener(ev, f, false);
  7015. ctx._events[ev] = f;
  7016. }
  7017. /**
  7018. * Helper fxn for sharing pixel methods
  7019. *
  7020. */
  7021. p5.Element.prototype._setProperty = function (prop, value) {
  7022. this[prop] = value;
  7023. };
  7024. module.exports = p5.Element;
  7025. },{"./core":17}],22:[function(require,module,exports){
  7026. /**
  7027. * @module Rendering
  7028. * @submodule Rendering
  7029. * @for p5
  7030. */
  7031. var p5 = require('./core');
  7032. var constants = require('./constants');
  7033. /**
  7034. * Thin wrapper around a renderer, to be used for creating a
  7035. * graphics buffer object. Use this class if you need
  7036. * to draw into an off-screen graphics buffer. The two parameters define the
  7037. * width and height in pixels. The fields and methods for this class are
  7038. * extensive, but mirror the normal drawing API for p5.
  7039. *
  7040. * @class p5.Graphics
  7041. * @constructor
  7042. * @extends p5.Element
  7043. * @param {String} elt DOM node that is wrapped
  7044. * @param {Object} [pInst] pointer to p5 instance
  7045. * @param {Boolean} whether we're using it as main canvas
  7046. */
  7047. p5.Graphics = function(w, h, renderer, pInst) {
  7048. var r = renderer || constants.P2D;
  7049. var c = document.createElement('canvas');
  7050. var node = this._userNode || document.body;
  7051. node.appendChild(c);
  7052. p5.Element.call(this, c, pInst, false);
  7053. this._styles = [];
  7054. this.width = w;
  7055. this.height = h;
  7056. this.pixelDensity = pInst.pixelDensity;
  7057. if (r === constants.WEBGL) {
  7058. this._graphics = new p5.Renderer3D(c, this, false);
  7059. } else {
  7060. this._graphics = new p5.Renderer2D(c, pInst, false);
  7061. }
  7062. this._graphics.resize(w, h);
  7063. this._graphics._applyDefaults();
  7064. pInst._elements.push(this);
  7065. // bind methods and props of p5 to the new object
  7066. for (var p in p5.prototype) {
  7067. if (!this[p]) {
  7068. if (typeof p5.prototype[p] === 'function') {
  7069. this[p] = p5.prototype[p].bind(this);
  7070. } else {
  7071. this[p] = p5.prototype[p];
  7072. }
  7073. }
  7074. }
  7075. return this;
  7076. };
  7077. p5.Graphics.prototype = Object.create(p5.Element.prototype);
  7078. module.exports = p5.Graphics;
  7079. },{"./constants":16,"./core":17}],23:[function(require,module,exports){
  7080. /**
  7081. * @module Rendering
  7082. * @submodule Rendering
  7083. * @for p5
  7084. */
  7085. var p5 = require('./core');
  7086. /**
  7087. * Main graphics and rendering context, as well as the base API
  7088. * implementation for p5.js "core". To be used as the superclass for
  7089. * Renderer2D and Renderer3D classes, respecitvely.
  7090. *
  7091. * @class p5.Renderer
  7092. * @constructor
  7093. * @extends p5.Element
  7094. * @param {String} elt DOM node that is wrapped
  7095. * @param {Object} [pInst] pointer to p5 instance
  7096. * @param {Boolean} whether we're using it as main canvas
  7097. */
  7098. p5.Renderer = function(elt, pInst, isMainCanvas) {
  7099. p5.Element.call(this, elt, pInst);
  7100. this.canvas = elt;
  7101. this._pInst = pInst;
  7102. if (isMainCanvas) {
  7103. this._isMainCanvas = true;
  7104. // for pixel method sharing with pimage
  7105. this._pInst._setProperty('_curElement', this);
  7106. this._pInst._setProperty('canvas', this.canvas);
  7107. this._pInst._setProperty('width', this.width);
  7108. this._pInst._setProperty('height', this.height);
  7109. } else { // hide if offscreen buffer by default
  7110. this.canvas.style.display = 'none';
  7111. this._styles = []; // non-main elt styles stored in p5.Renderer
  7112. }
  7113. };
  7114. p5.Renderer.prototype = Object.create(p5.Element.prototype);
  7115. /**
  7116. * Resize our canvas element.
  7117. */
  7118. p5.Renderer.prototype.resize = function(w, h) {
  7119. this.width = w;
  7120. this.height = h;
  7121. this.elt.width = w * this._pInst.pixelDensity;
  7122. this.elt.height = h * this._pInst.pixelDensity;
  7123. this.elt.style.width = w +'px';
  7124. this.elt.style.height = h + 'px';
  7125. if (this._isMainCanvas) {
  7126. this._pInst._setProperty('width', this.width);
  7127. this._pInst._setProperty('height', this.height);
  7128. }
  7129. };
  7130. module.exports = p5.Renderer;
  7131. },{"./core":17}],24:[function(require,module,exports){
  7132. var p5 = require('./core');
  7133. var canvas = require('./canvas');
  7134. var constants = require('./constants');
  7135. var filters = require('../image/filters');
  7136. require('./p5.Renderer');
  7137. /**
  7138. * 2D graphics renderer class. Can also be used as an off-screen
  7139. * graphics buffer. A p5.Renderer2D object can be constructed
  7140. * with the <code>createRenderer2D()</code> function. The fields and methods
  7141. * for this class are extensive, but mirror the normal drawing API for p5.
  7142. *
  7143. * @class p5.Renderer2D
  7144. * @constructor
  7145. * @extends p5.Renderer
  7146. * @param {String} elt DOM node that is wrapped
  7147. * @param {Object} [pInst] pointer to p5 instance
  7148. * @example
  7149. * <div>
  7150. * <code>
  7151. * var pg;
  7152. * function setup() {
  7153. * createCanvas(100, 100);
  7154. * pg = createRenderer2D(40, 40);
  7155. * }
  7156. * function draw() {
  7157. * background(200);
  7158. * pg.background(100);
  7159. * pg.noStroke();
  7160. * pg.ellipse(pg.width/2, pg.height/2, 50, 50);
  7161. * image(pg, 9, 30);
  7162. * image(pg, 51, 30);
  7163. * }
  7164. * </code>
  7165. * </div>
  7166. */
  7167. var styleEmpty = 'rgba(0,0,0,0)';
  7168. // var alphaThreshold = 0.00125; // minimum visible
  7169. p5.Renderer2D = function(elt, pInst, isMainCanvas){
  7170. p5.Renderer.call(this, elt, pInst, isMainCanvas);
  7171. this.drawingContext = this.canvas.getContext('2d');
  7172. this._pInst._setProperty('drawingContext', this.drawingContext);
  7173. return this;
  7174. };
  7175. p5.Renderer2D.prototype = Object.create(p5.Renderer.prototype);
  7176. p5.Renderer2D.prototype._applyDefaults = function() {
  7177. this.drawingContext.fillStyle = constants._DEFAULT_FILL;
  7178. this.drawingContext.strokeStyle = constants._DEFAULT_STROKE;
  7179. this.drawingContext.lineCap = constants.ROUND;
  7180. this.drawingContext.font = 'normal 12px sans-serif';
  7181. };
  7182. p5.Renderer2D.prototype.resize = function(w,h) {
  7183. p5.Renderer.prototype.resize.call(this, w,h);
  7184. this.drawingContext.scale(this._pInst.pixelDensity,
  7185. this._pInst.pixelDensity);
  7186. };
  7187. //////////////////////////////////////////////
  7188. // COLOR | Setting
  7189. //////////////////////////////////////////////
  7190. p5.Renderer2D.prototype.background = function() {
  7191. this.drawingContext.save();
  7192. this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);
  7193. this.drawingContext.scale(this._pInst.pixelDensity,
  7194. this._pInst.pixelDensity);
  7195. if (arguments[0] instanceof p5.Image) {
  7196. this._pInst.image(arguments[0], 0, 0, this.width, this.height);
  7197. } else {
  7198. var curFill = this.drawingContext.fillStyle;
  7199. // create background rect
  7200. var color = this._pInst.color.apply(this._pInst, arguments);
  7201. var newFill = color.toString();
  7202. this.drawingContext.fillStyle = newFill;
  7203. this.drawingContext.fillRect(0, 0, this.width, this.height);
  7204. // reset fill
  7205. this.drawingContext.fillStyle = curFill;
  7206. }
  7207. this.drawingContext.restore();
  7208. };
  7209. p5.Renderer2D.prototype.clear = function() {
  7210. this.drawingContext.clearRect(0, 0, this.width, this.height);
  7211. };
  7212. p5.Renderer2D.prototype.fill = function() {
  7213. var ctx = this.drawingContext;
  7214. var color = this._pInst.color.apply(this._pInst, arguments);
  7215. ctx.fillStyle = color.toString();
  7216. };
  7217. p5.Renderer2D.prototype.stroke = function() {
  7218. var ctx = this.drawingContext;
  7219. var color = this._pInst.color.apply(this._pInst, arguments);
  7220. ctx.strokeStyle = color.toString();
  7221. };
  7222. //////////////////////////////////////////////
  7223. // IMAGE | Loading & Displaying
  7224. //////////////////////////////////////////////
  7225. p5.Renderer2D.prototype.image = function (img, x, y, w, h) {
  7226. var frame = img.canvas || img.elt;
  7227. try {
  7228. if (this._pInst._tint && img.canvas) {
  7229. this.drawingContext.drawImage(this._getTintedImageCanvas(img),
  7230. x, y, w, h);
  7231. } else {
  7232. this.drawingContext.drawImage(frame, x, y, w, h);
  7233. }
  7234. } catch (e) {
  7235. if (e.name !== 'NS_ERROR_NOT_AVAILABLE') {
  7236. throw e;
  7237. }
  7238. }
  7239. };
  7240. p5.Renderer2D.prototype._getTintedImageCanvas = function (img) {
  7241. if (!img.canvas) {
  7242. return img;
  7243. }
  7244. var pixels = filters._toPixels(img.canvas);
  7245. var tmpCanvas = document.createElement('canvas');
  7246. tmpCanvas.width = img.canvas.width;
  7247. tmpCanvas.height = img.canvas.height;
  7248. var tmpCtx = tmpCanvas.getContext('2d');
  7249. var id = tmpCtx.createImageData(img.canvas.width, img.canvas.height);
  7250. var newPixels = id.data;
  7251. for (var i = 0; i < pixels.length; i += 4) {
  7252. var r = pixels[i];
  7253. var g = pixels[i + 1];
  7254. var b = pixels[i + 2];
  7255. var a = pixels[i + 3];
  7256. newPixels[i] = r * this._pInst._tint[0] / 255;
  7257. newPixels[i + 1] = g * this._pInst._tint[1] / 255;
  7258. newPixels[i + 2] = b * this._pInst._tint[2] / 255;
  7259. newPixels[i + 3] = a * this._pInst._tint[3] / 255;
  7260. }
  7261. tmpCtx.putImageData(id, 0, 0);
  7262. return tmpCanvas;
  7263. };
  7264. //////////////////////////////////////////////
  7265. // IMAGE | Pixels
  7266. //////////////////////////////////////////////
  7267. p5.Renderer2D.prototype.blendMode = function(mode) {
  7268. this.drawingContext.globalCompositeOperation = mode;
  7269. };
  7270. p5.Renderer2D.prototype.blend = function() {
  7271. var currBlend = this.drawingContext.globalCompositeOperation;
  7272. var blendMode = arguments[arguments.length - 1];
  7273. var copyArgs = Array.prototype.slice.call(
  7274. arguments,
  7275. 0,
  7276. arguments.length - 1
  7277. );
  7278. this.drawingContext.globalCompositeOperation = blendMode;
  7279. this._pInst.copy.apply(this._pInst, copyArgs);
  7280. this.drawingContext.globalCompositeOperation = currBlend;
  7281. };
  7282. p5.Renderer2D.prototype.copy = function () {
  7283. var srcImage, sx, sy, sw, sh, dx, dy, dw, dh;
  7284. if (arguments.length === 9) {
  7285. srcImage = arguments[0];
  7286. sx = arguments[1];
  7287. sy = arguments[2];
  7288. sw = arguments[3];
  7289. sh = arguments[4];
  7290. dx = arguments[5];
  7291. dy = arguments[6];
  7292. dw = arguments[7];
  7293. dh = arguments[8];
  7294. } else if (arguments.length === 8) {
  7295. srcImage = this._pInst;
  7296. sx = arguments[0];
  7297. sy = arguments[1];
  7298. sw = arguments[2];
  7299. sh = arguments[3];
  7300. dx = arguments[4];
  7301. dy = arguments[5];
  7302. dw = arguments[6];
  7303. dh = arguments[7];
  7304. } else {
  7305. throw new Error('Signature not supported');
  7306. }
  7307. p5.Renderer2D._copyHelper(srcImage, sx, sy, sw, sh, dx, dy, dw, dh);
  7308. };
  7309. p5.Renderer2D._copyHelper =
  7310. function (srcImage, sx, sy, sw, sh, dx, dy, dw, dh) {
  7311. var s = srcImage.canvas.width / srcImage.width;
  7312. this.drawingContext.drawImage(srcImage.canvas,
  7313. s * sx, s * sy, s * sw, s * sh, dx, dy, dw, dh);
  7314. };
  7315. p5.Renderer2D.prototype.get = function(x, y, w, h) {
  7316. if (x === undefined && y === undefined &&
  7317. w === undefined && h === undefined){
  7318. x = 0;
  7319. y = 0;
  7320. w = this.width;
  7321. h = this.height;
  7322. } else if (w === undefined && h === undefined) {
  7323. w = 1;
  7324. h = 1;
  7325. }
  7326. if(x > this.width || y > this.height || x < 0 || y < 0){
  7327. return [0, 0, 0, 255];
  7328. }
  7329. var pd = this.pixelDensity || this._pInst.pixelDensity;
  7330. if (w === 1 && h === 1){
  7331. var imageData = this.drawingContext.getImageData(x * pd, y * pd, w, h);
  7332. var data = imageData.data;
  7333. var pixels = [];
  7334. for (var i = 0; i < data.length; i += 4) {
  7335. pixels.push(data[i], data[i+1], data[i+2], data[i+3]);
  7336. }
  7337. return pixels;
  7338. } else {
  7339. var sx = x * pd;
  7340. var sy = y * pd;
  7341. //auto constrain the width and height to
  7342. //dimensions of the source image
  7343. var dw = Math.min(w, this.width);
  7344. var dh = Math.min(h, this.height);
  7345. var sw = dw * pd;
  7346. var sh = dh * pd;
  7347. var region = new p5.Image(dw, dh);
  7348. region.canvas.getContext('2d').drawImage(this.canvas, sx, sy, sw, sh,
  7349. 0, 0, dw, dh);
  7350. return region;
  7351. }
  7352. };
  7353. p5.Renderer2D.prototype.loadPixels = function () {
  7354. var pd = this.pixelDensity || this._pInst.pixelDensity;
  7355. var w = this.width * pd;
  7356. var h = this.height * pd;
  7357. var imageData = this.drawingContext.getImageData(0, 0, w, h);
  7358. if (this._pInst) {
  7359. this._pInst._setProperty('imageData', imageData);
  7360. this._pInst._setProperty('pixels', imageData.data);
  7361. } else { // if called by p5.Image
  7362. this._setProperty('imageData', imageData);
  7363. this._setProperty('pixels', imageData.data);
  7364. }
  7365. };
  7366. p5.Renderer2D.prototype.set = function (x, y, imgOrCol) {
  7367. var pd = this.pixelDensity || this._pInst.pixelDensity;
  7368. if (imgOrCol instanceof p5.Image) {
  7369. this.drawingContext.save();
  7370. this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);
  7371. this.drawingContext.scale(pd);
  7372. this.drawingContext.drawImage(imgOrCol.canvas, x, y);
  7373. this.loadPixels.call(this._pInst);
  7374. this.drawingContext.restore();
  7375. } else {
  7376. var ctx = this._pInst || this;
  7377. var r = 0, g = 0, b = 0, a = 0;
  7378. var idx = 4*((y * ctx.pixelDensity) *
  7379. (this.width * ctx.pixelDensity) + (x * ctx.pixelDensity));
  7380. if (!ctx.imageData) {
  7381. ctx.loadPixels.call(ctx);
  7382. }
  7383. if (typeof imgOrCol === 'number') {
  7384. if (idx < ctx.pixels.length) {
  7385. r = imgOrCol;
  7386. g = imgOrCol;
  7387. b = imgOrCol;
  7388. a = 255;
  7389. //this.updatePixels.call(this);
  7390. }
  7391. }
  7392. else if (imgOrCol instanceof Array) {
  7393. if (imgOrCol.length < 4) {
  7394. throw new Error('pixel array must be of the form [R, G, B, A]');
  7395. }
  7396. if (idx < ctx.pixels.length) {
  7397. r = imgOrCol[0];
  7398. g = imgOrCol[1];
  7399. b = imgOrCol[2];
  7400. a = imgOrCol[3];
  7401. //this.updatePixels.call(this);
  7402. }
  7403. } else if (imgOrCol instanceof p5.Color) {
  7404. if (idx < ctx.pixels.length) {
  7405. r = imgOrCol.rgba[0];
  7406. g = imgOrCol.rgba[1];
  7407. b = imgOrCol.rgba[2];
  7408. a = imgOrCol.rgba[3];
  7409. //this.updatePixels.call(this);
  7410. }
  7411. }
  7412. // loop over pixelDensity * pixelDensity
  7413. for (var i = 0; i < ctx.pixelDensity; i++) {
  7414. for (var j = 0; j < ctx.pixelDensity; j++) {
  7415. // loop over
  7416. idx = 4*((y * ctx.pixelDensity + j) * this.width *
  7417. ctx.pixelDensity + (x * ctx.pixelDensity + i));
  7418. ctx.pixels[idx] = r;
  7419. ctx.pixels[idx+1] = g;
  7420. ctx.pixels[idx+2] = b;
  7421. ctx.pixels[idx+3] = a;
  7422. }
  7423. }
  7424. }
  7425. };
  7426. p5.Renderer2D.prototype.updatePixels = function (x, y, w, h) {
  7427. var pd = this.pixelDensity || this._pInst.pixelDensity;
  7428. if (x === undefined &&
  7429. y === undefined &&
  7430. w === undefined &&
  7431. h === undefined) {
  7432. x = 0;
  7433. y = 0;
  7434. w = this.width;
  7435. h = this.height;
  7436. }
  7437. w *= pd;
  7438. h *= pd;
  7439. if (this._pInst) {
  7440. this.drawingContext.putImageData(this._pInst.imageData, x, y, 0, 0, w, h);
  7441. } else {
  7442. this.drawingContext.putImageData(this.imageData, x, y, 0, 0, w, h);
  7443. }
  7444. };
  7445. //////////////////////////////////////////////
  7446. // SHAPE | 2D Primitives
  7447. //////////////////////////////////////////////
  7448. /**
  7449. * Generate a cubic Bezier representing an arc on the unit circle of total
  7450. * angle `size` radians, beginning `start` radians above the x-axis. Up to
  7451. * four of these curves are combined to make a full arc.
  7452. *
  7453. * See www.joecridge.me/bezier.pdf for an explanation of the method.
  7454. */
  7455. p5.Renderer2D.prototype._acuteArcToBezier =
  7456. function _acuteArcToBezier(start, size) {
  7457. // Evauate constants.
  7458. var alpha = size / 2.0,
  7459. cos_alpha = Math.cos(alpha),
  7460. sin_alpha = Math.sin(alpha),
  7461. cot_alpha = 1.0 / Math.tan(alpha),
  7462. phi = start + alpha, // This is how far the arc needs to be rotated.
  7463. cos_phi = Math.cos(phi),
  7464. sin_phi = Math.sin(phi),
  7465. lambda = (4.0 - cos_alpha) / 3.0,
  7466. mu = sin_alpha + (cos_alpha - lambda) * cot_alpha;
  7467. // Return rotated waypoints.
  7468. return {
  7469. ax: Math.cos(start),
  7470. ay: Math.sin(start),
  7471. bx: lambda * cos_phi + mu * sin_phi,
  7472. by: lambda * sin_phi - mu * cos_phi,
  7473. cx: lambda * cos_phi - mu * sin_phi,
  7474. cy: lambda * sin_phi + mu * cos_phi,
  7475. dx: Math.cos(start + size),
  7476. dy: Math.sin(start + size)
  7477. };
  7478. };
  7479. p5.Renderer2D.prototype.arc =
  7480. function(x, y, w, h, start, stop, mode) {
  7481. var ctx = this.drawingContext;
  7482. var vals = canvas.arcModeAdjust(x, y, w, h, this._pInst._ellipseMode);
  7483. var rx = vals.w / 2.0;
  7484. var ry = vals.h / 2.0;
  7485. var epsilon = 0.00001; // Smallest visible angle on displays up to 4K.
  7486. var arcToDraw = 0;
  7487. var curves = [];
  7488. // Create curves
  7489. while(stop - start > epsilon) {
  7490. arcToDraw = Math.min(stop - start, constants.HALF_PI);
  7491. curves.push(this._acuteArcToBezier(start, arcToDraw));
  7492. start += arcToDraw;
  7493. }
  7494. // Fill curves
  7495. if (this._pInst._doFill) {
  7496. ctx.beginPath();
  7497. curves.forEach(function (curve, index) {
  7498. if (index === 0) {
  7499. ctx.moveTo(vals.x + curve.ax * rx, vals.y + curve.ay * ry);
  7500. }
  7501. ctx.bezierCurveTo(vals.x + curve.bx * rx, vals.y + curve.by * ry,
  7502. vals.x + curve.cx * rx, vals.y + curve.cy * ry,
  7503. vals.x + curve.dx * rx, vals.y + curve.dy * ry);
  7504. });
  7505. if (mode === constants.PIE || mode == null) {
  7506. ctx.lineTo(vals.x, vals.y);
  7507. }
  7508. ctx.closePath();
  7509. ctx.fill();
  7510. }
  7511. // Stroke curves
  7512. if (this._pInst._doStroke) {
  7513. ctx.beginPath();
  7514. curves.forEach(function (curve, index) {
  7515. if (index === 0) {
  7516. ctx.moveTo(vals.x + curve.ax * rx, vals.y + curve.ay * ry);
  7517. }
  7518. ctx.bezierCurveTo(vals.x + curve.bx * rx, vals.y + curve.by * ry,
  7519. vals.x + curve.cx * rx, vals.y + curve.cy * ry,
  7520. vals.x + curve.dx * rx, vals.y + curve.dy * ry);
  7521. });
  7522. if (mode === constants.PIE) {
  7523. ctx.lineTo(vals.x, vals.y);
  7524. ctx.closePath();
  7525. } else if (mode === constants.CHORD) {
  7526. ctx.closePath();
  7527. }
  7528. ctx.stroke();
  7529. }
  7530. return this;
  7531. };
  7532. p5.Renderer2D.prototype.ellipse = function(x, y, w, h) {
  7533. var ctx = this.drawingContext;
  7534. var doFill = this._pInst._doFill, doStroke = this._pInst._doStroke;
  7535. if (doFill && !doStroke) {
  7536. if(ctx.fillStyle === styleEmpty) {
  7537. return this;
  7538. }
  7539. } else if (!doFill && doStroke) {
  7540. if(ctx.strokeStyle === styleEmpty) {
  7541. return this;
  7542. }
  7543. }
  7544. var vals = canvas.modeAdjust(x, y, w, h, this._pInst._ellipseMode);
  7545. var kappa = 0.5522847498,
  7546. ox = (vals.w / 2) * kappa, // control point offset horizontal
  7547. oy = (vals.h / 2) * kappa, // control point offset vertical
  7548. xe = vals.x + vals.w, // x-end
  7549. ye = vals.y + vals.h, // y-end
  7550. xm = vals.x + vals.w / 2, // x-middle
  7551. ym = vals.y + vals.h / 2; // y-middle
  7552. ctx.beginPath();
  7553. ctx.moveTo(vals.x, ym);
  7554. ctx.bezierCurveTo(vals.x, ym - oy, xm - ox, vals.y, xm, vals.y);
  7555. ctx.bezierCurveTo(xm + ox, vals.y, xe, ym - oy, xe, ym);
  7556. ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  7557. ctx.bezierCurveTo(xm - ox, ye, vals.x, ym + oy, vals.x, ym);
  7558. ctx.closePath();
  7559. if (doFill) {
  7560. ctx.fill();
  7561. }
  7562. if (doStroke) {
  7563. ctx.stroke();
  7564. }
  7565. };
  7566. p5.Renderer2D.prototype.line = function(x1, y1, x2, y2) {
  7567. var ctx = this.drawingContext;
  7568. if (!this._pInst._doStroke) {
  7569. return this;
  7570. } else if(ctx.strokeStyle === styleEmpty){
  7571. return this;
  7572. }
  7573. // Translate the line by (0.5, 0.5) to draw it crisp
  7574. if (ctx.lineWidth % 2 === 1) {
  7575. ctx.translate(0.5, 0.5);
  7576. }
  7577. ctx.beginPath();
  7578. ctx.moveTo(x1, y1);
  7579. ctx.lineTo(x2, y2);
  7580. ctx.stroke();
  7581. if (ctx.lineWidth % 2 === 1) {
  7582. ctx.translate(-0.5, -0.5);
  7583. }
  7584. return this;
  7585. };
  7586. p5.Renderer2D.prototype.point = function(x, y) {
  7587. var ctx = this.drawingContext;
  7588. var s = ctx.strokeStyle;
  7589. var f = ctx.fillStyle;
  7590. if (!this._pInst._doStroke) {
  7591. return this;
  7592. } else if(ctx.strokeStyle === styleEmpty){
  7593. return this;
  7594. }
  7595. x = Math.round(x);
  7596. y = Math.round(y);
  7597. ctx.fillStyle = s;
  7598. if (ctx.lineWidth > 1) {
  7599. ctx.beginPath();
  7600. ctx.arc(
  7601. x,
  7602. y,
  7603. ctx.lineWidth / 2,
  7604. 0,
  7605. constants.TWO_PI,
  7606. false
  7607. );
  7608. ctx.fill();
  7609. } else {
  7610. ctx.fillRect(x, y, 1, 1);
  7611. }
  7612. ctx.fillStyle = f;
  7613. };
  7614. p5.Renderer2D.prototype.quad =
  7615. function(x1, y1, x2, y2, x3, y3, x4, y4) {
  7616. var ctx = this.drawingContext;
  7617. var doFill = this._pInst._doFill, doStroke = this._pInst._doStroke;
  7618. if (doFill && !doStroke) {
  7619. if(ctx.fillStyle === styleEmpty) {
  7620. return this;
  7621. }
  7622. } else if (!doFill && doStroke) {
  7623. if(ctx.strokeStyle === styleEmpty) {
  7624. return this;
  7625. }
  7626. }
  7627. ctx.beginPath();
  7628. ctx.moveTo(x1, y1);
  7629. ctx.lineTo(x2, y2);
  7630. ctx.lineTo(x3, y3);
  7631. ctx.lineTo(x4, y4);
  7632. ctx.closePath();
  7633. if (doFill) {
  7634. ctx.fill();
  7635. }
  7636. if (doStroke) {
  7637. ctx.stroke();
  7638. }
  7639. return this;
  7640. };
  7641. p5.Renderer2D.prototype.rect = function(x, y, w, h, tl, tr, br, bl) {
  7642. var ctx = this.drawingContext;
  7643. var doFill = this._pInst._doFill, doStroke = this._pInst._doStroke;
  7644. if (doFill && !doStroke) {
  7645. if(ctx.fillStyle === styleEmpty) {
  7646. return this;
  7647. }
  7648. } else if (!doFill && doStroke) {
  7649. if(ctx.strokeStyle === styleEmpty) {
  7650. return this;
  7651. }
  7652. }
  7653. var vals = canvas.modeAdjust(x, y, w, h, this._pInst._rectMode);
  7654. // Translate the line by (0.5, 0.5) to draw a crisp rectangle border
  7655. if (this._pInst._doStroke && ctx.lineWidth % 2 === 1) {
  7656. ctx.translate(0.5, 0.5);
  7657. }
  7658. ctx.beginPath();
  7659. if (typeof tl === 'undefined') {
  7660. // No rounded corners
  7661. ctx.rect(vals.x, vals.y, vals.w, vals.h);
  7662. } else {
  7663. // At least one rounded corner
  7664. // Set defaults when not specified
  7665. if (typeof tr === 'undefined') { tr = tl; }
  7666. if (typeof br === 'undefined') { br = tr; }
  7667. if (typeof bl === 'undefined') { bl = br; }
  7668. // Cache and compute several values
  7669. var _x = vals.x;
  7670. var _y = vals.y;
  7671. var _w = vals.w;
  7672. var _h = vals.h;
  7673. var hw = _w / 2;
  7674. var hh = _h / 2;
  7675. // Clip radii
  7676. if (_w < 2 * tl) { tl = hw; }
  7677. if (_h < 2 * tl) { tl = hh; }
  7678. if (_w < 2 * tr) { tr = hw; }
  7679. if (_h < 2 * tr) { tr = hh; }
  7680. if (_w < 2 * br) { br = hw; }
  7681. if (_h < 2 * br) { br = hh; }
  7682. if (_w < 2 * bl) { bl = hw; }
  7683. if (_h < 2 * bl) { bl = hh; }
  7684. // Draw shape
  7685. ctx.beginPath();
  7686. ctx.moveTo(_x + tl, _y);
  7687. ctx.arcTo(_x + _w, _y, _x + _w, _y + _h, tr);
  7688. ctx.arcTo(_x + _w, _y + _h, _x, _y + _h, br);
  7689. ctx.arcTo(_x, _y + _h, _x, _y, bl);
  7690. ctx.arcTo(_x, _y, _x + _w, _y, tl);
  7691. ctx.closePath();
  7692. }
  7693. if (this._pInst._doFill) {
  7694. ctx.fill();
  7695. }
  7696. if (this._pInst._doStroke) {
  7697. ctx.stroke();
  7698. }
  7699. if (this._pInst._doStroke && ctx.lineWidth % 2 === 1) {
  7700. ctx.translate(-0.5, -0.5);
  7701. }
  7702. return this;
  7703. };
  7704. p5.Renderer2D.prototype.triangle = function(x1, y1, x2, y2, x3, y3) {
  7705. var ctx = this.drawingContext;
  7706. var doFill = this._pInst._doFill, doStroke = this._pInst._doStroke;
  7707. if (doFill && !doStroke) {
  7708. if(ctx.fillStyle === styleEmpty) {
  7709. return this;
  7710. }
  7711. } else if (!doFill && doStroke) {
  7712. if(ctx.strokeStyle === styleEmpty) {
  7713. return this;
  7714. }
  7715. }
  7716. ctx.beginPath();
  7717. ctx.moveTo(x1, y1);
  7718. ctx.lineTo(x2, y2);
  7719. ctx.lineTo(x3, y3);
  7720. ctx.closePath();
  7721. if (doFill) {
  7722. ctx.fill();
  7723. }
  7724. if (doStroke) {
  7725. ctx.stroke();
  7726. }
  7727. };
  7728. p5.Renderer2D.prototype.endShape =
  7729. function (mode, vertices, isCurve, isBezier,
  7730. isQuadratic, isContour, shapeKind) {
  7731. if (vertices.length === 0) {
  7732. return this;
  7733. }
  7734. if (!this._pInst._doStroke && !this._pInst._doFill) {
  7735. return this;
  7736. }
  7737. var closeShape = mode === constants.CLOSE;
  7738. var v;
  7739. if (closeShape && !isContour) {
  7740. vertices.push(vertices[0]);
  7741. }
  7742. var i, j;
  7743. var numVerts = vertices.length;
  7744. if (isCurve && (shapeKind === constants.POLYGON || shapeKind === null)) {
  7745. if (numVerts > 3) {
  7746. var b = [], s = 1 - this._pInst._curveTightness;
  7747. this.drawingContext.beginPath();
  7748. this.drawingContext.moveTo(vertices[1][0], vertices[1][1]);
  7749. for (i = 1; i + 2 < numVerts; i++) {
  7750. v = vertices[i];
  7751. b[0] = [
  7752. v[0],
  7753. v[1]
  7754. ];
  7755. b[1] = [
  7756. v[0] + (s * vertices[i + 1][0] - s * vertices[i - 1][0]) / 6,
  7757. v[1] + (s * vertices[i + 1][1] - s * vertices[i - 1][1]) / 6
  7758. ];
  7759. b[2] = [
  7760. vertices[i + 1][0] +
  7761. (s * vertices[i][0]-s * vertices[i + 2][0]) / 6,
  7762. vertices[i + 1][1]+(s * vertices[i][1] - s*vertices[i + 2][1]) / 6
  7763. ];
  7764. b[3] = [
  7765. vertices[i + 1][0],
  7766. vertices[i + 1][1]
  7767. ];
  7768. this.drawingContext.bezierCurveTo(b[1][0],b[1][1],
  7769. b[2][0],b[2][1],b[3][0],b[3][1]);
  7770. }
  7771. if (closeShape) {
  7772. this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);
  7773. }
  7774. this._doFillStrokeClose();
  7775. }
  7776. } else if (isBezier&&(shapeKind===constants.POLYGON ||shapeKind === null)) {
  7777. this.drawingContext.beginPath();
  7778. for (i = 0; i < numVerts; i++) {
  7779. if (vertices[i].isVert) {
  7780. if (vertices[i].moveTo) {
  7781. this.drawingContext.moveTo(vertices[i][0], vertices[i][1]);
  7782. } else {
  7783. this.drawingContext.lineTo(vertices[i][0], vertices[i][1]);
  7784. }
  7785. } else {
  7786. this.drawingContext.bezierCurveTo(vertices[i][0], vertices[i][1],
  7787. vertices[i][2], vertices[i][3], vertices[i][4], vertices[i][5]);
  7788. }
  7789. }
  7790. this._doFillStrokeClose();
  7791. } else if (isQuadratic &&
  7792. (shapeKind === constants.POLYGON || shapeKind === null)) {
  7793. this.drawingContext.beginPath();
  7794. for (i = 0; i < numVerts; i++) {
  7795. if (vertices[i].isVert) {
  7796. if (vertices[i].moveTo) {
  7797. this.drawingContext.moveTo([0], vertices[i][1]);
  7798. } else {
  7799. this.drawingContext.lineTo(vertices[i][0], vertices[i][1]);
  7800. }
  7801. } else {
  7802. this.drawingContext.quadraticCurveTo(vertices[i][0], vertices[i][1],
  7803. vertices[i][2], vertices[i][3]);
  7804. }
  7805. }
  7806. this._doFillStrokeClose();
  7807. } else {
  7808. if (shapeKind === constants.POINTS) {
  7809. for (i = 0; i < numVerts; i++) {
  7810. v = vertices[i];
  7811. if (this._pInst._doStroke) {
  7812. this._pInst.stroke(v[6]);
  7813. }
  7814. this._pInst.point(v[0], v[1]);
  7815. }
  7816. } else if (shapeKind === constants.LINES) {
  7817. for (i = 0; i + 1 < numVerts; i += 2) {
  7818. v = vertices[i];
  7819. if (this._pInst._doStroke) {
  7820. this._pInst.stroke(vertices[i + 1][6]);
  7821. }
  7822. this._pInst.line(v[0], v[1], vertices[i + 1][0], vertices[i + 1][1]);
  7823. }
  7824. } else if (shapeKind === constants.TRIANGLES) {
  7825. for (i = 0; i + 2 < numVerts; i += 3) {
  7826. v = vertices[i];
  7827. this.drawingContext.beginPath();
  7828. this.drawingContext.moveTo(v[0], v[1]);
  7829. this.drawingContext.lineTo(vertices[i + 1][0], vertices[i + 1][1]);
  7830. this.drawingContext.lineTo(vertices[i + 2][0], vertices[i + 2][1]);
  7831. this.drawingContext.lineTo(v[0], v[1]);
  7832. if (this._pInst._doFill) {
  7833. this._pInst.fill(vertices[i + 2][5]);
  7834. this.drawingContext.fill();
  7835. }
  7836. if (this._pInst._doStroke) {
  7837. this._pInst.stroke(vertices[i + 2][6]);
  7838. this.drawingContext.stroke();
  7839. }
  7840. this.drawingContext.closePath();
  7841. }
  7842. } else if (shapeKind === constants.TRIANGLE_STRIP) {
  7843. for (i = 0; i + 1 < numVerts; i++) {
  7844. v = vertices[i];
  7845. this.drawingContext.beginPath();
  7846. this.drawingContext.moveTo(vertices[i + 1][0], vertices[i + 1][1]);
  7847. this.drawingContext.lineTo(v[0], v[1]);
  7848. if (this._pInst._doStroke) {
  7849. this._pInst.stroke(vertices[i + 1][6]);
  7850. }
  7851. if (this._pInst._doFill) {
  7852. this._pInst.fill(vertices[i + 1][5]);
  7853. }
  7854. if (i + 2 < numVerts) {
  7855. this.drawingContext.lineTo(vertices[i + 2][0], vertices[i + 2][1]);
  7856. if (this._pInst._doStroke) {
  7857. this._pInst.stroke(vertices[i + 2][6]);
  7858. }
  7859. if (this._pInst._doFill) {
  7860. this._pInst.fill(vertices[i + 2][5]);
  7861. }
  7862. }
  7863. this._doFillStrokeClose();
  7864. }
  7865. } else if (shapeKind === constants.TRIANGLE_FAN) {
  7866. if (numVerts > 2) {
  7867. this.drawingContext.beginPath();
  7868. this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);
  7869. this.drawingContext.lineTo(vertices[1][0], vertices[1][1]);
  7870. this.drawingContext.lineTo(vertices[2][0], vertices[2][1]);
  7871. if (this._pInst._doFill) {
  7872. this._pInst.fill(vertices[2][5]);
  7873. }
  7874. if (this._pInst._doStroke) {
  7875. this._pInst.stroke(vertices[2][6]);
  7876. }
  7877. this._doFillStrokeClose();
  7878. for (i = 3; i < numVerts; i++) {
  7879. v = vertices[i];
  7880. this.drawingContext.beginPath();
  7881. this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);
  7882. this.drawingContext.lineTo(vertices[i - 1][0], vertices[i - 1][1]);
  7883. this.drawingContext.lineTo(v[0], v[1]);
  7884. if (this._pInst._doFill) {
  7885. this._pInst.fill(v[5]);
  7886. }
  7887. if (this._pInst._doStroke) {
  7888. this._pInst.stroke(v[6]);
  7889. }
  7890. this._doFillStrokeClose();
  7891. }
  7892. }
  7893. } else if (shapeKind === constants.QUADS) {
  7894. for (i = 0; i + 3 < numVerts; i += 4) {
  7895. v = vertices[i];
  7896. this.drawingContext.beginPath();
  7897. this.drawingContext.moveTo(v[0], v[1]);
  7898. for (j = 1; j < 4; j++) {
  7899. this.drawingContext.lineTo(vertices[i + j][0], vertices[i + j][1]);
  7900. }
  7901. this.drawingContext.lineTo(v[0], v[1]);
  7902. if (this._pInst._doFill) {
  7903. this._pInst.fill(vertices[i + 3][5]);
  7904. }
  7905. if (this._pInst._doStroke) {
  7906. this._pInst.stroke(vertices[i + 3][6]);
  7907. }
  7908. this._doFillStrokeClose();
  7909. }
  7910. } else if (shapeKind === constants.QUAD_STRIP) {
  7911. if (numVerts > 3) {
  7912. for (i = 0; i + 1 < numVerts; i += 2) {
  7913. v = vertices[i];
  7914. this.drawingContext.beginPath();
  7915. if (i + 3 < numVerts) {
  7916. this.drawingContext.moveTo(vertices[i + 2][0], vertices[i+2][1]);
  7917. this.drawingContext.lineTo(v[0], v[1]);
  7918. this.drawingContext.lineTo(vertices[i + 1][0], vertices[i+1][1]);
  7919. this.drawingContext.lineTo(vertices[i + 3][0], vertices[i+3][1]);
  7920. if (this._pInst._doFill) {
  7921. this._pInst.fill(vertices[i + 3][5]);
  7922. }
  7923. if (this._pInst._doStroke) {
  7924. this._pInst.stroke(vertices[i + 3][6]);
  7925. }
  7926. } else {
  7927. this.drawingContext.moveTo(v[0], v[1]);
  7928. this.drawingContext.lineTo(vertices[i + 1][0], vertices[i+1][1]);
  7929. }
  7930. this._doFillStrokeClose();
  7931. }
  7932. }
  7933. } else {
  7934. this.drawingContext.beginPath();
  7935. this.drawingContext.moveTo(vertices[0][0], vertices[0][1]);
  7936. for (i = 1; i < numVerts; i++) {
  7937. v = vertices[i];
  7938. if (v.isVert) {
  7939. if (v.moveTo) {
  7940. this.drawingContext.moveTo(v[0], v[1]);
  7941. } else {
  7942. this.drawingContext.lineTo(v[0], v[1]);
  7943. }
  7944. }
  7945. }
  7946. this._doFillStrokeClose();
  7947. }
  7948. }
  7949. isCurve = false;
  7950. isBezier = false;
  7951. isQuadratic = false;
  7952. isContour = false;
  7953. if (closeShape) {
  7954. vertices.pop();
  7955. }
  7956. return this;
  7957. };
  7958. //////////////////////////////////////////////
  7959. // SHAPE | Attributes
  7960. //////////////////////////////////////////////
  7961. p5.Renderer2D.prototype.noSmooth = function() {
  7962. if ('imageSmoothingEnabled' in this.drawingContext) {
  7963. this.drawingContext.imageSmoothingEnabled = false;
  7964. }
  7965. else if ('mozImageSmoothingEnabled' in this.drawingContext) {
  7966. this.drawingContext.mozImageSmoothingEnabled = false;
  7967. }
  7968. else if ('webkitImageSmoothingEnabled' in this.drawingContext) {
  7969. this.drawingContext.webkitImageSmoothingEnabled = false;
  7970. }
  7971. else if ('msImageSmoothingEnabled' in this.drawingContext) {
  7972. this.drawingContext.msImageSmoothingEnabled = false;
  7973. }
  7974. return this;
  7975. };
  7976. p5.Renderer2D.prototype.smooth = function() {
  7977. if ('imageSmoothingEnabled' in this.drawingContext) {
  7978. this.drawingContext.imageSmoothingEnabled = true;
  7979. }
  7980. else if ('mozImageSmoothingEnabled' in this.drawingContext) {
  7981. this.drawingContext.mozImageSmoothingEnabled = true;
  7982. }
  7983. else if ('webkitImageSmoothingEnabled' in this.drawingContext) {
  7984. this.drawingContext.webkitImageSmoothingEnabled = true;
  7985. }
  7986. else if ('msImageSmoothingEnabled' in this.drawingContext) {
  7987. this.drawingContext.msImageSmoothingEnabled = true;
  7988. }
  7989. return this;
  7990. };
  7991. p5.Renderer2D.prototype.strokeCap = function(cap) {
  7992. if (cap === constants.ROUND ||
  7993. cap === constants.SQUARE ||
  7994. cap === constants.PROJECT) {
  7995. this.drawingContext.lineCap = cap;
  7996. }
  7997. return this;
  7998. };
  7999. p5.Renderer2D.prototype.strokeJoin = function(join) {
  8000. if (join === constants.ROUND ||
  8001. join === constants.BEVEL ||
  8002. join === constants.MITER) {
  8003. this.drawingContext.lineJoin = join;
  8004. }
  8005. return this;
  8006. };
  8007. p5.Renderer2D.prototype.strokeWeight = function(w) {
  8008. if (typeof w === 'undefined' || w === 0) {
  8009. // hack because lineWidth 0 doesn't work
  8010. this.drawingContext.lineWidth = 0.0001;
  8011. } else {
  8012. this.drawingContext.lineWidth = w;
  8013. }
  8014. return this;
  8015. };
  8016. p5.Renderer2D.prototype._getFill = function(){
  8017. return this.drawingContext.fillStyle;
  8018. };
  8019. p5.Renderer2D.prototype._getStroke = function(){
  8020. return this.drawingContext.strokeStyle;
  8021. };
  8022. //////////////////////////////////////////////
  8023. // SHAPE | Curves
  8024. //////////////////////////////////////////////
  8025. p5.Renderer2D.prototype.bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {
  8026. this._pInst.beginShape();
  8027. this._pInst.vertex(x1, y1);
  8028. this._pInst.bezierVertex(x2, y2, x3, y3, x4, y4);
  8029. this._pInst.endShape();
  8030. return this;
  8031. };
  8032. p5.Renderer2D.prototype.curve = function (x1, y1, x2, y2, x3, y3, x4, y4) {
  8033. this._pInst.beginShape();
  8034. this._pInst.curveVertex(x1, y1);
  8035. this._pInst.curveVertex(x2, y2);
  8036. this._pInst.curveVertex(x3, y3);
  8037. this._pInst.curveVertex(x4, y4);
  8038. this._pInst.endShape();
  8039. return this;
  8040. };
  8041. //////////////////////////////////////////////
  8042. // SHAPE | Vertex
  8043. //////////////////////////////////////////////
  8044. p5.Renderer2D.prototype._doFillStrokeClose = function () {
  8045. if (this._pInst._doFill) {
  8046. this.drawingContext.fill();
  8047. }
  8048. if (this._pInst._doStroke) {
  8049. this.drawingContext.stroke();
  8050. }
  8051. this.drawingContext.closePath();
  8052. };
  8053. //////////////////////////////////////////////
  8054. // TRANSFORM
  8055. //////////////////////////////////////////////
  8056. p5.Renderer2D.prototype.applyMatrix =
  8057. function(n00, n01, n02, n10, n11, n12) {
  8058. this.drawingContext.transform(n00, n01, n02, n10, n11, n12);
  8059. };
  8060. p5.Renderer2D.prototype.resetMatrix = function() {
  8061. this.drawingContext.setTransform(1, 0, 0, 1, 0, 0);
  8062. this.drawingContext.scale(this._pInst.pixelDensity,
  8063. this._pInst.pixelDensity);
  8064. return this;
  8065. };
  8066. p5.Renderer2D.prototype.rotate = function(r) {
  8067. this.drawingContext.rotate(r);
  8068. };
  8069. p5.Renderer2D.prototype.scale = function() {
  8070. var x = 1.0,
  8071. y = 1.0;
  8072. if (arguments.length === 1) {
  8073. x = y = arguments[0];
  8074. } else {
  8075. x = arguments[0];
  8076. y = arguments[1];
  8077. }
  8078. this.drawingContext.scale(x, y);
  8079. return this;
  8080. };
  8081. p5.Renderer2D.prototype.shearX = function(angle) {
  8082. if (this._pInst._angleMode === constants.DEGREES) {
  8083. angle = this._pInst.radians(angle);
  8084. }
  8085. this.drawingContext.transform(1, 0, this._pInst.tan(angle), 1, 0, 0);
  8086. return this;
  8087. };
  8088. p5.Renderer2D.prototype.shearY = function(angle) {
  8089. if (this._pInst._angleMode === constants.DEGREES) {
  8090. angle = this._pInst.radians(angle);
  8091. }
  8092. this.drawingContext.transform(1, this._pInst.tan(angle), 0, 1, 0, 0);
  8093. return this;
  8094. };
  8095. p5.Renderer2D.prototype.translate = function(x, y) {
  8096. this.drawingContext.translate(x, y);
  8097. return this;
  8098. };
  8099. //////////////////////////////////////////////
  8100. // TYPOGRAPHY
  8101. //
  8102. //////////////////////////////////////////////
  8103. p5.Renderer2D.prototype.text = function (str, x, y, maxWidth, maxHeight) {
  8104. var p = this._pInst, cars, n, ii, jj, line, testLine,
  8105. testWidth, words, totalHeight, baselineHacked;
  8106. // baselineHacked: (HACK)
  8107. // This is an ugly temporary fix to conform to
  8108. // Processing's vertical alignment implementation
  8109. // for BASELINE vetical alignment in a boundings box
  8110. if (!(p._doFill || p._doStroke)) {
  8111. return;
  8112. }
  8113. if (typeof str !== 'string') {
  8114. str = str.toString();
  8115. }
  8116. str = str.replace(/(\t)/g, ' ');
  8117. cars = str.split('\n');
  8118. if (typeof maxWidth !== 'undefined') {
  8119. totalHeight = 0;
  8120. for (ii = 0; ii < cars.length; ii++) {
  8121. line = '';
  8122. words = cars[ii].split(' ');
  8123. for (n = 0; n < words.length; n++) {
  8124. testLine = line + words[n] + ' ';
  8125. testWidth = this.textWidth(testLine);
  8126. if (testWidth > maxWidth) {
  8127. line = words[n] + ' ';
  8128. totalHeight += p.textLeading();
  8129. } else {
  8130. line = testLine;
  8131. }
  8132. }
  8133. }
  8134. if (this._pInst._rectMode === constants.CENTER ){
  8135. x -= maxWidth / 2;
  8136. y -= maxHeight / 2;
  8137. }
  8138. switch (this.drawingContext.textAlign) {
  8139. case constants.CENTER:
  8140. x += maxWidth / 2;
  8141. break;
  8142. case constants.RIGHT:
  8143. x += maxWidth;
  8144. break;
  8145. }
  8146. if (typeof maxHeight !== 'undefined') {
  8147. switch (this.drawingContext.textBaseline) {
  8148. case constants.BOTTOM:
  8149. y += (maxHeight - totalHeight);
  8150. break;
  8151. case constants._CTX_MIDDLE:
  8152. y += (maxHeight - totalHeight) / 2;
  8153. break;
  8154. case constants.BASELINE:
  8155. baselineHacked = true;
  8156. this.drawingContext.textBaseline = constants.TOP;
  8157. break;
  8158. }
  8159. }
  8160. for (ii = 0; ii < cars.length; ii++) {
  8161. line = '';
  8162. words = cars[ii].split(' ');
  8163. for (n = 0; n < words.length; n++) {
  8164. testLine = line + words[n] + ' ';
  8165. testWidth = this.textWidth(testLine);
  8166. if (testWidth > maxWidth && line.length > 0) {
  8167. this._renderText(p, line, x, y);
  8168. line = words[n] + ' ';
  8169. y += p.textLeading();
  8170. } else {
  8171. line = testLine;
  8172. }
  8173. }
  8174. this._renderText(p, line, x, y);
  8175. y += p.textLeading();
  8176. }
  8177. }
  8178. else {
  8179. for (jj = 0; jj < cars.length; jj++) {
  8180. this._renderText(p, cars[jj], x, y);
  8181. y += p.textLeading();
  8182. }
  8183. }
  8184. if (baselineHacked) {
  8185. this.drawingContext.textBaseline = constants.BASELINE;
  8186. }
  8187. return p;
  8188. };
  8189. p5.Renderer2D.prototype._renderText = function(p, line, x, y) {
  8190. p.push(); // fix to #803
  8191. if (!p._isOpenType()) { // a system/browser font
  8192. // no stroke unless specified by user
  8193. if (p._doStroke && p._strokeSet) {
  8194. this.drawingContext.strokeText(line, x, y);
  8195. }
  8196. if (p._doFill) {
  8197. // if fill hasn't been set by user, use default text fill
  8198. this.drawingContext.fillStyle = p._fillSet ?
  8199. this.drawingContext.fillStyle : constants._DEFAULT_TEXT_FILL;
  8200. this.drawingContext.fillText(line, x, y);
  8201. }
  8202. }
  8203. else { // an opentype font, let it handle the rendering
  8204. p._textFont._renderPath(line, x, y);
  8205. }
  8206. p.pop();
  8207. return p;
  8208. };
  8209. p5.Renderer2D.prototype.textWidth = function(s) {
  8210. if (this._pInst._isOpenType()) {
  8211. return this._pInst._textFont._textWidth(s);
  8212. }
  8213. return this.drawingContext.measureText(s).width;
  8214. };
  8215. p5.Renderer2D.prototype.textAlign = function(h, v) {
  8216. if (arguments.length) {
  8217. if (h === constants.LEFT ||
  8218. h === constants.RIGHT ||
  8219. h === constants.CENTER) {
  8220. this.drawingContext.textAlign = h;
  8221. }
  8222. if (v === constants.TOP ||
  8223. v === constants.BOTTOM ||
  8224. v === constants.CENTER ||
  8225. v === constants.BASELINE) {
  8226. if (v === constants.CENTER) {
  8227. this.drawingContext.textBaseline = constants._CTX_MIDDLE;
  8228. } else {
  8229. this.drawingContext.textBaseline = v;
  8230. }
  8231. }
  8232. return this._pInst;
  8233. } else {
  8234. var valign = this.drawingContext.textBaseline;
  8235. if (valign === constants._CTX_MIDDLE) {
  8236. valign = constants.CENTER;
  8237. }
  8238. return {
  8239. horizontal: this.drawingContext.textAlign,
  8240. vertical: valign
  8241. };
  8242. }
  8243. };
  8244. p5.Renderer2D.prototype._applyTextProperties = function() {
  8245. var font, p = this._pInst;
  8246. p._setProperty('_textAscent', null);
  8247. p._setProperty('_textDescent', null);
  8248. font = p._textFont;
  8249. if (p._isOpenType()) {
  8250. font = p._textFont.font.familyName;
  8251. p._setProperty('_textStyle', p._textFont.font.styleName);
  8252. }
  8253. this.drawingContext.font = p._textStyle + ' ' + p._textSize + 'px ' + font;
  8254. return p;
  8255. };
  8256. //////////////////////////////////////////////
  8257. // STRUCTURE
  8258. //////////////////////////////////////////////
  8259. p5.Renderer2D.prototype.push = function() {
  8260. this.drawingContext.save();
  8261. };
  8262. p5.Renderer2D.prototype.pop = function() {
  8263. this.drawingContext.restore();
  8264. };
  8265. module.exports = p5.Renderer2D;
  8266. },{"../image/filters":34,"./canvas":15,"./constants":16,"./core":17,"./p5.Renderer":23}],25:[function(require,module,exports){
  8267. /**
  8268. * @module Rendering
  8269. * @submodule Rendering
  8270. * @for p5
  8271. */
  8272. var p5 = require('./core');
  8273. var constants = require('./constants');
  8274. require('./p5.Graphics');
  8275. require('./p5.Renderer2D');
  8276. require('../3d/p5.Renderer3D');
  8277. /**
  8278. * Creates a canvas element in the document, and sets the dimensions of it
  8279. * in pixels. This method should be called only once at the start of setup.
  8280. * Calling createCanvas more than once in a sketch will result in very
  8281. * unpredicable behavior. If you want more than one drawing canvas
  8282. * you could use createGraphics (hidden by default but it can be shown).<br>
  8283. * The system variables width and height are set by the parameters passed
  8284. * to this function. If createCanvas() is not used, the window will be
  8285. * given a default size of 100x100 pixels.
  8286. *
  8287. * @method createCanvas
  8288. * @param {Number} w width of the canvas
  8289. * @param {Number} h height of the canvas
  8290. * @param optional:{String} renderer 'p2d' | 'webgl'
  8291. * @return {Object} canvas generated
  8292. * @example
  8293. * <div>
  8294. * <code>
  8295. * function setup() {
  8296. * createCanvas(100, 50);
  8297. * background(153);
  8298. * line(0, 0, width, height);
  8299. * }
  8300. * </code>
  8301. * </div>
  8302. */
  8303. p5.prototype.createCanvas = function(w, h, renderer) {
  8304. //optional: renderer, otherwise defaults to p2d
  8305. var r = renderer || constants.P2D;
  8306. var isDefault, c;
  8307. //4th arg (isDefault) used when called onLoad,
  8308. //otherwise hidden to the public api
  8309. if(arguments[3]){
  8310. isDefault =
  8311. (typeof arguments[3] === 'boolean') ? arguments[3] : false;
  8312. }
  8313. if(r === constants.WEBGL){
  8314. c = document.getElementById('defaultCanvas');
  8315. if(c){ //if defaultCanvas already exists
  8316. c.parentNode.removeChild(c); //replace the existing defaultCanvas
  8317. }
  8318. c = document.createElement('canvas');
  8319. c.id = 'defaultCanvas';
  8320. }
  8321. else {
  8322. if (isDefault) {
  8323. c = document.createElement('canvas');
  8324. c.id = 'defaultCanvas';
  8325. } else { // resize the default canvas if new one is created
  8326. c = this.canvas;
  8327. }
  8328. }
  8329. // set to invisible if still in setup (to prevent flashing with manipulate)
  8330. if (!this._setupDone) {
  8331. c.className += ' p5_hidden'; // tag to show later
  8332. c.style.visibility='hidden';
  8333. }
  8334. if (this._userNode) { // user input node case
  8335. this._userNode.appendChild(c);
  8336. } else {
  8337. document.body.appendChild(c);
  8338. }
  8339. // Init our graphics renderer
  8340. //webgl mode
  8341. if (r === constants.WEBGL) {
  8342. this._setProperty('_graphics', new p5.Renderer3D(c, this, true));
  8343. this._isdefaultGraphics = true;
  8344. }
  8345. //P2D mode
  8346. else {
  8347. if (!this._isdefaultGraphics) {
  8348. this._setProperty('_graphics', new p5.Renderer2D(c, this, true));
  8349. this._isdefaultGraphics = true;
  8350. }
  8351. }
  8352. this._graphics.resize(w, h);
  8353. this._graphics._applyDefaults();
  8354. return this._graphics;
  8355. };
  8356. /**
  8357. * Resizes the canvas to given width and height. Note that the
  8358. * canvas will be cleared so anything drawn previously in setup
  8359. * or draw will disappear on resize. Setup will not be called
  8360. * again.
  8361. * @method resizeCanvas
  8362. * @example
  8363. * <div class="norender"><code>
  8364. * function setup() {
  8365. * createCanvas(windowWidth, windowHeight);
  8366. * }
  8367. *
  8368. * function draw() {
  8369. * background(0, 100, 200);
  8370. * }
  8371. *
  8372. * function windowResized() {
  8373. * resizeCanvas(windowWidth, windowHeight);
  8374. * }
  8375. * </code></div>
  8376. */
  8377. p5.prototype.resizeCanvas = function (w, h, noRedraw) {
  8378. if (this._graphics) {
  8379. this._graphics.resize(w, h);
  8380. this._graphics._applyDefaults();
  8381. if (!noRedraw) {
  8382. this.redraw();
  8383. }
  8384. }
  8385. };
  8386. /**
  8387. * Removes the default canvas for a p5 sketch that doesn't
  8388. * require a canvas
  8389. * @method noCanvas
  8390. * @example
  8391. * <div>
  8392. * <code>
  8393. * function setup() {
  8394. * noCanvas();
  8395. * }
  8396. * </code>
  8397. * </div>
  8398. */
  8399. p5.prototype.noCanvas = function() {
  8400. if (this.canvas) {
  8401. this.canvas.parentNode.removeChild(this.canvas);
  8402. }
  8403. };
  8404. /**
  8405. * Creates and returns a new p5.Renderer object. Use this class if you need
  8406. * to draw into an off-screen graphics buffer. The two parameters define the
  8407. * width and height in pixels.
  8408. *
  8409. * @method createGraphics
  8410. * @param {Number} w width of the offscreen graphics buffer
  8411. * @param {Number} h height of the offscreen graphics buffer
  8412. * @param {String} renderer either 'p2d' or 'webgl'.
  8413. * undefined defaults to p2d
  8414. * @return {Object} offscreen graphics buffer
  8415. * @example
  8416. * <div>
  8417. * <code>
  8418. * var pg;
  8419. * function setup() {
  8420. * createCanvas(100, 100);
  8421. * pg = createGraphics(100, 100);
  8422. * }
  8423. * function draw() {
  8424. * background(200);
  8425. * pg.background(100);
  8426. * pg.noStroke();
  8427. * pg.ellipse(pg.width/2, pg.height/2, 50, 50);
  8428. * image(pg, 50, 50);
  8429. * image(pg, 0, 0, 50, 50);
  8430. * }
  8431. * </code>
  8432. * </div>
  8433. */
  8434. p5.prototype.createGraphics = function(w, h, renderer){
  8435. return new p5.Graphics(w, h, renderer, this);
  8436. };
  8437. /**
  8438. * Blends the pixels in the display window according to the defined mode.
  8439. * There is a choice of the following modes to blend the source pixels (A)
  8440. * with the ones of pixels already in the display window (B):
  8441. * <ul>
  8442. * <li><code>BLEND</code> - linear interpolation of colours: C =
  8443. * A*factor + B. This is the default blending mode.</li>
  8444. * <li><code>ADD</code> - sum of A and B</li>
  8445. * <li><code>DARKEST</code> - only the darkest colour succeeds: C =
  8446. * min(A*factor, B).</li>
  8447. * <li><code>LIGHTEST</code> - only the lightest colour succeeds: C =
  8448. * max(A*factor, B).</li>
  8449. * <li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>
  8450. * <li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less
  8451. * extreme.</li>
  8452. * <li><code>MULTIPLY</code> - multiply the colors, result will always be
  8453. * darker.</li>
  8454. * <li><code>SCREEN</code> - opposite multiply, uses inverse values of the
  8455. * colors.</li>
  8456. * <li><code>REPLACE</code> - the pixels entirely replace the others and
  8457. * don't utilize alpha (transparency) values.</li>
  8458. * <li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN
  8459. * </code>. Multiplies dark values, and screens light values.</li>
  8460. * <li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%
  8461. * gray, <code>MULTIPLY</code> when lower.</li>
  8462. * <li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and
  8463. * <code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh.
  8464. * </li>
  8465. * <li><code>DODGE</code> - lightens light tones and increases contrast,
  8466. * ignores darks.</li>
  8467. * <li><code>BURN</code> - darker areas are applied, increasing contrast,
  8468. * ignores lights.</li>
  8469. * </ul>
  8470. *
  8471. * @method blendMode
  8472. * @param {String/Constant} mode blend mode to set for canvas
  8473. * @example
  8474. * <div>
  8475. * <code>
  8476. * blendMode(LIGHTEST);
  8477. * strokeWeight(30);
  8478. * stroke(80, 150, 255);
  8479. * line(25, 25, 75, 75);
  8480. * stroke(255, 50, 50);
  8481. * line(75, 25, 25, 75);
  8482. * </code>
  8483. * </div>
  8484. * <div>
  8485. * <code>
  8486. * blendMode(MULTIPLY);
  8487. * strokeWeight(30);
  8488. * stroke(80, 150, 255);
  8489. * line(25, 25, 75, 75);
  8490. * stroke(255, 50, 50);
  8491. * line(75, 25, 25, 75);
  8492. * </code>
  8493. * </div>
  8494. */
  8495. p5.prototype.blendMode = function(mode) {
  8496. if (mode === constants.BLEND || mode === constants.DARKEST ||
  8497. mode === constants.LIGHTEST || mode === constants.DIFFERENCE ||
  8498. mode === constants.MULTIPLY || mode === constants.EXCLUSION ||
  8499. mode === constants.SCREEN || mode === constants.REPLACE ||
  8500. mode === constants.OVERLAY || mode === constants.HARD_LIGHT ||
  8501. mode === constants.SOFT_LIGHT || mode === constants.DODGE ||
  8502. mode === constants.BURN || mode === constants.ADD ||
  8503. mode === constants.NORMAL) {
  8504. this._graphics.blendMode(mode);
  8505. } else {
  8506. throw new Error('Mode '+mode+' not recognized.');
  8507. }
  8508. };
  8509. module.exports = p5;
  8510. },{"../3d/p5.Renderer3D":6,"./constants":16,"./core":17,"./p5.Graphics":22,"./p5.Renderer2D":24}],26:[function(require,module,exports){
  8511. // requestAnim shim layer by Paul Irish
  8512. window.requestAnimationFrame = (function(){
  8513. return window.requestAnimationFrame ||
  8514. window.webkitRequestAnimationFrame ||
  8515. window.mozRequestAnimationFrame ||
  8516. window.oRequestAnimationFrame ||
  8517. window.msRequestAnimationFrame ||
  8518. function(callback, element){
  8519. // should '60' here be framerate?
  8520. window.setTimeout(callback, 1000 / 60);
  8521. };
  8522. })();
  8523. // use window.performance() to get max fast and accurate time in milliseconds
  8524. window.performance = window.performance || {};
  8525. window.performance.now = (function(){
  8526. var load_date = Date.now();
  8527. return window.performance.now ||
  8528. window.performance.mozNow ||
  8529. window.performance.msNow ||
  8530. window.performance.oNow ||
  8531. window.performance.webkitNow ||
  8532. function () {
  8533. return Date.now() - load_date;
  8534. };
  8535. })();
  8536. /*
  8537. // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
  8538. // http://my.opera.com/emoller/blog/2011/12/20/
  8539. // requestanimationframe-for-smart-er-animating
  8540. // requestAnimationFrame polyfill by Erik Möller
  8541. // fixes from Paul Irish and Tino Zijdel
  8542. (function() {
  8543. var lastTime = 0;
  8544. var vendors = ['ms', 'moz', 'webkit', 'o'];
  8545. for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
  8546. window.requestAnimationFrame =
  8547. window[vendors[x]+'RequestAnimationFrame'];
  8548. window.cancelAnimationFrame =
  8549. window[vendors[x]+'CancelAnimationFrame'] ||
  8550. window[vendors[x]+'CancelRequestAnimationFrame'];
  8551. }
  8552. if (!window.requestAnimationFrame) {
  8553. window.requestAnimationFrame = function(callback, element) {
  8554. var currTime = new Date().getTime();
  8555. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  8556. var id = window.setTimeout(function()
  8557. { callback(currTime + timeToCall); }, timeToCall);
  8558. lastTime = currTime + timeToCall;
  8559. return id;
  8560. };
  8561. }
  8562. if (!window.cancelAnimationFrame) {
  8563. window.cancelAnimationFrame = function(id) {
  8564. clearTimeout(id);
  8565. };
  8566. }
  8567. }());
  8568. */
  8569. /**
  8570. * shim for Uint8ClampedArray.slice
  8571. * (allows arrayCopy to work with pixels[])
  8572. * with thanks to http://halfpapstudios.com/blog/tag/html5-canvas/
  8573. */
  8574. (function () {
  8575. 'use strict';
  8576. if (typeof Uint8ClampedArray !== 'undefined') {
  8577. //Firefox and Chrome
  8578. Uint8ClampedArray.prototype.slice = Array.prototype.slice;
  8579. }
  8580. }());
  8581. },{}],27:[function(require,module,exports){
  8582. /**
  8583. * @module Structure
  8584. * @submodule Structure
  8585. * @for p5
  8586. * @requires core
  8587. */
  8588. 'use strict';
  8589. var p5 = require('./core');
  8590. p5.prototype.exit = function() {
  8591. throw 'exit() not implemented, see remove()';
  8592. };
  8593. /**
  8594. * <p>Stops p5.js from continuously executing the code within draw().
  8595. * If loop() is called, the code in draw() begins to run continuously again.
  8596. * If using noLoop() in setup(), it should be the last line inside the block.
  8597. * </p>
  8598. *
  8599. * <p>When noLoop() is used, it's not possible to manipulate or access the
  8600. * screen inside event handling functions such as mousePressed() or
  8601. * keyPressed(). Instead, use those functions to call redraw() or loop(),
  8602. * which will run draw(), which can update the screen properly. This means
  8603. * that when noLoop() has been called, no drawing can happen, and functions
  8604. * like saveFrame() or loadPixels() may not be used.</p>
  8605. *
  8606. * <p>Note that if the sketch is resized, redraw() will be called to update
  8607. * the sketch, even after noLoop() has been specified. Otherwise, the sketch
  8608. * would enter an odd state until loop() was called.</p>
  8609. *
  8610. * @method noLoop
  8611. * @example
  8612. * <div><code>
  8613. * function setup() {
  8614. * createCanvas(100, 100);
  8615. * background(200);
  8616. * noLoop();
  8617. * }
  8618. * function draw() {
  8619. * line(10, 10, 90, 90);
  8620. * }
  8621. * </code></div>
  8622. *
  8623. * <div><code>
  8624. * var x = 0;
  8625. * function setup() {
  8626. * createCanvas(100, 100);
  8627. * }
  8628. *
  8629. * function draw() {
  8630. * background(204);
  8631. * x = x + 0.1;
  8632. * if (x > width) {
  8633. * x = 0;
  8634. * }
  8635. * line(x, 0, x, height);
  8636. * }
  8637. *
  8638. * function mousePressed() {
  8639. * noLoop();
  8640. * }
  8641. *
  8642. * function mouseReleased() {
  8643. * loop();
  8644. * }
  8645. * </code></div>
  8646. */
  8647. p5.prototype.noLoop = function() {
  8648. this._loop = false;
  8649. };
  8650. /**
  8651. * By default, p5.js loops through draw() continuously, executing the code
  8652. * within it. However, the draw() loop may be stopped by calling noLoop().
  8653. * In that case, the draw() loop can be resumed with loop().
  8654. *
  8655. * @method loop
  8656. * @example
  8657. * <div><code>
  8658. * var x = 0;
  8659. * function setup() {
  8660. * createCanvas(100, 100);
  8661. * noLoop();
  8662. * }
  8663. *
  8664. * function draw() {
  8665. * background(204);
  8666. * x = x + 0.1;
  8667. * if (x > width) {
  8668. * x = 0;
  8669. * }
  8670. * line(x, 0, x, height);
  8671. * }
  8672. *
  8673. * function mousePressed() {
  8674. * loop();
  8675. * }
  8676. *
  8677. * function mouseReleased() {
  8678. * noLoop();
  8679. * }
  8680. * </code></div>
  8681. */
  8682. p5.prototype.loop = function() {
  8683. this._loop = true;
  8684. this._draw();
  8685. };
  8686. /**
  8687. * The push() function saves the current drawing style settings and
  8688. * transformations, while pop() restores these settings. Note that these
  8689. * functions are always used together. They allow you to change the style
  8690. * and transformation settings and later return to what you had. When a new
  8691. * state is started with push(), it builds on the current style and transform
  8692. * information. The push() and pop() functions can be embedded to provide
  8693. * more control. (See the second example for a demonstration.)
  8694. * <br><br>
  8695. * push() stores information related to the current transformation state
  8696. * and style settings controlled by the following functions: fill(),
  8697. * stroke(), tint(), strokeWeight(), strokeCap(), strokeJoin(),
  8698. * imageMode(), rectMode(), ellipseMode(), colorMode(), textAlign(),
  8699. * textFont(), textMode(), textSize(), textLeading().
  8700. *
  8701. * @method push
  8702. * @example
  8703. * <div>
  8704. * <code>
  8705. * ellipse(0, 50, 33, 33); // Left circle
  8706. *
  8707. * push(); // Start a new drawing state
  8708. * strokeWeight(10);
  8709. * fill(204, 153, 0);
  8710. * translate(50, 0);
  8711. * ellipse(0, 50, 33, 33); // Middle circle
  8712. * pop(); // Restore original state
  8713. *
  8714. * ellipse(100, 50, 33, 33); // Right circle
  8715. * </code>
  8716. * </div>
  8717. * <div>
  8718. * <code>
  8719. * ellipse(0, 50, 33, 33); // Left circle
  8720. *
  8721. * push(); // Start a new drawing state
  8722. * strokeWeight(10);
  8723. * fill(204, 153, 0);
  8724. * ellipse(33, 50, 33, 33); // Left-middle circle
  8725. *
  8726. * push(); // Start another new drawing state
  8727. * stroke(0, 102, 153);
  8728. * ellipse(66, 50, 33, 33); // Right-middle circle
  8729. * pop(); // Restore previous state
  8730. *
  8731. * pop(); // Restore original state
  8732. *
  8733. * ellipse(100, 50, 33, 33); // Right circle
  8734. * </code>
  8735. * </div>
  8736. */
  8737. p5.prototype.push = function () {
  8738. this._graphics.push();
  8739. this._styles.push({
  8740. doStroke: this._doStroke,
  8741. doFill: this._doFill,
  8742. tint: this._tint,
  8743. imageMode: this._imageMode,
  8744. rectMode: this._rectMode,
  8745. ellipseMode: this._ellipseMode,
  8746. colorMode: this._colorMode,
  8747. textFont: this.textFont,
  8748. textLeading: this.textLeading,
  8749. textSize: this.textSize,
  8750. textStyle: this.textStyle
  8751. });
  8752. };
  8753. /**
  8754. * The push() function saves the current drawing style settings and
  8755. * transformations, while pop() restores these settings. Note that these
  8756. * functions are always used together. They allow you to change the style
  8757. * and transformation settings and later return to what you had. When a new
  8758. * state is started with push(), it builds on the current style and transform
  8759. * information. The push() and pop() functions can be embedded to provide
  8760. * more control. (See the second example for a demonstration.)
  8761. * <br><br>
  8762. * push() stores information related to the current transformation state
  8763. * and style settings controlled by the following functions: fill(),
  8764. * stroke(), tint(), strokeWeight(), strokeCap(), strokeJoin(),
  8765. * imageMode(), rectMode(), ellipseMode(), colorMode(), textAlign(),
  8766. * textFont(), textMode(), textSize(), textLeading().
  8767. *
  8768. * @method pop
  8769. * @example
  8770. * <div>
  8771. * <code>
  8772. * ellipse(0, 50, 33, 33); // Left circle
  8773. *
  8774. * push(); // Start a new drawing state
  8775. * translate(50, 0);
  8776. * strokeWeight(10);
  8777. * fill(204, 153, 0);
  8778. * ellipse(0, 50, 33, 33); // Middle circle
  8779. * pop(); // Restore original state
  8780. *
  8781. * ellipse(100, 50, 33, 33); // Right circle
  8782. * </code>
  8783. * </div>
  8784. * <div>
  8785. * <code>
  8786. * ellipse(0, 50, 33, 33); // Left circle
  8787. *
  8788. * push(); // Start a new drawing state
  8789. * strokeWeight(10);
  8790. * fill(204, 153, 0);
  8791. * ellipse(33, 50, 33, 33); // Left-middle circle
  8792. *
  8793. * push(); // Start another new drawing state
  8794. * stroke(0, 102, 153);
  8795. * ellipse(66, 50, 33, 33); // Right-middle circle
  8796. * pop(); // Restore previous state
  8797. *
  8798. * pop(); // Restore original state
  8799. *
  8800. * ellipse(100, 50, 33, 33); // Right circle
  8801. * </code>
  8802. * </div>
  8803. */
  8804. p5.prototype.pop = function () {
  8805. this._graphics.pop();
  8806. var lastS = this._styles.pop();
  8807. this._doStroke = lastS.doStroke;
  8808. this._doFill = lastS.doFill;
  8809. this._tint = lastS.tint;
  8810. this._imageMode = lastS.imageMode;
  8811. this._rectMode = lastS.rectMode;
  8812. this._ellipseMode = lastS.ellipseMode;
  8813. this._colorMode = lastS.colorMode;
  8814. this.textFont = lastS.textFont;
  8815. this.textLeading = lastS.textLeading;
  8816. this.textSize = lastS.textSize;
  8817. this.textStyle = lastS.textStyle;
  8818. };
  8819. p5.prototype.pushStyle = function() {
  8820. throw new Error('pushStyle() not used, see push()');
  8821. };
  8822. p5.prototype.popStyle = function() {
  8823. throw new Error('popStyle() not used, see pop()');
  8824. };
  8825. /**
  8826. *
  8827. * Executes the code within draw() one time. This functions allows the
  8828. * program to update the display window only when necessary, for example
  8829. * when an event registered by mousePressed() or keyPressed() occurs.
  8830. *
  8831. * In structuring a program, it only makes sense to call redraw() within
  8832. * events such as mousePressed(). This is because redraw() does not run
  8833. * draw() immediately (it only sets a flag that indicates an update is
  8834. * needed).
  8835. *
  8836. * The redraw() function does not work properly when called inside draw().
  8837. * To enable/disable animations, use loop() and noLoop().
  8838. *
  8839. * @method redraw
  8840. * @example
  8841. * <div><code>
  8842. * var x = 0;
  8843. *
  8844. * function setup() {
  8845. * createCanvas(100, 100);
  8846. * noLoop();
  8847. * }
  8848. *
  8849. * function draw() {
  8850. * background(204);
  8851. * line(x, 0, x, height);
  8852. * }
  8853. *
  8854. * function mousePressed() {
  8855. * x += 1;
  8856. * redraw();
  8857. * }
  8858. * </code></div>
  8859. */
  8860. p5.prototype.redraw = function () {
  8861. var userSetup = this.setup || window.setup;
  8862. var userDraw = this.draw || window.draw;
  8863. if (typeof userDraw === 'function') {
  8864. this.push();
  8865. if (typeof userSetup === 'undefined') {
  8866. this.scale(this.pixelDensity, this.pixelDensity);
  8867. }
  8868. this._registeredMethods.pre.forEach(function (f) {
  8869. f.call(this);
  8870. });
  8871. userDraw();
  8872. this._registeredMethods.post.forEach(function (f) {
  8873. f.call(this);
  8874. });
  8875. this.pop();
  8876. }
  8877. };
  8878. p5.prototype.size = function() {
  8879. throw 'size() not implemented, see createCanvas()';
  8880. };
  8881. module.exports = p5;
  8882. },{"./core":17}],28:[function(require,module,exports){
  8883. /**
  8884. * @module Transform
  8885. * @submodule Transform
  8886. * @for p5
  8887. * @requires core
  8888. * @requires constants
  8889. */
  8890. 'use strict';
  8891. var p5 = require('./core');
  8892. var constants = require('./constants');
  8893. /**
  8894. * Multiplies the current matrix by the one specified through the parameters.
  8895. * This is very slow because it will try to calculate the inverse of the
  8896. * transform, so avoid it whenever possible.
  8897. *
  8898. * @method applyMatrix
  8899. * @param {Number} n00 numbers which define the 3x2 matrix to be multiplied
  8900. * @param {Number} n01 numbers which define the 3x2 matrix to be multiplied
  8901. * @param {Number} n02 numbers which define the 3x2 matrix to be multiplied
  8902. * @param {Number} n10 numbers which define the 3x2 matrix to be multiplied
  8903. * @param {Number} n11 numbers which define the 3x2 matrix to be multiplied
  8904. * @param {Number} n12 numbers which define the 3x2 matrix to be multiplied
  8905. * @return {p5} the p5 object
  8906. * @example
  8907. * <div>
  8908. * <code>
  8909. * // Example in the works.
  8910. * </code>
  8911. * </div>
  8912. */
  8913. p5.prototype.applyMatrix = function(n00, n01, n02, n10, n11, n12) {
  8914. this._graphics.applyMatrix(n00, n01, n02, n10, n11, n12);
  8915. return this;
  8916. };
  8917. p5.prototype.popMatrix = function() {
  8918. throw new Error('popMatrix() not used, see pop()');
  8919. };
  8920. p5.prototype.printMatrix = function() {
  8921. throw new Error('printMatrix() not implemented');
  8922. };
  8923. p5.prototype.pushMatrix = function() {
  8924. throw new Error('pushMatrix() not used, see push()');
  8925. };
  8926. /**
  8927. * Replaces the current matrix with the identity matrix.
  8928. *
  8929. * @method resetMatrix
  8930. * @return {p5} the p5 object
  8931. * @example
  8932. * <div>
  8933. * <code>
  8934. * // Example in the works.
  8935. * </code>
  8936. * </div>
  8937. */
  8938. p5.prototype.resetMatrix = function() {
  8939. this._graphics.resetMatrix();
  8940. return this;
  8941. };
  8942. /**
  8943. * Rotates a shape the amount specified by the angle parameter. This
  8944. * function accounts for angleMode, so angles can be entered in either
  8945. * RADIANS or DEGREES.
  8946. *
  8947. * Objects are always rotated around their relative position to the
  8948. * origin and positive numbers rotate objects in a clockwise direction.
  8949. * Transformations apply to everything that happens after and subsequent
  8950. * calls to the function accumulates the effect. For example, calling
  8951. * rotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).
  8952. * All tranformations are reset when draw() begins again.
  8953. *
  8954. * Technically, rotate() multiplies the current transformation matrix
  8955. * by a rotation matrix. This function can be further controlled by
  8956. * the push() and pop().
  8957. *
  8958. * @method rotate
  8959. * @param {Number} angle the angle of rotation, specified in radians
  8960. * or degrees, depending on current angleMode
  8961. * @return {p5} the p5 object
  8962. * @example
  8963. * <div>
  8964. * <code>
  8965. * translate(width/2, height/2);
  8966. * rotate(PI/3.0);
  8967. * rect(-26, -26, 52, 52);
  8968. * </code>
  8969. * </div>
  8970. */
  8971. p5.prototype.rotate = function(r) {
  8972. if (this._angleMode === constants.DEGREES) {
  8973. r = this.radians(r);
  8974. }
  8975. this._graphics.rotate(r);
  8976. return this;
  8977. };
  8978. /**
  8979. * [rotateX description]
  8980. * @param {[type]} rad [description]
  8981. * @return {[type]} [description]
  8982. */
  8983. p5.prototype.rotateX = function(rad) {
  8984. if (this._graphics.isP3D) {
  8985. this._graphics.rotateX(rad);
  8986. } else {
  8987. throw 'not yet implemented.';
  8988. }
  8989. return this;
  8990. };
  8991. /**
  8992. * [rotateY description]
  8993. * @param {[type]} rad [description]
  8994. * @return {[type]} [description]
  8995. */
  8996. p5.prototype.rotateY = function(rad) {
  8997. if (this._graphics.isP3D) {
  8998. this._graphics.rotateY(rad);
  8999. } else {
  9000. throw 'not yet implemented.';
  9001. }
  9002. return this;
  9003. };
  9004. /**
  9005. * [rotateZ description]
  9006. * @param {[type]} rad [description]
  9007. * @return {[type]} [description]
  9008. */
  9009. p5.prototype.rotateZ = function(rad) {
  9010. if (this._graphics.isP3D) {
  9011. this._graphics.rotateZ(rad);
  9012. } else {
  9013. throw 'not supported in p2d. Please use webgl mode';
  9014. }
  9015. return this;
  9016. };
  9017. /**
  9018. * Increases or decreases the size of a shape by expanding and contracting
  9019. * vertices. Objects always scale from their relative origin to the
  9020. * coordinate system. Scale values are specified as decimal percentages.
  9021. * For example, the function call scale(2.0) increases the dimension of a
  9022. * shape by 200%.
  9023. *
  9024. * Transformations apply to everything that happens after and subsequent
  9025. * calls to the function multiply the effect. For example, calling scale(2.0)
  9026. * and then scale(1.5) is the same as scale(3.0). If scale() is called
  9027. * within draw(), the transformation is reset when the loop begins again.
  9028. *
  9029. * Using this fuction with the z parameter requires using P3D as a
  9030. * parameter for size(), as shown in the third example above. This function
  9031. * can be further controlled with push() and pop().
  9032. *
  9033. * @method scale
  9034. * @param {Number} s percentage to scale the object, or percentage to
  9035. * scale the object in the x-axis if multiple arguments
  9036. * are given
  9037. * @param {Number} [y] percentage to scale the object in the y-axis
  9038. * @return {p5} the p5 object
  9039. * @example
  9040. * <div>
  9041. * <code>
  9042. * translate(width/2, height/2);
  9043. * rotate(PI/3.0);
  9044. * rect(-26, -26, 52, 52);
  9045. * </code>
  9046. * </div>
  9047. *
  9048. * <div>
  9049. * <code>
  9050. * rect(30, 20, 50, 50);
  9051. * scale(0.5, 1.3);
  9052. * rect(30, 20, 50, 50);
  9053. * </code>
  9054. * </div>
  9055. */
  9056. p5.prototype.scale = function() {
  9057. if (this._graphics.isP3D) {
  9058. this._graphics.scale(arguments[0], arguments[1], arguments[2]);
  9059. } else {
  9060. this._graphics.scale.apply(this._graphics, arguments);
  9061. }
  9062. return this;
  9063. };
  9064. /**
  9065. * Shears a shape around the x-axis the amount specified by the angle
  9066. * parameter. Angles should be specified in the current angleMode.
  9067. * Objects are always sheared around their relative position to the origin
  9068. * and positive numbers shear objects in a clockwise direction.
  9069. *
  9070. * Transformations apply to everything that happens after and subsequent
  9071. * calls to the function accumulates the effect. For example, calling
  9072. * shearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).
  9073. * If shearX() is called within the draw(), the transformation is reset when
  9074. * the loop begins again.
  9075. *
  9076. * Technically, shearX() multiplies the current transformation matrix by a
  9077. * rotation matrix. This function can be further controlled by the
  9078. * push() and pop() functions.
  9079. *
  9080. * @method shearX
  9081. * @param {Number} angle angle of shear specified in radians or degrees,
  9082. * depending on current angleMode
  9083. * @return {p5} the p5 object
  9084. * @example
  9085. * <div>
  9086. * <code>
  9087. * translate(width/4, height/4);
  9088. * shearX(PI/4.0);
  9089. * rect(0, 0, 30, 30);
  9090. * </code>
  9091. * </div>
  9092. */
  9093. p5.prototype.shearX = function(angle) {
  9094. if (this._angleMode === constants.DEGREES) {
  9095. angle = this.radians(angle);
  9096. }
  9097. this._graphics.shearX(angle);
  9098. return this;
  9099. };
  9100. /**
  9101. * Shears a shape around the y-axis the amount specified by the angle
  9102. * parameter. Angles should be specified in the current angleMode. Objects
  9103. * are always sheared around their relative position to the origin and
  9104. * positive numbers shear objects in a clockwise direction.
  9105. *
  9106. * Transformations apply to everything that happens after and subsequent
  9107. * calls to the function accumulates the effect. For example, calling
  9108. * shearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If
  9109. * shearY() is called within the draw(), the transformation is reset when
  9110. * the loop begins again.
  9111. *
  9112. * Technically, shearY() multiplies the current transformation matrix by a
  9113. * rotation matrix. This function can be further controlled by the
  9114. * push() and pop() functions.
  9115. *
  9116. * @method shearY
  9117. * @param {Number} angle angle of shear specified in radians or degrees,
  9118. * depending on current angleMode
  9119. * @return {p5} the p5 object
  9120. * @example
  9121. * <div>
  9122. * <code>
  9123. * translate(width/4, height/4);
  9124. * shearY(PI/4.0);
  9125. * rect(0, 0, 30, 30);
  9126. * </code>
  9127. * </div>
  9128. */
  9129. p5.prototype.shearY = function(angle) {
  9130. if (this._angleMode === constants.DEGREES) {
  9131. angle = this.radians(angle);
  9132. }
  9133. this._graphics.shearY(angle);
  9134. return this;
  9135. };
  9136. /**
  9137. * Specifies an amount to displace objects within the display window.
  9138. * The x parameter specifies left/right translation, the y parameter
  9139. * specifies up/down translation.
  9140. *
  9141. * Transformations are cumulative and apply to everything that happens after
  9142. * and subsequent calls to the function accumulates the effect. For example,
  9143. * calling translate(50, 0) and then translate(20, 0) is the same as
  9144. * translate(70, 0). If translate() is called within draw(), the
  9145. * transformation is reset when the loop begins again. This function can be
  9146. * further controlled by using push() and pop().
  9147. *
  9148. * @method translate
  9149. * @param {Number} x left/right translation
  9150. * @param {Number} y up/down translation
  9151. * @return {p5} the p5 object
  9152. * @example
  9153. * <div>
  9154. * <code>
  9155. * translate(30, 20);
  9156. * rect(0, 0, 55, 55);
  9157. * </code>
  9158. * </div>
  9159. *
  9160. * <div>
  9161. * <code>
  9162. * rect(0, 0, 55, 55); // Draw rect at original 0,0
  9163. * translate(30, 20);
  9164. * rect(0, 0, 55, 55); // Draw rect at new 0,0
  9165. * translate(14, 14);
  9166. * rect(0, 0, 55, 55); // Draw rect at new 0,0
  9167. * </code>
  9168. * </div>
  9169. */
  9170. p5.prototype.translate = function(x, y, z) {
  9171. if (this._graphics.isP3D) {
  9172. this._graphics.translate(x, y, z);
  9173. } else {
  9174. this._graphics.translate(x, y);
  9175. }
  9176. return this;
  9177. };
  9178. module.exports = p5;
  9179. },{"./constants":16,"./core":17}],29:[function(require,module,exports){
  9180. /**
  9181. * @module Shape
  9182. * @submodule Vertex
  9183. * @for p5
  9184. * @requires core
  9185. * @requires constants
  9186. */
  9187. 'use strict';
  9188. var p5 = require('./core');
  9189. var constants = require('./constants');
  9190. var shapeKind = null;
  9191. var vertices = [];
  9192. var contourVertices = [];
  9193. var isBezier = false;
  9194. var isCurve = false;
  9195. var isQuadratic = false;
  9196. var isContour = false;
  9197. /**
  9198. * Use the beginContour() and endContour() functions to create negative
  9199. * shapes within shapes such as the center of the letter 'O'. beginContour()
  9200. * begins recording vertices for the shape and endContour() stops recording.
  9201. * The vertices that define a negative shape must "wind" in the opposite
  9202. * direction from the exterior shape. First draw vertices for the exterior
  9203. * clockwise order, then for internal shapes, draw vertices
  9204. * shape in counter-clockwise.
  9205. * <br><br>
  9206. * These functions can only be used within a beginShape()/endShape() pair and
  9207. * transformations such as translate(), rotate(), and scale() do not work
  9208. * within a beginContour()/endContour() pair. It is also not possible to use
  9209. * other shapes, such as ellipse() or rect() within.
  9210. *
  9211. * @method beginContour
  9212. * @return {Object} the p5 object
  9213. * @example
  9214. * <div>
  9215. * <code>
  9216. * translate(50, 50);
  9217. * stroke(255, 0, 0);
  9218. * beginShape();
  9219. * // Exterior part of shape, clockwise winding
  9220. * vertex(-40, -40);
  9221. * vertex(40, -40);
  9222. * vertex(40, 40);
  9223. * vertex(-40, 40);
  9224. * // Interior part of shape, counter-clockwise winding
  9225. * beginContour();
  9226. * vertex(-20, -20);
  9227. * vertex(-20, 20);
  9228. * vertex(20, 20);
  9229. * vertex(20, -20);
  9230. * endContour();
  9231. * endShape(CLOSE);
  9232. * </code>
  9233. * </div>
  9234. */
  9235. p5.prototype.beginContour = function() {
  9236. contourVertices = [];
  9237. isContour = true;
  9238. return this;
  9239. };
  9240. /**
  9241. * Using the beginShape() and endShape() functions allow creating more
  9242. * complex forms. beginShape() begins recording vertices for a shape and
  9243. * endShape() stops recording. The value of the kind parameter tells it which
  9244. * types of shapes to create from the provided vertices. With no mode
  9245. * specified, the shape can be any irregular polygon. The parameters
  9246. * available for beginShape() are POINTS, LINES, TRIANGLES, TRIANGLE_FAN,
  9247. * TRIANGLE_STRIP, QUADS, and QUAD_STRIP. After calling the beginShape()
  9248. * function, a series of vertex() commands must follow. To stop drawing the
  9249. * shape, call endShape(). Each shape will be outlined with the current
  9250. * stroke color and filled with the fill color.
  9251. *
  9252. * Transformations such as translate(), rotate(), and scale() do not work
  9253. * within beginShape(). It is also not possible to use other shapes, such as
  9254. * ellipse() or rect() within beginShape().
  9255. *
  9256. * @method beginShape
  9257. * @param {Number/Constant} kind either POINTS, LINES, TRIANGLES,
  9258. * TRIANGLE_FAN, TRIANGLE_STRIP, QUADS,
  9259. * or QUAD_STRIP
  9260. * @return {Object} the p5 object
  9261. * @example
  9262. * <div>
  9263. * <code>
  9264. * beginShape();
  9265. * vertex(30, 20);
  9266. * vertex(85, 20);
  9267. * vertex(85, 75);
  9268. * vertex(30, 75);
  9269. * endShape(CLOSE);
  9270. * </code>
  9271. * </div>
  9272. *
  9273. * <div>
  9274. * <code>
  9275. * // currently not working
  9276. * beginShape(POINTS);
  9277. * vertex(30, 20);
  9278. * vertex(85, 20);
  9279. * vertex(85, 75);
  9280. * vertex(30, 75);
  9281. * endShape();
  9282. * </code>
  9283. * </div>
  9284. *
  9285. * <div>
  9286. * <code>
  9287. * beginShape(LINES);
  9288. * vertex(30, 20);
  9289. * vertex(85, 20);
  9290. * vertex(85, 75);
  9291. * vertex(30, 75);
  9292. * endShape();
  9293. * </code>
  9294. * </div>
  9295. *
  9296. * <div>
  9297. * <code>
  9298. * noFill();
  9299. * beginShape();
  9300. * vertex(30, 20);
  9301. * vertex(85, 20);
  9302. * vertex(85, 75);
  9303. * vertex(30, 75);
  9304. * endShape();
  9305. * </code>
  9306. * </div>
  9307. *
  9308. * <div>
  9309. * <code>
  9310. * noFill();
  9311. * beginShape();
  9312. * vertex(30, 20);
  9313. * vertex(85, 20);
  9314. * vertex(85, 75);
  9315. * vertex(30, 75);
  9316. * endShape(CLOSE);
  9317. * </code>
  9318. * </div>
  9319. *
  9320. * <div>
  9321. * <code>
  9322. * beginShape(TRIANGLES);
  9323. * vertex(30, 75);
  9324. * vertex(40, 20);
  9325. * vertex(50, 75);
  9326. * vertex(60, 20);
  9327. * vertex(70, 75);
  9328. * vertex(80, 20);
  9329. * endShape();
  9330. * </code>
  9331. * </div>
  9332. *
  9333. * <div>
  9334. * <code>
  9335. * beginShape(TRIANGLE_STRIP);
  9336. * vertex(30, 75);
  9337. * vertex(40, 20);
  9338. * vertex(50, 75);
  9339. * vertex(60, 20);
  9340. * vertex(70, 75);
  9341. * vertex(80, 20);
  9342. * vertex(90, 75);
  9343. * endShape();
  9344. * </code>
  9345. * </div>
  9346. *
  9347. * <div>
  9348. * <code>
  9349. * beginShape(TRIANGLE_FAN);
  9350. * vertex(57.5, 50);
  9351. * vertex(57.5, 15);
  9352. * vertex(92, 50);
  9353. * vertex(57.5, 85);
  9354. * vertex(22, 50);
  9355. * vertex(57.5, 15);
  9356. * endShape();
  9357. * </code>
  9358. * </div>
  9359. *
  9360. * <div>
  9361. * <code>
  9362. * beginShape(QUADS);
  9363. * vertex(30, 20);
  9364. * vertex(30, 75);
  9365. * vertex(50, 75);
  9366. * vertex(50, 20);
  9367. * vertex(65, 20);
  9368. * vertex(65, 75);
  9369. * vertex(85, 75);
  9370. * vertex(85, 20);
  9371. * endShape();
  9372. * </code>
  9373. * </div>
  9374. *
  9375. * <div>
  9376. * <code>
  9377. * beginShape(QUAD_STRIP);
  9378. * vertex(30, 20);
  9379. * vertex(30, 75);
  9380. * vertex(50, 20);
  9381. * vertex(50, 75);
  9382. * vertex(65, 20);
  9383. * vertex(65, 75);
  9384. * vertex(85, 20);
  9385. * vertex(85, 75);
  9386. * endShape();
  9387. * </code>
  9388. * </div>
  9389. *
  9390. * <div>
  9391. * <code>
  9392. * beginShape();
  9393. * vertex(20, 20);
  9394. * vertex(40, 20);
  9395. * vertex(40, 40);
  9396. * vertex(60, 40);
  9397. * vertex(60, 60);
  9398. * vertex(20, 60);
  9399. * endShape(CLOSE);
  9400. * </code>
  9401. * </div>
  9402. */
  9403. p5.prototype.beginShape = function(kind) {
  9404. if (kind === constants.POINTS ||
  9405. kind === constants.LINES ||
  9406. kind === constants.TRIANGLES ||
  9407. kind === constants.TRIANGLE_FAN ||
  9408. kind === constants.TRIANGLE_STRIP ||
  9409. kind === constants.QUADS ||
  9410. kind === constants.QUAD_STRIP) {
  9411. shapeKind = kind;
  9412. } else {
  9413. shapeKind = null;
  9414. }
  9415. vertices = [];
  9416. contourVertices = [];
  9417. return this;
  9418. };
  9419. /**
  9420. * Specifies vertex coordinates for Bezier curves. Each call to
  9421. * bezierVertex() defines the position of two control points and
  9422. * one anchor point of a Bezier curve, adding a new segment to a
  9423. * line or shape. The first time bezierVertex() is used within a
  9424. * beginShape() call, it must be prefaced with a call to vertex()
  9425. * to set the first anchor point. This function must be used between
  9426. * beginShape() and endShape() and only when there is no MODE
  9427. * parameter specified to beginShape().
  9428. *
  9429. * @method bezierVertex
  9430. * @param {Number} x2 x-coordinate for the first control point
  9431. * @param {Number} y2 y-coordinate for the first control point
  9432. * @param {Number} x3 x-coordinate for the second control point
  9433. * @param {Number} y3 y-coordinate for the second control point
  9434. * @param {Number} x4 x-coordinate for the anchor point
  9435. * @param {Number} y4 y-coordinate for the anchor point
  9436. * @return {Object} the p5 object
  9437. * @example
  9438. * <div>
  9439. * <code>
  9440. * noFill();
  9441. * beginShape();
  9442. * vertex(30, 20);
  9443. * bezierVertex(80, 0, 80, 75, 30, 75);
  9444. * endShape();
  9445. * </code>
  9446. * </div>
  9447. *
  9448. * <div>
  9449. * <code>
  9450. * beginShape();
  9451. * vertex(30, 20);
  9452. * bezierVertex(80, 0, 80, 75, 30, 75);
  9453. * bezierVertex(50, 80, 60, 25, 30, 20);
  9454. * endShape();
  9455. * </code>
  9456. * </div>
  9457. */
  9458. p5.prototype.bezierVertex = function(x2, y2, x3, y3, x4, y4) {
  9459. if (vertices.length === 0) {
  9460. throw 'vertex() must be used once before calling bezierVertex()';
  9461. } else {
  9462. isBezier = true;
  9463. var vert = [];
  9464. for (var i = 0; i < arguments.length; i++) {
  9465. vert[i] = arguments[i];
  9466. }
  9467. vert.isVert = false;
  9468. if (isContour) {
  9469. contourVertices.push(vert);
  9470. } else {
  9471. vertices.push(vert);
  9472. }
  9473. }
  9474. return this;
  9475. };
  9476. /**
  9477. * Specifies vertex coordinates for curves. This function may only
  9478. * be used between beginShape() and endShape() and only when there
  9479. * is no MODE parameter specified to beginShape(). The first and
  9480. * last points in a series of curveVertex() lines will be used to
  9481. * guide the beginning and end of a the curve. A minimum of four
  9482. * points is required to draw a tiny curve between the second and
  9483. * third points. Adding a fifth point with curveVertex() will draw
  9484. * the curve between the second, third, and fourth points. The
  9485. * curveVertex() function is an implementation of Catmull-Rom
  9486. * splines.
  9487. *
  9488. * @method curveVertex
  9489. * @param {Number} x x-coordinate of the vertex
  9490. * @param {Number} y y-coordinate of the vertex
  9491. * @return {Object} the p5 object
  9492. * @example
  9493. * <div>
  9494. * <code>
  9495. * noFill();
  9496. * beginShape();
  9497. * curveVertex(84, 91);
  9498. * curveVertex(84, 91);
  9499. * curveVertex(68, 19);
  9500. * curveVertex(21, 17);
  9501. * curveVertex(32, 100);
  9502. * curveVertex(32, 100);
  9503. * endShape();
  9504. * </code>
  9505. * </div>
  9506. */
  9507. p5.prototype.curveVertex = function(x,y) {
  9508. isCurve = true;
  9509. this.vertex(x, y);
  9510. return this;
  9511. };
  9512. /**
  9513. * Use the beginContour() and endContour() functions to create negative
  9514. * shapes within shapes such as the center of the letter 'O'. beginContour()
  9515. * begins recording vertices for the shape and endContour() stops recording.
  9516. * The vertices that define a negative shape must "wind" in the opposite
  9517. * direction from the exterior shape. First draw vertices for the exterior
  9518. * clockwise order, then for internal shapes, draw vertices
  9519. * shape in counter-clockwise.
  9520. * <br><br>
  9521. * These functions can only be used within a beginShape()/endShape() pair and
  9522. * transformations such as translate(), rotate(), and scale() do not work
  9523. * within a beginContour()/endContour() pair. It is also not possible to use
  9524. * other shapes, such as ellipse() or rect() within.
  9525. *
  9526. * @method endContour
  9527. * @return {Object} the p5 object
  9528. * @example
  9529. * <div>
  9530. * <code>
  9531. * translate(50, 50);
  9532. * stroke(255, 0, 0);
  9533. * beginShape();
  9534. * // Exterior part of shape, clockwise winding
  9535. * vertex(-40, -40);
  9536. * vertex(40, -40);
  9537. * vertex(40, 40);
  9538. * vertex(-40, 40);
  9539. * // Interior part of shape, counter-clockwise winding
  9540. * beginContour();
  9541. * vertex(-20, -20);
  9542. * vertex(-20, 20);
  9543. * vertex(20, 20);
  9544. * vertex(20, -20);
  9545. * endContour();
  9546. * endShape(CLOSE);
  9547. * </code>
  9548. * </div>
  9549. */
  9550. p5.prototype.endContour = function() {
  9551. var vert = contourVertices[0].slice(); // copy all data
  9552. vert.isVert = contourVertices[0].isVert;
  9553. vert.moveTo = false;
  9554. contourVertices.push(vert);
  9555. vertices.push(vertices[0]);
  9556. for (var i = 0; i < contourVertices.length; i++) {
  9557. vertices.push(contourVertices[i]);
  9558. }
  9559. return this;
  9560. };
  9561. /**
  9562. * The endShape() function is the companion to beginShape() and may only be
  9563. * called after beginShape(). When endshape() is called, all of image data
  9564. * defined since the previous call to beginShape() is written into the image
  9565. * buffer. The constant CLOSE as the value for the MODE parameter to close
  9566. * the shape (to connect the beginning and the end).
  9567. *
  9568. * @method endShape
  9569. * @param {Number/Constant} mode use CLOSE to close the shape
  9570. * @return {Object} the p5 object
  9571. * @example
  9572. * <div>
  9573. * <code>
  9574. * noFill();
  9575. *
  9576. * beginShape();
  9577. * vertex(20, 20);
  9578. * vertex(45, 20);
  9579. * vertex(45, 80);
  9580. * endShape(CLOSE);
  9581. *
  9582. * beginShape();
  9583. * vertex(50, 20);
  9584. * vertex(75, 20);
  9585. * vertex(75, 80);
  9586. * endShape();
  9587. * </code>
  9588. * </div>
  9589. */
  9590. p5.prototype.endShape = function(mode) {
  9591. if (vertices.length === 0) { return this; }
  9592. if (!this._doStroke && !this._doFill) { return this; }
  9593. var closeShape = mode === constants.CLOSE;
  9594. // if the shape is closed, the first element is also the last element
  9595. if (closeShape && !isContour) {
  9596. vertices.push(vertices[0]);
  9597. }
  9598. this._graphics.endShape(mode, vertices, isCurve, isBezier,
  9599. isQuadratic, isContour, shapeKind);
  9600. // Reset some settings
  9601. isCurve = false;
  9602. isBezier = false;
  9603. isQuadratic = false;
  9604. isContour = false;
  9605. // If the shape is closed, the first element was added as last element.
  9606. // We must remove it again to prevent the list of vertices from growing
  9607. // over successive calls to endShape(CLOSE)
  9608. if (closeShape) {
  9609. vertices.pop();
  9610. }
  9611. return this;
  9612. };
  9613. /**
  9614. * Specifies vertex coordinates for quadratic Bezier curves. Each call to
  9615. * quadraticVertex() defines the position of one control points and one
  9616. * anchor point of a Bezier curve, adding a new segment to a line or shape.
  9617. * The first time quadraticVertex() is used within a beginShape() call, it
  9618. * must be prefaced with a call to vertex() to set the first anchor point.
  9619. * This function must be used between beginShape() and endShape() and only
  9620. * when there is no MODE parameter specified to beginShape().
  9621. *
  9622. * @method quadraticVertex
  9623. * @param {Number} cx x-coordinate for the control point
  9624. * @param {Number} cy y-coordinate for the control point
  9625. * @param {Number} x3 x-coordinate for the anchor point
  9626. * @param {Number} y3 y-coordinate for the anchor point
  9627. * @return {Object} the p5 object
  9628. * @example
  9629. * <div>
  9630. * <code>
  9631. * noFill();
  9632. * strokeWeight(4);
  9633. * beginShape();
  9634. * vertex(20, 20);
  9635. * quadraticVertex(80, 20, 50, 50);
  9636. * endShape();
  9637. * </code>
  9638. * </div>
  9639. *
  9640. * <div>
  9641. * <code>
  9642. * noFill();
  9643. * strokeWeight(4);
  9644. * beginShape();
  9645. * vertex(20, 20);
  9646. * quadraticVertex(80, 20, 50, 50);
  9647. * quadraticVertex(20, 80, 80, 80);
  9648. * vertex(80, 60);
  9649. * endShape();
  9650. * </code>
  9651. * </div>
  9652. */
  9653. p5.prototype.quadraticVertex = function(cx, cy, x3, y3) {
  9654. //if we're drawing a contour, put the points into an
  9655. // array for inside drawing
  9656. if(this._contourInited) {
  9657. var pt = {};
  9658. pt.x = cx;
  9659. pt.y = cy;
  9660. pt.x3 = x3;
  9661. pt.y3 = y3;
  9662. pt.type = constants.QUADRATIC;
  9663. this._contourVertices.push(pt);
  9664. return this;
  9665. }
  9666. if (vertices.length > 0) {
  9667. isQuadratic = true;
  9668. var vert = [];
  9669. for (var i = 0; i < arguments.length; i++) {
  9670. vert[i] = arguments[i];
  9671. }
  9672. vert.isVert = false;
  9673. if (isContour) {
  9674. contourVertices.push(vert);
  9675. } else {
  9676. vertices.push(vert);
  9677. }
  9678. } else {
  9679. throw 'vertex() must be used once before calling quadraticVertex()';
  9680. }
  9681. return this;
  9682. };
  9683. /**
  9684. * All shapes are constructed by connecting a series of vertices. vertex()
  9685. * is used to specify the vertex coordinates for points, lines, triangles,
  9686. * quads, and polygons. It is used exclusively within the beginShape() and
  9687. * endShape() functions.
  9688. *
  9689. * @method vertex
  9690. * @param {Number} x x-coordinate of the vertex
  9691. * @param {Number} y y-coordinate of the vertex
  9692. * @return {Object} the p5 object
  9693. * @example
  9694. * <div>
  9695. * <code>
  9696. * beginShape(POINTS);
  9697. * vertex(30, 20);
  9698. * vertex(85, 20);
  9699. * vertex(85, 75);
  9700. * vertex(30, 75);
  9701. * endShape();
  9702. * </code>
  9703. * </div>
  9704. */
  9705. p5.prototype.vertex = function(x, y, moveTo) {
  9706. var vert = [];
  9707. vert.isVert = true;
  9708. vert[0] = x;
  9709. vert[1] = y;
  9710. vert[2] = 0;
  9711. vert[3] = 0;
  9712. vert[4] = 0;
  9713. vert[5] = this._graphics._getFill();
  9714. vert[6] = this._graphics._getStroke();
  9715. if (moveTo) {
  9716. vert.moveTo = moveTo;
  9717. }
  9718. if (isContour) {
  9719. if (contourVertices.length === 0) {
  9720. vert.moveTo = true;
  9721. }
  9722. contourVertices.push(vert);
  9723. } else {
  9724. vertices.push(vert);
  9725. }
  9726. return this;
  9727. };
  9728. module.exports = p5;
  9729. },{"./constants":16,"./core":17}],30:[function(require,module,exports){
  9730. /**
  9731. * @module Events
  9732. * @submodule Acceleration
  9733. * @for p5
  9734. * @requires core
  9735. */
  9736. 'use strict';
  9737. var p5 = require('../core/core');
  9738. /**
  9739. * The system variable deviceOrientation always contains the orientation of
  9740. * the device. The value of this variable will either be set 'landscape'
  9741. * or 'portrait'. If no data is available it will be set to 'undefined'.
  9742. *
  9743. * @property deviceOrientation
  9744. */
  9745. p5.prototype.deviceOrientation = undefined;
  9746. /**
  9747. * The system variable accelerationX always contains the acceleration of the
  9748. * device along the x axis. Value is represented as meters per second squared.
  9749. *
  9750. * @property accelerationX
  9751. */
  9752. p5.prototype.accelerationX = 0;
  9753. /**
  9754. * The system variable accelerationY always contains the acceleration of the
  9755. * device along the y axis. Value is represented as meters per second squared.
  9756. *
  9757. * @property accelerationY
  9758. */
  9759. p5.prototype.accelerationY = 0;
  9760. /**
  9761. * The system variable accelerationZ always contains the acceleration of the
  9762. * device along the z axis. Value is represented as meters per second squared.
  9763. *
  9764. * @property accelerationZ
  9765. */
  9766. p5.prototype.accelerationZ = 0;
  9767. /**
  9768. * The system variable pAccelerationX always contains the acceleration of the
  9769. * device along the x axis in the frame previous to the current frame. Value
  9770. * is represented as meters per second squared.
  9771. *
  9772. * @property pAccelerationX
  9773. */
  9774. p5.prototype.pAccelerationX = 0;
  9775. /**
  9776. * The system variable pAccelerationY always contains the acceleration of the
  9777. * device along the y axis in the frame previous to the current frame. Value
  9778. * is represented as meters per second squared.
  9779. *
  9780. * @property pAccelerationY
  9781. */
  9782. p5.prototype.pAccelerationY = 0;
  9783. /**
  9784. * The system variable pAccelerationZ always contains the acceleration of the
  9785. * device along the z axis in the frame previous to the current frame. Value
  9786. * is represented as meters per second squared.
  9787. *
  9788. * @property pAccelerationZ
  9789. */
  9790. p5.prototype.pAccelerationZ = 0;
  9791. /**
  9792. * _updatePAccelerations updates the pAcceleration values
  9793. *
  9794. * @private
  9795. */
  9796. p5.prototype._updatePAccelerations = function(){
  9797. this._setProperty('pAccelerationX', this.accelerationX);
  9798. this._setProperty('pAccelerationY', this.accelerationY);
  9799. this._setProperty('pAccelerationZ', this.accelerationZ);
  9800. };
  9801. var move_threshold = 0.5;
  9802. /**
  9803. * The setMoveThreshold() function is used to set the movement threshold for
  9804. * the deviceMoved() function.
  9805. *
  9806. * @method setMoveThreshold
  9807. * @param {number} value The threshold value
  9808. */
  9809. p5.prototype.setMoveThreshold = function(val){
  9810. if(typeof val === 'number'){
  9811. move_threshold = val;
  9812. }
  9813. };
  9814. var old_max_axis = '';
  9815. var new_max_axis = '';
  9816. /**
  9817. * The deviceMoved() function is called when the devices orientation changes
  9818. * by more than the threshold value.
  9819. * @method deviceMoved
  9820. * @example
  9821. * <div>
  9822. * <code>
  9823. * // Run this example on a mobile device
  9824. * // Move the device around
  9825. * // to change the value.
  9826. *
  9827. * var value = 0;
  9828. * function draw() {
  9829. * fill(value);
  9830. * rect(25, 25, 50, 50);
  9831. * }
  9832. * function deviceMoved() {
  9833. * value = value + 5;
  9834. * if (value > 255) {
  9835. * value = 0;
  9836. * }
  9837. * }
  9838. * </code>
  9839. * </div>
  9840. */
  9841. /**
  9842. * The deviceTurned() function is called when the device rotates by
  9843. * more than 90 degrees.
  9844. * @method deviceTurned
  9845. * @example
  9846. * <div>
  9847. * <code>
  9848. * // Run this example on a mobile device
  9849. * // Rotate the device by 90 degrees
  9850. * // to change the value.
  9851. *
  9852. * var value = 0;
  9853. * function draw() {
  9854. * fill(value);
  9855. * rect(25, 25, 50, 50);
  9856. * }
  9857. * function deviceTurned() {
  9858. * value = value + 5;
  9859. * if (value > 255) {
  9860. * value = 0;
  9861. * }
  9862. * }
  9863. * </code>
  9864. * </div>
  9865. */
  9866. p5.prototype._ondeviceorientation = function (e) {
  9867. this._setProperty('accelerationX', e.beta);
  9868. this._setProperty('accelerationY', e.gamma);
  9869. this._setProperty('accelerationZ', e.alpha);
  9870. this._handleMotion();
  9871. };
  9872. p5.prototype._ondevicemotion = function (e) {
  9873. this._setProperty('accelerationX', e.acceleration.x * 2);
  9874. this._setProperty('accelerationY', e.acceleration.y * 2);
  9875. this._setProperty('accelerationZ', e.acceleration.z * 2);
  9876. this._handleMotion();
  9877. };
  9878. p5.prototype._onMozOrientation = function (e) {
  9879. this._setProperty('accelerationX', e.x);
  9880. this._setProperty('accelerationY', e.y);
  9881. this._setProperty('accelerationZ', e.z);
  9882. this._handleMotion();
  9883. };
  9884. p5.prototype._handleMotion = function() {
  9885. if (window.orientation === 90 || window.orientation === -90) {
  9886. this._setProperty('deviceOrientation', 'landscape');
  9887. } else if (window.orientation === 0) {
  9888. this._setProperty('deviceOrientation', 'portrait');
  9889. } else if (window.orientation === undefined) {
  9890. this._setProperty('deviceOrientation', 'undefined');
  9891. }
  9892. var deviceMoved = this.deviceMoved || window.deviceMoved;
  9893. if (typeof deviceMoved === 'function') {
  9894. if (Math.abs(this.accelerationX - this.pAccelerationX) > move_threshold ||
  9895. Math.abs(this.accelerationY - this.pAccelerationY) > move_threshold ||
  9896. Math.abs(this.accelerationZ - this.pAccelerationZ) > move_threshold) {
  9897. deviceMoved();
  9898. }
  9899. }
  9900. var deviceTurned = this.deviceTurned || window.deviceTurned;
  9901. if (typeof deviceTurned === 'function') {
  9902. var max_val = 0;
  9903. if (Math.abs(this.accelerationX) > max_val) {
  9904. max_val = this.accelerationX;
  9905. new_max_axis = 'x';
  9906. }
  9907. if (Math.abs(this.accelerationY) > max_val) {
  9908. max_val = this.accelerationY;
  9909. new_max_axis = 'y';
  9910. }
  9911. if (Math.abs(this.accelerationZ) > max_val) {
  9912. new_max_axis = 'z';
  9913. }
  9914. if (old_max_axis !== '' && old_max_axis !== new_max_axis) {
  9915. deviceTurned(new_max_axis);
  9916. }
  9917. old_max_axis = new_max_axis;
  9918. }
  9919. };
  9920. module.exports = p5;
  9921. },{"../core/core":17}],31:[function(require,module,exports){
  9922. /**
  9923. * @module Events
  9924. * @submodule Keyboard
  9925. * @for p5
  9926. * @requires core
  9927. */
  9928. 'use strict';
  9929. var p5 = require('../core/core');
  9930. /**
  9931. * Holds the key codes of currently pressed keys.
  9932. * @private
  9933. */
  9934. var downKeys = {};
  9935. /**
  9936. * The boolean system variable keyIsPressed is true if any key is pressed
  9937. * and false if no keys are pressed.
  9938. *
  9939. * @property keyIsPressed
  9940. * @example
  9941. * <div>
  9942. * <code>
  9943. * var value = 0;
  9944. * function draw() {
  9945. * if (keyIsPressed === true) {
  9946. * fill(0);
  9947. * } else {
  9948. * fill(255);
  9949. * }
  9950. * rect(25, 25, 50, 50);
  9951. * }
  9952. * </code>
  9953. * </div>
  9954. */
  9955. p5.prototype.isKeyPressed = false;
  9956. p5.prototype.keyIsPressed = false; // khan
  9957. /**
  9958. * The system variable key always contains the value of the most recent
  9959. * key on the keyboard that was typed. To get the proper capitalization, it
  9960. * is best to use it within keyTyped(). For non-ASCII keys, use the keyCode
  9961. * variable.
  9962. *
  9963. * @property key
  9964. * @example
  9965. * <div><code>
  9966. * // Click any key to display it!
  9967. * // (Not Guaranteed to be Case Sensitive)
  9968. * function setup() {
  9969. * fill(245, 123, 158);
  9970. * textSize(50);
  9971. * }
  9972. *
  9973. * function draw() {
  9974. * background(200);
  9975. * text(key, 33,65); // Display last key pressed.
  9976. * }
  9977. * </div></code>
  9978. */
  9979. p5.prototype.key = '';
  9980. /**
  9981. * The variable keyCode is used to detect special keys such as BACKSPACE,
  9982. * DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,
  9983. * DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.
  9984. *
  9985. * @property keyCode
  9986. * @example
  9987. * <div><code>
  9988. * var fillVal = 126;
  9989. * function draw() {
  9990. * fill(fillVal);
  9991. * rect(25, 25, 50, 50);
  9992. * }
  9993. *
  9994. * function keyPressed() {
  9995. * if (keyCode == UP_ARROW) {
  9996. * fillVal = 255;
  9997. * } else if (keyCode == DOWN_ARROW) {
  9998. * fillVal = 0;
  9999. * }
  10000. * return false; // prevent default
  10001. * }
  10002. * </code></div>
  10003. */
  10004. p5.prototype.keyCode = 0;
  10005. /**
  10006. * The keyPressed() function is called once every time a key is pressed. The
  10007. * keyCode for the key that was pressed is stored in the keyCode variable.
  10008. * <br><br>
  10009. * For non-ASCII keys, use the keyCode variable. You can check if the keyCode
  10010. * equals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,
  10011. * OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.
  10012. * <br><br>
  10013. * For ASCII keys that was pressed is stored in the key variable. However, it
  10014. * does not distinguish between uppercase and lowercase. For this reason, it
  10015. * is recommended to use keyTyped() to read the key variable, in which the
  10016. * case of the variable will be distinguished.
  10017. * <br><br>
  10018. * Because of how operating systems handle key repeats, holding down a key
  10019. * may cause multiple calls to keyTyped() (and keyReleased() as well). The
  10020. * rate of repeat is set by the operating system and how each computer is
  10021. * configured.<br><br>
  10022. * Browsers may have different default
  10023. * behaviors attached to various key events. To prevent any default
  10024. * behavior for this event, add "return false" to the end of the method.
  10025. *
  10026. * @method keyPressed
  10027. * @example
  10028. * <div>
  10029. * <code>
  10030. * var value = 0;
  10031. * function draw() {
  10032. * fill(value);
  10033. * rect(25, 25, 50, 50);
  10034. * }
  10035. * function keyPressed() {
  10036. * if (value === 0) {
  10037. * value = 255;
  10038. * } else {
  10039. * value = 0;
  10040. * }
  10041. * }
  10042. * </code>
  10043. * </div>
  10044. * <div>
  10045. * <code>
  10046. * var value = 0;
  10047. * function draw() {
  10048. * fill(value);
  10049. * rect(25, 25, 50, 50);
  10050. * }
  10051. * function keyPressed() {
  10052. * if (keyCode === LEFT_ARROW) {
  10053. * value = 255;
  10054. * } else if (keyCode === RIGHT_ARROW) {
  10055. * value = 0;
  10056. * }
  10057. * return false; // prevent any default behavior
  10058. * }
  10059. * </code>
  10060. * </div>
  10061. */
  10062. p5.prototype._onkeydown = function (e) {
  10063. this._setProperty('isKeyPressed', true);
  10064. this._setProperty('keyIsPressed', true);
  10065. this._setProperty('keyCode', e.which);
  10066. downKeys[e.which] = true;
  10067. var key = String.fromCharCode(e.which);
  10068. if (!key) {
  10069. key = e.which;
  10070. }
  10071. this._setProperty('key', key);
  10072. var keyPressed = this.keyPressed || window.keyPressed;
  10073. if (typeof keyPressed === 'function' && !e.charCode) {
  10074. var executeDefault = keyPressed(e);
  10075. if(executeDefault === false) {
  10076. e.preventDefault();
  10077. }
  10078. }
  10079. };
  10080. /**
  10081. * The keyReleased() function is called once every time a key is released.
  10082. * See key and keyCode for more information.<br><br>
  10083. * Browsers may have different default
  10084. * behaviors attached to various key events. To prevent any default
  10085. * behavior for this event, add "return false" to the end of the method.
  10086. *
  10087. * @method keyReleased
  10088. * @example
  10089. * <div>
  10090. * <code>
  10091. * var value = 0;
  10092. * function draw() {
  10093. * fill(value);
  10094. * rect(25, 25, 50, 50);
  10095. * }
  10096. * function keyReleased() {
  10097. * if (value === 0) {
  10098. * value = 255;
  10099. * } else {
  10100. * value = 0;
  10101. * }
  10102. * return false; // prevent any default behavior
  10103. * }
  10104. * </code>
  10105. * </div>
  10106. */
  10107. p5.prototype._onkeyup = function (e) {
  10108. var keyReleased = this.keyReleased || window.keyReleased;
  10109. this._setProperty('isKeyPressed', false);
  10110. this._setProperty('keyIsPressed', false);
  10111. downKeys[e.which] = false;
  10112. //delete this._downKeys[e.which];
  10113. var key = String.fromCharCode(e.which);
  10114. if (!key) {
  10115. key = e.which;
  10116. }
  10117. this._setProperty('key', key);
  10118. this._setProperty('keyCode', e.which);
  10119. if (typeof keyReleased === 'function') {
  10120. var executeDefault = keyReleased(e);
  10121. if(executeDefault === false) {
  10122. e.preventDefault();
  10123. }
  10124. }
  10125. };
  10126. /**
  10127. * The keyTyped() function is called once every time a key is pressed, but
  10128. * action keys such as Ctrl, Shift, and Alt are ignored. The most recent
  10129. * key pressed will be stored in the key variable.
  10130. * <br><br>
  10131. * Because of how operating systems handle key repeats, holding down a key
  10132. * will cause multiple calls to keyTyped(), the rate is set by the operating
  10133. * system and how each computer is configured.<br><br>
  10134. * Browsers may have different default
  10135. * behaviors attached to various key events. To prevent any default
  10136. * behavior for this event, add "return false" to the end of the method.
  10137. *
  10138. * @method keyTyped
  10139. * @example
  10140. * <div>
  10141. * <code>
  10142. * var value = 0;
  10143. * function draw() {
  10144. * fill(value);
  10145. * rect(25, 25, 50, 50);
  10146. * }
  10147. * function keyTyped() {
  10148. * if (key === 'a') {
  10149. * value = 255;
  10150. * } else if (key === 'b') {
  10151. * value = 0;
  10152. * }
  10153. * return false; // prevent any default behavior
  10154. * }
  10155. * </code>
  10156. * </div>
  10157. */
  10158. p5.prototype._onkeypress = function (e) {
  10159. this._setProperty('keyCode', e.which);
  10160. this._setProperty('key', String.fromCharCode(e.which));
  10161. var keyTyped = this.keyTyped || window.keyTyped;
  10162. if (typeof keyTyped === 'function') {
  10163. var executeDefault = keyTyped(e);
  10164. if(executeDefault === false) {
  10165. e.preventDefault();
  10166. }
  10167. }
  10168. };
  10169. /**
  10170. * The onblur function is called when the user is no longer focused
  10171. * on the p5 element. Because the keyup events will no fire if the user is
  10172. * not focused on the element we must assume all keys currently down have
  10173. * been released.
  10174. */
  10175. p5.prototype._onblur = function (e) {
  10176. downKeys = {};
  10177. };
  10178. /**
  10179. * The keyIsDown function checks if the key is currently down, i.e. pressed.
  10180. * It can be used if you have an object that moves, and you want several keys
  10181. * to be able to affect its behaviour simultaneously, such as moving a
  10182. * sprite diagonally. You can put in any number representing the keyCode of
  10183. * the key, or use any of the variable keyCode names listed
  10184. * <a href="http://p5js.org/reference/#p5/keyCode">here</a>.
  10185. *
  10186. * @method keyIsDown
  10187. * @param {Number} code The key to check for.
  10188. * @return {Boolean} whether key is down or not
  10189. * @example
  10190. * <div><code>
  10191. * var x = 100;
  10192. * var y = 100;
  10193. *
  10194. * function setup() {
  10195. * createCanvas(512, 512);
  10196. * }
  10197. *
  10198. * function draw() {
  10199. * if (keyIsDown(LEFT_ARROW))
  10200. * x-=5;
  10201. *
  10202. * if (keyIsDown(RIGHT_ARROW))
  10203. * x+=5;
  10204. *
  10205. * if (keyIsDown(UP_ARROW))
  10206. * y-=5;
  10207. *
  10208. * if (keyIsDown(DOWN_ARROW))
  10209. * y+=5;
  10210. *
  10211. * clear();
  10212. * fill(255, 0, 0);
  10213. * ellipse(x, y, 50, 50);
  10214. * }
  10215. * </code></div>
  10216. */
  10217. p5.prototype.keyIsDown = function(code) {
  10218. return downKeys[code];
  10219. };
  10220. module.exports = p5;
  10221. },{"../core/core":17}],32:[function(require,module,exports){
  10222. /**
  10223. * @module Events
  10224. * @submodule Mouse
  10225. * @for p5
  10226. * @requires core
  10227. * @requires constants
  10228. */
  10229. 'use strict';
  10230. var p5 = require('../core/core');
  10231. var constants = require('../core/constants');
  10232. /**
  10233. * The system variable mouseX always contains the current horizontal
  10234. * position of the mouse, relative to (0, 0) of the canvas.
  10235. *
  10236. * @property mouseX
  10237. *
  10238. * @example
  10239. * <div>
  10240. * <code>
  10241. * // Move the mouse across the canvas
  10242. * function draw() {
  10243. * background(244, 248, 252);
  10244. * line(mouseX, 0, mouseX, 100);
  10245. * }
  10246. * </code>
  10247. * </div>
  10248. */
  10249. p5.prototype.mouseX = 0;
  10250. /**
  10251. * The system variable mouseY always contains the current vertical position
  10252. * of the mouse, relative to (0, 0) of the canvas.
  10253. *
  10254. * @property mouseY
  10255. *
  10256. * @example
  10257. * <div>
  10258. * <code>
  10259. * // Move the mouse across the canvas
  10260. * function draw() {
  10261. * background(244, 248, 252);
  10262. * line(0, mouseY, 100, mouseY);
  10263. *}
  10264. * </code>
  10265. * </div>
  10266. */
  10267. p5.prototype.mouseY = 0;
  10268. /**
  10269. * The system variable pmouseX always contains the horizontal position of
  10270. * the mouse in the frame previous to the current frame, relative to (0, 0)
  10271. * of the canvas.
  10272. *
  10273. * @property pmouseX
  10274. *
  10275. * @example
  10276. * <div>
  10277. * <code>
  10278. * // Move the mouse across the canvas to leave a trail
  10279. * function setup() {
  10280. * //slow down the frameRate to make it more visible
  10281. * frameRate(10);
  10282. * }
  10283. *
  10284. * function draw() {
  10285. * background(244, 248, 252);
  10286. * line(mouseX, mouseY, pmouseX, pmouseY);
  10287. * print(pmouseX + " -> " + mouseX);
  10288. * }
  10289. *
  10290. * </code>
  10291. * </div>
  10292. */
  10293. p5.prototype.pmouseX = 0;
  10294. /**
  10295. * The system variable pmouseY always contains the vertical position of the
  10296. * mouse in the frame previous to the current frame, relative to (0, 0) of
  10297. * the canvas.
  10298. *
  10299. * @property pmouseY
  10300. *
  10301. * @example
  10302. * <div>
  10303. * <code>
  10304. * function draw() {
  10305. * background(237, 34, 93);
  10306. * fill(0);
  10307. * //draw a square only if the mouse is not moving
  10308. * if(mouseY == pmouseY && mouseX == pmouseX)
  10309. * rect(20,20,60,60);
  10310. *
  10311. * print(pmouseY + " -> " + mouseY);
  10312. * }
  10313. *
  10314. * </code>
  10315. * </div>
  10316. */
  10317. p5.prototype.pmouseY = 0;
  10318. /**
  10319. * The system variable winMouseX always contains the current horizontal
  10320. * position of the mouse, relative to (0, 0) of the window.
  10321. *
  10322. * @property winMouseX
  10323. *
  10324. * @example
  10325. * <div>
  10326. * <code>
  10327. * var myCanvas;
  10328. *
  10329. * function setup() {
  10330. * //use a variable to store a pointer to the canvas
  10331. * myCanvas = createCanvas(100, 100);
  10332. * }
  10333. *
  10334. * function draw() {
  10335. * background(237, 34, 93);
  10336. * fill(0);
  10337. *
  10338. * //move the canvas to the horizontal mouse position
  10339. * //relative to the window
  10340. * myCanvas.position(winMouseX+1, windowHeight/2);
  10341. *
  10342. * //the y of the square is relative to the canvas
  10343. * rect(20,mouseY,60,60);
  10344. * }
  10345. *
  10346. * </code>
  10347. * </div>
  10348. */
  10349. p5.prototype.winMouseX = 0;
  10350. /**
  10351. * The system variable winMouseY always contains the current vertical
  10352. * position of the mouse, relative to (0, 0) of the window.
  10353. *
  10354. * @property winMouseY
  10355. *
  10356. * @example
  10357. * <div>
  10358. * <code>
  10359. *var myCanvas;
  10360. *
  10361. * function setup() {
  10362. * //use a variable to store a pointer to the canvas
  10363. * myCanvas = createCanvas(100, 100);
  10364. * }
  10365. *
  10366. * function draw() {
  10367. * background(237, 34, 93);
  10368. * fill(0);
  10369. *
  10370. * //move the canvas to the vertical mouse position
  10371. * //relative to the window
  10372. * myCanvas.position(windowWidth/2, winMouseY+1);
  10373. *
  10374. * //the x of the square is relative to the canvas
  10375. * rect(mouseX,20,60,60);
  10376. * }
  10377. *
  10378. * </code>
  10379. * </div>
  10380. */
  10381. p5.prototype.winMouseY = 0;
  10382. /**
  10383. * The system variable pwinMouseX always contains the horizontal position
  10384. * of the mouse in the frame previous to the current frame, relative to
  10385. * (0, 0) of the window.
  10386. *
  10387. * @property pwinMouseX
  10388. *
  10389. * @example
  10390. * <div>
  10391. * <code>
  10392. *
  10393. * var myCanvas;
  10394. *
  10395. * function setup() {
  10396. * //use a variable to store a pointer to the canvas
  10397. * myCanvas = createCanvas(100, 100);
  10398. * noStroke();
  10399. * fill(237, 34, 93);
  10400. * }
  10401. *
  10402. * function draw() {
  10403. * clear();
  10404. * //the difference between previous and
  10405. * //current x position is the horizontal mouse speed
  10406. * var speed = abs(winMouseX-pwinMouseX);
  10407. * //change the size of the circle
  10408. * //according to the horizontal speed
  10409. * ellipse(50, 50, 10+speed*5, 10+speed*5);
  10410. * //move the canvas to the mouse position
  10411. * myCanvas.position( winMouseX+1, winMouseY+1);
  10412. * }
  10413. *
  10414. * </code>
  10415. * </div>
  10416. */
  10417. p5.prototype.pwinMouseX = 0;
  10418. /**
  10419. * The system variable pwinMouseY always contains the vertical position of
  10420. * the mouse in the frame previous to the current frame, relative to (0, 0)
  10421. * of the window.
  10422. *
  10423. * @property pwinMouseY
  10424. *
  10425. *
  10426. * @example
  10427. * <div>
  10428. * <code>
  10429. *
  10430. * var myCanvas;
  10431. *
  10432. * function setup() {
  10433. * //use a variable to store a pointer to the canvas
  10434. * myCanvas = createCanvas(100, 100);
  10435. * noStroke();
  10436. * fill(237, 34, 93);
  10437. * }
  10438. *
  10439. * function draw() {
  10440. * clear();
  10441. * //the difference between previous and
  10442. * //current y position is the vertical mouse speed
  10443. * var speed = abs(winMouseY-pwinMouseY);
  10444. * //change the size of the circle
  10445. * //according to the vertical speed
  10446. * ellipse(50, 50, 10+speed*5, 10+speed*5);
  10447. * //move the canvas to the mouse position
  10448. * myCanvas.position( winMouseX+1, winMouseY+1);
  10449. * }
  10450. *
  10451. * </code>
  10452. * </div>
  10453. */
  10454. p5.prototype.pwinMouseY = 0;
  10455. /**
  10456. * Processing automatically tracks if the mouse button is pressed and which
  10457. * button is pressed. The value of the system variable mouseButton is either
  10458. * LEFT, RIGHT, or CENTER depending on which button was pressed last.
  10459. * Warning: different browsers may track mouseButton differently.
  10460. *
  10461. * @property mouseButton
  10462. *
  10463. * @example
  10464. * <div>
  10465. * <code>
  10466. * function draw() {
  10467. * background(237, 34, 93);
  10468. * fill(0);
  10469. *
  10470. * if (mouseIsPressed) {
  10471. * if (mouseButton == LEFT)
  10472. * ellipse(50, 50, 50, 50);
  10473. * if (mouseButton == RIGHT)
  10474. * rect(25, 25, 50, 50);
  10475. * if (mouseButton == CENTER)
  10476. * triangle(23, 75, 50, 20, 78, 75);
  10477. * }
  10478. *
  10479. * print(mouseButton);
  10480. * }
  10481. * </code>
  10482. * </div>
  10483. */
  10484. p5.prototype.mouseButton = 0;
  10485. /**
  10486. * The boolean system variable mouseIsPressed is true if the mouse is pressed
  10487. * and false if not.
  10488. *
  10489. * @property mouseIsPressed
  10490. *
  10491. * @example
  10492. * <div>
  10493. * <code>
  10494. * function draw() {
  10495. * background(237, 34, 93);
  10496. * fill(0);
  10497. *
  10498. * if (mouseIsPressed)
  10499. * ellipse(50, 50, 50, 50);
  10500. * else
  10501. * rect(25, 25, 50, 50);
  10502. *
  10503. * print(mouseIsPressed);
  10504. * }
  10505. * </code>
  10506. * </div>
  10507. */
  10508. p5.prototype.mouseIsPressed = false;
  10509. p5.prototype.isMousePressed = false; // both are supported
  10510. p5.prototype._updateMouseCoords = function(e) {
  10511. if(e.type === 'touchstart' ||
  10512. e.type === 'touchmove' ||
  10513. e.type === 'touchend') {
  10514. this._setProperty('mouseX', this.touchX);
  10515. this._setProperty('mouseY', this.touchY);
  10516. } else {
  10517. if(this._curElement !== null) {
  10518. var mousePos = getMousePos(this._curElement.elt, e);
  10519. this._setProperty('mouseX', mousePos.x);
  10520. this._setProperty('mouseY', mousePos.y);
  10521. }
  10522. }
  10523. this._setProperty('winMouseX', e.pageX);
  10524. this._setProperty('winMouseY', e.pageY);
  10525. };
  10526. p5.prototype._updatePMouseCoords = function(e) {
  10527. this._setProperty('pmouseX', this.mouseX);
  10528. this._setProperty('pmouseY', this.mouseY);
  10529. this._setProperty('pwinMouseX', this.winMouseX);
  10530. this._setProperty('pwinMouseY', this.winMouseY);
  10531. };
  10532. function getMousePos(canvas, evt) {
  10533. var rect = canvas.getBoundingClientRect();
  10534. return {
  10535. x: evt.clientX - rect.left,
  10536. y: evt.clientY - rect.top
  10537. };
  10538. }
  10539. p5.prototype._setMouseButton = function(e) {
  10540. if (e.button === 1) {
  10541. this._setProperty('mouseButton', constants.CENTER);
  10542. } else if (e.button === 2) {
  10543. this._setProperty('mouseButton', constants.RIGHT);
  10544. } else {
  10545. this._setProperty('mouseButton', constants.LEFT);
  10546. if(e.type === 'touchstart' || e.type === 'touchmove') {
  10547. this._setProperty('mouseX', this.touchX);
  10548. this._setProperty('mouseY', this.touchY);
  10549. }
  10550. }
  10551. };
  10552. /**
  10553. * The mouseMoved() function is called every time the mouse moves and a mouse
  10554. * button is not pressed.<br><br>
  10555. * Browsers may have different default
  10556. * behaviors attached to various mouse events. To prevent any default
  10557. * behavior for this event, add `return false` to the end of the method.
  10558. *
  10559. * @method mouseMoved
  10560. * @example
  10561. * <div>
  10562. * <code>
  10563. * // Move the mouse across the page
  10564. * // to change its value
  10565. *
  10566. * var value = 0;
  10567. * function draw() {
  10568. * fill(value);
  10569. * rect(25, 25, 50, 50);
  10570. * }
  10571. * function mouseMoved() {
  10572. * value = value + 5;
  10573. * if (value > 255) {
  10574. * value = 0;
  10575. * }
  10576. * }
  10577. * </code>
  10578. * </div>
  10579. *
  10580. * <div class="norender">
  10581. * <code>
  10582. * function mouseMoved() {
  10583. * ellipse(mouseX, mouseY, 5, 5);
  10584. * // prevent default
  10585. * return false;
  10586. * }
  10587. * </code>
  10588. * </div>
  10589. */
  10590. /**
  10591. * The mouseDragged() function is called once every time the mouse moves and
  10592. * a mouse button is pressed. If no mouseDragged() function is defined, the
  10593. * touchMoved() function will be called instead if it is defined.<br><br>
  10594. * Browsers may have different default
  10595. * behaviors attached to various mouse events. To prevent any default
  10596. * behavior for this event, add `return false` to the end of the method.
  10597. *
  10598. * @method mouseDragged
  10599. * @example
  10600. * <div>
  10601. * <code>
  10602. * // Drag the mouse across the page
  10603. * // to change its value
  10604. *
  10605. * var value = 0;
  10606. * function draw() {
  10607. * fill(value);
  10608. * rect(25, 25, 50, 50);
  10609. * }
  10610. * function mouseDragged() {
  10611. * value = value + 5;
  10612. * if (value > 255) {
  10613. * value = 0;
  10614. * }
  10615. * }
  10616. * </code>
  10617. * </div>
  10618. *
  10619. * <div class="norender">
  10620. * <code>
  10621. * function mouseDragged() {
  10622. * ellipse(mouseX, mouseY, 5, 5);
  10623. * // prevent default
  10624. * return false;
  10625. * }
  10626. * </code>
  10627. * </div>
  10628. */
  10629. p5.prototype._onmousemove = function(e){
  10630. var context = this._isGlobal ? window : this;
  10631. var executeDefault;
  10632. this._updateMouseCoords(e);
  10633. if (!this.isMousePressed) {
  10634. if (typeof context.mouseMoved === 'function') {
  10635. executeDefault = context.mouseMoved(e);
  10636. if(executeDefault === false) {
  10637. e.preventDefault();
  10638. }
  10639. }
  10640. }
  10641. else {
  10642. if (typeof context.mouseDragged === 'function') {
  10643. executeDefault = context.mouseDragged(e);
  10644. if(executeDefault === false) {
  10645. e.preventDefault();
  10646. }
  10647. } else if (typeof context.touchMoved === 'function') {
  10648. executeDefault = context.touchMoved(e);
  10649. if(executeDefault === false) {
  10650. e.preventDefault();
  10651. }
  10652. this._updateTouchCoords(e);
  10653. }
  10654. }
  10655. };
  10656. /**
  10657. * The mousePressed() function is called once after every time a mouse button
  10658. * is pressed. The mouseButton variable (see the related reference entry)
  10659. * can be used to determine which button has been pressed. If no
  10660. * mousePressed() function is defined, the touchStarted() function will be
  10661. * called instead if it is defined.<br><br>
  10662. * Browsers may have different default
  10663. * behaviors attached to various mouse events. To prevent any default
  10664. * behavior for this event, add `return false` to the end of the method.
  10665. *
  10666. * @method mousePressed
  10667. * @example
  10668. * <div>
  10669. * <code>
  10670. * // Click within the image to change
  10671. * // the value of the rectangle
  10672. *
  10673. * var value = 0;
  10674. * function draw() {
  10675. * fill(value);
  10676. * rect(25, 25, 50, 50);
  10677. * }
  10678. * function mousePressed() {
  10679. * if (value == 0) {
  10680. * value = 255;
  10681. * } else {
  10682. * value = 0;
  10683. * }
  10684. * }
  10685. * </code>
  10686. * </div>
  10687. *
  10688. * <div class="norender">
  10689. * <code>
  10690. * function mousePressed() {
  10691. * ellipse(mouseX, mouseY, 5, 5);
  10692. * // prevent default
  10693. * return false;
  10694. * }
  10695. * </code>
  10696. * </div>
  10697. */
  10698. p5.prototype._onmousedown = function(e) {
  10699. var context = this._isGlobal ? window : this;
  10700. var executeDefault;
  10701. this._setProperty('isMousePressed', true);
  10702. this._setProperty('mouseIsPressed', true);
  10703. this._setMouseButton(e);
  10704. this._updateMouseCoords(e);
  10705. if (typeof context.mousePressed === 'function') {
  10706. executeDefault = context.mousePressed(e);
  10707. if(executeDefault === false) {
  10708. e.preventDefault();
  10709. }
  10710. } else if (typeof context.touchStarted === 'function') {
  10711. executeDefault = context.touchStarted(e);
  10712. if(executeDefault === false) {
  10713. e.preventDefault();
  10714. }
  10715. this._updateTouchCoords(e);
  10716. }
  10717. };
  10718. /**
  10719. * The mouseReleased() function is called every time a mouse button is
  10720. * released. If no mouseReleased() function is defined, the touchEnded()
  10721. * function will be called instead if it is defined.<br><br>
  10722. * Browsers may have different default
  10723. * behaviors attached to various mouse events. To prevent any default
  10724. * behavior for this event, add `return false` to the end of the method.
  10725. *
  10726. *
  10727. * @method mouseReleased
  10728. * @example
  10729. * <div>
  10730. * <code>
  10731. * // Click within the image to change
  10732. * // the value of the rectangle
  10733. * // after the mouse has been clicked
  10734. *
  10735. * var value = 0;
  10736. * function draw() {
  10737. * fill(value);
  10738. * rect(25, 25, 50, 50);
  10739. * }
  10740. * function mouseReleased() {
  10741. * if (value == 0) {
  10742. * value = 255;
  10743. * } else {
  10744. * value = 0;
  10745. * }
  10746. * }
  10747. * </code>
  10748. * </div>
  10749. *
  10750. * <div class="norender">
  10751. * <code>
  10752. * function mouseReleased() {
  10753. * ellipse(mouseX, mouseY, 5, 5);
  10754. * // prevent default
  10755. * return false;
  10756. * }
  10757. * </code>
  10758. * </div>
  10759. */
  10760. p5.prototype._onmouseup = function(e) {
  10761. var context = this._isGlobal ? window : this;
  10762. var executeDefault;
  10763. this._setProperty('isMousePressed', false);
  10764. this._setProperty('mouseIsPressed', false);
  10765. if (typeof context.mouseReleased === 'function') {
  10766. executeDefault = context.mouseReleased(e);
  10767. if(executeDefault === false) {
  10768. e.preventDefault();
  10769. }
  10770. } else if (typeof context.touchEnded === 'function') {
  10771. executeDefault = context.touchEnded(e);
  10772. if(executeDefault === false) {
  10773. e.preventDefault();
  10774. }
  10775. this._updateTouchCoords(e);
  10776. }
  10777. };
  10778. /**
  10779. * The mouseClicked() function is called once after a mouse button has been
  10780. * pressed and then released.<br><br>
  10781. * Browsers may have different default
  10782. * behaviors attached to various mouse events. To prevent any default
  10783. * behavior for this event, add `return false` to the end of the method.
  10784. *
  10785. * @method mouseClicked
  10786. * @example
  10787. * <div>
  10788. * <code>
  10789. * // Click within the image to change
  10790. * // the value of the rectangle
  10791. * // after the mouse has been clicked
  10792. *
  10793. * var value = 0;
  10794. * function draw() {
  10795. * fill(value);
  10796. * rect(25, 25, 50, 50);
  10797. * }
  10798. * function mouseClicked() {
  10799. * if (value == 0) {
  10800. * value = 255;
  10801. * } else {
  10802. * value = 0;
  10803. * }
  10804. * }
  10805. * </code>
  10806. * </div>
  10807. *
  10808. * <div class="norender">
  10809. * <code>
  10810. * function mouseClicked() {
  10811. * ellipse(mouseX, mouseY, 5, 5);
  10812. * // prevent default
  10813. * return false;
  10814. * }
  10815. * </code>
  10816. * </div>
  10817. */
  10818. p5.prototype._onclick = function(e) {
  10819. var context = this._isGlobal ? window : this;
  10820. if (typeof context.mouseClicked === 'function') {
  10821. var executeDefault = context.mouseClicked(e);
  10822. if(executeDefault === false) {
  10823. e.preventDefault();
  10824. }
  10825. }
  10826. };
  10827. /**
  10828. * The function mouseWheel is executed every time a scroll event is detected
  10829. * either triggered by an actual mouse wheel or by a touchpad.<br>
  10830. * The event.delta property returns -1 or +1 depending on the scroll
  10831. * direction and the user's settings. (on OS X with "natural" scrolling
  10832. * enabled, the values are inverted).<br><br>
  10833. * Browsers may have different default behaviors attached to various
  10834. * mouse events. To prevent any default behavior for this event, add
  10835. * `return false` to the end of the method.
  10836. *
  10837. * The event.wheelDelta or event.detail properties can also be accessed but
  10838. * their behavior may differ depending on the browser.
  10839. * See <a href="http://www.javascriptkit.com/javatutors/onmousewheel.shtml">
  10840. * mouse wheel event in JS</a>.
  10841. *
  10842. * @method mouseWheel
  10843. *
  10844. * @example
  10845. * <div>
  10846. * <code>
  10847. * var pos = 25;
  10848. *
  10849. * function draw() {
  10850. * background(237, 34, 93);
  10851. * fill(0);
  10852. * rect(25, pos, 50, 50);
  10853. * }
  10854. *
  10855. * function mouseWheel(event) {
  10856. * //event.delta can be +1 or -1 depending
  10857. * //on the wheel/scroll direction
  10858. * print(event.delta);
  10859. * //move the square one pixel up or down
  10860. * pos += event.delta;
  10861. * //uncomment to block page scrolling
  10862. * //return false;
  10863. * }
  10864. * </code>
  10865. * </div>
  10866. */
  10867. p5.prototype._onmousewheel = p5.prototype._onDOMMouseScroll = function(e) {
  10868. var context = this._isGlobal ? window : this;
  10869. if (typeof context.mouseWheel === 'function') {
  10870. //creating a delta property (either +1 or -1)
  10871. //for cross-browser compatibility
  10872. e.delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
  10873. var executeDefault = context.mouseWheel(e);
  10874. if(executeDefault === false) {
  10875. e.preventDefault();
  10876. }
  10877. }
  10878. };
  10879. module.exports = p5;
  10880. },{"../core/constants":16,"../core/core":17}],33:[function(require,module,exports){
  10881. /**
  10882. * @module Events
  10883. * @submodule Touch
  10884. * @for p5
  10885. * @requires core
  10886. */
  10887. 'use strict';
  10888. var p5 = require('../core/core');
  10889. /**
  10890. * The system variable touchX always contains the horizontal position of
  10891. * one finger, relative to (0, 0) of the canvas. This is best used for
  10892. * single touch interactions. For multi-touch interactions, use the
  10893. * touches[] array.
  10894. *
  10895. * @property touchX
  10896. */
  10897. p5.prototype.touchX = 0;
  10898. /**
  10899. * The system variable touchY always contains the vertical position of
  10900. * one finger, relative to (0, 0) of the canvas. This is best used for
  10901. * single touch interactions. For multi-touch interactions, use the
  10902. * touches[] array.
  10903. *
  10904. * @property touchY
  10905. */
  10906. p5.prototype.touchY = 0;
  10907. /**
  10908. * The system variable ptouchX always contains the horizontal position of
  10909. * one finger, relative to (0, 0) of the canvas, in the frame previous to the
  10910. * current frame.
  10911. *
  10912. * @property ptouchX
  10913. */
  10914. p5.prototype.ptouchX = 0;
  10915. /**
  10916. * The system variable ptouchY always contains the vertical position of
  10917. * one finger, relative to (0, 0) of the canvas, in the frame previous to the
  10918. * current frame.
  10919. *
  10920. * @property ptouchY
  10921. */
  10922. p5.prototype.ptouchY = 0;
  10923. /**
  10924. * The system variable touches[] contains an array of the positions of all
  10925. * current touch points, relative to (0, 0) of the canvas. Each element in
  10926. * the array is an object with x and y properties.
  10927. *
  10928. * @property touches[]
  10929. */
  10930. p5.prototype.touches = [];
  10931. /**
  10932. * The boolean system variable touchIsDown is true if the screen is
  10933. * touched and false if not.
  10934. *
  10935. * @property touchIsDown
  10936. */
  10937. p5.prototype.touchIsDown = false;
  10938. p5.prototype._updateTouchCoords = function(e) {
  10939. if(e.type === 'mousedown' ||
  10940. e.type === 'mousemove' ||
  10941. e.type === 'mouseup'){
  10942. this._setProperty('touchX', this.mouseX);
  10943. this._setProperty('touchY', this.mouseY);
  10944. } else {
  10945. var touchPos = getTouchPos(this._curElement.elt, e, 0);
  10946. this._setProperty('touchX', touchPos.x);
  10947. this._setProperty('touchY', touchPos.y);
  10948. var touches = [];
  10949. for(var i = 0; i < e.touches.length; i++){
  10950. var pos = getTouchPos(this._curElement.elt, e, i);
  10951. touches[i] = {x: pos.x, y: pos.y};
  10952. }
  10953. this._setProperty('touches', touches);
  10954. }
  10955. };
  10956. p5.prototype._updatePTouchCoords = function() {
  10957. this._setProperty('ptouchX', this.touchX);
  10958. this._setProperty('ptouchY', this.touchY);
  10959. };
  10960. function getTouchPos(canvas, e, i) {
  10961. i = i || 0;
  10962. var rect = canvas.getBoundingClientRect();
  10963. var touch = e.touches[i] || e.changedTouches[i];
  10964. return {
  10965. x: touch.clientX - rect.left,
  10966. y: touch.clientY - rect.top
  10967. };
  10968. }
  10969. /**
  10970. * The touchStarted() function is called once after every time a touch is
  10971. * registered. If no touchStarted() function is defined, the mousePressed()
  10972. * function will be called instead if it is defined. Browsers may have
  10973. * different default
  10974. * behaviors attached to various touch events. To prevent any default
  10975. * behavior for this event, add `return false` to the end of the method.
  10976. *
  10977. * @method touchStarted
  10978. * @example
  10979. * <div>
  10980. * <code>
  10981. * // Touch within the image to change
  10982. * // the value of the rectangle
  10983. *
  10984. * var value = 0;
  10985. * function draw() {
  10986. * fill(value);
  10987. * rect(25, 25, 50, 50);
  10988. * }
  10989. * function touchStarted() {
  10990. * if (value == 0) {
  10991. * value = 255;
  10992. * } else {
  10993. * value = 0;
  10994. * }
  10995. * }
  10996. * </code>
  10997. * </div>
  10998. *
  10999. * <div class="norender">
  11000. * <code>
  11001. * function touchStarted() {
  11002. * ellipse(touchX, touchY, 5, 5);
  11003. * // prevent default
  11004. * return false;
  11005. * }
  11006. * </code>
  11007. * </div>
  11008. */
  11009. p5.prototype._ontouchstart = function(e) {
  11010. var context = this._isGlobal ? window : this;
  11011. var executeDefault;
  11012. this._updateTouchCoords(e);
  11013. this._setProperty('touchIsDown', true);
  11014. if(typeof context.touchStarted === 'function') {
  11015. executeDefault = context.touchStarted(e);
  11016. if(executeDefault === false) {
  11017. e.preventDefault();
  11018. }
  11019. } else if (typeof context.mousePressed === 'function') {
  11020. executeDefault = context.mousePressed(e);
  11021. if(executeDefault === false) {
  11022. e.preventDefault();
  11023. }
  11024. //this._setMouseButton(e);
  11025. }
  11026. };
  11027. /**
  11028. * The touchMoved() function is called every time a touch move is registered.
  11029. * If no touchStarted() function is defined, the mouseDragged() function will
  11030. * be called instead if it is defined. Browsers may have different default
  11031. * behaviors attached to various touch events. To prevent any default
  11032. * behavior for this event, add `return false` to the end of the method.
  11033. *
  11034. * @method touchMoved
  11035. * @example
  11036. * <div>
  11037. * <code>
  11038. * // Move your finger across the page
  11039. * // to change its value
  11040. *
  11041. * var value = 0;
  11042. * function draw() {
  11043. * fill(value);
  11044. * rect(25, 25, 50, 50);
  11045. * }
  11046. * function touchMoved() {
  11047. * value = value + 5;
  11048. * if (value > 255) {
  11049. * value = 0;
  11050. * }
  11051. * }
  11052. * </code>
  11053. * </div>
  11054. *
  11055. * <div class="norender">
  11056. * <code>
  11057. * function touchMoved() {
  11058. * ellipse(touchX, touchY, 5, 5);
  11059. * // prevent default
  11060. * return false;
  11061. * }
  11062. * </code>
  11063. * </div>
  11064. */
  11065. p5.prototype._ontouchmove = function(e) {
  11066. var context = this._isGlobal ? window : this;
  11067. var executeDefault;
  11068. this._updateTouchCoords(e);
  11069. if (typeof context.touchMoved === 'function') {
  11070. executeDefault = context.touchMoved(e);
  11071. if(executeDefault === false) {
  11072. e.preventDefault();
  11073. }
  11074. } else if (typeof context.mouseDragged === 'function') {
  11075. executeDefault = context.mouseDragged(e);
  11076. if(executeDefault === false) {
  11077. e.preventDefault();
  11078. }
  11079. this._updateMouseCoords(e);
  11080. }
  11081. };
  11082. /**
  11083. * The touchEnded() function is called every time a touch ends. If no
  11084. * touchStarted() function is defined, the mouseReleased() function will be
  11085. * called instead if it is defined. Browsers may have different default
  11086. * behaviors attached to various touch events. To prevent any default
  11087. * behavior for this event, add `return false` to the end of the method.
  11088. *
  11089. * @method touchEnded
  11090. * @example
  11091. * <div>
  11092. * <code>
  11093. * // Release touch within the image to
  11094. * // change the value of the rectangle
  11095. *
  11096. * var value = 0;
  11097. * function draw() {
  11098. * fill(value);
  11099. * rect(25, 25, 50, 50);
  11100. * }
  11101. * function touchEnded() {
  11102. * if (value == 0) {
  11103. * value = 255;
  11104. * } else {
  11105. * value = 0;
  11106. * }
  11107. * }
  11108. * </code>
  11109. * </div>
  11110. *
  11111. * <div class="norender">
  11112. * <code>
  11113. * function touchEnded() {
  11114. * ellipse(touchX, touchY, 5, 5);
  11115. * // prevent default
  11116. * return false;
  11117. * }
  11118. * </code>
  11119. * </div>
  11120. */
  11121. p5.prototype._ontouchend = function(e) {
  11122. this._updateTouchCoords(e);
  11123. if (this.touches.length === 0) {
  11124. this._setProperty('touchIsDown', false);
  11125. }
  11126. var context = this._isGlobal ? window : this;
  11127. var executeDefault;
  11128. if (typeof context.touchEnded === 'function') {
  11129. executeDefault = context.touchEnded(e);
  11130. if(executeDefault === false) {
  11131. e.preventDefault();
  11132. }
  11133. } else if (typeof context.mouseReleased === 'function') {
  11134. executeDefault = context.mouseReleased(e);
  11135. if(executeDefault === false) {
  11136. e.preventDefault();
  11137. }
  11138. this._updateMouseCoords(e);
  11139. }
  11140. };
  11141. module.exports = p5;
  11142. },{"../core/core":17}],34:[function(require,module,exports){
  11143. /*global ImageData:false */
  11144. /**
  11145. * This module defines the filters for use with image buffers.
  11146. *
  11147. * This module is basically a collection of functions stored in an object
  11148. * as opposed to modules. The functions are destructive, modifying
  11149. * the passed in canvas rather than creating a copy.
  11150. *
  11151. * Generally speaking users of this module will use the Filters.apply method
  11152. * on a canvas to create an effect.
  11153. *
  11154. * A number of functions are borrowed/adapted from
  11155. * http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
  11156. * or the java processing implementation.
  11157. */
  11158. 'use strict';
  11159. var Filters = {};
  11160. /*
  11161. * Helper functions
  11162. */
  11163. /**
  11164. * Returns the pixel buffer for a canvas
  11165. *
  11166. * @private
  11167. *
  11168. * @param {Canvas|ImageData} canvas the canvas to get pixels from
  11169. * @return {Uint8ClampedArray} a one-dimensional array containing
  11170. * the data in thc RGBA order, with integer
  11171. * values between 0 and 255
  11172. */
  11173. Filters._toPixels = function (canvas) {
  11174. if (canvas instanceof ImageData) {
  11175. return canvas.data;
  11176. } else {
  11177. return canvas.getContext('2d').getImageData(
  11178. 0,
  11179. 0,
  11180. canvas.width,
  11181. canvas.height
  11182. ).data;
  11183. }
  11184. };
  11185. /**
  11186. * Returns a 32 bit number containing ARGB data at ith pixel in the
  11187. * 1D array containing pixels data.
  11188. *
  11189. * @private
  11190. *
  11191. * @param {Uint8ClampedArray} data array returned by _toPixels()
  11192. * @param {Integer} i index of a 1D Image Array
  11193. * @return {Integer} 32 bit integer value representing
  11194. * ARGB value.
  11195. */
  11196. Filters._getARGB = function (data, i) {
  11197. var offset = i * 4;
  11198. return (data[offset+3] << 24) & 0xff000000 |
  11199. (data[offset] << 16) & 0x00ff0000 |
  11200. (data[offset+1] << 8) & 0x0000ff00 |
  11201. data[offset+2] & 0x000000ff;
  11202. };
  11203. /**
  11204. * Modifies pixels RGBA values to values contained in the data object.
  11205. *
  11206. * @private
  11207. *
  11208. * @param {Uint8ClampedArray} pixels array returned by _toPixels()
  11209. * @param {Int32Array} data source 1D array where each value
  11210. * represents ARGB values
  11211. */
  11212. Filters._setPixels = function (pixels, data) {
  11213. var offset = 0;
  11214. for( var i = 0, al = pixels.length; i < al; i++) {
  11215. offset = i*4;
  11216. pixels[offset + 0] = (data[i] & 0x00ff0000)>>>16;
  11217. pixels[offset + 1] = (data[i] & 0x0000ff00)>>>8;
  11218. pixels[offset + 2] = (data[i] & 0x000000ff);
  11219. pixels[offset + 3] = (data[i] & 0xff000000)>>>24;
  11220. }
  11221. };
  11222. /**
  11223. * Returns the ImageData object for a canvas
  11224. * https://developer.mozilla.org/en-US/docs/Web/API/ImageData
  11225. *
  11226. * @private
  11227. *
  11228. * @param {Canvas|ImageData} canvas canvas to get image data from
  11229. * @return {ImageData} Holder of pixel data (and width and
  11230. * height) for a canvas
  11231. */
  11232. Filters._toImageData = function (canvas) {
  11233. if (canvas instanceof ImageData) {
  11234. return canvas;
  11235. } else {
  11236. return canvas.getContext('2d').getImageData(
  11237. 0,
  11238. 0,
  11239. canvas.width,
  11240. canvas.height
  11241. );
  11242. }
  11243. };
  11244. /**
  11245. * Returns a blank ImageData object.
  11246. *
  11247. * @private
  11248. *
  11249. * @param {Integer} width
  11250. * @param {Integer} height
  11251. * @return {ImageData}
  11252. */
  11253. Filters._createImageData = function (width, height) {
  11254. Filters._tmpCanvas = document.createElement('canvas');
  11255. Filters._tmpCtx = Filters._tmpCanvas.getContext('2d');
  11256. return this._tmpCtx.createImageData(width, height);
  11257. };
  11258. /**
  11259. * Applys a filter function to a canvas.
  11260. *
  11261. * The difference between this and the actual filter functions defined below
  11262. * is that the filter functions generally modify the pixel buffer but do
  11263. * not actually put that data back to the canvas (where it would actually
  11264. * update what is visible). By contrast this method does make the changes
  11265. * actually visible in the canvas.
  11266. *
  11267. * The apply method is the method that callers of this module would generally
  11268. * use. It has been separated from the actual filters to support an advanced
  11269. * use case of creating a filter chain that executes without actually updating
  11270. * the canvas in between everystep.
  11271. *
  11272. * @param {[type]} func [description]
  11273. * @param {[type]} canvas [description]
  11274. * @param {[type]} level [description]
  11275. * @return {[type]} [description]
  11276. */
  11277. Filters.apply = function (canvas, func, filterParam) {
  11278. var ctx = canvas.getContext('2d');
  11279. var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  11280. //Filters can either return a new ImageData object, or just modify
  11281. //the one they received.
  11282. var newImageData = func(imageData, filterParam);
  11283. if (newImageData instanceof ImageData) {
  11284. ctx.putImageData(newImageData, 0, 0, 0, 0, canvas.width, canvas.height);
  11285. } else {
  11286. ctx.putImageData(imageData, 0, 0, 0, 0, canvas.width, canvas.height);
  11287. }
  11288. };
  11289. /*
  11290. * Filters
  11291. */
  11292. /**
  11293. * Converts the image to black and white pixels depending if they are above or
  11294. * below the threshold defined by the level parameter. The parameter must be
  11295. * between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.
  11296. *
  11297. * Borrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
  11298. *
  11299. * @param {Canvas} canvas
  11300. * @param {Float} level
  11301. */
  11302. Filters.threshold = function (canvas, level) {
  11303. var pixels = Filters._toPixels(canvas);
  11304. if (level === undefined) {
  11305. level = 0.5;
  11306. }
  11307. var thresh = Math.floor(level * 255);
  11308. for (var i = 0; i < pixels.length; i += 4) {
  11309. var r = pixels[i];
  11310. var g = pixels[i + 1];
  11311. var b = pixels[i + 2];
  11312. var gray = (0.2126 * r + 0.7152 * g + 0.0722 * b);
  11313. var val;
  11314. if (gray >= thresh) {
  11315. val = 255;
  11316. } else {
  11317. val = 0;
  11318. }
  11319. pixels[i] = pixels[i + 1] = pixels[i + 2] = val;
  11320. }
  11321. };
  11322. /**
  11323. * Converts any colors in the image to grayscale equivalents.
  11324. * No parameter is used.
  11325. *
  11326. * Borrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/
  11327. *
  11328. * @param {Canvas} canvas
  11329. */
  11330. Filters.gray = function (canvas) {
  11331. var pixels = Filters._toPixels(canvas);
  11332. for (var i = 0; i < pixels.length; i += 4) {
  11333. var r = pixels[i];
  11334. var g = pixels[i + 1];
  11335. var b = pixels[i + 2];
  11336. // CIE luminance for RGB
  11337. var gray = (0.2126 * r + 0.7152 * g + 0.0722 * b);
  11338. pixels[i] = pixels[i + 1] = pixels[i + 2] = gray;
  11339. }
  11340. };
  11341. /**
  11342. * Sets the alpha channel to entirely opaque. No parameter is used.
  11343. *
  11344. * @param {Canvas} canvas
  11345. */
  11346. Filters.opaque = function (canvas) {
  11347. var pixels = Filters._toPixels(canvas);
  11348. for (var i = 0; i < pixels.length; i += 4) {
  11349. pixels[i + 3] = 255;
  11350. }
  11351. return pixels;
  11352. };
  11353. /**
  11354. * Sets each pixel to its inverse value. No parameter is used.
  11355. * @param {Invert}
  11356. */
  11357. Filters.invert = function (canvas) {
  11358. var pixels = Filters._toPixels(canvas);
  11359. for (var i = 0; i < pixels.length; i += 4) {
  11360. pixels[i] = 255 - pixels[i];
  11361. pixels[i + 1] = 255 - pixels[i + 1];
  11362. pixels[i + 2] = 255 - pixels[i + 2];
  11363. }
  11364. };
  11365. /**
  11366. * Limits each channel of the image to the number of colors specified as
  11367. * the parameter. The parameter can be set to values between 2 and 255, but
  11368. * results are most noticeable in the lower ranges.
  11369. *
  11370. * Adapted from java based processing implementation
  11371. *
  11372. * @param {Canvas} canvas
  11373. * @param {Integer} level
  11374. */
  11375. Filters.posterize = function (canvas, level) {
  11376. var pixels = Filters._toPixels(canvas);
  11377. if ((level < 2) || (level > 255)) {
  11378. throw new Error(
  11379. 'Level must be greater than 2 and less than 255 for posterize'
  11380. );
  11381. }
  11382. var levels1 = level - 1;
  11383. for (var i = 0; i < pixels.length; i+=4) {
  11384. var rlevel = pixels[i];
  11385. var glevel = pixels[i + 1];
  11386. var blevel = pixels[i + 2];
  11387. pixels[i] = (((rlevel * level) >> 8) * 255) / levels1;
  11388. pixels[i + 1] = (((glevel * level) >> 8) * 255) / levels1;
  11389. pixels[i + 2] = (((blevel * level) >> 8) * 255) / levels1;
  11390. }
  11391. };
  11392. /**
  11393. * reduces the bright areas in an image
  11394. * @param {Canvas} canvas
  11395. *
  11396. */
  11397. Filters.dilate = function (canvas) {
  11398. var pixels = Filters._toPixels(canvas);
  11399. var currIdx = 0;
  11400. var maxIdx = pixels.length ? pixels.length/4 : 0;
  11401. var out = new Int32Array(maxIdx);
  11402. var currRowIdx, maxRowIdx, colOrig, colOut, currLum;
  11403. var idxRight, idxLeft, idxUp, idxDown,
  11404. colRight, colLeft, colUp, colDown,
  11405. lumRight, lumLeft, lumUp, lumDown;
  11406. while(currIdx < maxIdx) {
  11407. currRowIdx = currIdx;
  11408. maxRowIdx = currIdx + canvas.width;
  11409. while (currIdx < maxRowIdx) {
  11410. colOrig = colOut = Filters._getARGB(pixels, currIdx);
  11411. idxLeft = currIdx - 1;
  11412. idxRight = currIdx + 1;
  11413. idxUp = currIdx - canvas.width;
  11414. idxDown = currIdx + canvas.width;
  11415. if (idxLeft < currRowIdx) {
  11416. idxLeft = currIdx;
  11417. }
  11418. if (idxRight >= maxRowIdx) {
  11419. idxRight = currIdx;
  11420. }
  11421. if (idxUp < 0){
  11422. idxUp = 0;
  11423. }
  11424. if (idxDown >= maxIdx) {
  11425. idxDown = currIdx;
  11426. }
  11427. colUp = Filters._getARGB(pixels, idxUp);
  11428. colLeft = Filters._getARGB(pixels, idxLeft);
  11429. colDown = Filters._getARGB(pixels, idxDown);
  11430. colRight = Filters._getARGB(pixels, idxRight);
  11431. //compute luminance
  11432. currLum = 77*(colOrig>>16&0xff) +
  11433. 151*(colOrig>>8&0xff) +
  11434. 28*(colOrig&0xff);
  11435. lumLeft = 77*(colLeft>>16&0xff) +
  11436. 151*(colLeft>>8&0xff) +
  11437. 28*(colLeft&0xff);
  11438. lumRight = 77*(colRight>>16&0xff) +
  11439. 151*(colRight>>8&0xff) +
  11440. 28*(colRight&0xff);
  11441. lumUp = 77*(colUp>>16&0xff) +
  11442. 151*(colUp>>8&0xff) +
  11443. 28*(colUp&0xff);
  11444. lumDown = 77*(colDown>>16&0xff) +
  11445. 151*(colDown>>8&0xff) +
  11446. 28*(colDown&0xff);
  11447. if (lumLeft > currLum) {
  11448. colOut = colLeft;
  11449. currLum = lumLeft;
  11450. }
  11451. if (lumRight > currLum) {
  11452. colOut = colRight;
  11453. currLum = lumRight;
  11454. }
  11455. if (lumUp > currLum) {
  11456. colOut = colUp;
  11457. currLum = lumUp;
  11458. }
  11459. if (lumDown > currLum) {
  11460. colOut = colDown;
  11461. currLum = lumDown;
  11462. }
  11463. out[currIdx++]=colOut;
  11464. }
  11465. }
  11466. Filters._setPixels(pixels, out);
  11467. };
  11468. /**
  11469. * increases the bright areas in an image
  11470. * @param {Canvas} canvas
  11471. *
  11472. */
  11473. Filters.erode = function(canvas) {
  11474. var pixels = Filters._toPixels(canvas);
  11475. var currIdx = 0;
  11476. var maxIdx = pixels.length ? pixels.length/4 : 0;
  11477. var out = new Int32Array(maxIdx);
  11478. var currRowIdx, maxRowIdx, colOrig, colOut, currLum;
  11479. var idxRight, idxLeft, idxUp, idxDown,
  11480. colRight, colLeft, colUp, colDown,
  11481. lumRight, lumLeft, lumUp, lumDown;
  11482. while(currIdx < maxIdx) {
  11483. currRowIdx = currIdx;
  11484. maxRowIdx = currIdx + canvas.width;
  11485. while (currIdx < maxRowIdx) {
  11486. colOrig = colOut = Filters._getARGB(pixels, currIdx);
  11487. idxLeft = currIdx - 1;
  11488. idxRight = currIdx + 1;
  11489. idxUp = currIdx - canvas.width;
  11490. idxDown = currIdx + canvas.width;
  11491. if (idxLeft < currRowIdx) {
  11492. idxLeft = currIdx;
  11493. }
  11494. if (idxRight >= maxRowIdx) {
  11495. idxRight = currIdx;
  11496. }
  11497. if (idxUp < 0) {
  11498. idxUp = 0;
  11499. }
  11500. if (idxDown >= maxIdx) {
  11501. idxDown = currIdx;
  11502. }
  11503. colUp = Filters._getARGB(pixels, idxUp);
  11504. colLeft = Filters._getARGB(pixels, idxLeft);
  11505. colDown = Filters._getARGB(pixels, idxDown);
  11506. colRight = Filters._getARGB(pixels, idxRight);
  11507. //compute luminance
  11508. currLum = 77*(colOrig>>16&0xff) +
  11509. 151*(colOrig>>8&0xff) +
  11510. 28*(colOrig&0xff);
  11511. lumLeft = 77*(colLeft>>16&0xff) +
  11512. 151*(colLeft>>8&0xff) +
  11513. 28*(colLeft&0xff);
  11514. lumRight = 77*(colRight>>16&0xff) +
  11515. 151*(colRight>>8&0xff) +
  11516. 28*(colRight&0xff);
  11517. lumUp = 77*(colUp>>16&0xff) +
  11518. 151*(colUp>>8&0xff) +
  11519. 28*(colUp&0xff);
  11520. lumDown = 77*(colDown>>16&0xff) +
  11521. 151*(colDown>>8&0xff) +
  11522. 28*(colDown&0xff);
  11523. if (lumLeft < currLum) {
  11524. colOut = colLeft;
  11525. currLum = lumLeft;
  11526. }
  11527. if (lumRight < currLum) {
  11528. colOut = colRight;
  11529. currLum = lumRight;
  11530. }
  11531. if (lumUp < currLum) {
  11532. colOut = colUp;
  11533. currLum = lumUp;
  11534. }
  11535. if (lumDown < currLum) {
  11536. colOut = colDown;
  11537. currLum = lumDown;
  11538. }
  11539. out[currIdx++]=colOut;
  11540. }
  11541. }
  11542. Filters._setPixels(pixels, out);
  11543. };
  11544. // BLUR
  11545. // internal kernel stuff for the gaussian blur filter
  11546. var blurRadius;
  11547. var blurKernelSize;
  11548. var blurKernel;
  11549. var blurMult;
  11550. /*
  11551. * Port of https://github.com/processing/processing/blob/
  11552. * master/core/src/processing/core/PImage.java#L1250
  11553. *
  11554. * Optimized code for building the blur kernel.
  11555. * further optimized blur code (approx. 15% for radius=20)
  11556. * bigger speed gains for larger radii (~30%)
  11557. * added support for various image types (ALPHA, RGB, ARGB)
  11558. * [toxi 050728]
  11559. */
  11560. function buildBlurKernel(r) {
  11561. var radius = (r * 3.5)|0;
  11562. radius = (radius < 1) ? 1 : ((radius < 248) ? radius : 248);
  11563. if (blurRadius !== radius) {
  11564. blurRadius = radius;
  11565. blurKernelSize = 1 + blurRadius<<1;
  11566. blurKernel = new Int32Array(blurKernelSize);
  11567. blurMult = new Array(blurKernelSize);
  11568. for(var l = 0; l < blurKernelSize; l++){
  11569. blurMult[l] = new Int32Array(256);
  11570. }
  11571. var bk,bki;
  11572. var bm,bmi;
  11573. for (var i = 1, radiusi = radius - 1; i < radius; i++) {
  11574. blurKernel[radius+i] = blurKernel[radiusi] = bki = radiusi * radiusi;
  11575. bm = blurMult[radius+i];
  11576. bmi = blurMult[radiusi--];
  11577. for (var j = 0; j < 256; j++){
  11578. bm[j] = bmi[j] = bki * j;
  11579. }
  11580. }
  11581. bk = blurKernel[radius] = radius * radius;
  11582. bm = blurMult[radius];
  11583. for (var k = 0; k < 256; k++){
  11584. bm[k] = bk * k;
  11585. }
  11586. }
  11587. }
  11588. // Port of https://github.com/processing/processing/blob/
  11589. // master/core/src/processing/core/PImage.java#L1433
  11590. function blurARGB(canvas, radius) {
  11591. var pixels = Filters._toPixels(canvas);
  11592. var width = canvas.width;
  11593. var height = canvas.height;
  11594. var numPackedPixels = width * height;
  11595. var argb = new Int32Array(numPackedPixels);
  11596. for (var j = 0; j < numPackedPixels; j++) {
  11597. argb[j] = Filters._getARGB(pixels, j);
  11598. }
  11599. var sum, cr, cg, cb, ca;
  11600. var read, ri, ym, ymi, bk0;
  11601. var a2 = new Int32Array(numPackedPixels);
  11602. var r2 = new Int32Array(numPackedPixels);
  11603. var g2 = new Int32Array(numPackedPixels);
  11604. var b2 = new Int32Array(numPackedPixels);
  11605. var yi = 0;
  11606. buildBlurKernel(radius);
  11607. var x, y, i;
  11608. var bm;
  11609. for (y = 0; y < height; y++) {
  11610. for (x = 0; x < width; x++) {
  11611. cb = cg = cr = ca = sum = 0;
  11612. read = x - blurRadius;
  11613. if (read < 0) {
  11614. bk0 = -read;
  11615. read = 0;
  11616. } else {
  11617. if (read >= width) {
  11618. break;
  11619. }
  11620. bk0 = 0;
  11621. }
  11622. for (i = bk0; i < blurKernelSize; i++) {
  11623. if (read >= width) {
  11624. break;
  11625. }
  11626. var c = argb[read + yi];
  11627. bm = blurMult[i];
  11628. ca += bm[(c & -16777216) >>> 24];
  11629. cr += bm[(c & 16711680) >> 16];
  11630. cg += bm[(c & 65280) >> 8];
  11631. cb += bm[c & 255];
  11632. sum += blurKernel[i];
  11633. read++;
  11634. }
  11635. ri = yi + x;
  11636. a2[ri] = ca / sum;
  11637. r2[ri] = cr / sum;
  11638. g2[ri] = cg / sum;
  11639. b2[ri] = cb / sum;
  11640. }
  11641. yi += width;
  11642. }
  11643. yi = 0;
  11644. ym = -blurRadius;
  11645. ymi = ym * width;
  11646. for (y = 0; y < height; y++) {
  11647. for (x = 0; x < width; x++) {
  11648. cb = cg = cr = ca = sum = 0;
  11649. if (ym < 0) {
  11650. bk0 = ri = -ym;
  11651. read = x;
  11652. } else {
  11653. if (ym >= height) {
  11654. break;
  11655. }
  11656. bk0 = 0;
  11657. ri = ym;
  11658. read = x + ymi;
  11659. }
  11660. for (i = bk0; i < blurKernelSize; i++) {
  11661. if (ri >= height) {
  11662. break;
  11663. }
  11664. bm = blurMult[i];
  11665. ca += bm[a2[read]];
  11666. cr += bm[r2[read]];
  11667. cg += bm[g2[read]];
  11668. cb += bm[b2[read]];
  11669. sum += blurKernel[i];
  11670. ri++;
  11671. read += width;
  11672. }
  11673. argb[x + yi] = (ca/sum)<<24 | (cr/sum)<<16 | (cg/sum)<<8 | (cb/sum);
  11674. }
  11675. yi += width;
  11676. ymi += width;
  11677. ym++;
  11678. }
  11679. Filters._setPixels(pixels, argb);
  11680. }
  11681. Filters.blur = function(canvas, radius){
  11682. blurARGB(canvas, radius);
  11683. };
  11684. module.exports = Filters;
  11685. },{}],35:[function(require,module,exports){
  11686. /**
  11687. * @module Image
  11688. * @submodule Image
  11689. * @for p5
  11690. * @requires core
  11691. */
  11692. /**
  11693. * This module defines the p5 methods for the p5.Image class
  11694. * for drawing images to the main display canvas.
  11695. */
  11696. 'use strict';
  11697. var p5 = require('../core/core');
  11698. var constants = require('../core/constants');
  11699. /* global frames:true */// This is not global, but JSHint is not aware that
  11700. // this module is implicitly enclosed with Browserify: this overrides the
  11701. // redefined-global error and permits using the name "frames" for the array
  11702. // of saved animation frames.
  11703. var frames = [];
  11704. p5.prototype._imageMode = constants.CORNER;
  11705. p5.prototype._tint = null;
  11706. /**
  11707. * Creates a new p5.Image (the datatype for storing images). This provides a
  11708. * fresh buffer of pixels to play with. Set the size of the buffer with the
  11709. * width and height parameters.
  11710. *
  11711. * .pixels gives access to an array containing the values for all the pixels
  11712. * in the display window.
  11713. * These values are numbers. This array is the size (including an appropriate
  11714. * factor for the pixelDensity) of the display window x4,
  11715. * representing the R, G, B, A values in order for each pixel, moving from
  11716. * left to right across each row, then down each column. See .pixels for
  11717. * more info. It may also be simpler to use set() or get().
  11718. * <br><br>
  11719. * Before accessing the pixels of an image, the data must loaded with the
  11720. * loadPixels()
  11721. * function. After the array data has been modified, the updatePixels()
  11722. * function must be run to update the changes.
  11723. *
  11724. * @method createImage
  11725. * @param {Integer} width width in pixels
  11726. * @param {Integer} height height in pixels
  11727. * @return {p5.Image} the p5.Image object
  11728. * @example
  11729. * <div>
  11730. * <code>
  11731. * img = createImage(66, 66);
  11732. * img.loadPixels();
  11733. * for (i = 0; i < img.width; i++) {
  11734. * for (j = 0; j < img.height; j++) {
  11735. * img.set(i, j, color(0, 90, 102));
  11736. * }
  11737. * }
  11738. * img.updatePixels();
  11739. * image(img, 17, 17);
  11740. * </code>
  11741. * </div>
  11742. *
  11743. * <div>
  11744. * <code>
  11745. * img = createImage(66, 66);
  11746. * img.loadPixels();
  11747. * for (i = 0; i < img.width; i++) {
  11748. * for (j = 0; j < img.height; j++) {
  11749. * img.set(i, j, color(0, 90, 102, i % img.width * 2));
  11750. * }
  11751. * }
  11752. * img.updatePixels();
  11753. * image(img, 17, 17);
  11754. * image(img, 34, 34);
  11755. * </code>
  11756. * </div>
  11757. *
  11758. * <div>
  11759. * <code>
  11760. * var pink = color(255, 102, 204);
  11761. * img = createImage(66, 66);
  11762. * img.loadPixels();
  11763. * var d = pixelDensity;
  11764. * var halfImage = 4 * (width * d) * (height/2 * d);
  11765. * for (var i = 0; i < halfImage; i+=4) {
  11766. * img.pixels[i] = red(pink);
  11767. * img.pixels[i+1] = green(pink);
  11768. * img.pixels[i+2] = blue(pink);
  11769. * img.pixels[i+3] = alpha(pink);
  11770. * }
  11771. * img.updatePixels();
  11772. * image(img, 17, 17);
  11773. * </code>
  11774. * </div>
  11775. */
  11776. p5.prototype.createImage = function(width, height) {
  11777. return new p5.Image(width, height);
  11778. };
  11779. /**
  11780. * Save the current canvas as an image. In Safari, will open the
  11781. * image in the window and the user must provide their own
  11782. * filename on save-as. Other browsers will either save the
  11783. * file immediately, or prompt the user with a dialogue window.
  11784. *
  11785. * @method saveCanvas
  11786. * @param {[selectedCanvas]} canvas a variable representing a
  11787. * specific html5 canvas (optional)
  11788. * @param {[String]} filename
  11789. * @param {[String]} extension 'jpg' or 'png'
  11790. * @example
  11791. * <div class='norender'><code>
  11792. * function setup() {
  11793. * var c = createCanvas(100, 100);
  11794. * background(255, 0, 0);
  11795. * saveCanvas(c, 'myCanvas', 'jpg');
  11796. * }
  11797. * </code></div>
  11798. * <div class='norender'><code>
  11799. * // note that this example has the same result as above
  11800. * // if no canvas is specified, defaults to main canvas
  11801. * function setup() {
  11802. * createCanvas(100, 100);
  11803. * background(255, 0, 0);
  11804. * saveCanvas('myCanvas', 'jpg');
  11805. * }
  11806. * </code></div>
  11807. * <div class='norender'><code>
  11808. * // all of the following are valid
  11809. * saveCanvas(c, 'myCanvas', 'jpg');
  11810. * saveCanvas(c, 'myCanvas');
  11811. * saveCanvas(c);
  11812. * saveCanvas('myCanvas', 'png');
  11813. * saveCanvas('myCanvas');
  11814. * saveCanvas();
  11815. * </code></div>
  11816. */
  11817. p5.prototype.saveCanvas = function() {
  11818. var cnv, filename, extension;
  11819. if (arguments.length === 3) {
  11820. cnv = arguments[0];
  11821. filename = arguments[1];
  11822. extension = arguments[2];
  11823. } else if (arguments.length === 2) {
  11824. if (typeof arguments[0] === 'object') {
  11825. cnv = arguments[0];
  11826. filename = arguments[1];
  11827. } else {
  11828. filename = arguments[0];
  11829. extension = arguments[1];
  11830. }
  11831. } else if (arguments.length === 1) {
  11832. if (typeof arguments[0] === 'object') {
  11833. cnv = arguments[0];
  11834. } else {
  11835. filename = arguments[0];
  11836. }
  11837. }
  11838. if (cnv instanceof p5.Element) {
  11839. cnv = cnv.elt;
  11840. }
  11841. if (!(cnv instanceof HTMLCanvasElement)) {
  11842. cnv = null;
  11843. }
  11844. if (!extension) {
  11845. extension = p5.prototype._checkFileExtension(filename, extension)[1];
  11846. if (extension === '') {
  11847. extension = 'png';
  11848. }
  11849. }
  11850. if (!cnv) {
  11851. if (this._curElement && this._curElement.elt) {
  11852. cnv = this._curElement.elt;
  11853. }
  11854. }
  11855. if ( p5.prototype._isSafari() ) {
  11856. var aText = 'Hello, Safari user!\n';
  11857. aText += 'Now capturing a screenshot...\n';
  11858. aText += 'To save this image,\n';
  11859. aText += 'go to File --> Save As.\n';
  11860. alert(aText);
  11861. window.location.href = cnv.toDataURL();
  11862. } else {
  11863. var mimeType;
  11864. if (typeof(extension) === 'undefined') {
  11865. extension = 'png';
  11866. mimeType = 'image/png';
  11867. }
  11868. else {
  11869. switch(extension){
  11870. case 'png':
  11871. mimeType = 'image/png';
  11872. break;
  11873. case 'jpeg':
  11874. mimeType = 'image/jpeg';
  11875. break;
  11876. case 'jpg':
  11877. mimeType = 'image/jpeg';
  11878. break;
  11879. default:
  11880. mimeType = 'image/png';
  11881. break;
  11882. }
  11883. }
  11884. var downloadMime = 'image/octet-stream';
  11885. var imageData = cnv.toDataURL(mimeType);
  11886. imageData = imageData.replace(mimeType, downloadMime);
  11887. p5.prototype.downloadFile(imageData, filename, extension);
  11888. }
  11889. };
  11890. /**
  11891. * Capture a sequence of frames that can be used to create a movie.
  11892. * Accepts a callback. For example, you may wish to send the frames
  11893. * to a server where they can be stored or converted into a movie.
  11894. * If no callback is provided, the browser will attempt to download
  11895. * all of the images that have just been created.
  11896. *
  11897. * @method saveFrames
  11898. * @param {[type]} filename [description]
  11899. * @param {[type]} extension [description]
  11900. * @param {[type]} _duration [description]
  11901. * @param {[type]} _fps [description]
  11902. * @param {[Function]} callback [description]
  11903. * @return {[type]} [description]
  11904. */
  11905. p5.prototype.saveFrames = function(fName, ext, _duration, _fps, callback) {
  11906. var duration = _duration || 3;
  11907. duration = p5.prototype.constrain(duration, 0, 15);
  11908. duration = duration * 1000;
  11909. var fps = _fps || 15;
  11910. fps = p5.prototype.constrain(fps, 0, 22);
  11911. var count = 0;
  11912. var makeFrame = p5.prototype._makeFrame;
  11913. var cnv = this._curElement.elt;
  11914. var frameFactory = setInterval(function(){
  11915. makeFrame(fName + count, ext, cnv);
  11916. count++;
  11917. },1000/fps);
  11918. setTimeout(function(){
  11919. clearInterval(frameFactory);
  11920. if (callback) {
  11921. callback(frames);
  11922. }
  11923. else {
  11924. for (var i = 0; i < frames.length; i++) {
  11925. var f = frames[i];
  11926. p5.prototype.downloadFile(f.imageData, f.filename, f.ext);
  11927. }
  11928. }
  11929. frames = []; // clear frames
  11930. }, duration + 0.01);
  11931. };
  11932. p5.prototype._makeFrame = function(filename, extension, _cnv) {
  11933. var cnv;
  11934. if (this) {
  11935. cnv = this._curElement.elt;
  11936. } else {
  11937. cnv = _cnv;
  11938. }
  11939. var mimeType;
  11940. if (!extension) {
  11941. extension = 'png';
  11942. mimeType = 'image/png';
  11943. }
  11944. else {
  11945. switch(extension.toLowerCase()){
  11946. case 'png':
  11947. mimeType = 'image/png';
  11948. break;
  11949. case 'jpeg':
  11950. mimeType = 'image/jpeg';
  11951. break;
  11952. case 'jpg':
  11953. mimeType = 'image/jpeg';
  11954. break;
  11955. default:
  11956. mimeType = 'image/png';
  11957. break;
  11958. }
  11959. }
  11960. var downloadMime = 'image/octet-stream';
  11961. var imageData = cnv.toDataURL(mimeType);
  11962. imageData = imageData.replace(mimeType, downloadMime);
  11963. var thisFrame = {};
  11964. thisFrame.imageData = imageData;
  11965. thisFrame.filename = filename;
  11966. thisFrame.ext = extension;
  11967. frames.push(thisFrame);
  11968. };
  11969. module.exports = p5;
  11970. },{"../core/constants":16,"../core/core":17}],36:[function(require,module,exports){
  11971. /**
  11972. * @module Image
  11973. * @submodule Loading & Displaying
  11974. * @for p5
  11975. * @requires core
  11976. */
  11977. 'use strict';
  11978. var p5 = require('../core/core');
  11979. var Filters = require('./filters');
  11980. var canvas = require('../core/canvas');
  11981. var constants = require('../core/constants');
  11982. require('../core/error_helpers');
  11983. /**
  11984. * Loads an image from a path and creates a p5.Image from it.
  11985. *
  11986. * The image may not be immediately available for rendering
  11987. * If you want to ensure that the image is ready before doing
  11988. * anything with it you can do perform those operations in the
  11989. * callback, or place the loadImage() call in preload().
  11990. *
  11991. * @method loadImage
  11992. * @param {String} path Path of the image to be loaded
  11993. * @param {Function(p5.Image)} [successCallback] Function to be called once
  11994. * the image is loaded. Will be passed the
  11995. * p5.Image.
  11996. * @param {Function(Event)} [failureCallback] called with event error if
  11997. * the image fails to load.
  11998. * @return {p5.Image} the p5.Image object
  11999. * @example
  12000. * <div>
  12001. * <code>
  12002. * var img;
  12003. * function preload() {
  12004. * img = loadImage("assets/laDefense.jpg");
  12005. * }
  12006. * function setup() {
  12007. * image(img, 0, 0);
  12008. * }
  12009. * </code>
  12010. * </div>
  12011. * <div>
  12012. * <code>
  12013. * function setup() {
  12014. * // here we use a callback to display the image after loading
  12015. * loadImage("assets/laDefense.jpg", function(img) {
  12016. * image(img, 0, 0);
  12017. * });
  12018. * }
  12019. * </code>
  12020. * </div>
  12021. */
  12022. p5.prototype.loadImage = function(path, successCallback, failureCallback) {
  12023. var img = new Image();
  12024. var pImg = new p5.Image(1, 1, this);
  12025. img.onload = function() {
  12026. pImg.width = pImg.canvas.width = img.width;
  12027. pImg.height = pImg.canvas.height = img.height;
  12028. // Draw the image into the backing canvas of the p5.Image
  12029. pImg.canvas.getContext('2d').drawImage(img, 0, 0);
  12030. if (typeof successCallback === 'function') {
  12031. successCallback(pImg);
  12032. }
  12033. };
  12034. img.onerror = function(e) {
  12035. p5._friendlyFileLoadError(0,img.src);
  12036. if (typeof failureCallback === 'function') {
  12037. failureCallback(e);
  12038. }
  12039. };
  12040. //set crossOrigin in case image is served which CORS headers
  12041. //this will let us draw to canvas without tainting it.
  12042. //see https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image
  12043. // When using data-uris the file will be loaded locally
  12044. // so we don't need to worry about crossOrigin with base64 file types
  12045. if(path.indexOf('data:image/') !== 0) {
  12046. img.crossOrigin = 'Anonymous';
  12047. }
  12048. //start loading the image
  12049. img.src = path;
  12050. return pImg;
  12051. };
  12052. /**
  12053. * Draw an image to the main canvas of the p5js sketch
  12054. *
  12055. * @method image
  12056. * @param {p5.Image} image the image to display
  12057. * @param {Number} [x=0] x-coordinate of the image
  12058. * @param {Number} [y=0] y-coordinate of the image
  12059. * @param {Number} [width] width to display the image
  12060. * @param {Number} [height] height to display the image
  12061. * @example
  12062. * <div>
  12063. * <code>
  12064. * var img;
  12065. * function preload() {
  12066. * img = loadImage("assets/laDefense.jpg");
  12067. * }
  12068. * function setup() {
  12069. * image(img, 0, 0);
  12070. * }
  12071. * </code>
  12072. * </div>
  12073. * <div>
  12074. * <code>
  12075. * function setup() {
  12076. * // here we use a callback to display the image after loading
  12077. * loadImage("assets/laDefense.jpg", function(img) {
  12078. * image(img, 0, 0);
  12079. * });
  12080. * }
  12081. * </code>
  12082. * </div>
  12083. */
  12084. p5.prototype.image = function(img, x, y, width, height) {
  12085. // Temporarily disabling until options for p5.Graphics are added.
  12086. // this._validateParameters(
  12087. // 'image',
  12088. // arguments,
  12089. // [
  12090. // ['p5.Image', 'Number', 'Number'],
  12091. // ['p5.Image', 'Number', 'Number', 'Number', 'Number']
  12092. // ]
  12093. // );
  12094. // set defaults
  12095. x = x || 0;
  12096. y = y || 0;
  12097. width = width || img.width;
  12098. height = height || img.height;
  12099. var vals = canvas.modeAdjust(x, y, width, height, this._imageMode);
  12100. // tint the image if there is a tint
  12101. this._graphics.image(img, vals.x, vals.y, vals.w, vals.h);
  12102. };
  12103. /**
  12104. * Sets the fill value for displaying images. Images can be tinted to
  12105. * specified colors or made transparent by including an alpha value.
  12106. *
  12107. * To apply transparency to an image without affecting its color, use
  12108. * white as the tint color and specify an alpha value. For instance,
  12109. * tint(255, 128) will make an image 50% transparent (assuming the default
  12110. * alpha range of 0-255, which can be changed with colorMode()).
  12111. *
  12112. * The value for the gray parameter must be less than or equal to the current
  12113. * maximum value as specified by colorMode(). The default maximum value is
  12114. * 255.
  12115. *
  12116. * @method tint
  12117. * @param {Number|Array} v1 gray value, red or hue value (depending on the
  12118. * current color mode), or color Array
  12119. * @param {Number|Array} [v2] green or saturation value (depending on the
  12120. * current color mode)
  12121. * @param {Number|Array} [v3] blue or brightness value (depending on the
  12122. * current color mode)
  12123. * @param {Number|Array} [a] opacity of the background
  12124. * @example
  12125. * <div>
  12126. * <code>
  12127. * var img;
  12128. * function preload() {
  12129. * img = loadImage("assets/laDefense.jpg");
  12130. * }
  12131. * function setup() {
  12132. * image(img, 0, 0);
  12133. * tint(0, 153, 204); // Tint blue
  12134. * image(img, 50, 0);
  12135. * }
  12136. * </code>
  12137. * </div>
  12138. *
  12139. * <div>
  12140. * <code>
  12141. * var img;
  12142. * function preload() {
  12143. * img = loadImage("assets/laDefense.jpg");
  12144. * }
  12145. * function setup() {
  12146. * image(img, 0, 0);
  12147. * tint(0, 153, 204, 126); // Tint blue and set transparency
  12148. * image(img, 50, 0);
  12149. * }
  12150. * </code>
  12151. * </div>
  12152. *
  12153. * <div>
  12154. * <code>
  12155. * var img;
  12156. * function preload() {
  12157. * img = loadImage("assets/laDefense.jpg");
  12158. * }
  12159. * function setup() {
  12160. * image(img, 0, 0);
  12161. * tint(255, 126); // Apply transparency without changing color
  12162. * image(img, 50, 0);
  12163. * }
  12164. * </code>
  12165. * </div>
  12166. */
  12167. p5.prototype.tint = function () {
  12168. var c = this.color.apply(this, arguments);
  12169. this._tint = c.rgba;
  12170. };
  12171. /**
  12172. * Removes the current fill value for displaying images and reverts to
  12173. * displaying images with their original hues.
  12174. *
  12175. * @method noTint
  12176. * @example
  12177. * <div>
  12178. * <code>
  12179. * var img;
  12180. * function preload() {
  12181. * img = loadImage("assets/bricks.jpg");
  12182. * }
  12183. * function setup() {
  12184. * tint(0, 153, 204); // Tint blue
  12185. * image(img, 0, 0);
  12186. * noTint(); // Disable tint
  12187. * image(img, 50, 0);
  12188. * }
  12189. * </code>
  12190. * </div>
  12191. */
  12192. p5.prototype.noTint = function() {
  12193. this._tint = null;
  12194. };
  12195. /**
  12196. * Apply the current tint color to the input image, return the resulting
  12197. * canvas.
  12198. *
  12199. * @param {p5.Image} The image to be tinted
  12200. * @return {canvas} The resulting tinted canvas
  12201. *
  12202. */
  12203. p5.prototype._getTintedImageCanvas = function(img) {
  12204. if (!img.canvas) {
  12205. return img;
  12206. }
  12207. var pixels = Filters._toPixels(img.canvas);
  12208. var tmpCanvas = document.createElement('canvas');
  12209. tmpCanvas.width = img.canvas.width;
  12210. tmpCanvas.height = img.canvas.height;
  12211. var tmpCtx = tmpCanvas.getContext('2d');
  12212. var id = tmpCtx.createImageData(img.canvas.width, img.canvas.height);
  12213. var newPixels = id.data;
  12214. for(var i = 0; i < pixels.length; i += 4) {
  12215. var r = pixels[i];
  12216. var g = pixels[i+1];
  12217. var b = pixels[i+2];
  12218. var a = pixels[i+3];
  12219. newPixels[i] = r*this._tint[0]/255;
  12220. newPixels[i+1] = g*this._tint[1]/255;
  12221. newPixels[i+2] = b*this._tint[2]/255;
  12222. newPixels[i+3] = a*this._tint[3]/255;
  12223. }
  12224. tmpCtx.putImageData(id, 0, 0);
  12225. return tmpCanvas;
  12226. };
  12227. /**
  12228. * Set image mode. Modifies the location from which images are drawn by
  12229. * changing the way in which parameters given to image() are interpreted.
  12230. * The default mode is imageMode(CORNER), which interprets the second and
  12231. * third parameters of image() as the upper-left corner of the image. If
  12232. * two additional parameters are specified, they are used to set the image's
  12233. * width and height.
  12234. *
  12235. * imageMode(CORNERS) interprets the second and third parameters of image()
  12236. * as the location of one corner, and the fourth and fifth parameters as the
  12237. * opposite corner.
  12238. * imageMode(CENTER) interprets the second and third parameters of image()
  12239. * as the image's center point. If two additional parameters are specified,
  12240. * they are used to set the image's width and height.
  12241. *
  12242. * @method imageMode
  12243. * @param {String} m The mode: either CORNER, CORNERS, or CENTER.
  12244. * @example
  12245. *
  12246. * <div>
  12247. * <code>
  12248. * var img;
  12249. * function preload() {
  12250. * img = loadImage("assets/bricks.jpg");
  12251. * }
  12252. * function setup() {
  12253. * imageMode(CORNER);
  12254. * image(img, 10, 10, 50, 50);
  12255. * }
  12256. * </code>
  12257. * </div>
  12258. *
  12259. * <div>
  12260. * <code>
  12261. * var img;
  12262. * function preload() {
  12263. * img = loadImage("assets/bricks.jpg");
  12264. * }
  12265. * function setup() {
  12266. * imageMode(CORNERS);
  12267. * image(img, 10, 10, 90, 40);
  12268. * }
  12269. * </code>
  12270. * </div>
  12271. *
  12272. * <div>
  12273. * <code>
  12274. * var img;
  12275. * function preload() {
  12276. * img = loadImage("assets/bricks.jpg");
  12277. * }
  12278. * function setup() {
  12279. * imageMode(CENTER);
  12280. * image(img, 50, 50, 80, 80);
  12281. * }
  12282. * </code>
  12283. * </div>
  12284. */
  12285. p5.prototype.imageMode = function(m) {
  12286. if (m === constants.CORNER ||
  12287. m === constants.CORNERS ||
  12288. m === constants.CENTER) {
  12289. this._imageMode = m;
  12290. }
  12291. };
  12292. module.exports = p5;
  12293. },{"../core/canvas":15,"../core/constants":16,"../core/core":17,"../core/error_helpers":20,"./filters":34}],37:[function(require,module,exports){
  12294. /**
  12295. * @module Image
  12296. * @submodule Image
  12297. * @requires core
  12298. * @requires constants
  12299. * @requires filters
  12300. */
  12301. /**
  12302. * This module defines the p5.Image class and P5 methods for
  12303. * drawing images to the main display canvas.
  12304. */
  12305. 'use strict';
  12306. var p5 = require('../core/core');
  12307. var Filters = require('./filters');
  12308. /*
  12309. * Class methods
  12310. */
  12311. /**
  12312. * Creates a new p5.Image. A p5.Image is a canvas backed representation of an
  12313. * image. p5 can display .gif, .jpg and .png images. Images may be displayed
  12314. * in 2D and 3D space. Before an image is used, it must be loaded with the
  12315. * loadImage() function. The p5.Image class contains fields for the width and
  12316. * height of the image, as well as an array called pixels[] that contains the
  12317. * values for every pixel in the image. The methods described below allow
  12318. * easy access to the image's pixels and alpha channel and simplify the
  12319. * process of compositing.
  12320. *
  12321. * Before using the pixels[] array, be sure to use the loadPixels() method on
  12322. * the image to make sure that the pixel data is properly loaded.
  12323. *
  12324. * @class p5.Image
  12325. * @constructor
  12326. * @param {Number} width
  12327. * @param {Number} height
  12328. * @param {Object} pInst An instance of a p5 sketch.
  12329. */
  12330. p5.Image = function(width, height){
  12331. /**
  12332. * Image width.
  12333. * @property width
  12334. */
  12335. this.width = width;
  12336. /**
  12337. * Image height.
  12338. * @property height
  12339. */
  12340. this.height = height;
  12341. this.canvas = document.createElement('canvas');
  12342. this.canvas.width = this.width;
  12343. this.canvas.height = this.height;
  12344. this.drawingContext = this.canvas.getContext('2d');
  12345. this.pixelDensity = 1;
  12346. /**
  12347. * Array containing the values for all the pixels in the display window.
  12348. * These values are numbers. This array is the size (include an appropriate
  12349. * factor for pixelDensity) of the display window x4,
  12350. * representing the R, G, B, A values in order for each pixel, moving from
  12351. * left to right across each row, then down each column. Retina and other
  12352. * high denisty displays may have more pixels[] (by a factor of
  12353. * pixelDensity^2).
  12354. * For example, if the image is 100x100 pixels, there will be 40,000. With
  12355. * pixelDensity = 2, there will be 160,000. The first four values
  12356. * (indices 0-3) in the array will be the R, G, B, A values of the pixel at
  12357. * (0, 0). The second four values (indices 4-7) will contain the R, G, B, A
  12358. * values of the pixel at (1, 0). More generally, to set values for a pixel
  12359. * at (x, y):
  12360. * <code><pre>var d = pixelDensity;
  12361. * for (var i = 0; i < d; i++) {
  12362. * for (var j = 0; j < d; j++) {
  12363. * // loop over
  12364. * idx = 4*((y * d + j) * width * d + (x * d + i));
  12365. * pixels[idx] = r;
  12366. * pixels[idx+1] = g;
  12367. * pixels[idx+2] = b;
  12368. * pixels[idx+3] = a;
  12369. * }
  12370. * }
  12371. * <br><br>
  12372. * Before accessing this array, the data must loaded with the loadPixels()
  12373. * function. After the array data has been modified, the updatePixels()
  12374. * function must be run to update the changes.
  12375. * @property pixels[]
  12376. * @example
  12377. * <div>
  12378. * <code>
  12379. * img = createImage(66, 66);
  12380. * img.loadPixels();
  12381. * for (i = 0; i < img.width; i++) {
  12382. * for (j = 0; j < img.height; j++) {
  12383. * img.set(i, j, color(0, 90, 102));
  12384. * }
  12385. * }
  12386. * img.updatePixels();
  12387. * image(img, 17, 17);
  12388. * </code>
  12389. * </div>
  12390. * <div>
  12391. * <code>
  12392. * var pink = color(255, 102, 204);
  12393. * img = createImage(66, 66);
  12394. * img.loadPixels();
  12395. * for (var i = 0; i < 4*(width*height/2); i+=4) {
  12396. * img.pixels[i] = red(pink);
  12397. * img.pixels[i+1] = green(pink);
  12398. * img.pixels[i+2] = blue(pink);
  12399. * img.pixels[i+3] = alpha(pink);
  12400. * }
  12401. * img.updatePixels();
  12402. * image(img, 17, 17);
  12403. * </code>
  12404. * </div>
  12405. */
  12406. this.pixels = [];
  12407. };
  12408. /**
  12409. * Helper fxn for sharing pixel methods
  12410. *
  12411. */
  12412. p5.Image.prototype._setProperty = function (prop, value) {
  12413. this[prop] = value;
  12414. };
  12415. /**
  12416. * Loads the pixels data for this image into the [pixels] attribute.
  12417. *
  12418. * @method loadPixels
  12419. */
  12420. p5.Image.prototype.loadPixels = function(){
  12421. p5.Renderer2D.prototype.loadPixels.call(this);
  12422. };
  12423. /**
  12424. * Updates the backing canvas for this image with the contents of
  12425. * the [pixels] array.
  12426. *
  12427. * @method updatePixels
  12428. * @param {Integer|undefined} x x-offset of the target update area for the
  12429. * underlying canvas
  12430. * @param {Integer|undefined} y y-offset of the target update area for the
  12431. * underlying canvas
  12432. * @param {Integer|undefined} w height of the target update area for the
  12433. * underlying canvas
  12434. * @param {Integer|undefined} h height of the target update area for the
  12435. * underlying canvas
  12436. */
  12437. p5.Image.prototype.updatePixels = function(x, y, w, h){
  12438. p5.Renderer2D.prototype.updatePixels.call(this, x, y, w, h);
  12439. };
  12440. /**
  12441. * Get a region of pixels from an image.
  12442. *
  12443. * If no params are passed, those whole image is returned,
  12444. * if x and y are the only params passed a single pixel is extracted
  12445. * if all params are passed a rectangle region is extracted and a p5.Image
  12446. * is returned.
  12447. *
  12448. * Returns undefined if the region is outside the bounds of the image
  12449. *
  12450. * @method get
  12451. * @param {Number} [x] x-coordinate of the pixel
  12452. * @param {Number} [y] y-coordinate of the pixel
  12453. * @param {Number} [w] width
  12454. * @param {Number} [h] height
  12455. * @return {Array/Color | p5.Image} color of pixel at x,y in array format
  12456. * [R, G, B, A] or p5.Image
  12457. */
  12458. p5.Image.prototype.get = function(x, y, w, h){
  12459. return p5.Renderer2D.prototype.get.call(this, x, y, w, h);
  12460. };
  12461. /**
  12462. * Set the color of a single pixel or write an image into
  12463. * this p5.Image.
  12464. *
  12465. * Note that for a large number of pixels this will
  12466. * be slower than directly manipulating the pixels array
  12467. * and then calling updatePixels().
  12468. *
  12469. * @method set
  12470. * @param {Number} x x-coordinate of the pixel
  12471. * @param {Number} y y-coordinate of the pixel
  12472. * @param {Number|Array|Object} a grayscale value | pixel array |
  12473. * a p5.Color | image to copy
  12474. * @example
  12475. * <div>
  12476. * <code>
  12477. * img = createImage(66, 66);
  12478. * img.loadPixels();
  12479. * for (i = 0; i < img.width; i++) {
  12480. * for (j = 0; j < img.height; j++) {
  12481. * img.set(i, j, color(0, 90, 102, i % img.width * 2));
  12482. * }
  12483. * }
  12484. * img.updatePixels();
  12485. * image(img, 17, 17);
  12486. * image(img, 34, 34);
  12487. * </code>
  12488. * </div>
  12489. */
  12490. p5.Image.prototype.set = function(x, y, imgOrCol){
  12491. p5.Renderer2D.prototype.set.call(this, x, y, imgOrCol);
  12492. };
  12493. /**
  12494. * Resize the image to a new width and height. To make the image scale
  12495. * proportionally, use 0 as the value for the wide or high parameter.
  12496. * For instance, to make the width of an image 150 pixels, and change
  12497. * the height using the same proportion, use resize(150, 0).
  12498. *
  12499. * @method resize
  12500. * @param {Number} width the resized image width
  12501. * @param {Number} height the resized image height
  12502. * @example
  12503. * <div><code>
  12504. * var img;
  12505. *
  12506. * function setup() {
  12507. * img = loadImage("assets/rockies.jpg");
  12508. * }
  12509. * function draw() {
  12510. * image(img, 0, 0);
  12511. * }
  12512. *
  12513. * function mousePressed() {
  12514. * img.resize(50, 100);
  12515. * }
  12516. * </code></div>
  12517. */
  12518. p5.Image.prototype.resize = function(width, height){
  12519. // Copy contents to a temporary canvas, resize the original
  12520. // and then copy back.
  12521. //
  12522. // There is a faster approach that involves just one copy and swapping the
  12523. // this.canvas reference. We could switch to that approach if (as i think
  12524. // is the case) there an expectation that the user would not hold a
  12525. // reference to the backing canvas of a p5.Image. But since we do not
  12526. // enforce that at the moment, I am leaving in the slower, but safer
  12527. // implementation.
  12528. width = width || this.canvas.width;
  12529. height = height || this.canvas.height;
  12530. var tempCanvas = document.createElement('canvas');
  12531. tempCanvas.width = width;
  12532. tempCanvas.height = height;
  12533. tempCanvas.getContext('2d').drawImage(this.canvas,
  12534. 0, 0, this.canvas.width, this.canvas.height,
  12535. 0, 0, tempCanvas.width, tempCanvas.height
  12536. );
  12537. // Resize the original canvas, which will clear its contents
  12538. this.canvas.width = this.width = width;
  12539. this.canvas.height = this.height = height;
  12540. //Copy the image back
  12541. this.drawingContext.drawImage(tempCanvas,
  12542. 0, 0, width, height,
  12543. 0, 0, width, height
  12544. );
  12545. if(this.pixels.length > 0){
  12546. this.loadPixels();
  12547. }
  12548. };
  12549. /**
  12550. * Copies a region of pixels from one image to another. If no
  12551. * srcImage is specified this is used as the source. If the source
  12552. * and destination regions aren't the same size, it will
  12553. * automatically resize source pixels to fit the specified
  12554. * target region.
  12555. *
  12556. * @method copy
  12557. * @param {p5.Image|undefined} srcImage source image
  12558. * @param {Integer} sx X coordinate of the source's upper left corner
  12559. * @param {Integer} sy Y coordinate of the source's upper left corner
  12560. * @param {Integer} sw source image width
  12561. * @param {Integer} sh source image height
  12562. * @param {Integer} dx X coordinate of the destination's upper left corner
  12563. * @param {Integer} dy Y coordinate of the destination's upper left corner
  12564. * @param {Integer} dw destination image width
  12565. * @param {Integer} dh destination image height
  12566. */
  12567. p5.Image.prototype.copy = function () {
  12568. p5.prototype.copy.apply(this, arguments);
  12569. };
  12570. /**
  12571. * Masks part of an image from displaying by loading another
  12572. * image and using it's alpha channel as an alpha channel for
  12573. * this image.
  12574. *
  12575. * @method mask
  12576. * @param {p5.Image|undefined} srcImage source image
  12577. *
  12578. * TODO: - Accept an array of alpha values.
  12579. * - Use other channels of an image. p5 uses the
  12580. * blue channel (which feels kind of arbitrary). Note: at the
  12581. * moment this method does not match native processings original
  12582. * functionality exactly.
  12583. *
  12584. * http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
  12585. *
  12586. */
  12587. p5.Image.prototype.mask = function(p5Image) {
  12588. if(p5Image === undefined){
  12589. p5Image = this;
  12590. }
  12591. var currBlend = this.drawingContext.globalCompositeOperation;
  12592. var scaleFactor = 1;
  12593. if (p5Image instanceof p5.Renderer) {
  12594. scaleFactor = p5Image._pInst.pixelDensity;
  12595. }
  12596. var copyArgs = [
  12597. p5Image,
  12598. 0,
  12599. 0,
  12600. scaleFactor*p5Image.width,
  12601. scaleFactor*p5Image.height,
  12602. 0,
  12603. 0,
  12604. this.width,
  12605. this.height
  12606. ];
  12607. this.drawingContext.globalCompositeOperation = 'destination-in';
  12608. this.copy.apply(this, copyArgs);
  12609. this.drawingContext.globalCompositeOperation = currBlend;
  12610. };
  12611. /**
  12612. * Applies an image filter to a p5.Image
  12613. *
  12614. * @method filter
  12615. * @param {String} operation one of threshold, gray, invert, posterize and
  12616. * opaque see Filters.js for docs on each available
  12617. * filter
  12618. * @param {Number|undefined} value
  12619. */
  12620. p5.Image.prototype.filter = function(operation, value) {
  12621. Filters.apply(this.canvas, Filters[operation.toLowerCase()], value);
  12622. };
  12623. /**
  12624. * Copies a region of pixels from one image to another, using a specified
  12625. * blend mode to do the operation.
  12626. *
  12627. * @method blend
  12628. * @param {p5.Image|undefined} srcImage source image
  12629. * @param {Integer} sx X coordinate of the source's upper left corner
  12630. * @param {Integer} sy Y coordinate of the source's upper left corner
  12631. * @param {Integer} sw source image width
  12632. * @param {Integer} sh source image height
  12633. * @param {Integer} dx X coordinate of the destination's upper left corner
  12634. * @param {Integer} dy Y coordinate of the destination's upper left corner
  12635. * @param {Integer} dw destination image width
  12636. * @param {Integer} dh destination image height
  12637. * @param {Integer} blendMode the blend mode
  12638. *
  12639. * Available blend modes are: normal | multiply | screen | overlay |
  12640. * darken | lighten | color-dodge | color-burn | hard-light |
  12641. * soft-light | difference | exclusion | hue | saturation |
  12642. * color | luminosity
  12643. *
  12644. *
  12645. * http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
  12646. *
  12647. */
  12648. p5.Image.prototype.blend = function() {
  12649. p5.prototype.blend.apply(this, arguments);
  12650. };
  12651. /**
  12652. * Saves the image to a file and force the browser to download it.
  12653. * Accepts two strings for filename and file extension
  12654. * Supports png (default) and jpg.
  12655. *
  12656. * @method save
  12657. * @param {String} filename give your file a name
  12658. * @param {String} extension 'png' or 'jpg'
  12659. */
  12660. p5.Image.prototype.save = function(filename, extension) {
  12661. var mimeType;
  12662. if (!extension) {
  12663. extension = 'png';
  12664. mimeType = 'image/png';
  12665. }
  12666. else {
  12667. // en.wikipedia.org/wiki/Comparison_of_web_browsers#Image_format_support
  12668. switch(extension.toLowerCase()){
  12669. case 'png':
  12670. mimeType = 'image/png';
  12671. break;
  12672. case 'jpeg':
  12673. mimeType = 'image/jpeg';
  12674. break;
  12675. case 'jpg':
  12676. mimeType = 'image/jpeg';
  12677. break;
  12678. default:
  12679. mimeType = 'image/png';
  12680. break;
  12681. }
  12682. }
  12683. var downloadMime = 'image/octet-stream';
  12684. var imageData = this.canvas.toDataURL(mimeType);
  12685. imageData = imageData.replace(mimeType, downloadMime);
  12686. //Make the browser download the file
  12687. p5.prototype.downloadFile(imageData, filename, extension);
  12688. };
  12689. module.exports = p5.Image;
  12690. },{"../core/core":17,"./filters":34}],38:[function(require,module,exports){
  12691. /**
  12692. * @module Image
  12693. * @submodule Pixels
  12694. * @for p5
  12695. * @requires core
  12696. */
  12697. 'use strict';
  12698. var p5 = require('../core/core');
  12699. var Filters = require('./filters');
  12700. require('../color/p5.Color');
  12701. /**
  12702. * <a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference
  12703. * /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>
  12704. * containing the values for all the pixels in the display window.
  12705. * These values are numbers. This array is the size (include an appropriate
  12706. * factor for pixelDensity) of the display window x4,
  12707. * representing the R, G, B, A values in order for each pixel, moving from
  12708. * left to right across each row, then down each column. Retina and other
  12709. * high denisty displays will have more pixels[] (by a factor of
  12710. * pixelDensity^2).
  12711. * For example, if the image is 100x100 pixels, there will be 40,000. On a
  12712. * retina display, there will be 160,000. The first four values
  12713. * (indices 0-3) in the array will be the R, G, B, A values of the pixel at
  12714. * (0, 0). The second four values (indices 4-7) will contain the R, G, B, A
  12715. * values of the pixel at (1, 0). More generally, to set values for a pixel
  12716. * at (x, y):
  12717. * <code><pre>var d = pixelDensity;
  12718. * for (var i = 0; i < d; i++) {
  12719. * for (var j = 0; j < d; j++) {
  12720. * // loop over
  12721. * idx = 4*((y * d + j) * width * d + (x * d + i));
  12722. * pixels[idx] = r;
  12723. * pixels[idx+1] = g;
  12724. * pixels[idx+2] = b;
  12725. * pixels[idx+3] = a;
  12726. * }
  12727. * }
  12728. * </pre></code>
  12729. * While the above method is complex, it is flexible enough to work with
  12730. * any pixelDensity. Note that set() will automatically take care of
  12731. * setting all the appropriate values in pixels[] for a given (x, y) at
  12732. * any pixelDensity, but the performance may not be as fast when lots of
  12733. * modifications are made to the pixel array.
  12734. * <br><br>
  12735. * Before accessing this array, the data must loaded with the loadPixels()
  12736. * function. After the array data has been modified, the updatePixels()
  12737. * function must be run to update the changes.
  12738. * <br><br>
  12739. * Note that this is not a standard javascript array. This means that
  12740. * standard javascript functions such as <code>slice()</code> or
  12741. * <code>arrayCopy()</code> do not
  12742. * work.
  12743. *
  12744. * @property pixels[]
  12745. * @example
  12746. * <div>
  12747. * <code>
  12748. * var pink = color(255, 102, 204);
  12749. * loadPixels();
  12750. * var d = pixelDensity;
  12751. * var halfImage = 4 * (width * d) * (height/2 * d);
  12752. * for (var i = 0; i < halfImage; i+=4) {
  12753. * pixels[i] = red(pink);
  12754. * pixels[i+1] = green(pink);
  12755. * pixels[i+2] = blue(pink);
  12756. * pixels[i+3] = alpha(pink);
  12757. * }
  12758. * updatePixels();
  12759. * </code>
  12760. * </div>
  12761. */
  12762. p5.prototype.pixels = [];
  12763. /**
  12764. * Copies a region of pixels from one image to another, using a specified
  12765. * blend mode to do the operation.<br><br>
  12766. * Available blend modes are: BLEND | DARKEST | LIGHTEST | DIFFERENCE |
  12767. * MULTIPLY| EXCLUSION | SCREEN | REPLACE | OVERLAY | HARD_LIGHT |
  12768. * SOFT_LIGHT | DODGE | BURN | ADD | NORMAL
  12769. *
  12770. *
  12771. * @method blend
  12772. * @param {p5.Image|undefined} srcImage source image
  12773. * @param {Integer} sx X coordinate of the source's upper left corner
  12774. * @param {Integer} sy Y coordinate of the source's upper left corner
  12775. * @param {Integer} sw source image width
  12776. * @param {Integer} sh source image height
  12777. * @param {Integer} dx X coordinate of the destination's upper left corner
  12778. * @param {Integer} dy Y coordinate of the destination's upper left corner
  12779. * @param {Integer} dw destination image width
  12780. * @param {Integer} dh destination image height
  12781. * @param {Integer} blendMode the blend mode
  12782. *
  12783. * @example
  12784. * <div><code>
  12785. * var img0;
  12786. * var img1;
  12787. *
  12788. * function preload() {
  12789. * img0 = loadImage("assets/rockies.jpg");
  12790. * img1 = loadImage("assets/bricks_third.jpg");
  12791. * }
  12792. *
  12793. * function setup() {
  12794. * background(img0);
  12795. * image(img1, 0, 0);
  12796. * blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);
  12797. * }
  12798. * </code></div>
  12799. * <div><code>
  12800. * var img0;
  12801. * var img1;
  12802. *
  12803. * function preload() {
  12804. * img0 = loadImage("assets/rockies.jpg");
  12805. * img1 = loadImage("assets/bricks_third.jpg");
  12806. * }
  12807. *
  12808. * function setup() {
  12809. * background(img0);
  12810. * image(img1, 0, 0);
  12811. * blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);
  12812. * }
  12813. * </code></div>
  12814. * <div><code>
  12815. * var img0;
  12816. * var img1;
  12817. *
  12818. * function preload() {
  12819. * img0 = loadImage("assets/rockies.jpg");
  12820. * img1 = loadImage("assets/bricks_third.jpg");
  12821. * }
  12822. *
  12823. * function setup() {
  12824. * background(img0);
  12825. * image(img1, 0, 0);
  12826. * blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);
  12827. * }
  12828. * </code></div>
  12829. */
  12830. p5.prototype.blend = function() {
  12831. this._graphics.blend.apply(this._graphics, arguments);
  12832. };
  12833. /**
  12834. * Copies a region of the canvas to another region of the canvas
  12835. * and copies a region of pixels from an image used as the srcImg parameter
  12836. * into the canvas srcImage is specified this is used as the source. If
  12837. * the source and destination regions aren't the same size, it will
  12838. * automatically resize source pixels to fit the specified
  12839. * target region.
  12840. *
  12841. * @method copy
  12842. * @param {p5.Image|undefined} srcImage source image
  12843. * @param {Integer} sx X coordinate of the source's upper left corner
  12844. * @param {Integer} sy Y coordinate of the source's upper left corner
  12845. * @param {Integer} sw source image width
  12846. * @param {Integer} sh source image height
  12847. * @param {Integer} dx X coordinate of the destination's upper left corner
  12848. * @param {Integer} dy Y coordinate of the destination's upper left corner
  12849. * @param {Integer} dw destination image width
  12850. * @param {Integer} dh destination image height
  12851. *
  12852. * @example
  12853. * <div><code>
  12854. * var img;
  12855. *
  12856. * function preload() {
  12857. * img = loadImage("assets/rockies.jpg");
  12858. * }
  12859. *
  12860. * function setup() {
  12861. * background(img0);
  12862. * image(img1, 0, 0);
  12863. * copy(7, 22, 10, 10, 35, 25, 50, 50);
  12864. * stroke(255);
  12865. * noFill();
  12866. * // Rectangle shows area being copied
  12867. * rect(7, 22, 10, 10);
  12868. * }
  12869. * </code></div>
  12870. */
  12871. p5.prototype.copy = function () {
  12872. p5.Renderer2D._copyHelper.apply(this, arguments);
  12873. };
  12874. /**
  12875. * Applies a filter to the canvas.
  12876. * <br><br>
  12877. *
  12878. * The presets options are:
  12879. * <br><br>
  12880. *
  12881. * THRESHOLD
  12882. * Converts the image to black and white pixels depending if they are above or
  12883. * below the threshold defined by the level parameter. The parameter must be
  12884. * between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.
  12885. * <br><br>
  12886. *
  12887. * GRAY
  12888. * Converts any colors in the image to grayscale equivalents. No parameter
  12889. * is used.
  12890. * <br><br>
  12891. *
  12892. * OPAQUE
  12893. * Sets the alpha channel to entirely opaque. No parameter is used.
  12894. * <br><br>
  12895. *
  12896. * INVERT
  12897. * Sets each pixel to its inverse value. No parameter is used.
  12898. * <br><br>
  12899. *
  12900. * POSTERIZE
  12901. * Limits each channel of the image to the number of colors specified as the
  12902. * parameter. The parameter can be set to values between 2 and 255, but
  12903. * results are most noticeable in the lower ranges.
  12904. * <br><br>
  12905. *
  12906. * BLUR
  12907. * Executes a Guassian blur with the level parameter specifying the extent
  12908. * of the blurring. If no parameter is used, the blur is equivalent to
  12909. * Guassian blur of radius 1. Larger values increase the blur.
  12910. * <br><br>
  12911. *
  12912. * ERODE
  12913. * Reduces the light areas. No parameter is used.
  12914. * <br><br>
  12915. *
  12916. * DILATE
  12917. * Increases the light areas. No parameter is used.
  12918. *
  12919. * @method filter
  12920. * @param {String} kind
  12921. *
  12922. * @param {Number|undefined} param
  12923. *
  12924. *
  12925. * @example
  12926. * <div>
  12927. * <code>
  12928. * var img;
  12929. * function preload() {
  12930. * img = loadImage("assets/bricks.jpg");
  12931. * }
  12932. * function setup() {
  12933. * image(img, 0, 0);
  12934. * filter(THRESHOLD);
  12935. * }
  12936. * </code>
  12937. * </div>
  12938. *
  12939. * <div>
  12940. * <code>
  12941. * var img;
  12942. * function preload() {
  12943. * img = loadImage("assets/bricks.jpg");
  12944. * }
  12945. * function setup() {
  12946. * image(img, 0, 0);
  12947. * filter(GRAY);
  12948. * }
  12949. * </code>
  12950. * </div>
  12951. *
  12952. * <div>
  12953. * <code>
  12954. * var img;
  12955. * function preload() {
  12956. * img = loadImage("assets/bricks.jpg");
  12957. * }
  12958. * function setup() {
  12959. * image(img, 0, 0);
  12960. * filter(OPAQUE);
  12961. * }
  12962. * </code>
  12963. * </div>
  12964. *
  12965. * <div>
  12966. * <code>
  12967. * var img;
  12968. * function preload() {
  12969. * img = loadImage("assets/bricks.jpg");
  12970. * }
  12971. * function setup() {
  12972. * image(img, 0, 0);
  12973. * filter(INVERT);
  12974. * }
  12975. * </code>
  12976. * </div>
  12977. *
  12978. * <div>
  12979. * <code>
  12980. * var img;
  12981. * function preload() {
  12982. * img = loadImage("assets/bricks.jpg");
  12983. * }
  12984. * function setup() {
  12985. * image(img, 0, 0);
  12986. * filter(POSTERIZE,3);
  12987. * }
  12988. * </code>
  12989. * </div>
  12990. *
  12991. * <div>
  12992. * <code>
  12993. * var img;
  12994. * function preload() {
  12995. * img = loadImage("assets/bricks.jpg");
  12996. * }
  12997. * function setup() {
  12998. * image(img, 0, 0);
  12999. * filter(DILATE);
  13000. * }
  13001. * </code>
  13002. * </div>
  13003. *
  13004. * <div>
  13005. * <code>
  13006. * var img;
  13007. * function preload() {
  13008. * img = loadImage("assets/bricks.jpg");
  13009. * }
  13010. * function setup() {
  13011. * image(img, 0, 0);
  13012. * filter(BLUR,3);
  13013. * }
  13014. * </code>
  13015. * </div>
  13016. *
  13017. * <div>
  13018. * <code>
  13019. * var img;
  13020. * function preload() {
  13021. * img = loadImage("assets/bricks.jpg");
  13022. * }
  13023. * function setup() {
  13024. * image(img, 0, 0);
  13025. * filter(ERODE);
  13026. * }
  13027. * </code>
  13028. * </div>
  13029. */
  13030. p5.prototype.filter = function(operation, value) {
  13031. Filters.apply(this.canvas, Filters[operation.toLowerCase()], value);
  13032. };
  13033. /**
  13034. * Returns an array of [R,G,B,A] values for any pixel or grabs a section of
  13035. * an image. If no parameters are specified, the entire image is returned.
  13036. * Use the x and y parameters to get the value of one pixel. Get a section of
  13037. * the display window by specifying additional w and h parameters. When
  13038. * getting an image, the x and y parameters define the coordinates for the
  13039. * upper-left corner of the image, regardless of the current imageMode().
  13040. *
  13041. * If the pixel requested is outside of the image window, [0,0,0,255] is
  13042. * returned. To get the numbers scaled according to the current color ranges
  13043. * and taking into account colorMode, use getColor instead of get.
  13044. *
  13045. * Getting the color of a single pixel with get(x, y) is easy, but not as fast
  13046. * as grabbing the data directly from pixels[]. The equivalent statement to
  13047. * get(x, y) using pixels[] with pixel density d is
  13048. * [pixels[(y*width*d+x)*d],
  13049. * pixels[(y*width*d+x)*d+1],
  13050. * pixels[(y*width*d+x)*d+2],
  13051. * pixels[(y*width*d+x)*d+3] ].
  13052. * See the reference for pixels[] for more information.
  13053. *
  13054. * @method get
  13055. * @param {Number} [x] x-coordinate of the pixel
  13056. * @param {Number} [y] y-coordinate of the pixel
  13057. * @param {Number} [w] width
  13058. * @param {Number} [h] height
  13059. * @return {Array|p5.Image} values of pixel at x,y in array format
  13060. * [R, G, B, A] or p5.Image
  13061. * @example
  13062. * <div>
  13063. * <code>
  13064. * var img;
  13065. * function preload() {
  13066. * img = loadImage("assets/rockies.jpg");
  13067. * }
  13068. * function setup() {
  13069. * image(img, 0, 0);
  13070. * var c = get();
  13071. * image(c, width/2, 0);
  13072. * }
  13073. * </code>
  13074. * </div>
  13075. *
  13076. * <div>
  13077. * <code>
  13078. * var img;
  13079. * function preload() {
  13080. * img = loadImage("assets/rockies.jpg");
  13081. * }
  13082. * function setup() {
  13083. * image(img, 0, 0);
  13084. * var c = get(50, 90);
  13085. * fill(c);
  13086. * noStroke();
  13087. * rect(25, 25, 50, 50);
  13088. * }
  13089. * </code>
  13090. * </div>
  13091. */
  13092. p5.prototype.get = function(x, y, w, h){
  13093. return this._graphics.get(x, y, w, h);
  13094. };
  13095. /**
  13096. * Loads the pixel data for the display window into the pixels[] array. This
  13097. * function must always be called before reading from or writing to pixels[].
  13098. *
  13099. * @method loadPixels
  13100. * @example
  13101. * <div>
  13102. * <code>
  13103. * var img;
  13104. * function preload() {
  13105. * img = loadImage("assets/rockies.jpg");
  13106. * }
  13107. *
  13108. * function setup() {
  13109. * image(img, 0, 0);
  13110. * var d = pixelDensity;
  13111. * var halfImage = 4 * (img.width * d) *
  13112. (img.height/2 * d);
  13113. * loadPixels();
  13114. * for (var i = 0; i < halfImage; i++) {
  13115. * pixels[i+halfImage] = pixels[i];
  13116. * }
  13117. * updatePixels();
  13118. * }
  13119. * </code>
  13120. * </div>
  13121. */
  13122. p5.prototype.loadPixels = function() {
  13123. this._graphics.loadPixels();
  13124. };
  13125. /**
  13126. * <p>Changes the color of any pixel, or writes an image directly to the
  13127. * display window.</p>
  13128. * <p>The x and y parameters specify the pixel to change and the c parameter
  13129. * specifies the color value. This can be a p5.COlor object, or [R, G, B, A]
  13130. * pixel array. It can also be a single grayscale value.
  13131. * When setting an image, the x and y parameters define the coordinates for
  13132. * the upper-left corner of the image, regardless of the current imageMode().
  13133. * </p>
  13134. * <p>
  13135. * After using set(), you must call updatePixels() for your changes to
  13136. * appear. This should be called once all pixels have been set.
  13137. * </p>
  13138. * <p>Setting the color of a single pixel with set(x, y) is easy, but not as
  13139. * fast as putting the data directly into pixels[]. Setting the pixels[]
  13140. * values directly may be complicated when working with a retina display,
  13141. * but will perform better when lots of pixels need to be set directly on
  13142. * every loop.</p>
  13143. * <p>See the reference for pixels[] for more information.</p>
  13144. *
  13145. * @method set
  13146. * @param {Number} x x-coordinate of the pixel
  13147. * @param {Number} y y-coordinate of the pixel
  13148. * @param {Number|Array|Object} c insert a grayscale value | a pixel array |
  13149. * a p5.Color object | a p5.Image to copy
  13150. * @example
  13151. * <div>
  13152. * <code>
  13153. * var black = color(0);
  13154. * set(30, 20, black);
  13155. * set(85, 20, black);
  13156. * set(85, 75, black);
  13157. * set(30, 75, black);
  13158. * updatePixels();
  13159. * </code>
  13160. * </div>
  13161. *
  13162. * <div>
  13163. * <code>
  13164. * for (var i = 30; i < width-15; i++) {
  13165. * for (var j = 20; j < height-25; j++) {
  13166. * var c = color(204-j, 153-i, 0);
  13167. * set(i, j, c);
  13168. * }
  13169. * }
  13170. * updatePixels();
  13171. * </code>
  13172. * </div>
  13173. *
  13174. * <div>
  13175. * <code>
  13176. * var img;
  13177. * function preload() {
  13178. * img = loadImage("assets/rockies.jpg");
  13179. * }
  13180. *
  13181. * function setup() {
  13182. * set(0, 0, img);
  13183. * updatePixels();
  13184. * line(0, 0, width, height);
  13185. * line(0, height, width, 0);
  13186. * }
  13187. * </code>
  13188. * </div>
  13189. */
  13190. p5.prototype.set = function (x, y, imgOrCol) {
  13191. this._graphics.set(x, y, imgOrCol);
  13192. };
  13193. /**
  13194. * Updates the display window with the data in the pixels[] array.
  13195. * Use in conjunction with loadPixels(). If you're only reading pixels from
  13196. * the array, there's no need to call updatePixels() — updating is only
  13197. * necessary to apply changes. updatePixels() should be called anytime the
  13198. * pixels array is manipulated or set() is called.
  13199. *
  13200. * @method updatePixels
  13201. * @param {Number} [x] x-coordinate of the upper-left corner of region
  13202. * to update
  13203. * @param {Number} [y] y-coordinate of the upper-left corner of region
  13204. * to update
  13205. * @param {Number} [w] width of region to update
  13206. * @param {Number} [w] height of region to update
  13207. * @example
  13208. * <div>
  13209. * <code>
  13210. * var img;
  13211. * function preload() {
  13212. * img = loadImage("assets/rockies.jpg");
  13213. * }
  13214. *
  13215. * function setup() {
  13216. * image(img, 0, 0);
  13217. * var halfImage = 4 * (img.width * pixelDensity) *
  13218. * (img.height * pixelDensity/2);
  13219. * loadPixels();
  13220. * for (var i = 0; i < halfImage; i++) {
  13221. * pixels[i+halfImage] = pixels[i];
  13222. * }
  13223. * updatePixels();
  13224. * }
  13225. * </code>
  13226. * </div>
  13227. */
  13228. p5.prototype.updatePixels = function (x, y, w, h) {
  13229. this._graphics.updatePixels(x, y, w, h);
  13230. };
  13231. module.exports = p5;
  13232. },{"../color/p5.Color":11,"../core/core":17,"./filters":34}],39:[function(require,module,exports){
  13233. /* global opentype:false */
  13234. /**
  13235. * @module IO
  13236. * @submodule Input
  13237. * @for p5
  13238. * @requires core
  13239. * @requires reqwest
  13240. */
  13241. 'use strict';
  13242. var p5 = require('../core/core');
  13243. var reqwest = require('reqwest');
  13244. require('../core/error_helpers');
  13245. /**
  13246. * Loads an opentype font file (.otf, .ttf) from a file or a URL,
  13247. * and returns a PFont Object. This method is asynchronous,
  13248. * meaning it may not finish before the next line in your sketch
  13249. * is executed.
  13250. *
  13251. * @method loadFont
  13252. * @param {String} path name of the file or url to load
  13253. * @param {Function} [callback] function to be executed after
  13254. * loadFont()
  13255. * completes
  13256. * @return {Object} p5.Font object
  13257. * @example
  13258. *
  13259. * <p>Calling loadFont() inside preload() guarantees to complete the
  13260. * operation before setup() and draw() are called.</p>
  13261. *
  13262. * <div><code>
  13263. * var myFont;
  13264. * function preload() {
  13265. * myFont = loadFont('assets/AvenirNextLTPro-Demi.otf');
  13266. * }
  13267. *
  13268. * function setup() {
  13269. * fill('#ED225D');
  13270. * textFont(myFont);
  13271. * textSize(36);
  13272. * text('p5*js', 10, 50);
  13273. * }
  13274. * </code></div>
  13275. *
  13276. * <p>Outside preload(), you may supply a callback function to handle the
  13277. * object:</p>
  13278. *
  13279. * <div><code>
  13280. * function setup() {
  13281. * loadFont('assets/AvenirNextLTPro-Demi.otf', drawText);
  13282. * }
  13283. *
  13284. * function drawText(font) {
  13285. * fill('#ED225D');
  13286. * textFont(font, 36);
  13287. * text('p5*js', 10, 50);
  13288. * }
  13289. * function draw(){
  13290. * }
  13291. * </code></div>
  13292. *
  13293. */
  13294. p5.prototype.loadFont = function(path, callback) {
  13295. var p5Font = new p5.Font(this);
  13296. opentype.load(path, function(err, font) {
  13297. if (err) {
  13298. throw Error(err);
  13299. }
  13300. p5Font.font = font;
  13301. if (typeof callback !== 'undefined') {
  13302. callback(p5Font);
  13303. }
  13304. });
  13305. return p5Font;
  13306. };
  13307. //BufferedReader
  13308. p5.prototype.createInput = function() {
  13309. // TODO
  13310. throw 'not yet implemented';
  13311. };
  13312. p5.prototype.createReader = function() {
  13313. // TODO
  13314. throw 'not yet implemented';
  13315. };
  13316. p5.prototype.loadBytes = function() {
  13317. // TODO
  13318. throw 'not yet implemented';
  13319. };
  13320. /**
  13321. * Loads a JSON file from a file or a URL, and returns an Object or Array.
  13322. * This method is asynchronous, meaning it may not finish before the next
  13323. * line in your sketch is executed.
  13324. *
  13325. * @method loadJSON
  13326. * @param {String} path name of the file or url to load
  13327. * @param {Function} [callback] function to be executed after
  13328. * loadJSON()
  13329. * completes, Array is passed in as first
  13330. * argument
  13331. * @param {String} [datatype] "json" or "jsonp"
  13332. * @return {Object|Array} JSON data
  13333. * @example
  13334. *
  13335. * <p>Calling loadJSON() inside preload() guarantees to complete the
  13336. * operation before setup() and draw() are called.</p>
  13337. *
  13338. * <div><code>
  13339. * var weather;
  13340. * function preload() {
  13341. * var url = 'http://api.openweathermap.org/data/2.5/weather?q=London,UK';
  13342. * weather = loadJSON(url);
  13343. * }
  13344. *
  13345. * function setup() {
  13346. * noLoop();
  13347. * }
  13348. *
  13349. * function draw() {
  13350. * background(200);
  13351. * // get the humidity value out of the loaded JSON
  13352. * var humidity = weather.main.humidity;
  13353. * fill(0, humidity); // use the humidity value to set the alpha
  13354. * ellipse(width/2, height/2, 50, 50);
  13355. * }
  13356. * </code></div>
  13357. *
  13358. * <p>Outside preload(), you may supply a callback function to handle the
  13359. * object:</p>
  13360. * <div><code>
  13361. * function setup() {
  13362. * noLoop();
  13363. * var url = 'http://api.openweathermap.org/data/2.5/weather?q=NewYork,USA';
  13364. * loadJSON(url, drawWeather);
  13365. * }
  13366. *
  13367. * function draw() {
  13368. * background(200);
  13369. * }
  13370. *
  13371. * function drawWeather(weather) {
  13372. * // get the humidity value out of the loaded JSON
  13373. * var humidity = weather.main.humidity;
  13374. * fill(0, humidity); // use the humidity value to set the alpha
  13375. * ellipse(width/2, height/2, 50, 50);
  13376. * }
  13377. * </code></div>
  13378. *
  13379. */
  13380. p5.prototype.loadJSON = function() {
  13381. var path = arguments[0];
  13382. var callback = arguments[1];
  13383. var ret = []; // array needed for preload
  13384. // assume jsonp for URLs
  13385. var t = 'json'; //= path.indexOf('http') === -1 ? 'json' : 'jsonp';
  13386. // check for explicit data type argument
  13387. if (typeof arguments[2] === 'string'){
  13388. if (arguments[2] === 'jsonp' || arguments[2] === 'json') {
  13389. t = arguments[2];
  13390. }
  13391. }
  13392. reqwest({url: path, type: t, crossOrigin: true})
  13393. .then(function(resp) {
  13394. for (var k in resp) {
  13395. ret[k] = resp[k];
  13396. }
  13397. if (typeof callback !== 'undefined') {
  13398. callback(resp);
  13399. }
  13400. });
  13401. return ret;
  13402. };
  13403. /**
  13404. * Reads the contents of a file and creates a String array of its individual
  13405. * lines. If the name of the file is used as the parameter, as in the above
  13406. * example, the file must be located in the sketch directory/folder.
  13407. *
  13408. * Alternatively, the file maybe be loaded from anywhere on the local
  13409. * computer using an absolute path (something that starts with / on Unix and
  13410. * Linux, or a drive letter on Windows), or the filename parameter can be a
  13411. * URL for a file found on a network.
  13412. *
  13413. * This method is asynchronous, meaning it may not finish before the next
  13414. * line in your sketch is executed.
  13415. *
  13416. * @method loadStrings
  13417. * @param {String} filename name of the file or url to load
  13418. * @param {Function} [callback] function to be executed after loadStrings()
  13419. * completes, Array is passed in as first
  13420. * argument
  13421. * @return {Array} Array of Strings
  13422. * @example
  13423. *
  13424. * <p>Calling loadStrings() inside preload() guarantees to complete the
  13425. * operation before setup() and draw() are called.</p>
  13426. *
  13427. * <div><code>
  13428. * var result;
  13429. * function preload() {
  13430. * result = loadStrings('assets/test.txt');
  13431. * }
  13432. * function setup() {
  13433. * background(200);
  13434. * var ind = floor(random(result.length));
  13435. * text(result[ind], 10, 10, 80, 80);
  13436. * }
  13437. * </code></div>
  13438. *
  13439. * <p>Outside preload(), you may supply a callback function to handle the
  13440. * object:</p>
  13441. *
  13442. * <div><code>
  13443. * function setup() {
  13444. * loadStrings('assets/test.txt', pickString);
  13445. * }
  13446. *
  13447. * function pickString(result) {
  13448. * background(200);
  13449. * var ind = floor(random(result.length));
  13450. * text(result[ind], 10, 10, 80, 80);
  13451. * }
  13452. * </code></div>
  13453. */
  13454. p5.prototype.loadStrings = function (path, callback) {
  13455. var ret = [];
  13456. var req = new XMLHttpRequest();
  13457. req.open('GET', path, true);
  13458. req.onreadystatechange = function () {
  13459. if (req.readyState === 4 && (req.status === 200 )) {
  13460. var arr = req.responseText.match(/[^\r\n]+/g);
  13461. for (var k in arr) {
  13462. ret[k] = arr[k];
  13463. }
  13464. if (typeof callback !== 'undefined') {
  13465. callback(ret);
  13466. }
  13467. }
  13468. else{
  13469. p5._friendlyFileLoadError(3,path);
  13470. }
  13471. };
  13472. req.send(null);
  13473. return ret;
  13474. };
  13475. /**
  13476. * <p>Reads the contents of a file or URL and creates a p5.Table object with
  13477. * its values. If a file is specified, it must be located in the sketch's
  13478. * "data" folder. The filename parameter can also be a URL to a file found
  13479. * online. By default, the file is assumed to be comma-separated (in CSV
  13480. * format). Table only looks for a header row if the 'header' option is
  13481. * included.</p>
  13482. *
  13483. * <p>Possible options include:
  13484. * <ul>
  13485. * <li>csv - parse the table as comma-separated values</li>
  13486. * <li>tsv - parse the table as tab-separated values</li>
  13487. * <li>header - this table has a header (title) row</li>
  13488. * </ul>
  13489. * </p>
  13490. *
  13491. * <p>When passing in multiple options, pass them in as separate parameters,
  13492. * seperated by commas. For example:
  13493. * <br><br>
  13494. * <code>
  13495. * loadTable("my_csv_file.csv", "csv", "header")
  13496. * </code>
  13497. * </p>
  13498. *
  13499. * <p> All files loaded and saved use UTF-8 encoding.</p>
  13500. *
  13501. * <p>This method is asynchronous, meaning it may not finish before the next
  13502. * line in your sketch is executed. Calling loadTable() inside preload()
  13503. * guarantees to complete the operation before setup() and draw() are called.
  13504. * Outside preload(), you may supply a callback function to handle the object.
  13505. * </p>
  13506. *
  13507. * @method loadTable
  13508. * @param {String} filename name of the file or URL to load
  13509. * @param {String|Strings} [options] "header" "csv" "tsv"
  13510. * @param {Function} [callback] function to be executed after
  13511. * loadTable() completes, Table object is
  13512. * passed in as first argument
  13513. * @return {Object} Table object containing data
  13514. *
  13515. * @example
  13516. * <div class="norender">
  13517. * <code>
  13518. * // Given the following CSV file called "mammals.csv"
  13519. * // located in the project's "assets" folder:
  13520. * //
  13521. * // id,species,name
  13522. * // 0,Capra hircus,Goat
  13523. * // 1,Panthera pardus,Leopard
  13524. * // 2,Equus zebra,Zebra
  13525. *
  13526. * var table;
  13527. *
  13528. * function preload() {
  13529. * //my table is comma separated value "csv"
  13530. * //and has a header specifying the columns labels
  13531. * table = loadTable("assets/mammals.csv", "csv", "header");
  13532. * //the file can be remote
  13533. * //table = loadTable("http://p5js.org/reference/assets/mammals.csv",
  13534. * // "csv", "header");
  13535. * }
  13536. *
  13537. * function setup() {
  13538. * //count the columns
  13539. * print(table.getRowCount() + " total rows in table");
  13540. * print(table.getColumnCount() + " total columns in table");
  13541. *
  13542. * print(table.getColumn("name"));
  13543. * //["Goat", "Leopard", "Zebra"]
  13544. *
  13545. * //cycle through the table
  13546. * for (var r = 0; r < table.getRowCount(); r++)
  13547. * for (var c = 0; c < table.getColumnCount(); c++) {
  13548. * print(table.getString(r, c));
  13549. * }
  13550. * }
  13551. * </code>
  13552. * </div>
  13553. */
  13554. p5.prototype.loadTable = function (path) {
  13555. var callback = null;
  13556. var options = [];
  13557. var header = false;
  13558. var sep = ',';
  13559. var separatorSet = false;
  13560. for (var i = 1; i < arguments.length; i++) {
  13561. if (typeof(arguments[i]) === 'function' ){
  13562. callback = arguments[i];
  13563. }
  13564. else if (typeof(arguments[i]) === 'string') {
  13565. options.push(arguments[i]);
  13566. if (arguments[i] === 'header') {
  13567. header = true;
  13568. }
  13569. if (arguments[i] === 'csv') {
  13570. if (separatorSet) {
  13571. throw new Error('Cannot set multiple separator types.');
  13572. }
  13573. else {
  13574. sep = ',';
  13575. separatorSet = true;
  13576. }
  13577. }
  13578. else if (arguments[i] === 'tsv') {
  13579. if (separatorSet) {
  13580. throw new Error('Cannot set multiple separator types.');
  13581. }
  13582. else {
  13583. sep = '\t';
  13584. separatorSet = true;
  13585. }
  13586. }
  13587. }
  13588. }
  13589. var t = new p5.Table();
  13590. reqwest({url: path, crossOrigin: true, type: 'csv'})
  13591. .then(function(resp) {
  13592. resp = resp.responseText;
  13593. var state = {};
  13594. // define constants
  13595. var PRE_TOKEN = 0,
  13596. MID_TOKEN = 1,
  13597. POST_TOKEN = 2,
  13598. POST_RECORD = 4;
  13599. var QUOTE = '\"',
  13600. CR = '\r',
  13601. LF = '\n';
  13602. var records = [];
  13603. var offset = 0;
  13604. var currentRecord = null;
  13605. var currentChar;
  13606. var recordBegin = function () {
  13607. state.escaped = false;
  13608. currentRecord = [];
  13609. tokenBegin();
  13610. };
  13611. var recordEnd = function () {
  13612. state.currentState = POST_RECORD;
  13613. records.push(currentRecord);
  13614. currentRecord = null;
  13615. };
  13616. var tokenBegin = function() {
  13617. state.currentState = PRE_TOKEN;
  13618. state.token = '';
  13619. };
  13620. var tokenEnd = function() {
  13621. currentRecord.push(state.token);
  13622. tokenBegin();
  13623. };
  13624. while(true) {
  13625. currentChar = resp[offset++];
  13626. // EOF
  13627. if(currentChar == null) {
  13628. if (state.escaped) {
  13629. throw new Error('Unclosed quote in file.');
  13630. }
  13631. if (currentRecord){
  13632. tokenEnd();
  13633. recordEnd();
  13634. break;
  13635. }
  13636. }
  13637. if(currentRecord === null) {
  13638. recordBegin();
  13639. }
  13640. // Handle opening quote
  13641. if (state.currentState === PRE_TOKEN) {
  13642. if (currentChar === QUOTE) {
  13643. state.escaped = true;
  13644. state.currentState = MID_TOKEN;
  13645. continue;
  13646. }
  13647. state.currentState = MID_TOKEN;
  13648. }
  13649. // mid-token and escaped, look for sequences and end quote
  13650. if (state.currentState === MID_TOKEN && state.escaped) {
  13651. if (currentChar === QUOTE) {
  13652. if (resp[offset] === QUOTE) {
  13653. state.token += QUOTE;
  13654. offset++;
  13655. }
  13656. else {
  13657. state.escaped = false;
  13658. state.currentState = POST_TOKEN;
  13659. }
  13660. }
  13661. else {
  13662. state.token += currentChar;
  13663. }
  13664. continue;
  13665. }
  13666. // fall-through: mid-token or post-token, not escaped
  13667. if (currentChar === CR ) {
  13668. if( resp[offset] === LF ) {
  13669. offset++;
  13670. }
  13671. tokenEnd();
  13672. recordEnd();
  13673. }
  13674. else if (currentChar === LF) {
  13675. tokenEnd();
  13676. recordEnd();
  13677. }
  13678. else if (currentChar === sep) {
  13679. tokenEnd();
  13680. }
  13681. else if( state.currentState === MID_TOKEN ){
  13682. state.token += currentChar;
  13683. }
  13684. }
  13685. // set up column names
  13686. if (header) {
  13687. t.columns = records.shift();
  13688. }
  13689. else {
  13690. for (i = 0; i < records.length; i++){
  13691. t.columns[i] = i.toString();
  13692. }
  13693. }
  13694. var row;
  13695. for (i =0; i<records.length; i++) {
  13696. //Handles row of 'undefined' at end of some CSVs
  13697. if (i === records.length - 1 && records[i].length === 1) {
  13698. if(records[i][0] === 'undefined'){
  13699. break;
  13700. }
  13701. }
  13702. row = new p5.TableRow();
  13703. row.arr = records[i];
  13704. row.obj = makeObject(records[i], t.columns);
  13705. t.addRow(row);
  13706. }
  13707. if (callback !== null) {
  13708. callback(t);
  13709. }
  13710. })
  13711. .fail(function(err,msg){
  13712. p5._friendlyFileLoadError(2,path);
  13713. if (typeof callback !== 'undefined') {
  13714. callback(false);
  13715. }
  13716. });
  13717. return t;
  13718. };
  13719. // helper function to turn a row into a JSON object
  13720. function makeObject(row, headers) {
  13721. var ret = {};
  13722. headers = headers || [];
  13723. if (typeof(headers) === 'undefined'){
  13724. for (var j = 0; j < row.length; j++ ){
  13725. headers[j.toString()] = j;
  13726. }
  13727. }
  13728. for (var i = 0; i < headers.length; i++){
  13729. var key = headers[i];
  13730. var val = row[i];
  13731. ret[key] = val;
  13732. }
  13733. return ret;
  13734. }
  13735. /**
  13736. * Reads the contents of a file and creates an XML object with its values.
  13737. * If the name of the file is used as the parameter, as in the above example,
  13738. * the file must be located in the sketch directory/folder.
  13739. *
  13740. * Alternatively, the file maybe be loaded from anywhere on the local
  13741. * computer using an absolute path (something that starts with / on Unix and
  13742. * Linux, or a drive letter on Windows), or the filename parameter can be a
  13743. * URL for a file found on a network.
  13744. *
  13745. * This method is asynchronous, meaning it may not finish before the next
  13746. * line in your sketch is executed. Calling loadXML() inside preload()
  13747. * guarantees to complete the operation before setup() and draw() are called.
  13748. * Outside preload(), you may supply a callback function to handle the object.
  13749. *
  13750. * @method loadXML
  13751. * @param {String} filename name of the file or URL to load
  13752. * @param {Function} [callback] function to be executed after loadXML()
  13753. * completes, XML object is passed in as
  13754. * first argument
  13755. * @return {Object} XML object containing data
  13756. */
  13757. p5.prototype.loadXML = function(path, callback) {
  13758. var ret = document.implementation.createDocument(null, null);
  13759. reqwest({
  13760. url: path,
  13761. type: 'xml',
  13762. crossOrigin: true,
  13763. error: function(err){
  13764. p5._friendlyFileLoadError(1,path);
  13765. }
  13766. })
  13767. .then(function(resp){
  13768. var x = resp.documentElement;
  13769. ret.appendChild(x);
  13770. if (typeof callback !== 'undefined') {
  13771. callback(resp);
  13772. }
  13773. });
  13774. return ret;
  13775. };
  13776. // name clash with window.open
  13777. // p5.prototype.open = function() {
  13778. // // TODO
  13779. // };
  13780. p5.prototype.parseXML = function() {
  13781. // TODO
  13782. throw 'not yet implemented';
  13783. };
  13784. p5.prototype.selectFolder = function() {
  13785. // TODO
  13786. throw 'not yet implemented';
  13787. };
  13788. p5.prototype.selectInput = function() {
  13789. // TODO
  13790. throw 'not yet implemented';
  13791. };
  13792. /**
  13793. * Method for executing an HTTP GET request. If data type is not specified,
  13794. * p5 will try to guess based on the URL, defaulting to text.
  13795. *
  13796. * @method httpGet
  13797. * @param {String} path name of the file or url to load
  13798. * @param {Object} [data] param data passed sent with request
  13799. * @param {String} [datatype] "json", "jsonp", "xml", or "text"
  13800. * @param {Function} [callback] function to be executed after
  13801. * httpGet() completes, data is passed in
  13802. * as first argument
  13803. */
  13804. p5.prototype.httpGet = function () {
  13805. var args = Array.prototype.slice.call(arguments);
  13806. args.push('GET');
  13807. p5.prototype.httpDo.apply(this, args);
  13808. };
  13809. /**
  13810. * Method for executing an HTTP POST request. If data type is not specified,
  13811. * p5 will try to guess based on the URL, defaulting to text.
  13812. *
  13813. * @method httpPost
  13814. * @param {String} path name of the file or url to load
  13815. * @param {Object} [data] param data passed sent with request
  13816. * @param {String} [datatype] "json", "jsonp", "xml", or "text"
  13817. * @param {Function} [callback] function to be executed after
  13818. * httpGet() completes, data is passed in
  13819. * as first argument
  13820. */
  13821. p5.prototype.httpPost = function () {
  13822. var args = Array.prototype.slice.call(arguments);
  13823. args.push('POST');
  13824. p5.prototype.httpDo.apply(this, args);
  13825. };
  13826. /**
  13827. * Method for executing an HTTP request. If data type is not specified,
  13828. * p5 will try to guess based on the URL, defaulting to text.
  13829. *
  13830. * @method httpDo
  13831. * @param {String} path name of the file or url to load
  13832. * @param {String} [method] either "GET", "POST", or "PUT",
  13833. * defaults to "GET"
  13834. * @param {Object} [data] param data passed sent with request
  13835. * @param {String} [datatype] "json", "jsonp", "xml", or "text"
  13836. * @param {Function} [callback] function to be executed after
  13837. * httpGet() completes, data is passed in
  13838. * as first argument
  13839. */
  13840. p5.prototype.httpDo = function() {
  13841. var method = 'GET';
  13842. var path = arguments[0];
  13843. var data = {};
  13844. var type = '';
  13845. var callback;
  13846. for (var i=1; i<arguments.length; i++) {
  13847. var a = arguments[i];
  13848. if (typeof a === 'string') {
  13849. if (a === 'GET' || a === 'POST' || a === 'PUT') {
  13850. method = a;
  13851. } else {
  13852. type = a;
  13853. }
  13854. } else if (typeof a === 'object') {
  13855. data = a;
  13856. } else if (typeof a === 'function') {
  13857. callback = a;
  13858. }
  13859. }
  13860. // do some sort of smart type checking
  13861. if (type === '') {
  13862. if (path.indexOf('json') !== -1) {
  13863. type = 'json';
  13864. } else if (path.indexOf('xml') !== -1) {
  13865. type = 'xml';
  13866. } else {
  13867. type = 'text';
  13868. }
  13869. }
  13870. reqwest({
  13871. url: path,
  13872. method: method,
  13873. data: data,
  13874. type: type,
  13875. crossOrigin: true,
  13876. success: function (resp) {
  13877. if (typeof callback !== 'undefined') {
  13878. if (type === 'text') {
  13879. callback(resp.response);
  13880. } else {
  13881. callback(resp);
  13882. }
  13883. }
  13884. }
  13885. });
  13886. };
  13887. /**
  13888. * @module IO
  13889. * @submodule Output
  13890. * @for p5
  13891. */
  13892. window.URL = window.URL || window.webkitURL;
  13893. // private array of p5.PrintWriter objects
  13894. p5.prototype._pWriters = [];
  13895. p5.prototype.beginRaw = function() {
  13896. // TODO
  13897. throw 'not yet implemented';
  13898. };
  13899. p5.prototype.beginRecord = function() {
  13900. // TODO
  13901. throw 'not yet implemented';
  13902. };
  13903. p5.prototype.createOutput = function() {
  13904. // TODO
  13905. throw 'not yet implemented';
  13906. };
  13907. p5.prototype.createWriter = function(name, extension) {
  13908. var newPW;
  13909. // check that it doesn't already exist
  13910. for (var i in p5.prototype._pWriters) {
  13911. if (p5.prototype._pWriters[i].name === name) {
  13912. // if a p5.PrintWriter w/ this name already exists...
  13913. // return p5.prototype._pWriters[i]; // return it w/ contents intact.
  13914. // or, could return a new, empty one with a unique name:
  13915. newPW = new p5.PrintWriter(name + window.millis(), extension);
  13916. p5.prototype._pWriters.push( newPW );
  13917. return newPW;
  13918. }
  13919. }
  13920. newPW = new p5.PrintWriter(name, extension);
  13921. p5.prototype._pWriters.push( newPW );
  13922. return newPW;
  13923. };
  13924. p5.prototype.endRaw = function() {
  13925. // TODO
  13926. throw 'not yet implemented';
  13927. };
  13928. p5.prototype.endRecord = function() {
  13929. // TODO
  13930. throw 'not yet implemented';
  13931. };
  13932. p5.PrintWriter = function(filename, extension) {
  13933. var self = this;
  13934. this.name = filename;
  13935. this.content = '';
  13936. this.print = function(data) { this.content += data; };
  13937. this.println = function(data) { this.content += data + '\n'; };
  13938. this.flush = function() { this.content = ''; };
  13939. this.close = function() {
  13940. // convert String to Array for the writeFile Blob
  13941. var arr = [];
  13942. arr.push(this.content);
  13943. p5.prototype.writeFile(arr, filename, extension);
  13944. // remove from _pWriters array and delete self
  13945. for (var i in p5.prototype._pWriters) {
  13946. if (p5.prototype._pWriters[i].name === this.name) {
  13947. // remove from _pWriters array
  13948. p5.prototype._pWriters.splice(i, 1);
  13949. }
  13950. }
  13951. self.flush();
  13952. self = {};
  13953. };
  13954. };
  13955. p5.prototype.saveBytes = function() {
  13956. // TODO
  13957. throw 'not yet implemented';
  13958. };
  13959. // object, filename, options --> saveJSON, saveStrings, saveTable
  13960. // filename, [extension] [canvas] --> saveImage
  13961. /**
  13962. * <p>Save an image, text, json, csv, wav, or html. Prompts download to
  13963. * the client's computer. <b>Note that it is not recommended to call save()
  13964. * within draw if it's looping, as the save() function will open a new save
  13965. * dialog every frame.</b></p>
  13966. * <p>The default behavior is to save the canvas as an image. You can
  13967. * optionally specify a filename.
  13968. * For example:</p>
  13969. * <pre class='language-javascript'><code>
  13970. * save();
  13971. * save('myCanvas.jpg'); // save a specific canvas with a filename
  13972. * </code></pre>
  13973. *
  13974. * <p>Alternately, the first parameter can be a pointer to a canvas
  13975. * p5.Element, an Array of Strings,
  13976. * an Array of JSON, a JSON object, a p5.Table, a p5.Image, or a
  13977. * p5.SoundFile (requires p5.sound). The second parameter is a filename
  13978. * (including extension). The third parameter is for options specific
  13979. * to this type of object. This method will save a file that fits the
  13980. * given paramaters. For example:</p>
  13981. *
  13982. * <pre class='language-javascript'><code>
  13983. *
  13984. * save('myCanvas.jpg'); // Saves canvas as an image
  13985. *
  13986. * var cnv = createCanvas(100, 100);
  13987. * save(cnv, 'myCanvas.jpg'); // Saves canvas as an image
  13988. *
  13989. * var gb = createGraphics(100, 100);
  13990. * save(gb, 'myGraphics.jpg'); // Saves p5.Renderer object as an image
  13991. *
  13992. * save(myTable, 'myTable.html'); // Saves table as html file
  13993. * save(myTable, 'myTable.csv',); // Comma Separated Values
  13994. * save(myTable, 'myTable.tsv'); // Tab Separated Values
  13995. *
  13996. * save(myJSON, 'my.json'); // Saves pretty JSON
  13997. * save(myJSON, 'my.json', true); // Optimizes JSON filesize
  13998. *
  13999. * save(img, 'my.png'); // Saves pImage as a png image
  14000. *
  14001. * save(arrayOfStrings, 'my.txt'); // Saves strings to a text file with line
  14002. * // breaks after each item in the array
  14003. * </code></pre>
  14004. *
  14005. * @method save
  14006. * @param {[Object|String]} objectOrFilename If filename is provided, will
  14007. * save canvas as an image with
  14008. * either png or jpg extension
  14009. * depending on the filename.
  14010. * If object is provided, will
  14011. * save depending on the object
  14012. * and filename (see examples
  14013. * above).
  14014. * @param {[String]} filename If an object is provided as the first
  14015. * parameter, then the second parameter
  14016. * indicates the filename,
  14017. * and should include an appropriate
  14018. * file extension (see examples above).
  14019. * @param {[Boolean/String]} options Additional options depend on
  14020. * filetype. For example, when saving JSON,
  14021. * <code>true</code> indicates that the
  14022. * output will be optimized for filesize,
  14023. * rather than readability.
  14024. */
  14025. p5.prototype.save = function(object, _filename, _options) {
  14026. // parse the arguments and figure out which things we are saving
  14027. var args = arguments;
  14028. // =================================================
  14029. // OPTION 1: saveCanvas...
  14030. // if no arguments are provided, save canvas
  14031. var cnv = this._curElement.elt;
  14032. if (args.length === 0) {
  14033. p5.prototype.saveCanvas(cnv);
  14034. return;
  14035. }
  14036. // otherwise, parse the arguments
  14037. // if first param is a p5Graphics, then saveCanvas
  14038. else if (args[0] instanceof p5.Renderer) {
  14039. p5.prototype.saveCanvas(args[0].elt, args[1], args[2]);
  14040. return;
  14041. }
  14042. // if 1st param is String and only one arg, assume it is canvas filename
  14043. else if (args.length === 1 && typeof(args[0]) === 'string') {
  14044. p5.prototype.saveCanvas(cnv, args[0]);
  14045. }
  14046. // =================================================
  14047. // OPTION 2: extension clarifies saveStrings vs. saveJSON
  14048. else {
  14049. var extension = _checkFileExtension(args[1], args[2])[1];
  14050. switch(extension){
  14051. case 'json':
  14052. p5.prototype.saveJSON(args[0], args[1], args[2]);
  14053. return;
  14054. case 'txt':
  14055. p5.prototype.saveStrings(args[0], args[1], args[2]);
  14056. return;
  14057. // =================================================
  14058. // OPTION 3: decide based on object...
  14059. default:
  14060. if (args[0] instanceof Array) {
  14061. p5.prototype.saveStrings(args[0], args[1], args[2]);
  14062. }
  14063. else if (args[0] instanceof p5.Table) {
  14064. p5.prototype.saveTable(args[0], args[1], args[2], args[3]);
  14065. }
  14066. else if (args[0] instanceof p5.Image) {
  14067. p5.prototype.saveCanvas(args[0].canvas, args[1]);
  14068. }
  14069. else if (args[0] instanceof p5.SoundFile) {
  14070. p5.prototype.saveSound(args[0], args[1], args[2], args[3]);
  14071. }
  14072. }
  14073. }
  14074. };
  14075. /**
  14076. * Writes the contents of an Array or a JSON object to a .json file.
  14077. * The file saving process and location of the saved file will
  14078. * vary between web browsers.
  14079. *
  14080. * @method saveJSON
  14081. * @param {Array|Object} json
  14082. * @param {String} filename
  14083. * @param {Boolean} [optimize] If true, removes line breaks
  14084. * and spaces from the output
  14085. * file to optimize filesize
  14086. * (but not readability).
  14087. * @example
  14088. * <div><code>
  14089. * var json;
  14090. *
  14091. * function setup() {
  14092. *
  14093. * json = {}; // new JSON Object
  14094. *
  14095. * json.id = 0;
  14096. * json.species = 'Panthera leo';
  14097. * json.name = 'Lion';
  14098. *
  14099. * // To save, un-comment the line below, then click 'run'
  14100. * // saveJSONObject(json, 'lion.json');
  14101. * }
  14102. *
  14103. * // Saves the following to a file called "lion.json":
  14104. * // {
  14105. * // "id": 0,
  14106. * // "species": "Panthera leo",
  14107. * // "name": "Lion"
  14108. * // }
  14109. * </div></code>
  14110. */
  14111. p5.prototype.saveJSON = function(json, filename, opt) {
  14112. var stringify;
  14113. if (opt){
  14114. stringify = JSON.stringify( json );
  14115. } else {
  14116. stringify = JSON.stringify( json, undefined, 2);
  14117. }
  14118. console.log(stringify);
  14119. this.saveStrings(stringify.split('\n'), filename, 'json');
  14120. };
  14121. p5.prototype.saveJSONObject = p5.prototype.saveJSON;
  14122. p5.prototype.saveJSONArray = p5.prototype.saveJSON;
  14123. p5.prototype.saveStream = function() {
  14124. // TODO
  14125. throw 'not yet implemented';
  14126. };
  14127. /**
  14128. * Writes an array of Strings to a text file, one line per String.
  14129. * The file saving process and location of the saved file will
  14130. * vary between web browsers.
  14131. *
  14132. * @method saveStrings
  14133. * @param {Array} list string array to be written
  14134. * @param {String} filename filename for output
  14135. * @example
  14136. * <div><code>
  14137. * var words = 'apple bear cat dog';
  14138. *
  14139. * // .split() outputs an Array
  14140. * var list = split(words, ' ');
  14141. *
  14142. * // To save the file, un-comment next line and click 'run'
  14143. * // saveStrings(list, 'nouns.txt');
  14144. *
  14145. * // Saves the following to a file called 'nouns.txt':
  14146. * //
  14147. * // apple
  14148. * // bear
  14149. * // cat
  14150. * // dog
  14151. * </code></div>
  14152. */
  14153. p5.prototype.saveStrings = function(list, filename, extension) {
  14154. var ext = extension || 'txt';
  14155. var pWriter = this.createWriter(filename, ext);
  14156. for (var i in list) {
  14157. if (i < list.length - 1) {
  14158. pWriter.println(list[i]);
  14159. } else {
  14160. pWriter.print(list[i]);
  14161. }
  14162. }
  14163. pWriter.close();
  14164. pWriter.flush();
  14165. };
  14166. p5.prototype.saveXML = function() {
  14167. // TODO
  14168. throw 'not yet implemented';
  14169. };
  14170. p5.prototype.selectOutput = function() {
  14171. // TODO
  14172. throw 'not yet implemented';
  14173. };
  14174. // =======
  14175. // HELPERS
  14176. // =======
  14177. function escapeHelper(content) {
  14178. return content
  14179. .replace(/&/g, '&amp;')
  14180. .replace(/</g, '&lt;')
  14181. .replace(/>/g, '&gt;')
  14182. .replace(/"/g, '&quot;')
  14183. .replace(/'/g, '&#039;');
  14184. }
  14185. /**
  14186. * Writes the contents of a Table object to a file. Defaults to a
  14187. * text file with comma-separated-values ('csv') but can also
  14188. * use tab separation ('tsv'), or generate an HTML table ('html').
  14189. * The file saving process and location of the saved file will
  14190. * vary between web browsers.
  14191. *
  14192. * @method saveTable
  14193. * @param {p5.Table} Table the Table object to save to a file
  14194. * @param {String} filename the filename to which the Table should be saved
  14195. * @param {[String]} options can be one of "tsv", "csv", or "html"
  14196. * @example
  14197. * <div><code>
  14198. * var table;
  14199. *
  14200. * function setup() {
  14201. * table = new p5.Table();
  14202. *
  14203. * table.addColumn('id');
  14204. * table.addColumn('species');
  14205. * table.addColumn('name');
  14206. *
  14207. * var newRow = table.addRow();
  14208. * newRow.setNum('id', table.getRowCount() - 1);
  14209. * newRow.setString('species', 'Panthera leo');
  14210. * newRow.setString('name', 'Lion');
  14211. *
  14212. * // To save, un-comment next line then click 'run'
  14213. * // saveTable(table, 'new.csv');
  14214. * }
  14215. *
  14216. * // Saves the following to a file called 'new.csv':
  14217. * // id,species,name
  14218. * // 0,Panthera leo,Lion
  14219. * </code></div>
  14220. */
  14221. p5.prototype.saveTable = function(table, filename, options) {
  14222. var pWriter = this.createWriter(filename, options);
  14223. var header = table.columns;
  14224. var sep = ','; // default to CSV
  14225. if (options === 'tsv') {
  14226. sep = '\t';
  14227. }
  14228. if (options !== 'html') {
  14229. // make header if it has values
  14230. if (header[0] !== '0') {
  14231. for (var h = 0; h < header.length; h++ ) {
  14232. if (h < header.length - 1){
  14233. pWriter.print(header[h] + sep);
  14234. } else {
  14235. pWriter.println(header[h]);
  14236. }
  14237. }
  14238. }
  14239. // make rows
  14240. for (var i = 0; i < table.rows.length; i++ ) {
  14241. var j;
  14242. for (j = 0; j < table.rows[i].arr.length; j++) {
  14243. if (j < table.rows[i].arr.length - 1) {
  14244. pWriter.print(table.rows[i].arr[j] + sep);
  14245. }
  14246. else if (i < table.rows.length - 1) {
  14247. pWriter.println(table.rows[i].arr[j]);
  14248. } else {
  14249. pWriter.print(table.rows[i].arr[j]); // no line break
  14250. }
  14251. }
  14252. }
  14253. }
  14254. // otherwise, make HTML
  14255. else {
  14256. pWriter.println('<html>');
  14257. pWriter.println('<head>');
  14258. var str = ' <meta http-equiv=\"content-type\" content';
  14259. str += '=\"text/html;charset=utf-8\" />';
  14260. pWriter.println(str);
  14261. pWriter.println('</head>');
  14262. pWriter.println('<body>');
  14263. pWriter.println(' <table>');
  14264. // make header if it has values
  14265. if (header[0] !== '0') {
  14266. pWriter.println(' <tr>');
  14267. for (var k = 0; k < header.length; k++ ) {
  14268. var e = escapeHelper(header[k]);
  14269. pWriter.println(' <td>' +e);
  14270. pWriter.println(' </td>');
  14271. }
  14272. pWriter.println(' </tr>');
  14273. }
  14274. // make rows
  14275. for (var row = 0; row < table.rows.length; row++) {
  14276. pWriter.println(' <tr>');
  14277. for (var col = 0; col < table.columns.length; col++) {
  14278. var entry = table.rows[row].getString(col);
  14279. var htmlEntry = escapeHelper(entry);
  14280. pWriter.println(' <td>' +htmlEntry);
  14281. pWriter.println(' </td>');
  14282. }
  14283. pWriter.println(' </tr>');
  14284. }
  14285. pWriter.println(' </table>');
  14286. pWriter.println('</body>');
  14287. pWriter.print('</html>');
  14288. }
  14289. // close and flush the pWriter
  14290. pWriter.close();
  14291. pWriter.flush();
  14292. }; // end saveTable()
  14293. /**
  14294. * Generate a blob of file data as a url to prepare for download.
  14295. * Accepts an array of data, a filename, and an extension (optional).
  14296. * This is a private function because it does not do any formatting,
  14297. * but it is used by saveStrings, saveJSON, saveTable etc.
  14298. *
  14299. * @param {Array} dataToDownload
  14300. * @param {String} filename
  14301. * @param {[String]} extension
  14302. * @private
  14303. */
  14304. p5.prototype.writeFile = function(dataToDownload, filename, extension) {
  14305. var type = 'application\/octet-stream';
  14306. if (p5.prototype._isSafari() ) {
  14307. type = 'text\/plain';
  14308. }
  14309. var blob = new Blob(dataToDownload, {'type': type});
  14310. var href = window.URL.createObjectURL(blob);
  14311. p5.prototype.downloadFile(href, filename, extension);
  14312. };
  14313. /**
  14314. * Forces download. Accepts a url to filedata/blob, a filename,
  14315. * and an extension (optional).
  14316. * This is a private function because it does not do any formatting,
  14317. * but it is used by saveStrings, saveJSON, saveTable etc.
  14318. *
  14319. * @param {String} href i.e. an href generated by createObjectURL
  14320. * @param {[String]} filename
  14321. * @param {[String]} extension
  14322. */
  14323. p5.prototype.downloadFile = function(href, fName, extension) {
  14324. var fx = _checkFileExtension(fName, extension);
  14325. var filename = fx[0];
  14326. var ext = fx[1];
  14327. var a = document.createElement('a');
  14328. a.href = href;
  14329. a.download = filename;
  14330. // Firefox requires the link to be added to the DOM before click()
  14331. a.onclick = destroyClickedElement;
  14332. a.style.display = 'none';
  14333. document.body.appendChild(a);
  14334. // Safari will open this file in the same page as a confusing Blob.
  14335. if (p5.prototype._isSafari() ) {
  14336. var aText = 'Hello, Safari user! To download this file...\n';
  14337. aText += '1. Go to File --> Save As.\n';
  14338. aText += '2. Choose "Page Source" as the Format.\n';
  14339. aText += '3. Name it with this extension: .\"' + ext+'\"';
  14340. alert(aText);
  14341. }
  14342. a.click();
  14343. href = null;
  14344. };
  14345. /**
  14346. * Returns a file extension, or another string
  14347. * if the provided parameter has no extension.
  14348. *
  14349. * @param {String} filename
  14350. * @return {Array} [fileName, fileExtension]
  14351. *
  14352. * @private
  14353. */
  14354. function _checkFileExtension(filename, extension) {
  14355. if (!extension || extension === true || extension === 'true') {
  14356. extension = '';
  14357. }
  14358. if (!filename) {
  14359. filename = 'untitled';
  14360. }
  14361. var ext = '';
  14362. // make sure the file will have a name, see if filename needs extension
  14363. if (filename && filename.indexOf('.') > -1) {
  14364. ext = filename.split('.').pop();
  14365. }
  14366. // append extension if it doesn't exist
  14367. if (extension) {
  14368. if (ext !== extension) {
  14369. ext = extension;
  14370. filename = filename + '.' + ext;
  14371. }
  14372. }
  14373. return [filename, ext];
  14374. }
  14375. p5.prototype._checkFileExtension = _checkFileExtension;
  14376. /**
  14377. * Returns true if the browser is Safari, false if not.
  14378. * Safari makes trouble for downloading files.
  14379. *
  14380. * @return {Boolean} [description]
  14381. * @private
  14382. */
  14383. p5.prototype._isSafari = function() {
  14384. var x = Object.prototype.toString.call(window.HTMLElement);
  14385. return x.indexOf('Constructor') > 0;
  14386. };
  14387. /**
  14388. * Helper function, a callback for download that deletes
  14389. * an invisible anchor element from the DOM once the file
  14390. * has been automatically downloaded.
  14391. *
  14392. * @private
  14393. */
  14394. function destroyClickedElement(event) {
  14395. document.body.removeChild(event.target);
  14396. }
  14397. module.exports = p5;
  14398. },{"../core/core":17,"../core/error_helpers":20,"reqwest":1}],40:[function(require,module,exports){
  14399. /**
  14400. * @module IO
  14401. * @submodule Table
  14402. * @requires core
  14403. */
  14404. 'use strict';
  14405. var p5 = require('../core/core');
  14406. /**
  14407. * Table Options
  14408. * <p>Generic class for handling tabular data, typically from a
  14409. * CSV, TSV, or other sort of spreadsheet file.</p>
  14410. * <p>CSV files are
  14411. * <a href="http://en.wikipedia.org/wiki/Comma-separated_values">
  14412. * comma separated values</a>, often with the data in quotes. TSV
  14413. * files use tabs as separators, and usually don't bother with the
  14414. * quotes.</p>
  14415. * <p>File names should end with .csv if they're comma separated.</p>
  14416. * <p>A rough "spec" for CSV can be found
  14417. * <a href="http://tools.ietf.org/html/rfc4180">here</a>.</p>
  14418. * <p>To load files, use the loadTable method.</p>
  14419. * <p>To save tables to your computer, use the save method
  14420. * or the saveTable method.</p>
  14421. *
  14422. * Possible options include:
  14423. * <ul>
  14424. * <li>csv - parse the table as comma-separated values
  14425. * <li>tsv - parse the table as tab-separated values
  14426. * <li>header - this table has a header (title) row
  14427. * </ul>
  14428. */
  14429. /**
  14430. * Table objects store data with multiple rows and columns, much
  14431. * like in a traditional spreadsheet. Tables can be generated from
  14432. * scratch, dynamically, or using data from an existing file.
  14433. *
  14434. * @class p5.Table
  14435. * @constructor
  14436. * @param {Array} [rows] An array of p5.TableRow objects
  14437. * @return {p5.Table} p5.Table generated
  14438. */
  14439. p5.Table = function (rows) {
  14440. /**
  14441. * @property columns
  14442. * @type {Array}
  14443. */
  14444. this.columns = [];
  14445. /**
  14446. * @property rows
  14447. * @type {Array}
  14448. */
  14449. this.rows = [];
  14450. };
  14451. /**
  14452. * Use addRow() to add a new row of data to a p5.Table object. By default,
  14453. * an empty row is created. Typically, you would store a reference to
  14454. * the new row in a TableRow object (see newRow in the example above),
  14455. * and then set individual values using set().
  14456. *
  14457. * If a p5.TableRow object is included as a parameter, then that row is
  14458. * duplicated and added to the table.
  14459. *
  14460. * @method addRow
  14461. * @param {p5.TableRow} [row] row to be added to the table
  14462. *
  14463. * @example
  14464. * <div class="norender">
  14465. * <code>
  14466. * // Given the CSV file "mammals.csv"
  14467. * // in the project's "assets" folder:
  14468. * //
  14469. * // id,species,name
  14470. * // 0,Capra hircus,Goat
  14471. * // 1,Panthera pardus,Leopard
  14472. * // 2,Equus zebra,Zebra
  14473. *
  14474. * var table;
  14475. *
  14476. * function preload() {
  14477. * //my table is comma separated value "csv"
  14478. * //and has a header specifying the columns labels
  14479. * table = loadTable("assets/mammals.csv", "csv", "header");
  14480. * }
  14481. *
  14482. * function setup() {
  14483. * //add a row
  14484. * var newRow = table.addRow();
  14485. * newRow.setString("id", table.getRowCount() - 1);
  14486. * newRow.setString("species", "Canis Lupus");
  14487. * newRow.setString("name", "Wolf");
  14488. *
  14489. * //print the results
  14490. * for (var r = 0; r < table.getRowCount(); r++)
  14491. * for (var c = 0; c < table.getColumnCount(); c++)
  14492. * print(table.getString(r, c));
  14493. * }
  14494. * </code>
  14495. * </div>
  14496. */
  14497. p5.Table.prototype.addRow = function(row) {
  14498. // make sure it is a valid TableRow
  14499. var r = row || new p5.TableRow();
  14500. if (typeof(r.arr) === 'undefined' || typeof(r.obj) === 'undefined') {
  14501. //r = new p5.prototype.TableRow(r);
  14502. throw 'invalid TableRow: ' + r;
  14503. }
  14504. r.table = this;
  14505. this.rows.push(r);
  14506. return r;
  14507. };
  14508. /**
  14509. * Removes a row from the table object.
  14510. *
  14511. * @method removeRow
  14512. * @param {Number} id ID number of the row to remove
  14513. *
  14514. * @example
  14515. * <div class="norender">
  14516. * <code>
  14517. * // Given the CSV file "mammals.csv"
  14518. * // in the project's "assets" folder:
  14519. * //
  14520. * // id,species,name
  14521. * // 0,Capra hircus,Goat
  14522. * // 1,Panthera pardus,Leopard
  14523. * // 2,Equus zebra,Zebra
  14524. *
  14525. * var table;
  14526. *
  14527. * function preload() {
  14528. * //my table is comma separated value "csv"
  14529. * //and has a header specifying the columns labels
  14530. * table = loadTable("assets/mammals.csv", "csv", "header");
  14531. * }
  14532. *
  14533. * function setup() {
  14534. * //remove the first row
  14535. * var r = table.removeRow(0);
  14536. *
  14537. * //print the results
  14538. * for (var r = 0; r < table.getRowCount(); r++)
  14539. * for (var c = 0; c < table.getColumnCount(); c++)
  14540. * print(table.getString(r, c));
  14541. * }
  14542. * </code>
  14543. * </div>
  14544. */
  14545. p5.Table.prototype.removeRow = function(id) {
  14546. this.rows[id].table = null; // remove reference to table
  14547. var chunk = this.rows.splice(id+1, this.rows.length);
  14548. this.rows.pop();
  14549. this.rows = this.rows.concat(chunk);
  14550. };
  14551. /**
  14552. * Returns a reference to the specified p5.TableRow. The reference
  14553. * can then be used to get and set values of the selected row.
  14554. *
  14555. * @method getRow
  14556. * @param {Number} rowID ID number of the row to get
  14557. * @return {TableRow} p5.TableRow object
  14558. *
  14559. * @example
  14560. * <div class="norender">
  14561. * <code>
  14562. * // Given the CSV file "mammals.csv"
  14563. * // in the project's "assets" folder:
  14564. * //
  14565. * // id,species,name
  14566. * // 0,Capra hircus,Goat
  14567. * // 1,Panthera pardus,Leopard
  14568. * // 2,Equus zebra,Zebra
  14569. *
  14570. * var table;
  14571. *
  14572. * function preload() {
  14573. * //my table is comma separated value "csv"
  14574. * //and has a header specifying the columns labels
  14575. * table = loadTable("assets/mammals.csv", "csv", "header");
  14576. * }
  14577. *
  14578. * function setup() {
  14579. * var row = table.getRow(1);
  14580. * //print it column by column
  14581. * //note: a row is an object, not an array
  14582. * for (var c = 0; c < table.getColumnCount(); c++)
  14583. * print(row.getString(c));
  14584. * }
  14585. * </code>
  14586. * </div>
  14587. */
  14588. p5.Table.prototype.getRow = function(r) {
  14589. return this.rows[r];
  14590. };
  14591. /**
  14592. * Gets all rows from the table. Returns an array of p5.TableRows.
  14593. *
  14594. * @method getRows
  14595. * @return {Array} Array of p5.TableRows
  14596. *
  14597. * @example
  14598. * <div class="norender">
  14599. * <code>
  14600. * // Given the CSV file "mammals.csv"
  14601. * // in the project's "assets" folder:
  14602. * //
  14603. * // id,species,name
  14604. * // 0,Capra hircus,Goat
  14605. * // 1,Panthera pardus,Leopard
  14606. * // 2,Equus zebra,Zebra
  14607. *
  14608. * var table;
  14609. *
  14610. * function preload() {
  14611. * //my table is comma separated value "csv"
  14612. * //and has a header specifying the columns labels
  14613. * table = loadTable("assets/mammals.csv", "csv", "header");
  14614. * }
  14615. *
  14616. * function setup() {
  14617. * var rows = table.getRows();
  14618. *
  14619. * //warning: rows is an array of objects
  14620. * for (var r = 0; r < rows.length; r++)
  14621. * rows[r].set("name", "Unicorn");
  14622. *
  14623. * //print the results
  14624. * for (var r = 0; r < table.getRowCount(); r++)
  14625. * for (var c = 0; c < table.getColumnCount(); c++)
  14626. * print(table.getString(r, c));
  14627. * }
  14628. * </code>
  14629. * </div>
  14630. */
  14631. p5.Table.prototype.getRows = function() {
  14632. return this.rows;
  14633. };
  14634. /**
  14635. * Finds the first row in the Table that contains the value
  14636. * provided, and returns a reference to that row. Even if
  14637. * multiple rows are possible matches, only the first matching
  14638. * row is returned. The column to search may be specified by
  14639. * either its ID or title.
  14640. *
  14641. * @method findRow
  14642. * @param {String} value The value to match
  14643. * @param {Number|String} column ID number or title of the
  14644. * column to search
  14645. * @return {TableRow}
  14646. *
  14647. * @example
  14648. * <div class="norender">
  14649. * <code>
  14650. * // Given the CSV file "mammals.csv"
  14651. * // in the project's "assets" folder:
  14652. * //
  14653. * // id,species,name
  14654. * // 0,Capra hircus,Goat
  14655. * // 1,Panthera pardus,Leopard
  14656. * // 2,Equus zebra,Zebra
  14657. *
  14658. * var table;
  14659. *
  14660. * function preload() {
  14661. * //my table is comma separated value "csv"
  14662. * //and has a header specifying the columns labels
  14663. * table = loadTable("assets/mammals.csv", "csv", "header");
  14664. * }
  14665. *
  14666. * function setup() {
  14667. * //find the animal named zebra
  14668. * var row = table.findRow("Zebra", "name");
  14669. * //find the corresponding species
  14670. * print(row.getString("species"));
  14671. * }
  14672. * </code>
  14673. * </div>
  14674. */
  14675. p5.Table.prototype.findRow = function(value, column) {
  14676. // try the Object
  14677. if (typeof(column) === 'string') {
  14678. for (var i = 0; i < this.rows.length; i++){
  14679. if (this.rows[i].obj[column] === value) {
  14680. return this.rows[i];
  14681. }
  14682. }
  14683. }
  14684. // try the Array
  14685. else {
  14686. for (var j = 0; j < this.rows.length; j++){
  14687. if (this.rows[j].arr[column] === value) {
  14688. return this.rows[j];
  14689. }
  14690. }
  14691. }
  14692. // otherwise...
  14693. return null;
  14694. };
  14695. /**
  14696. * Finds the rows in the Table that contain the value
  14697. * provided, and returns references to those rows. Returns an
  14698. * Array, so for must be used to iterate through all the rows,
  14699. * as shown in the example above. The column to search may be
  14700. * specified by either its ID or title.
  14701. *
  14702. * @method findRows
  14703. * @param {String} value The value to match
  14704. * @param {Number|String} column ID number or title of the
  14705. * column to search
  14706. * @return {Array} An Array of TableRow objects
  14707. *
  14708. * @example
  14709. * <div class="norender">
  14710. * <code>
  14711. * // Given the CSV file "mammals.csv"
  14712. * // in the project's "assets" folder:
  14713. * //
  14714. * // id,species,name
  14715. * // 0,Capra hircus,Goat
  14716. * // 1,Panthera pardus,Leopard
  14717. * // 2,Equus zebra,Zebra
  14718. *
  14719. * var table;
  14720. *
  14721. * function preload() {
  14722. * //my table is comma separated value "csv"
  14723. * //and has a header specifying the columns labels
  14724. * table = loadTable("assets/mammals.csv", "csv", "header");
  14725. * }
  14726. *
  14727. * function setup() {
  14728. * //add another goat
  14729. * var newRow = table.addRow();
  14730. * newRow.setString("id", table.getRowCount() - 1);
  14731. * newRow.setString("species", "Scape Goat");
  14732. * newRow.setString("name", "Goat");
  14733. *
  14734. * //find the rows containing animals named Goat
  14735. * var rows = table.findRows("Goat", "name");
  14736. * print(rows.length + " Goats found");
  14737. * }
  14738. * </code>
  14739. * </div>
  14740. */
  14741. p5.Table.prototype.findRows = function(value, column) {
  14742. var ret = [];
  14743. if (typeof(column) === 'string') {
  14744. for (var i = 0; i < this.rows.length; i++){
  14745. if (this.rows[i].obj[column] === value) {
  14746. ret.push( this.rows[i] );
  14747. }
  14748. }
  14749. }
  14750. // try the Array
  14751. else {
  14752. for (var j = 0; j < this.rows.length; j++){
  14753. if (this.rows[j].arr[column] === value) {
  14754. ret.push( this.rows[j] );
  14755. }
  14756. }
  14757. }
  14758. return ret;
  14759. };
  14760. /**
  14761. * Finds the first row in the Table that matches the regular
  14762. * expression provided, and returns a reference to that row.
  14763. * Even if multiple rows are possible matches, only the first
  14764. * matching row is returned. The column to search may be
  14765. * specified by either its ID or title.
  14766. *
  14767. * @method matchRow
  14768. * @param {String} regexp The regular expression to match
  14769. * @param {String|Number} column The column ID (number) or
  14770. * title (string)
  14771. * @return {TableRow} TableRow object
  14772. */
  14773. p5.Table.prototype.matchRow = function(regexp, column) {
  14774. if (typeof(column) === 'number') {
  14775. for (var j = 0; j < this.rows.length; j++) {
  14776. if ( this.rows[j].arr[column].match(regexp) ) {
  14777. return this.rows[j];
  14778. }
  14779. }
  14780. }
  14781. else {
  14782. for (var i = 0; i < this.rows.length; i++) {
  14783. if ( this.rows[i].obj[column].match(regexp) ) {
  14784. return this.rows[i];
  14785. }
  14786. }
  14787. }
  14788. return null;
  14789. };
  14790. /**
  14791. * Finds the first row in the Table that matches the regular
  14792. * expression provided, and returns a reference to that row.
  14793. * Even if multiple rows are possible matches, only the first
  14794. * matching row is returned. The column to search may be specified
  14795. * by either its ID or title.
  14796. *
  14797. * @method matchRows
  14798. * @param {String} regexp The regular expression to match
  14799. * @param {String|Number} [column] The column ID (number) or
  14800. * title (string)
  14801. * @return {Array} An Array of TableRow objects
  14802. */
  14803. p5.Table.prototype.matchRows = function(regexp, column) {
  14804. var ret = [];
  14805. if (typeof(column) === 'number') {
  14806. for (var j = 0; j < this.rows.length; j++) {
  14807. if ( this.rows[j].arr[column].match(regexp) ) {
  14808. ret.push( this.rows[j] );
  14809. }
  14810. }
  14811. }
  14812. else {
  14813. for (var i = 0; i < this.rows.length; i++) {
  14814. if ( this.rows[i].obj[column].match(regexp) ) {
  14815. ret.push( this.rows[i] );
  14816. }
  14817. }
  14818. }
  14819. return ret;
  14820. };
  14821. /**
  14822. * Retrieves all values in the specified column, and returns them
  14823. * as an array. The column may be specified by either its ID or title.
  14824. *
  14825. * @method getColumn
  14826. * @param {String|Number} column String or Number of the column to return
  14827. * @return {Array} Array of column values
  14828. *
  14829. * @example
  14830. * <div class="norender">
  14831. * <code>
  14832. * // Given the CSV file "mammals.csv"
  14833. * // in the project's "assets" folder:
  14834. * //
  14835. * // id,species,name
  14836. * // 0,Capra hircus,Goat
  14837. * // 1,Panthera pardus,Leopard
  14838. * // 2,Equus zebra,Zebra
  14839. *
  14840. * var table;
  14841. *
  14842. * function preload() {
  14843. * //my table is comma separated value "csv"
  14844. * //and has a header specifying the columns labels
  14845. * table = loadTable("assets/mammals.csv", "csv", "header");
  14846. * }
  14847. *
  14848. * function setup() {
  14849. * //getColumn returns an array that can be printed directly
  14850. * print(table.getColumn("species"));
  14851. * //outputs ["Capra hircus", "Panthera pardus", "Equus zebra"]
  14852. * }
  14853. * </code>
  14854. * </div>
  14855. */
  14856. p5.Table.prototype.getColumn = function(value) {
  14857. var ret = [];
  14858. if (typeof(value) === 'string'){
  14859. for (var i = 0; i < this.rows.length; i++){
  14860. ret.push (this.rows[i].obj[value]);
  14861. }
  14862. } else {
  14863. for (var j = 0; j < this.rows.length; j++){
  14864. ret.push (this.rows[j].arr[value]);
  14865. }
  14866. }
  14867. return ret;
  14868. };
  14869. /**
  14870. * Removes all rows from a Table. While all rows are removed,
  14871. * columns and column titles are maintained.
  14872. *
  14873. * @method clearRows
  14874. *
  14875. * @example
  14876. * <div class="norender">
  14877. * <code>
  14878. * // Given the CSV file "mammals.csv"
  14879. * // in the project's "assets" folder:
  14880. * //
  14881. * // id,species,name
  14882. * // 0,Capra hircus,Goat
  14883. * // 1,Panthera pardus,Leopard
  14884. * // 2,Equus zebra,Zebra
  14885. *
  14886. * var table;
  14887. *
  14888. * function preload() {
  14889. * //my table is comma separated value "csv"
  14890. * //and has a header specifying the columns labels
  14891. * table = loadTable("assets/mammals.csv", "csv", "header");
  14892. * }
  14893. *
  14894. * function setup() {
  14895. * table.clearRows();
  14896. * print(table.getRowCount() + " total rows in table");
  14897. * print(table.getColumnCount() + " total columns in table");
  14898. * }
  14899. * </code>
  14900. * </div>
  14901. */
  14902. p5.Table.prototype.clearRows = function() {
  14903. delete this.rows;
  14904. this.rows = [];
  14905. };
  14906. /**
  14907. * Use addColumn() to add a new column to a Table object.
  14908. * Typically, you will want to specify a title, so the column
  14909. * may be easily referenced later by name. (If no title is
  14910. * specified, the new column's title will be null.)
  14911. *
  14912. * @method addColumn
  14913. * @param {String} [title] title of the given column
  14914. *
  14915. * @example
  14916. * <div class="norender">
  14917. * <code>
  14918. * // Given the CSV file "mammals.csv"
  14919. * // in the project's "assets" folder:
  14920. * //
  14921. * // id,species,name
  14922. * // 0,Capra hircus,Goat
  14923. * // 1,Panthera pardus,Leopard
  14924. * // 2,Equus zebra,Zebra
  14925. *
  14926. * var table;
  14927. *
  14928. * function preload() {
  14929. * //my table is comma separated value "csv"
  14930. * //and has a header specifying the columns labels
  14931. * table = loadTable("assets/mammals.csv", "csv", "header");
  14932. * }
  14933. *
  14934. * function setup() {
  14935. * table.addColumn("carnivore");
  14936. * table.set(0, "carnivore", "no");
  14937. * table.set(1, "carnivore", "yes");
  14938. * table.set(2, "carnivore", "no");
  14939. *
  14940. * //print the results
  14941. * for (var r = 0; r < table.getRowCount(); r++)
  14942. * for (var c = 0; c < table.getColumnCount(); c++)
  14943. * print(table.getString(r, c));
  14944. * }
  14945. * </code>
  14946. * </div>
  14947. */
  14948. p5.Table.prototype.addColumn = function(title) {
  14949. var t = title || null;
  14950. this.columns.push(t);
  14951. };
  14952. /**
  14953. * Returns the total number of columns in a Table.
  14954. *
  14955. * @return {Number} Number of columns in this table
  14956. */
  14957. p5.Table.prototype.getColumnCount = function() {
  14958. return this.columns.length;
  14959. };
  14960. /**
  14961. * Returns the total number of rows in a Table.
  14962. *
  14963. * @method getRowCount
  14964. * @return {Number} Number of rows in this table
  14965. */
  14966. p5.Table.prototype.getRowCount = function() {
  14967. return this.rows.length;
  14968. };
  14969. /**
  14970. * <p>Removes any of the specified characters (or "tokens").</p>
  14971. *
  14972. * <p>If no column is specified, then the values in all columns and
  14973. * rows are processed. A specific column may be referenced by
  14974. * either its ID or title.</p>
  14975. *
  14976. * @method removeTokens
  14977. * @param {String} chars String listing characters to be removed
  14978. * @param {String|Number} [column] Column ID (number)
  14979. * or name (string)
  14980. */
  14981. p5.Table.prototype.removeTokens = function(chars, column) {
  14982. var escape= function(s) {
  14983. return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
  14984. };
  14985. var charArray = [];
  14986. for (var i = 0; i < chars.length; i++) {
  14987. charArray.push( escape( chars.charAt(i) ) );
  14988. }
  14989. var regex = new RegExp(charArray.join('|'), 'g');
  14990. if (typeof(column) === 'undefined'){
  14991. for (var c = 0; c < this.columns.length; c++) {
  14992. for (var d = 0; d < this.rows.length; d++) {
  14993. var s = this.rows[d].arr[c];
  14994. s = s.replace(regex, '');
  14995. this.rows[d].arr[c] = s;
  14996. this.rows[d].obj[this.columns[c]] = s;
  14997. }
  14998. }
  14999. }
  15000. else if (typeof(column) === 'string'){
  15001. for (var j = 0; j < this.rows.length; j++) {
  15002. var val = this.rows[j].obj[column];
  15003. val = val.replace(regex, '');
  15004. this.rows[j].obj[column] = val;
  15005. var pos = this.columns.indexOf(column);
  15006. this.rows[j].arr[pos] = val;
  15007. }
  15008. }
  15009. else {
  15010. for (var k = 0; k < this.rows.length; k++) {
  15011. var str = this.rows[k].arr[column];
  15012. str = str.replace(regex, '');
  15013. this.rows[k].arr[column] = str;
  15014. this.rows[k].obj[this.columns[column]] = str;
  15015. }
  15016. }
  15017. };
  15018. /**
  15019. * Trims leading and trailing whitespace, such as spaces and tabs,
  15020. * from String table values. If no column is specified, then the
  15021. * values in all columns and rows are trimmed. A specific column
  15022. * may be referenced by either its ID or title.
  15023. *
  15024. * @method trim
  15025. * @param {String|Number} column Column ID (number)
  15026. * or name (string)
  15027. */
  15028. p5.Table.prototype.trim = function(column) {
  15029. var regex = new RegExp( (' '), 'g');
  15030. if (typeof(column) === 'undefined'){
  15031. for (var c = 0; c < this.columns.length; c++) {
  15032. for (var d = 0; d < this.rows.length; d++) {
  15033. var s = this.rows[d].arr[c];
  15034. s = s.replace(regex, '');
  15035. this.rows[d].arr[c] = s;
  15036. this.rows[d].obj[this.columns[c]] = s;
  15037. }
  15038. }
  15039. }
  15040. else if (typeof(column) === 'string'){
  15041. for (var j = 0; j < this.rows.length; j++) {
  15042. var val = this.rows[j].obj[column];
  15043. val = val.replace(regex, '');
  15044. this.rows[j].obj[column] = val;
  15045. var pos = this.columns.indexOf(column);
  15046. this.rows[j].arr[pos] = val;
  15047. }
  15048. }
  15049. else {
  15050. for (var k = 0; k < this.rows.length; k++) {
  15051. var str = this.rows[k].arr[column];
  15052. str = str.replace(regex, '');
  15053. this.rows[k].arr[column] = str;
  15054. this.rows[k].obj[this.columns[column]] = str;
  15055. }
  15056. }
  15057. };
  15058. /**
  15059. * Use removeColumn() to remove an existing column from a Table
  15060. * object. The column to be removed may be identified by either
  15061. * its title (a String) or its index value (an int).
  15062. * removeColumn(0) would remove the first column, removeColumn(1)
  15063. * would remove the second column, and so on.
  15064. *
  15065. * @method removeColumn
  15066. * @param {String|Number} column columnName (string) or ID (number)
  15067. *
  15068. * @example
  15069. * <div class="norender">
  15070. * <code>
  15071. * // Given the CSV file "mammals.csv"
  15072. * // in the project's "assets" folder:
  15073. * //
  15074. * // id,species,name
  15075. * // 0,Capra hircus,Goat
  15076. * // 1,Panthera pardus,Leopard
  15077. * // 2,Equus zebra,Zebra
  15078. *
  15079. * var table;
  15080. *
  15081. * function preload() {
  15082. * //my table is comma separated value "csv"
  15083. * //and has a header specifying the columns labels
  15084. * table = loadTable("assets/mammals.csv", "csv", "header");
  15085. * }
  15086. *
  15087. * function setup() {
  15088. * table.removeColumn("id");
  15089. * print(table.getColumnCount());
  15090. * }
  15091. * </code>
  15092. * </div>
  15093. */
  15094. p5.Table.prototype.removeColumn = function(c) {
  15095. var cString;
  15096. var cNumber;
  15097. if (typeof(c) === 'string') {
  15098. // find the position of c in the columns
  15099. cString = c;
  15100. cNumber = this.columns.indexOf(c);
  15101. console.log('string');
  15102. }
  15103. else{
  15104. cNumber = c;
  15105. cString = this.columns[c];
  15106. }
  15107. var chunk = this.columns.splice(cNumber+1, this.columns.length);
  15108. this.columns.pop();
  15109. this.columns = this.columns.concat(chunk);
  15110. for (var i = 0; i < this.rows.length; i++){
  15111. var tempR = this.rows[i].arr;
  15112. var chip = tempR.splice(cNumber+1, tempR.length);
  15113. tempR.pop();
  15114. this.rows[i].arr = tempR.concat(chip);
  15115. delete this.rows[i].obj[cString];
  15116. }
  15117. };
  15118. /**
  15119. * Stores a value in the Table's specified row and column.
  15120. * The row is specified by its ID, while the column may be specified
  15121. * by either its ID or title.
  15122. *
  15123. * @method set
  15124. * @param {String|Number} column column ID (Number)
  15125. * or title (String)
  15126. * @param {String|Number} value value to assign
  15127. *
  15128. * @example
  15129. * <div class="norender">
  15130. * <code>
  15131. * // Given the CSV file "mammals.csv"
  15132. * // in the project's "assets" folder:
  15133. * //
  15134. * // id,species,name
  15135. * // 0,Capra hircus,Goat
  15136. * // 1,Panthera pardus,Leopard
  15137. * // 2,Equus zebra,Zebra
  15138. *
  15139. * var table;
  15140. *
  15141. * function preload() {
  15142. * //my table is comma separated value "csv"
  15143. * //and has a header specifying the columns labels
  15144. * table = loadTable("assets/mammals.csv", "csv", "header");
  15145. * }
  15146. *
  15147. * function setup() {
  15148. * table.set(0, "species", "Canis Lupus");
  15149. * table.set(0, "name", "Wolf");
  15150. *
  15151. * //print the results
  15152. * for (var r = 0; r < table.getRowCount(); r++)
  15153. * for (var c = 0; c < table.getColumnCount(); c++)
  15154. * print(table.getString(r, c));
  15155. * }
  15156. * </code>
  15157. * </div>
  15158. */
  15159. p5.Table.prototype.set = function(row, column, value) {
  15160. this.rows[row].set(column, value);
  15161. };
  15162. /**
  15163. * Stores a Float value in the Table's specified row and column.
  15164. * The row is specified by its ID, while the column may be specified
  15165. * by either its ID or title.
  15166. *
  15167. * @method setNum
  15168. * @param {Number} row row ID
  15169. * @param {String|Number} column column ID (Number)
  15170. * or title (String)
  15171. * @param {Number} value value to assign
  15172. *
  15173. * @example
  15174. * <div class="norender">
  15175. * <code>
  15176. * // Given the CSV file "mammals.csv"
  15177. * // in the project's "assets" folder:
  15178. * //
  15179. * // id,species,name
  15180. * // 0,Capra hircus,Goat
  15181. * // 1,Panthera pardus,Leopard
  15182. * // 2,Equus zebra,Zebra
  15183. *
  15184. * var table;
  15185. *
  15186. * function preload() {
  15187. * //my table is comma separated value "csv"
  15188. * //and has a header specifying the columns labels
  15189. * table = loadTable("assets/mammals.csv", "csv", "header");
  15190. * }
  15191. *
  15192. * function setup() {
  15193. * table.setNum(1, "id", 1);
  15194. *
  15195. * print(table.getColumn(0));
  15196. * //["0", 1, "2"]
  15197. * }
  15198. * </code>
  15199. * </div>
  15200. */
  15201. p5.Table.prototype.setNum = function(row, column, value){
  15202. this.rows[row].set(column, value);
  15203. };
  15204. /**
  15205. * Stores a String value in the Table's specified row and column.
  15206. * The row is specified by its ID, while the column may be specified
  15207. * by either its ID or title.
  15208. *
  15209. * @method setString
  15210. * @param {Number} row row ID
  15211. * @param {String|Number} column column ID (Number)
  15212. * or title (String)
  15213. * @param {String} value value to assign
  15214. */
  15215. p5.Table.prototype.setString = function(row, column, value){
  15216. this.rows[row].set(column, value);
  15217. };
  15218. /**
  15219. * Retrieves a value from the Table's specified row and column.
  15220. * The row is specified by its ID, while the column may be specified by
  15221. * either its ID or title.
  15222. *
  15223. * @method get
  15224. * @param {Number} row row ID
  15225. * @param {String|Number} column columnName (string) or
  15226. * ID (number)
  15227. * @return {String|Number}
  15228. *
  15229. * @example
  15230. * <div class="norender">
  15231. * <code>
  15232. * // Given the CSV file "mammals.csv"
  15233. * // in the project's "assets" folder:
  15234. * //
  15235. * // id,species,name
  15236. * // 0,Capra hircus,Goat
  15237. * // 1,Panthera pardus,Leopard
  15238. * // 2,Equus zebra,Zebra
  15239. *
  15240. * var table;
  15241. *
  15242. * function preload() {
  15243. * //my table is comma separated value "csv"
  15244. * //and has a header specifying the columns labels
  15245. * table = loadTable("assets/mammals.csv", "csv", "header");
  15246. * }
  15247. *
  15248. * function setup() {
  15249. * print(table.get(0, 1));
  15250. * //Capra hircus
  15251. * print(table.get(0, "species"));
  15252. * //Capra hircus
  15253. * }
  15254. * </code>
  15255. * </div>
  15256. */
  15257. p5.Table.prototype.get = function(row, column) {
  15258. return this.rows[row].get(column);
  15259. };
  15260. /**
  15261. * Retrieves a Float value from the Table's specified row and column.
  15262. * The row is specified by its ID, while the column may be specified by
  15263. * either its ID or title.
  15264. *
  15265. * @method getNum
  15266. * @param {Number} row row ID
  15267. * @param {String|Number} column columnName (string) or
  15268. * ID (number)
  15269. * @return {Number}
  15270. *
  15271. * @example
  15272. * <div class="norender">
  15273. * <code>
  15274. * // Given the CSV file "mammals.csv"
  15275. * // in the project's "assets" folder:
  15276. * //
  15277. * // id,species,name
  15278. * // 0,Capra hircus,Goat
  15279. * // 1,Panthera pardus,Leopard
  15280. * // 2,Equus zebra,Zebra
  15281. *
  15282. * var table;
  15283. *
  15284. * function preload() {
  15285. * //my table is comma separated value "csv"
  15286. * //and has a header specifying the columns labels
  15287. * table = loadTable("assets/mammals.csv", "csv", "header");
  15288. * }
  15289. *
  15290. * function setup() {
  15291. * print(table.getNum(1, 0) + 100);
  15292. * //id 1 + 100 = 101
  15293. * }
  15294. * </code>
  15295. * </div>
  15296. */
  15297. p5.Table.prototype.getNum = function(row, column) {
  15298. return this.rows[row].getNum(column);
  15299. };
  15300. /**
  15301. * Retrieves a String value from the Table's specified row and column.
  15302. * The row is specified by its ID, while the column may be specified by
  15303. * either its ID or title.
  15304. *
  15305. * @method getString
  15306. * @param {Number} row row ID
  15307. * @param {String|Number} column columnName (string) or
  15308. * ID (number)
  15309. * @return {String}
  15310. *
  15311. * @example
  15312. * <div class="norender">
  15313. * <code>
  15314. * // Given the CSV file "mammals.csv"
  15315. * // in the project's "assets" folder:
  15316. * //
  15317. * // id,species,name
  15318. * // 0,Capra hircus,Goat
  15319. * // 1,Panthera pardus,Leopard
  15320. * // 2,Equus zebra,Zebra
  15321. *
  15322. * var table;
  15323. *
  15324. * function preload() {
  15325. * //my table is comma separated value "csv"
  15326. * //and has a header specifying the columns labels
  15327. * table = loadTable("assets/mammals.csv", "csv", "header");
  15328. * }
  15329. *
  15330. * function setup() {
  15331. * var tableArray = table.getArray();
  15332. *
  15333. * //output each row as array
  15334. * for (var i = 0; i < tableArray.length; i++)
  15335. * print(tableArray[i]);
  15336. * }
  15337. * </code>
  15338. * </div>
  15339. */
  15340. p5.Table.prototype.getString = function(row, column) {
  15341. return this.rows[row].getString(column);
  15342. };
  15343. /**
  15344. * Retrieves all table data and returns as an object. If a column name is
  15345. * passed in, each row object will be stored with that attribute as its
  15346. * title.
  15347. *
  15348. * @method getObject
  15349. * @param {String} headerColumn Name of the column which should be used to
  15350. * title each row object (optional)
  15351. * @return {Object}
  15352. *
  15353. * @example
  15354. * <div class="norender">
  15355. * <code>
  15356. * // Given the CSV file "mammals.csv"
  15357. * // in the project's "assets" folder:
  15358. * //
  15359. * // id,species,name
  15360. * // 0,Capra hircus,Goat
  15361. * // 1,Panthera pardus,Leopard
  15362. * // 2,Equus zebra,Zebra
  15363. *
  15364. * var table;
  15365. *
  15366. * function preload() {
  15367. * //my table is comma separated value "csv"
  15368. * //and has a header specifying the columns labels
  15369. * table = loadTable("assets/mammals.csv", "csv", "header");
  15370. * }
  15371. *
  15372. * function setup() {
  15373. * var tableObject = table.getObject();
  15374. *
  15375. * print(tableObject);
  15376. * //outputs an object
  15377. * }
  15378. * </code>
  15379. * </div>
  15380. */
  15381. p5.Table.prototype.getObject = function (headerColumn) {
  15382. var tableObject = {};
  15383. var obj, cPos, index;
  15384. for(var i = 0; i < this.rows.length; i++) {
  15385. obj = this.rows[i].obj;
  15386. if (typeof(headerColumn) === 'string'){
  15387. cPos = this.columns.indexOf(headerColumn); // index of columnID
  15388. if (cPos >= 0) {
  15389. index = obj[headerColumn];
  15390. tableObject[index] = obj;
  15391. } else {
  15392. throw 'This table has no column named "' + headerColumn +'"';
  15393. }
  15394. } else {
  15395. tableObject[i] = this.rows[i].obj;
  15396. }
  15397. }
  15398. return tableObject;
  15399. };
  15400. /**
  15401. * Retrieves all table data and returns it as a multidimensional array.
  15402. *
  15403. * @method getArray
  15404. * @return {Array}
  15405. */
  15406. p5.Table.prototype.getArray = function () {
  15407. var tableArray = [];
  15408. for(var i = 0; i < this.rows.length; i++) {
  15409. tableArray.push(this.rows[i].arr);
  15410. }
  15411. return tableArray;
  15412. };
  15413. module.exports = p5.Table;
  15414. },{"../core/core":17}],41:[function(require,module,exports){
  15415. /**
  15416. * @module IO
  15417. * @submodule Table
  15418. * @requires core
  15419. */
  15420. 'use strict';
  15421. var p5 = require('../core/core');
  15422. /**
  15423. * A TableRow object represents a single row of data values,
  15424. * stored in columns, from a table.
  15425. *
  15426. * A Table Row contains both an ordered array, and an unordered
  15427. * JSON object.
  15428. *
  15429. * @class p5.TableRow
  15430. * @constructor
  15431. * @param {String} [str] optional: populate the row with a
  15432. * string of values, separated by the
  15433. * separator
  15434. * @param {String} [separator] comma separated values (csv) by default
  15435. */
  15436. p5.TableRow = function (str, separator) {
  15437. var arr = [];
  15438. var obj = {};
  15439. if (str){
  15440. separator = separator || ',';
  15441. arr = str.split(separator);
  15442. }
  15443. for (var i = 0; i < arr.length; i++){
  15444. var key = i;
  15445. var val = arr[i];
  15446. obj[key] = val;
  15447. }
  15448. this.arr = arr;
  15449. this.obj = obj;
  15450. this.table = null;
  15451. };
  15452. /**
  15453. * Stores a value in the TableRow's specified column.
  15454. * The column may be specified by either its ID or title.
  15455. *
  15456. * @method set
  15457. * @param {String|Number} column Column ID (Number)
  15458. * or Title (String)
  15459. * @param {String|Number} value The value to be stored
  15460. */
  15461. p5.TableRow.prototype.set = function(column, value) {
  15462. // if typeof column is string, use .obj
  15463. if (typeof(column) === 'string'){
  15464. var cPos = this.table.columns.indexOf(column); // index of columnID
  15465. if (cPos >= 0) {
  15466. this.obj[column] = value;
  15467. this.arr[cPos] = value;
  15468. }
  15469. else {
  15470. throw 'This table has no column named "' + column +'"';
  15471. }
  15472. }
  15473. // if typeof column is number, use .arr
  15474. else {
  15475. if (column < this.table.columns.length) {
  15476. this.arr[column] = value;
  15477. var cTitle = this.table.columns[column];
  15478. this.obj[cTitle] = value;
  15479. }
  15480. else {
  15481. throw 'Column #' + column + ' is out of the range of this table';
  15482. }
  15483. }
  15484. };
  15485. /**
  15486. * Stores a Float value in the TableRow's specified column.
  15487. * The column may be specified by either its ID or title.
  15488. *
  15489. * @method setNum
  15490. * @param {String|Number} column Column ID (Number)
  15491. * or Title (String)
  15492. * @param {Number} value The value to be stored
  15493. * as a Float
  15494. */
  15495. p5.TableRow.prototype.setNum = function(column, value){
  15496. var floatVal = parseFloat(value, 10);
  15497. this.set(column, floatVal);
  15498. };
  15499. /**
  15500. * Stores a String value in the TableRow's specified column.
  15501. * The column may be specified by either its ID or title.
  15502. *
  15503. * @method setString
  15504. * @param {String|Number} column Column ID (Number)
  15505. * or Title (String)
  15506. * @param {String} value The value to be stored
  15507. * as a String
  15508. */
  15509. p5.TableRow.prototype.setString = function(column, value){
  15510. var stringVal = value.toString();
  15511. this.set(column, stringVal);
  15512. };
  15513. /**
  15514. * Retrieves a value from the TableRow's specified column.
  15515. * The column may be specified by either its ID or title.
  15516. *
  15517. * @method get
  15518. * @param {String|Number} column columnName (string) or
  15519. * ID (number)
  15520. * @return {String|Number}
  15521. */
  15522. p5.TableRow.prototype.get = function(column) {
  15523. if (typeof(column) === 'string'){
  15524. return this.obj[column];
  15525. } else {
  15526. return this.arr[column];
  15527. }
  15528. };
  15529. /**
  15530. * Retrieves a Float value from the TableRow's specified
  15531. * column. The column may be specified by either its ID or
  15532. * title.
  15533. *
  15534. * @method getNum
  15535. * @param {String|Number} column columnName (string) or
  15536. * ID (number)
  15537. * @return {Number} Float Floating point number
  15538. */
  15539. p5.TableRow.prototype.getNum = function(column) {
  15540. var ret;
  15541. if (typeof(column) === 'string'){
  15542. ret = parseFloat(this.obj[column], 10);
  15543. } else {
  15544. ret = parseFloat(this.arr[column], 10);
  15545. }
  15546. if (ret.toString() === 'NaN') {
  15547. throw 'Error: ' + this.obj[column]+ ' is NaN (Not a Number)';
  15548. }
  15549. return ret;
  15550. };
  15551. /**
  15552. * Retrieves an String value from the TableRow's specified
  15553. * column. The column may be specified by either its ID or
  15554. * title.
  15555. *
  15556. * @method getString
  15557. * @param {String|Number} column columnName (string) or
  15558. * ID (number)
  15559. * @return {String} String
  15560. */
  15561. p5.TableRow.prototype.getString = function(column) {
  15562. if (typeof(column) === 'string'){
  15563. return this.obj[column].toString();
  15564. } else {
  15565. return this.arr[column].toString();
  15566. }
  15567. };
  15568. module.exports = p5.TableRow;
  15569. },{"../core/core":17}],42:[function(require,module,exports){
  15570. /**
  15571. * @module Math
  15572. * @submodule Calculation
  15573. * @for p5
  15574. * @requires core
  15575. */
  15576. 'use strict';
  15577. var p5 = require('../core/core');
  15578. /**
  15579. * Calculates the absolute value (magnitude) of a number. Maps to Math.abs().
  15580. * The absolute value of a number is always positive.
  15581. *
  15582. * @method abs
  15583. * @param {Number} n number to compute
  15584. * @return {Number} absolute value of given number
  15585. * @example
  15586. * <div class = "norender"><code>
  15587. * function setup() {
  15588. * var x = -3;
  15589. * var y = abs(x);
  15590. *
  15591. * print(x); // -3
  15592. * print(y); // 3
  15593. * }
  15594. * </div></code>
  15595. */
  15596. p5.prototype.abs = Math.abs;
  15597. /**
  15598. * Calculates the closest int value that is greater than or equal to the
  15599. * value of the parameter. Maps to Math.ceil(). For example, ceil(9.03)
  15600. * returns the value 10.
  15601. *
  15602. * @method ceil
  15603. * @param {Number} n number to round up
  15604. * @return {Number} rounded up number
  15605. * @example
  15606. * <div><code>
  15607. * function draw() {
  15608. * background(200);
  15609. * // map, mouseX between 0 and 5.
  15610. * var ax = map(mouseX, 0, 100, 0, 5);
  15611. * var ay = 66;
  15612. *
  15613. * //Get the ceiling of the mapped number.
  15614. * var bx = ceil(map(mouseX, 0, 100, 0,5));
  15615. * var by = 33;
  15616. *
  15617. * // Multiply the mapped numbers by 20 to more easily
  15618. * // see the changes.
  15619. * stroke(0);
  15620. * fill(0);
  15621. * line(0, ay, ax * 20, ay);
  15622. * line(0, by, bx * 20, by);
  15623. *
  15624. * // Reformat the float returned by map and draw it.
  15625. * noStroke();
  15626. * text(nfc(ax, 2,2), ax, ay - 5);
  15627. * text(nfc(bx,1,1), bx, by - 5);
  15628. * }
  15629. * </div></code>
  15630. */
  15631. p5.prototype.ceil = Math.ceil;
  15632. /**
  15633. * Constrains a value between a minimum and maximum value.
  15634. *
  15635. * @method constrain
  15636. * @param {Number} n number to constrain
  15637. * @param {Number} low minimum limit
  15638. * @param {Number} high maximum limit
  15639. * @return {Number} constrained number
  15640. * @example
  15641. * <div><code>
  15642. * function draw() {
  15643. * background(200);
  15644. *
  15645. * var leftWall = 25;
  15646. * var rightWall = 75;
  15647. *
  15648. * // xm is just the mouseX, while
  15649. * // xc is the mouseX, but constrained
  15650. * // between the leftWall and rightWall!
  15651. * var xm = mouseX;
  15652. * var xc = constrain(mouseX, leftWall, rightWall);
  15653. *
  15654. * // Draw the walls.
  15655. * stroke(150);
  15656. * line(leftWall, 0, leftWall, height);
  15657. * line(rightWall, 0, rightWall, height);
  15658. *
  15659. * // Draw xm and xc as circles.
  15660. * noStroke();
  15661. * fill(150);
  15662. * ellipse(xm, 33, 9,9); // Not Constrained
  15663. * fill(0);
  15664. * ellipse(xc, 66, 9,9); // Constrained
  15665. * }
  15666. * </div></code>
  15667. */
  15668. p5.prototype.constrain = function(n, low, high) {
  15669. return Math.max(Math.min(n, high), low);
  15670. };
  15671. /**
  15672. * Calculates the distance between two points.
  15673. *
  15674. * @method dist
  15675. * @param {Number} x1 x-coordinate of the first point
  15676. * @param {Number} y1 y-coordinate of the first point
  15677. * @param {Number} x2 x-coordinate of the second point
  15678. * @param {Number} y2 y-coordinate of the second point
  15679. * @return {Number} distance between the two points
  15680. * @example
  15681. * <div><code>
  15682. * // Move your mouse inside the canvas to see the
  15683. * // change in distance between two points!
  15684. * function draw() {
  15685. * background(200);
  15686. * fill(0);
  15687. *
  15688. * var x1 = 10;
  15689. * var y1 = 90;
  15690. * var x2 = mouseX;
  15691. * var y2 = mouseY;
  15692. *
  15693. * line(x1, y1, x2, y2);
  15694. * ellipse(x1, y1, 7, 7);
  15695. * ellipse(x2, y2, 7, 7);
  15696. *
  15697. * // d is the length of the line
  15698. * // the distance from point 1 to point 2.
  15699. * var d = int(dist(x1, y1, x2, y2));
  15700. *
  15701. * // Let's write d along the line we are drawing!
  15702. * push();
  15703. * translate( (x1+x2)/2, (y1+y2)/2 );
  15704. * rotate( atan2(y2-y1,x2-x1) );
  15705. * text(nfc(d,1,1), 0, -5);
  15706. * pop();
  15707. * // Fancy!
  15708. * }
  15709. * </div></code>
  15710. */
  15711. p5.prototype.dist = function(x1, y1, x2, y2) {
  15712. return Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
  15713. };
  15714. /**
  15715. * Returns Euler's number e (2.71828...) raised to the power of the n
  15716. * parameter. Maps to Math.exp().
  15717. *
  15718. * @method exp
  15719. * @param {Number} n exponent to raise
  15720. * @return {Number} e^n
  15721. * @example
  15722. * <div><code>
  15723. * function draw() {
  15724. * background(200);
  15725. *
  15726. * // Compute the exp() function with a value between 0 and 2
  15727. * var xValue = map(mouseX, 0, width, 0, 2);
  15728. * var yValue = exp(xValue);
  15729. *
  15730. * var y = map(yValue, 0, 8, height, 0);
  15731. *
  15732. * var legend = "exp (" + nfc(xValue, 3) +")\n= " + nf(yValue, 1, 4);
  15733. * stroke(150);
  15734. * line(mouseX, y, mouseX, height);
  15735. * fill(0);
  15736. * text(legend, 5, 15);
  15737. * noStroke();
  15738. * ellipse (mouseX,y, 7, 7);
  15739. *
  15740. * // Draw the exp(x) curve,
  15741. * // over the domain of x from 0 to 2
  15742. * noFill();
  15743. * stroke(0);
  15744. * beginShape();
  15745. * for (var x = 0; x < width; x++) {
  15746. * xValue = map(x, 0, width, 0, 2);
  15747. * yValue = exp(xValue);
  15748. * y = map(yValue, 0, 8, height, 0);
  15749. * vertex(x, y);
  15750. * }
  15751. *
  15752. * endShape();
  15753. * line(0, 0, 0, height);
  15754. * line(0, height-1, width, height-1);
  15755. * }
  15756. * </div></code>
  15757. */
  15758. p5.prototype.exp = Math.exp;
  15759. /**
  15760. * Calculates the closest int value that is less than or equal to the
  15761. * value of the parameter. Maps to Math.floor().
  15762. *
  15763. * @method floor
  15764. * @param {Number} n number to round down
  15765. * @return {Number} rounded down number
  15766. * @example
  15767. * <div><code>
  15768. * function draw() {
  15769. * background(200);
  15770. * //map, mouseX between 0 and 5.
  15771. * var ax = map(mouseX, 0, 100, 0, 5);
  15772. * var ay = 66;
  15773. *
  15774. * //Get the floor of the mapped number.
  15775. * var bx = floor(map(mouseX, 0, 100, 0,5));
  15776. * var by = 33;
  15777. *
  15778. * // Multiply the mapped numbers by 20 to more easily
  15779. * // see the changes.
  15780. * stroke(0);
  15781. * fill(0);
  15782. * line(0, ay, ax * 20, ay);
  15783. * line(0, by, bx * 20, by);
  15784. *
  15785. * // Reformat the float returned by map and draw it.
  15786. * noStroke();
  15787. * text(nfc(ax, 2,2), ax, ay - 5);
  15788. * text(nfc(bx,1,1), bx, by - 5);
  15789. * }
  15790. * </div></code>
  15791. */
  15792. p5.prototype.floor = Math.floor;
  15793. /**
  15794. * Calculates a number between two numbers at a specific increment. The amt
  15795. * parameter is the amount to interpolate between the two values where 0.0
  15796. * equal to the first point, 0.1 is very near the first point, 0.5 is
  15797. * half-way in between, etc. The lerp function is convenient for creating
  15798. * motion along a straight path and for drawing dotted lines.
  15799. *
  15800. * @method lerp
  15801. * @param {Number} start first value
  15802. * @param {Number} stop second value
  15803. * @param {Number} amt number between 0.0 and 1.0
  15804. * @return {Number} lerped value
  15805. * @example
  15806. * <div><code>
  15807. * function setup() {
  15808. * background(200);
  15809. * var a = 20;
  15810. * var b = 80;
  15811. * var c = lerp(a,b, .2);
  15812. * var d = lerp(a,b, .5);
  15813. * var e = lerp(a,b, .8);
  15814. *
  15815. * var y = 50
  15816. *
  15817. * strokeWeight(5);
  15818. * stroke(0); // Draw the original points in black
  15819. * point(a, y);
  15820. * int(b, y);
  15821. *
  15822. * stroke(100); // Draw the lerp points in gray
  15823. * point(c, y);
  15824. * point(d, y);
  15825. * point(e, y);
  15826. * }
  15827. * </div></code>
  15828. */
  15829. p5.prototype.lerp = function(start, stop, amt) {
  15830. return amt*(stop-start)+start;
  15831. };
  15832. /**
  15833. * Calculates the natural logarithm (the base-e logarithm) of a number. This
  15834. * function expects the n parameter to be a value greater than 0.0. Maps to
  15835. * Math.log().
  15836. *
  15837. * @method log
  15838. * @param {Number} n number greater than 0
  15839. * @return {Number} natural logarithm of n
  15840. * @example
  15841. * <div><code>
  15842. * function draw() {
  15843. * background(200);
  15844. * var maxX = 2.8;
  15845. * var maxY = 1.5;
  15846. *
  15847. * // Compute the natural log of a value between 0 and maxX
  15848. * var xValue = map(mouseX, 0, width, 0, maxX);
  15849. * if (xValue > 0) { // Cannot take the log of a negative number.
  15850. * var yValue = log(xValue);
  15851. * var y = map(yValue, -maxY, maxY, height, 0);
  15852. *
  15853. * // Display the calculation occurring.
  15854. * var legend = "log(" + nf(xValue, 1, 2) + ")\n= " + nf(yValue, 1, 3);
  15855. * stroke(150);
  15856. * line(mouseX, y, mouseX, height);
  15857. * fill(0);
  15858. * text (legend, 5, 15);
  15859. * noStroke();
  15860. * ellipse (mouseX, y, 7, 7);
  15861. * }
  15862. *
  15863. * // Draw the log(x) curve,
  15864. * // over the domain of x from 0 to maxX
  15865. * noFill();
  15866. * stroke(0);
  15867. * beginShape();
  15868. * for(var x=0; x<width; x++) {
  15869. * xValue = map(x, 0, width, 0, maxX);
  15870. * yValue = log(xValue);
  15871. * y = map(yValue, -maxY, maxY, height, 0);
  15872. * vertex(x, y);
  15873. * }
  15874. * endShape();
  15875. * line(0,0,0,height);
  15876. * line(0,height/2,width, height/2);
  15877. * }
  15878. * </div></code>
  15879. */
  15880. p5.prototype.log = Math.log;
  15881. /**
  15882. * Calculates the magnitude (or length) of a vector. A vector is a direction
  15883. * in space commonly used in computer graphics and linear algebra. Because it
  15884. * has no "start" position, the magnitude of a vector can be thought of as
  15885. * the distance from the coordinate 0,0 to its x,y value. Therefore, mag() is
  15886. * a shortcut for writing dist(0, 0, x, y).
  15887. *
  15888. * @method mag
  15889. * @param {Number} a first value
  15890. * @param {Number} b second value
  15891. * @return {Number} magnitude of vector from (0,0) to (a,b)
  15892. * @example
  15893. * <div><code>
  15894. * function setup() {
  15895. * var x1 = 20;
  15896. * var x2 = 80;
  15897. * var y1 = 30;
  15898. * var y2 = 70;
  15899. *
  15900. * line(0, 0, x1, y1);
  15901. * print(mag(x1, y1)); // Prints "36.05551"
  15902. * line(0, 0, x2, y1);
  15903. * print(mag(x2, y1)); // Prints "85.44004"
  15904. * line(0, 0, x1, y2);
  15905. * print(mag(x1, y2)); // Prints "72.8011"
  15906. * line(0, 0, x2, y2);
  15907. * print(mag(x2, y2)); // Prints "106.30146"
  15908. * }
  15909. * </div></code>
  15910. */
  15911. p5.prototype.mag = function(x, y) {
  15912. return Math.sqrt(x*x+y*y);
  15913. };
  15914. /**
  15915. * Re-maps a number from one range to another.
  15916. * In the first example above, the number 25 is converted from a value in the
  15917. * range of 0 to 100 into a value that ranges from the left edge of the
  15918. * window (0) to the right edge (width).
  15919. *
  15920. * @method map
  15921. * @param {Number} value the incoming value to be converted
  15922. * @param {Number} start1 lower bound of the value's current range
  15923. * @param {Number} stop1 upper bound of the value's current range
  15924. * @param {Number} start2 lower bound of the value's target range
  15925. * @param {Number} stop upper bound of the value's target range
  15926. * @return {Number} remapped number
  15927. * @example
  15928. * <div><code>
  15929. * createCanvas(200, 200);
  15930. * var value = 25;
  15931. * var m = map(value, 0, 100, 0, width);
  15932. * ellipse(m, 200, 10, 10);
  15933. * </code></div>
  15934. *
  15935. * <div><code>
  15936. * function setup() {
  15937. * createCanvs(200, 200);
  15938. * noStroke();
  15939. * }
  15940. *
  15941. * function draw() {
  15942. * background(204);
  15943. * var x1 = map(mouseX, 0, width, 50, 150);
  15944. * ellipse(x1, 75, 50, 50);
  15945. * var x2 = map(mouseX, 0, width, 0, 200);
  15946. * ellipse(x2, 125, 50, 50);
  15947. * }
  15948. * </div></code>
  15949. */
  15950. p5.prototype.map = function(n, start1, stop1, start2, stop2) {
  15951. return ((n-start1)/(stop1-start1))*(stop2-start2)+start2;
  15952. };
  15953. /**
  15954. * Determines the largest value in a sequence of numbers, and then returns
  15955. * that value. max() accepts any number of Number parameters, or an Array
  15956. * of any length.
  15957. *
  15958. * @method max
  15959. * @param {Number|Array} n0 Numbers to compare
  15960. * @return {Number} maximum Number
  15961. * @example
  15962. * <div><code>
  15963. * function setup() {
  15964. * // Change the elements in the array and run the sketch
  15965. * // to show how max() works!
  15966. * numArray = new Array(2,1,5,4,8,9);
  15967. * fill(0);
  15968. * noStroke();
  15969. * text("Array Elements", 0, 10);
  15970. * // Draw all numbers in the array
  15971. * var spacing = 15;
  15972. * var elemsY = 25;
  15973. * for(var i = 0; i < numArray.length; i++) {
  15974. * text(numArray[i], i * spacing, elemsY);
  15975. * }
  15976. * maxX = 33;
  15977. * maxY = 80;
  15978. * // Draw the Maximum value in the array.
  15979. * textSize(32);
  15980. * text(max(numArray), maxX, maxY);
  15981. * }
  15982. * </div></code>
  15983. */
  15984. p5.prototype.max = function() {
  15985. if (arguments[0] instanceof Array) {
  15986. return Math.max.apply(null,arguments[0]);
  15987. } else {
  15988. return Math.max.apply(null,arguments);
  15989. }
  15990. };
  15991. /**
  15992. * Determines the smallest value in a sequence of numbers, and then returns
  15993. * that value. min() accepts any number of Number parameters, or an Array
  15994. * of any length.
  15995. *
  15996. * @method min
  15997. * @param {Number|Array} n0 Numbers to compare
  15998. * @return {Number} minimum Number
  15999. * @example
  16000. * <div><code>
  16001. * function setup() {
  16002. * // Change the elements in the array and run the sketch
  16003. * // to show how min() works!
  16004. * numArray = new Array(2,1,5,4,8,9);
  16005. * fill(0);
  16006. * noStroke();
  16007. * text("Array Elements", 0, 10);
  16008. * // Draw all numbers in the array
  16009. * var spacing = 15;
  16010. * var elemsY = 25;
  16011. * for(var i = 0; i < numArray.length; i++) {
  16012. * text(numArray[i], i * spacing, elemsY);
  16013. * }
  16014. * maxX = 33;
  16015. * maxY = 80;
  16016. * // Draw the Minimum value in the array.
  16017. * textSize(32);
  16018. * text(min(numArray), maxX, maxY);
  16019. * }
  16020. * </div></code>
  16021. */
  16022. p5.prototype.min = function() {
  16023. if (arguments[0] instanceof Array) {
  16024. return Math.min.apply(null,arguments[0]);
  16025. } else {
  16026. return Math.min.apply(null,arguments);
  16027. }
  16028. };
  16029. /**
  16030. * Normalizes a number from another range into a value between 0 and 1.
  16031. * Identical to map(value, low, high, 0, 1).
  16032. * Numbers outside of the range are not clamped to 0 and 1, because
  16033. * out-of-range values are often intentional and useful. (See the second
  16034. * example above.)
  16035. *
  16036. * @method norm
  16037. * @param {Number} value incoming value to be normalized
  16038. * @param {Number} start lower bound of the value's current range
  16039. * @param {Number} stop upper bound of the value's current range
  16040. * @return {Number} normalized number
  16041. * @example
  16042. * <div><code>
  16043. * function draw() {
  16044. * background(200);
  16045. * currentNum = mouseX;
  16046. * lowerBound = 0;
  16047. * upperBound = width; //100;
  16048. * normalized = norm(currentNum, lowerBound, upperBound);
  16049. * lineY = 70
  16050. * line(0, lineY, width, lineY);
  16051. * //Draw an ellipse mapped to the non-normalized value.
  16052. * noStroke();
  16053. * fill(50)
  16054. * var s = 7; // ellipse size
  16055. * ellipse(currentNum, lineY, s, s);
  16056. *
  16057. * // Draw the guide
  16058. * guideY = lineY + 15;
  16059. * text("0", 0, guideY);
  16060. * textAlign(RIGHT);
  16061. * text("100", width, guideY);
  16062. *
  16063. * // Draw the normalized value
  16064. * textAlign(LEFT);
  16065. * fill(0);
  16066. * textSize(32);
  16067. * normalY = 40;
  16068. * normalX = 20;
  16069. * text(normalized, normalX, normalY);
  16070. * }
  16071. * </div></code>
  16072. */
  16073. p5.prototype.norm = function(n, start, stop) {
  16074. return this.map(n, start, stop, 0, 1);
  16075. };
  16076. /**
  16077. * Facilitates exponential expressions. The pow() function is an efficient
  16078. * way of multiplying numbers by themselves (or their reciprocals) in large
  16079. * quantities. For example, pow(3, 5) is equivalent to the expression
  16080. * 3*3*3*3*3 and pow(3, -5) is equivalent to 1 / 3*3*3*3*3. Maps to
  16081. * Math.pow().
  16082. *
  16083. * @method pow
  16084. * @param {Number} n base of the exponential expression
  16085. * @param {Number} e power by which to raise the base
  16086. * @return {Number} n^e
  16087. * @example
  16088. * <div><code>
  16089. * function setup() {
  16090. * //Exponentially increase the size of an ellipse.
  16091. * eSize = 3; // Original Size
  16092. * eLoc = 10; // Original Location
  16093. *
  16094. * ellipse(eLoc, eLoc, eSize, eSize);
  16095. *
  16096. * ellipse(eLoc*2, eLoc*2, pow(eSize, 2), pow(eSize, 2));
  16097. *
  16098. * ellipse(eLoc*4, eLoc*4, pow(eSize, 3), pow(eSize, 3));
  16099. *
  16100. * ellipse(eLoc*8, eLoc*8, pow(eSize, 4), pow(eSize, 4));
  16101. * }
  16102. * </div></code>
  16103. */
  16104. p5.prototype.pow = Math.pow;
  16105. /**
  16106. * Calculates the integer closest to the n parameter. For example,
  16107. * round(133.8) returns the value 134. Maps to Math.round().
  16108. *
  16109. * @method round
  16110. * @param {Number} n number to round
  16111. * @return {Number} rounded number
  16112. * @example
  16113. * <div><code>
  16114. * function draw() {
  16115. * background(200);
  16116. * //map, mouseX between 0 and 5.
  16117. * var ax = map(mouseX, 0, 100, 0, 5);
  16118. * var ay = 66;
  16119. *
  16120. * // Round the mapped number.
  16121. * var bx = round(map(mouseX, 0, 100, 0,5));
  16122. * var by = 33;
  16123. *
  16124. * // Multiply the mapped numbers by 20 to more easily
  16125. * // see the changes.
  16126. * stroke(0);
  16127. * fill(0);
  16128. * line(0, ay, ax * 20, ay);
  16129. * line(0, by, bx * 20, by);
  16130. *
  16131. * // Reformat the float returned by map and draw it.
  16132. * noStroke();
  16133. * text(nfc(ax, 2,2), ax, ay - 5);
  16134. * text(nfc(bx,1,1), bx, by - 5);
  16135. * }
  16136. * </div></code>
  16137. */
  16138. p5.prototype.round = Math.round;
  16139. /**
  16140. * Squares a number (multiplies a number by itself). The result is always a
  16141. * positive number, as multiplying two negative numbers always yields a
  16142. * positive result. For example, -1 * -1 = 1.
  16143. *
  16144. * @method sq
  16145. * @param {Number} n number to square
  16146. * @return {Number} squared number
  16147. * @example
  16148. * <div><code>
  16149. * function draw() {
  16150. * background(200);
  16151. * eSize = 7;
  16152. * x1 = map(mouseX, 0, width, 0, 10);
  16153. * y1 = 80;
  16154. * x2 = sq(x1);
  16155. * y2 = 20;
  16156. *
  16157. * // Draw the non-squared.
  16158. * line(0, y1, width, y1);
  16159. * ellipse(x1, y1, eSize, eSize);
  16160. *
  16161. * // Draw the squared.
  16162. * line(0, y2, width, y2);
  16163. * ellipse(x2, y2, eSize, eSize);
  16164. *
  16165. * // Draw dividing line.
  16166. * stroke(100)
  16167. * line(0, height/2, width, height/2);
  16168. *
  16169. * // Draw text.
  16170. * noStroke();
  16171. * fill(0);
  16172. * text("x = " + x1, 0, y1 + spacing);
  16173. * text("sqrt(x) = " + x2, 0, y2 + spacing);
  16174. * }
  16175. * </div></code>
  16176. */
  16177. p5.prototype.sq = function(n) { return n*n; };
  16178. /**
  16179. * Calculates the square root of a number. The square root of a number is
  16180. * always positive, even though there may be a valid negative root. The
  16181. * square root s of number a is such that s*s = a. It is the opposite of
  16182. * squaring. Maps to Math.sqrt().
  16183. *
  16184. * @method sqrt
  16185. * @param {Number} n non-negative number to square root
  16186. * @return {Number} square root of number
  16187. * @example
  16188. * <div><code>
  16189. * function draw() {
  16190. * background(200);
  16191. * eSize = 7;
  16192. * x1 = mouseX;
  16193. * y1 = 80;
  16194. * x2 = sqrt(x1);
  16195. * y2 = 20;
  16196. *
  16197. * // Draw the non-squared.
  16198. * line(0, y1, width, y1);
  16199. * ellipse(x1, y1, eSize, eSize);
  16200. *
  16201. * // Draw the squared.
  16202. * line(0, y2, width, y2);
  16203. * ellipse(x2, y2, eSize, eSize);
  16204. *
  16205. * // Draw dividing line.
  16206. * stroke(100)
  16207. * line(0, height/2, width, height/2);
  16208. *
  16209. * // Draw text.
  16210. * noStroke();
  16211. * fill(0);
  16212. * var spacing = 15;
  16213. * text("x = " + x1, 0, y1 + spacing);
  16214. * text("sqrt(x) = " + x2, 0, y2 + spacing);
  16215. * }
  16216. * </div></code>
  16217. */
  16218. p5.prototype.sqrt = Math.sqrt;
  16219. module.exports = p5;
  16220. },{"../core/core":17}],43:[function(require,module,exports){
  16221. /**
  16222. * @module Math
  16223. * @submodule Math
  16224. * @for p5
  16225. * @requires core
  16226. */
  16227. 'use strict';
  16228. var p5 = require('../core/core');
  16229. /**
  16230. * Creates a new p5.Vector (the datatype for storing vectors). This provides a
  16231. * two or three dimensional vector, specifically a Euclidean (also known as
  16232. * geometric) vector. A vector is an entity that has both magnitude and
  16233. * direction.
  16234. *
  16235. * @method createVector
  16236. * @param {Number} [x] x component of the vector
  16237. * @param {Number} [y] y component of the vector
  16238. * @param {Number} [z] z component of the vector
  16239. */
  16240. p5.prototype.createVector = function (x, y, z) {
  16241. if (this instanceof p5) {
  16242. return new p5.Vector(this, arguments);
  16243. } else {
  16244. return new p5.Vector(x, y, z);
  16245. }
  16246. };
  16247. module.exports = p5;
  16248. },{"../core/core":17}],44:[function(require,module,exports){
  16249. //////////////////////////////////////////////////////////////
  16250. // http://mrl.nyu.edu/~perlin/noise/
  16251. // Adapting from PApplet.java
  16252. // which was adapted from toxi
  16253. // which was adapted from the german demo group farbrausch
  16254. // as used in their demo "art": http://www.farb-rausch.de/fr010src.zip
  16255. // someday we might consider using "improved noise"
  16256. // http://mrl.nyu.edu/~perlin/paper445.pdf
  16257. // See: https://github.com/shiffman/The-Nature-of-Code-Examples-p5.js/
  16258. // blob/master/introduction/Noise1D/noise.js
  16259. /**
  16260. * @module Math
  16261. * @submodule Noise
  16262. * @for p5
  16263. * @requires core
  16264. */
  16265. 'use strict';
  16266. var p5 = require('../core/core');
  16267. var PERLIN_YWRAPB = 4;
  16268. var PERLIN_YWRAP = 1<<PERLIN_YWRAPB;
  16269. var PERLIN_ZWRAPB = 8;
  16270. var PERLIN_ZWRAP = 1<<PERLIN_ZWRAPB;
  16271. var PERLIN_SIZE = 4095;
  16272. var perlin_octaves = 4; // default to medium smooth
  16273. var perlin_amp_falloff = 0.5; // 50% reduction/octave
  16274. // [toxi 031112]
  16275. // Maybe we should have a lookup table for speed
  16276. var SINCOS_PRECISION = 0.5;
  16277. var SINCOS_LENGTH = Math.floor(360 / SINCOS_PRECISION);
  16278. var sinLUT = new Array(SINCOS_LENGTH);
  16279. var cosLUT = new Array(SINCOS_LENGTH);
  16280. var DEG_TO_RAD = Math.PI/180.0;
  16281. for (var i = 0; i < SINCOS_LENGTH; i++) {
  16282. sinLUT[i] = Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
  16283. cosLUT[i] = Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
  16284. }
  16285. var perlin_PI = SINCOS_LENGTH;
  16286. perlin_PI >>= 1;
  16287. var perlin;
  16288. /**
  16289. * Returns the Perlin noise value at specified coordinates. Perlin noise is
  16290. * a random sequence generator producing a more natural ordered, harmonic
  16291. * succession of numbers compared to the standard <b>random()</b> function.
  16292. * It was invented by Ken Perlin in the 1980s and been used since in
  16293. * graphical applications to produce procedural textures, natural motion,
  16294. * shapes, terrains etc.<br /><br /> The main difference to the
  16295. * <b>random()</b> function is that Perlin noise is defined in an infinite
  16296. * n-dimensional space where each pair of coordinates corresponds to a
  16297. * fixed semi-random value (fixed only for the lifespan of the program).
  16298. * The resulting value will always be between 0.0 and 1.0. p5.js can
  16299. * compute 1D, 2D and 3D noise, depending on the number of coordinates
  16300. * given. The noise value can be animated by moving through the noise space
  16301. * as demonstrated in the example above. The 2nd and 3rd dimension can also
  16302. * be interpreted as time.<br /><br />The actual noise is structured
  16303. * similar to an audio signal, in respect to the function's use of
  16304. * frequencies. Similar to the concept of harmonics in physics, perlin
  16305. * noise is computed over several octaves which are added together for the
  16306. * final result. <br /><br />Another way to adjust the character of the
  16307. * resulting sequence is the scale of the input coordinates. As the
  16308. * function works within an infinite space the value of the coordinates
  16309. * doesn't matter as such, only the distance between successive coordinates
  16310. * does (eg. when using <b>noise()</b> within a loop). As a general rule
  16311. * the smaller the difference between coordinates, the smoother the
  16312. * resulting noise sequence will be. Steps of 0.005-0.03 work best for most
  16313. * applications, but this will differ depending on use.
  16314. *
  16315. *
  16316. * @method noise
  16317. * @param {Number} x x-coordinate in noise space
  16318. * @param {Number} y y-coordinate in noise space
  16319. * @param {Number} z z-coordinate in noise space
  16320. * @return {Number} Perlin noise value (between 0 and 1) at specified
  16321. * coordinates
  16322. * @example
  16323. * <div>
  16324. * <code>var xoff = 0.0;
  16325. *
  16326. * function draw() {
  16327. * background(204);
  16328. * xoff = xoff + .01;
  16329. * var n = noise(xoff) * width;
  16330. * line(n, 0, n, height);
  16331. * }
  16332. * </code>
  16333. * </div>
  16334. * <div>
  16335. * <code>var noiseScale=0.02;
  16336. *
  16337. * function draw() {
  16338. * background(0);
  16339. * for (var x=0; x < width; x++) {
  16340. * var noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);
  16341. * stroke(noiseVal*255);
  16342. * line(x, mouseY+noiseVal*80, x, height);
  16343. * }
  16344. * }
  16345. * </code>
  16346. * </div>
  16347. */
  16348. p5.prototype.noise = function(x,y,z) {
  16349. // is this legit?
  16350. y = y || 0;
  16351. z = z || 0;
  16352. if (perlin == null) {
  16353. // need to deal with seeding?
  16354. //if (perlinRandom == null) {
  16355. // perlinRandom = new Random();
  16356. //}
  16357. perlin = new Array(PERLIN_SIZE + 1);
  16358. for (var i = 0; i < PERLIN_SIZE + 1; i++) {
  16359. perlin[i] = Math.random();
  16360. }
  16361. }
  16362. if (x<0) { x=-x; }
  16363. if (y<0) { y=-y; }
  16364. if (z<0) { z=-z; }
  16365. var xi=Math.floor(x), yi=Math.floor(y), zi=Math.floor(z);
  16366. var xf = x - xi;
  16367. var yf = y - yi;
  16368. var zf = z - zi;
  16369. var rxf, ryf;
  16370. var r=0;
  16371. var ampl=0.5;
  16372. var n1,n2,n3;
  16373. // Is this right do just have this here?
  16374. var noise_fsc = function(i) {
  16375. // using cosine lookup table
  16376. return 0.5*(1.0-cosLUT[Math.floor(i*perlin_PI)%SINCOS_LENGTH]);
  16377. };
  16378. for (var o=0; o<perlin_octaves; o++) {
  16379. var of=xi+(yi<<PERLIN_YWRAPB)+(zi<<PERLIN_ZWRAPB);
  16380. rxf= noise_fsc(xf);
  16381. ryf= noise_fsc(yf);
  16382. n1 = perlin[of&PERLIN_SIZE];
  16383. n1 += rxf*(perlin[(of+1)&PERLIN_SIZE]-n1);
  16384. n2 = perlin[(of+PERLIN_YWRAP)&PERLIN_SIZE];
  16385. n2 += rxf*(perlin[(of+PERLIN_YWRAP+1)&PERLIN_SIZE]-n2);
  16386. n1 += ryf*(n2-n1);
  16387. of += PERLIN_ZWRAP;
  16388. n2 = perlin[of&PERLIN_SIZE];
  16389. n2 += rxf*(perlin[(of+1)&PERLIN_SIZE]-n2);
  16390. n3 = perlin[(of+PERLIN_YWRAP)&PERLIN_SIZE];
  16391. n3 += rxf*(perlin[(of+PERLIN_YWRAP+1)&PERLIN_SIZE]-n3);
  16392. n2 += ryf*(n3-n2);
  16393. n1 += noise_fsc(zf)*(n2-n1);
  16394. r += n1*ampl;
  16395. ampl *= perlin_amp_falloff;
  16396. xi<<=1;
  16397. xf*=2;
  16398. yi<<=1;
  16399. yf*=2;
  16400. zi<<=1;
  16401. zf*=2;
  16402. if (xf>=1.0) { xi++; xf--; }
  16403. if (yf>=1.0) { yi++; yf--; }
  16404. if (zf>=1.0) { zi++; zf--; }
  16405. }
  16406. return r;
  16407. };
  16408. // [toxi 040903]
  16409. // make perlin noise quality user controlled to allow
  16410. // for different levels of detail. lower values will produce
  16411. // smoother results as higher octaves are suppressed
  16412. /**
  16413. *
  16414. * Adjusts the character and level of detail produced by the Perlin noise
  16415. * function. Similar to harmonics in physics, noise is computed over
  16416. * several octaves. Lower octaves contribute more to the output signal and
  16417. * as such define the overall intensity of the noise, whereas higher octaves
  16418. * create finer grained details in the noise sequence. By default, noise is
  16419. * computed over 4 octaves with each octave contributing exactly half than
  16420. * its predecessor, starting at 50% strength for the 1st octave. This
  16421. * falloff amount can be changed by adding an additional function
  16422. * parameter. Eg. a falloff factor of 0.75 means each octave will now have
  16423. * 75% impact (25% less) of the previous lower octave. Any value between
  16424. * 0.0 and 1.0 is valid, however note that values greater than 0.5 might
  16425. * result in greater than 1.0 values returned by <b>noise()</b>.<br /><br
  16426. * />By changing these parameters, the signal created by the <b>noise()</b>
  16427. * function can be adapted to fit very specific needs and characteristics.
  16428. *
  16429. * @method noiseDetail
  16430. * @param {Number} lod number of octaves to be used by the noise
  16431. * @param {Number} falloff falloff factor for each octave
  16432. * @example
  16433. * <div>
  16434. * <code>
  16435. *
  16436. * var noiseVal;
  16437. * var noiseScale=0.02;
  16438. *
  16439. * function setup() {
  16440. * createCanvas(100,100);
  16441. * }
  16442. *
  16443. * function draw() {
  16444. * background(0);
  16445. * for (var y = 0; y < height; y++) {
  16446. * for (var x = 0; x < width/2; x++) {
  16447. * noiseDetail(2,0.2);
  16448. * noiseVal = noise((mouseX+x) * noiseScale,
  16449. * (mouseY+y) * noiseScale);
  16450. * stroke(noiseVal*255);
  16451. * point(x,y);
  16452. * noiseDetail(8,0.65);
  16453. * noiseVal = noise((mouseX + x + width/2) * noiseScale,
  16454. * (mouseY + y) * noiseScale);
  16455. * stroke(noiseVal*255);
  16456. * point(x + width/2, y);
  16457. * }
  16458. * }
  16459. * }
  16460. * </code>
  16461. * </div>
  16462. */
  16463. p5.prototype.noiseDetail = function(lod, falloff) {
  16464. if (lod>0) { perlin_octaves=lod; }
  16465. if (falloff>0) { perlin_amp_falloff=falloff; }
  16466. };
  16467. /**
  16468. * Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>
  16469. * produces different results each time the program is run. Set the
  16470. * <b>value</b> parameter to a constant to return the same pseudo-random
  16471. * numbers each time the software is run.
  16472. *
  16473. * @method noiseSeed
  16474. * @param {Number} seed the seed value
  16475. * @example
  16476. * <div>
  16477. * <code>var xoff = 0.0;
  16478. *
  16479. * function setup() {
  16480. * noiseSeed(99);
  16481. * stroke(0, 10);
  16482. * }
  16483. *
  16484. * function draw() {
  16485. * xoff = xoff + .01;
  16486. * var n = noise(xoff) * width;
  16487. * line(n, 0, n, height);
  16488. * }
  16489. * </code>
  16490. * </div>
  16491. */
  16492. p5.prototype.noiseSeed = function(seed) {
  16493. // Linear Congruential Generator
  16494. // Variant of a Lehman Generator
  16495. var lcg = (function() {
  16496. // Set to values from http://en.wikipedia.org/wiki/Numerical_Recipes
  16497. // m is basically chosen to be large (as it is the max period)
  16498. // and for its relationships to a and c
  16499. var m = 4294967296,
  16500. // a - 1 should be divisible by m's prime factors
  16501. a = 1664525,
  16502. // c and m should be co-prime
  16503. c = 1013904223,
  16504. seed, z;
  16505. return {
  16506. setSeed : function(val) {
  16507. // pick a random seed if val is undefined or null
  16508. // the >>> 0 casts the seed to an unsigned 32-bit integer
  16509. z = seed = (val == null ? Math.random() * m : val) >>> 0;
  16510. },
  16511. getSeed : function() {
  16512. return seed;
  16513. },
  16514. rand : function() {
  16515. // define the recurrence relationship
  16516. z = (a * z + c) % m;
  16517. // return a float in [0, 1)
  16518. // if z = m then z / m = 0 therefore (z % m) / m < 1 always
  16519. return z / m;
  16520. }
  16521. };
  16522. }());
  16523. lcg.setSeed(seed);
  16524. perlin = new Array(PERLIN_SIZE + 1);
  16525. for (var i = 0; i < PERLIN_SIZE + 1; i++) {
  16526. perlin[i] = lcg.rand();
  16527. }
  16528. };
  16529. module.exports = p5;
  16530. },{"../core/core":17}],45:[function(require,module,exports){
  16531. /**
  16532. * @module Math
  16533. * @submodule Math
  16534. * @requires constants
  16535. */
  16536. 'use strict';
  16537. var p5 = require('../core/core');
  16538. var polarGeometry = require('./polargeometry');
  16539. var constants = require('../core/constants');
  16540. /**
  16541. * A class to describe a two or three dimensional vector, specifically
  16542. * a Euclidean (also known as geometric) vector. A vector is an entity
  16543. * that has both magnitude and direction. The datatype, however, stores
  16544. * the components of the vector (x,y for 2D, and x,y,z for 3D). The magnitude
  16545. * and direction can be accessed via the methods mag() and heading(). In many
  16546. * of the p5.js examples, you will see p5.Vector used to describe a position,
  16547. * velocity, or acceleration. For example, if you consider a rectangle moving
  16548. * across the screen, at any given instant it has a position (a vector that
  16549. * points from the origin to its location), a velocity (the rate at which the
  16550. * object's position changes per time unit, expressed as a vector), and
  16551. * acceleration (the rate at which the object's velocity changes per time
  16552. * unit, expressed as a vector). Since vectors represent groupings of values,
  16553. * we cannot simply use traditional addition/multiplication/etc. Instead,
  16554. * we'll need to do some "vector" math, which is made easy by the methods
  16555. * inside the p5.Vector class.
  16556. *
  16557. * @class p5.Vector
  16558. * @constructor
  16559. * @param {Number} [x] x component of the vector
  16560. * @param {Number} [y] y component of the vector
  16561. * @param {Number} [z] z component of the vector
  16562. * @example
  16563. * <div>
  16564. * <code>
  16565. * var v1 = createVector(40, 50);
  16566. * var v2 = createVector(40, 50);
  16567. *
  16568. * ellipse(v1.x, v1.y, 50, 50);
  16569. * ellipse(v2.x, v2.y, 50, 50);
  16570. * v1.add(v2);
  16571. * ellipse(v1.x, v1.y, 50, 50);
  16572. * </code>
  16573. * </div>
  16574. */
  16575. p5.Vector = function() {
  16576. var x,y,z;
  16577. // This is how it comes in with createVector()
  16578. if(arguments[0] instanceof p5) {
  16579. // save reference to p5 if passed in
  16580. this.p5 = arguments[0];
  16581. x = arguments[1][0] || 0;
  16582. y = arguments[1][1] || 0;
  16583. z = arguments[1][2] || 0;
  16584. // This is what we'll get with new p5.Vector()
  16585. } else {
  16586. x = arguments[0] || 0;
  16587. y = arguments[1] || 0;
  16588. z = arguments[2] || 0;
  16589. }
  16590. /**
  16591. * The x component of the vector
  16592. * @property x
  16593. * @type {Number}
  16594. */
  16595. this.x = x;
  16596. /**
  16597. * The y component of the vector
  16598. * @property y
  16599. * @type {Number}
  16600. */
  16601. this.y = y;
  16602. /**
  16603. * The z component of the vector
  16604. * @property z
  16605. * @type {Number}
  16606. */
  16607. this.z = z;
  16608. };
  16609. /**
  16610. * Returns a string representation of a vector v by calling String(v)
  16611. * or v.toString(). This method is useful for logging vectors in the
  16612. * console.
  16613. * @method toString
  16614. * @example
  16615. * <div class = "norender"><code>
  16616. * function setup() {
  16617. * var v = createVector(20,30);
  16618. * print(String(v)); // prints "p5.Vector Object : [20, 30, 0]"
  16619. * }
  16620. * </div></code>
  16621. *
  16622. */
  16623. p5.Vector.prototype.toString = function p5VectorToString() {
  16624. return 'p5.Vector Object : ['+ this.x +', '+ this.y +', '+ this.z + ']';
  16625. };
  16626. /**
  16627. * Sets the x, y, and z component of the vector using two or three separate
  16628. * variables, the data from a p5.Vector, or the values from a float array.
  16629. * @method set
  16630. *
  16631. * @param {Number|p5.Vector|Array} [x] the x component of the vector or a
  16632. * p5.Vector or an Array
  16633. * @param {Number} [y] the y component of the vector
  16634. * @param {Number} [z] the z component of the vector
  16635. * @example
  16636. * <div class="norender">
  16637. * <code>
  16638. * function setup() {
  16639. * var v = createVector(1, 2, 3);
  16640. * v.set(4,5,6); // Sets vector to [4, 5, 6]
  16641. *
  16642. * var v1 = createVector(0, 0, 0);
  16643. * var arr = [1, 2, 3];
  16644. * v1.set(arr); // Sets vector to [1, 2, 3]
  16645. * }
  16646. * </code>
  16647. * </div>
  16648. */
  16649. p5.Vector.prototype.set = function (x, y, z) {
  16650. if (x instanceof p5.Vector) {
  16651. this.x = x.x || 0;
  16652. this.y = x.y || 0;
  16653. this.z = x.z || 0;
  16654. return this;
  16655. }
  16656. if (x instanceof Array) {
  16657. this.x = x[0] || 0;
  16658. this.y = x[1] || 0;
  16659. this.z = x[2] || 0;
  16660. return this;
  16661. }
  16662. this.x = x || 0;
  16663. this.y = y || 0;
  16664. this.z = z || 0;
  16665. return this;
  16666. };
  16667. /**
  16668. * Gets a copy of the vector, returns a p5.Vector object.
  16669. *
  16670. * @method copy
  16671. * @return {p5.Vector} the copy of the p5.Vector object
  16672. * @example
  16673. * <div class="norender">
  16674. * <code>
  16675. * var v1 = createVector(1, 2, 3);
  16676. * var v2 = v.copy();
  16677. * print(v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
  16678. * // Prints "true"
  16679. * </code>
  16680. * </div>
  16681. */
  16682. p5.Vector.prototype.copy = function () {
  16683. if (this.p5) {
  16684. return new p5.Vector(this.p5,[this.x, this.y, this.z]);
  16685. } else {
  16686. return new p5.Vector(this.x,this.y,this.z);
  16687. }
  16688. };
  16689. /**
  16690. * Adds x, y, and z components to a vector, adds one vector to another, or
  16691. * adds two independent vectors together. The version of the method that adds
  16692. * two vectors together is a static method and returns a p5.Vector, the others
  16693. * acts directly on the vector. See the examples for more context.
  16694. *
  16695. * @method add
  16696. * @chainable
  16697. * @param {Number|p5.Vector|Array} x the x component of the vector to be
  16698. * added or a p5.Vector or an Array
  16699. * @param {Number} [y] the y component of the vector to be
  16700. * added
  16701. * @param {Number} [z] the z component of the vector to be
  16702. * added
  16703. * @return {p5.Vector} the p5.Vector object.
  16704. * @example
  16705. * <div class="norender">
  16706. * <code>
  16707. * var v = createVector(1, 2, 3);
  16708. * v.add(4,5,6);
  16709. * // v's compnents are set to [5, 7, 9]
  16710. * </code>
  16711. * </div>
  16712. * <div class="norender">
  16713. * <code>
  16714. * // Static method
  16715. * var v1 = createVector(1, 2, 3);
  16716. * var v2 = createVector(2, 3, 4);
  16717. *
  16718. * var v3 = p5.Vector.add(v1, v2);
  16719. * // v3 has components [3, 5, 7]
  16720. * </code>
  16721. * </div>
  16722. */
  16723. p5.Vector.prototype.add = function (x, y, z) {
  16724. if (x instanceof p5.Vector) {
  16725. this.x += x.x || 0;
  16726. this.y += x.y || 0;
  16727. this.z += x.z || 0;
  16728. return this;
  16729. }
  16730. if (x instanceof Array) {
  16731. this.x += x[0] || 0;
  16732. this.y += x[1] || 0;
  16733. this.z += x[2] || 0;
  16734. return this;
  16735. }
  16736. this.x += x || 0;
  16737. this.y += y || 0;
  16738. this.z += z || 0;
  16739. return this;
  16740. };
  16741. /**
  16742. * Subtracts x, y, and z components from a vector, subtracts one vector from
  16743. * another, or subtracts two independent vectors. The version of the method
  16744. * that subtracts two vectors is a static method and returns a p5.Vector, the
  16745. * other acts directly on the vector. See the examples for more context.
  16746. *
  16747. * @method sub
  16748. * @chainable
  16749. * @param {Number|p5.Vector|Array} x the x component of the vector or a
  16750. * p5.Vector or an Array
  16751. * @param {Number} [y] the y component of the vector
  16752. * @param {Number} [z] the z component of the vector
  16753. * @return {p5.Vector} p5.Vector object.
  16754. * @example
  16755. * <div class="norender">
  16756. * <code>
  16757. * var v = createVector(4, 5, 6);
  16758. * v.sub(1, 1, 1);
  16759. * // v's compnents are set to [3, 4, 5]
  16760. * </code>
  16761. * </div>
  16762. *
  16763. * <div class="norender">
  16764. * <code>
  16765. * // Static method
  16766. * var v1 = createVector(2, 3, 4);
  16767. * var v2 = createVector(1, 2, 3);
  16768. *
  16769. * var v3 = p5.Vector.sub(v1, v2);
  16770. * // v3 has compnents [1, 1, 1]
  16771. * </code>
  16772. * </div>
  16773. */
  16774. p5.Vector.prototype.sub = function (x, y, z) {
  16775. if (x instanceof p5.Vector) {
  16776. this.x -= x.x || 0;
  16777. this.y -= x.y || 0;
  16778. this.z -= x.z || 0;
  16779. return this;
  16780. }
  16781. if (x instanceof Array) {
  16782. this.x -= x[0] || 0;
  16783. this.y -= x[1] || 0;
  16784. this.z -= x[2] || 0;
  16785. return this;
  16786. }
  16787. this.x -= x || 0;
  16788. this.y -= y || 0;
  16789. this.z -= z || 0;
  16790. return this;
  16791. };
  16792. /**
  16793. * Multiply the vector by a scalar. The static version of this method
  16794. * creates a new p5.Vector while the non static version acts on the vector
  16795. * directly. See the examples for more context.
  16796. *
  16797. * @method mult
  16798. * @chainable
  16799. * @param {Number} n the number to multiply with the vector
  16800. * @return {p5.Vector} a reference to the p5.Vector object (allow chaining)
  16801. * @example
  16802. * <div class="norender">
  16803. * <code>
  16804. * var v = createVector(1, 2, 3);
  16805. * v.mult(2);
  16806. * // v's compnents are set to [2, 4, 6]
  16807. * </code>
  16808. * </div>
  16809. *
  16810. * <div class="norender">
  16811. * <code>
  16812. * // Static method
  16813. * var v1 = createVector(1, 2, 3);
  16814. * var v2 = p5.Vector.mult(v1, 2);
  16815. * // v2 has compnents [2, 4, 6]
  16816. * </code>
  16817. * </div>
  16818. */
  16819. p5.Vector.prototype.mult = function (n) {
  16820. this.x *= n || 0;
  16821. this.y *= n || 0;
  16822. this.z *= n || 0;
  16823. return this;
  16824. };
  16825. /**
  16826. * Divide the vector by a scalar. The static version of this method creates a
  16827. * new p5.Vector while the non static version acts on the vector directly.
  16828. * See the examples for more context.
  16829. *
  16830. * @method div
  16831. * @chainable
  16832. * @param {number} n the number to divide the vector by
  16833. * @return {p5.Vector} a reference to the p5.Vector object (allow chaining)
  16834. * @example
  16835. * <div class="norender">
  16836. * <code>
  16837. * var v = createVector(6, 4, 2);
  16838. * v.div(2); //v's compnents are set to [3, 2, 1]
  16839. * </code>
  16840. * </div>
  16841. *
  16842. * <div class="norender">
  16843. * <code>
  16844. * // Static method
  16845. * var v1 = createVector(6, 4, 2);
  16846. * var v2 = p5.Vector.div(v, 2);
  16847. * // v2 has compnents [3, 2, 1]
  16848. * </code>
  16849. * </div>
  16850. */
  16851. p5.Vector.prototype.div = function (n) {
  16852. this.x /= n;
  16853. this.y /= n;
  16854. this.z /= n;
  16855. return this;
  16856. };
  16857. /**
  16858. * Calculates the magnitude (length) of the vector and returns the result as
  16859. * a float (this is simply the equation sqrt(x*x + y*y + z*z).)
  16860. *
  16861. * @method mag
  16862. * @return {Number} magnitude of the vector
  16863. * @example
  16864. * <div class="norender">
  16865. * <code>
  16866. * var v = createVector(20.0, 30.0, 40.0);
  16867. * var m = v.mag(10);
  16868. * print(m); // Prints "53.85164807134504"
  16869. * </code>
  16870. * </div>
  16871. */
  16872. p5.Vector.prototype.mag = function () {
  16873. return Math.sqrt(this.magSq());
  16874. };
  16875. /**
  16876. * Calculates the squared magnitude of the vector and returns the result
  16877. * as a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)
  16878. * Faster if the real length is not required in the
  16879. * case of comparing vectors, etc.
  16880. *
  16881. * @method magSq
  16882. * @return {number} squared magnitude of the vector
  16883. * @example
  16884. * <div class="norender">
  16885. * <code>
  16886. * // Static method
  16887. * var v1 = createVector(6, 4, 2);
  16888. * print(v1.magSq()); // Prints "56"
  16889. * </code>
  16890. * </div>
  16891. */
  16892. p5.Vector.prototype.magSq = function () {
  16893. var x = this.x, y = this.y, z = this.z;
  16894. return (x * x + y * y + z * z);
  16895. };
  16896. /**
  16897. * Calculates the dot product of two vectors. The version of the method
  16898. * that computes the dot product of two independent vectors is a static
  16899. * method. See the examples for more context.
  16900. *
  16901. *
  16902. * @method dot
  16903. * @param {Number|p5.Vector} x x component of the vector or a p5.Vector
  16904. * @param {Number} [y] y component of the vector
  16905. * @param {Number} [z] z component of the vector
  16906. * @return {Number} the dot product
  16907. *
  16908. * @example
  16909. * <div class="norender">
  16910. * <code>
  16911. * var v1 = createVector(1, 2, 3);
  16912. * var v2 = createVector(2, 3, 4);
  16913. *
  16914. * print(v1.dot(v2)); // Prints "20"
  16915. * </code>
  16916. * </div>
  16917. *
  16918. * <div class="norender">
  16919. * <code>
  16920. * //Static method
  16921. * var v1 = createVector(1, 2, 3);
  16922. * var v2 = createVector(3, 2, 1);
  16923. * print (p5.Vector.dot(v1, v2)); // Prints "10"
  16924. * </code>
  16925. * </div>
  16926. */
  16927. p5.Vector.prototype.dot = function (x, y, z) {
  16928. if (x instanceof p5.Vector) {
  16929. return this.dot(x.x, x.y, x.z);
  16930. }
  16931. return this.x * (x || 0) +
  16932. this.y * (y || 0) +
  16933. this.z * (z || 0);
  16934. };
  16935. /**
  16936. * Calculates and returns a vector composed of the cross product between
  16937. * two vectors. Both the static and non static methods return a new p5.Vector.
  16938. * See the examples for more context.
  16939. *
  16940. * @method cross
  16941. * @param {p5.Vector} v p5.Vector to be crossed
  16942. * @return {p5.Vector} p5.Vector composed of cross product
  16943. * @example
  16944. * <div class="norender">
  16945. * <code>
  16946. * var v1 = createVector(1, 2, 3);
  16947. * var v2 = createVector(1, 2, 3);
  16948. *
  16949. * v1.cross(v2); // v's components are [0, 0, 0]
  16950. * </code>
  16951. * </div>
  16952. *
  16953. * <div class="norender">
  16954. * <code>
  16955. * // Static method
  16956. * var v1 = createVector(1, 0, 0);
  16957. * var v2 = createVector(0, 1, 0);
  16958. *
  16959. * var crossProduct = p5.Vector.cross(v1, v2);
  16960. * // crossProduct has components [0, 0, 1]
  16961. * </code>
  16962. * </div>
  16963. */
  16964. p5.Vector.prototype.cross = function (v) {
  16965. var x = this.y * v.z - this.z * v.y;
  16966. var y = this.z * v.x - this.x * v.z;
  16967. var z = this.x * v.y - this.y * v.x;
  16968. if (this.p5) {
  16969. return new p5.Vector(this.p5,[x,y,z]);
  16970. } else {
  16971. return new p5.Vector(x,y,z);
  16972. }
  16973. };
  16974. /**
  16975. * Calculates the Euclidean distance between two points (considering a
  16976. * point as a vector object).
  16977. *
  16978. * @method dist
  16979. * @param {p5.Vector} v the x, y, and z coordinates of a p5.Vector
  16980. * @return {Number} the distance
  16981. * @example
  16982. * <div class="norender">
  16983. * <code>
  16984. * var v1 = createVector(1, 0, 0);
  16985. * var v2 = createVector(0, 1, 0);
  16986. *
  16987. * var distance = v1.dist(v2); // distance is 1.4142...
  16988. * </code>
  16989. * </div>
  16990. * <div class="norender">
  16991. * <code>
  16992. * // Static method
  16993. * var v1 = createVector(1, 0, 0);
  16994. * var v2 = createVector(0, 1, 0);
  16995. *
  16996. * var distance = p5.Vector.dist(v1,v2);
  16997. * // distance is 1.4142...
  16998. * </code>
  16999. * </div>
  17000. */
  17001. p5.Vector.prototype.dist = function (v) {
  17002. var d = v.copy().sub(this);
  17003. return d.mag();
  17004. };
  17005. /**
  17006. * Normalize the vector to length 1 (make it a unit vector).
  17007. *
  17008. * @method normalize
  17009. * @return {p5.Vector} normalized p5.Vector
  17010. * @example
  17011. * <div class="norender">
  17012. * <code>
  17013. * var v = createVector(10, 20, 2);
  17014. * // v has compnents [10.0, 20.0, 2.0]
  17015. * v.normalize();
  17016. * // v's compnents are set to
  17017. * // [0.4454354, 0.8908708, 0.089087084]
  17018. * </code>
  17019. * </div>
  17020. *
  17021. */
  17022. p5.Vector.prototype.normalize = function () {
  17023. return this.div(this.mag());
  17024. };
  17025. /**
  17026. * Limit the magnitude of this vector to the value used for the <b>max</b>
  17027. * parameter.
  17028. *
  17029. * @method limit
  17030. * @param {Number} max the maximum magnitude for the vector
  17031. * @return {p5.Vector} the modified p5.Vector
  17032. * @example
  17033. * <div class="norender">
  17034. * <code>
  17035. * var v = createVector(10, 20, 2);
  17036. * // v has compnents [10.0, 20.0, 2.0]
  17037. * v.limit(5);
  17038. * // v's compnents are set to
  17039. * // [2.2271771, 4.4543543, 0.4454354]
  17040. * </code>
  17041. * </div>
  17042. */
  17043. p5.Vector.prototype.limit = function (l) {
  17044. var mSq = this.magSq();
  17045. if(mSq > l*l) {
  17046. this.div(Math.sqrt(mSq)); //normalize it
  17047. this.mult(l);
  17048. }
  17049. return this;
  17050. };
  17051. /**
  17052. * Set the magnitude of this vector to the value used for the <b>len</b>
  17053. * parameter.
  17054. *
  17055. * @method setMag
  17056. * @param {number} len the new length for this vector
  17057. * @return {p5.Vector} the modified p5.Vector
  17058. * @example
  17059. * <div class="norender">
  17060. * <code>
  17061. * var v1 = createVector(10, 20, 2);
  17062. * // v has compnents [10.0, 20.0, 2.0]
  17063. * v1.setMag(10);
  17064. * // v's compnents are set to [6.0, 8.0, 0.0]
  17065. * </code>
  17066. * </div>
  17067. */
  17068. p5.Vector.prototype.setMag = function (n) {
  17069. return this.normalize().mult(n);
  17070. };
  17071. /**
  17072. * Calculate the angle of rotation for this vector (only 2D vectors)
  17073. *
  17074. * @method heading
  17075. * @return {Number} the angle of rotation
  17076. * @example
  17077. * <div class = "norender"><code>
  17078. * function setup() {
  17079. * var v1 = createVector(30,50);
  17080. * print(v1.heading()); // 1.0303768265243125
  17081. *
  17082. * var v1 = createVector(40,50);
  17083. * print(v1.heading()); // 0.8960553845713439
  17084. *
  17085. * var v1 = createVector(30,70);
  17086. * print(v1.heading()); // 1.1659045405098132
  17087. * }
  17088. * </div></code>
  17089. */
  17090. p5.Vector.prototype.heading = function () {
  17091. var h = Math.atan2(this.y, this.x);
  17092. if (this.p5) {
  17093. if (this.p5._angleMode === constants.RADIANS) {
  17094. return h;
  17095. } else {
  17096. return polarGeometry.radiansToDegrees(h);
  17097. }
  17098. } else {
  17099. return h;
  17100. }
  17101. };
  17102. /**
  17103. * Rotate the vector by an angle (only 2D vectors), magnitude remains the
  17104. * same
  17105. *
  17106. * @method rotate
  17107. * @param {number} angle the angle of rotation
  17108. * @return {p5.Vector} the modified p5.Vector
  17109. * @example
  17110. * <div class="norender">
  17111. * <code>
  17112. * var v = createVector(10.0, 20.0);
  17113. * // v has compnents [10.0, 20.0, 0.0]
  17114. * v.rotate(HALF_PI);
  17115. * // v's compnents are set to [-20.0, 9.999999, 0.0]
  17116. * </code>
  17117. * </div>
  17118. */
  17119. p5.Vector.prototype.rotate = function (a) {
  17120. if (this.p5) {
  17121. if (this.p5._angleMode === constants.DEGREES) {
  17122. a = polarGeometry.degreesToRadians(a);
  17123. }
  17124. }
  17125. var newHeading = this.heading() + a;
  17126. var mag = this.mag();
  17127. this.x = Math.cos(newHeading) * mag;
  17128. this.y = Math.sin(newHeading) * mag;
  17129. return this;
  17130. };
  17131. /**
  17132. * Linear interpolate the vector to another vector
  17133. *
  17134. * @method lerp
  17135. * @param {p5.Vector} x the x component or the p5.Vector to lerp to
  17136. * @param {p5.Vector} [y] y the y component
  17137. * @param {p5.Vector} [z] z the z component
  17138. * @param {Number} amt the amount of interpolation; some value between 0.0
  17139. * (old vector) and 1.0 (new vector). 0.1 is very near
  17140. * the new vector. 0.5 is halfway in between.
  17141. * @return {p5.Vector} the modified p5.Vector
  17142. * @example
  17143. * <div class="norender">
  17144. * <code>
  17145. * var v = createVector(1, 1, 0);
  17146. *
  17147. * v.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]
  17148. * </code>
  17149. * </div>
  17150. *
  17151. * <div class="norender">
  17152. * <code>
  17153. * var v1 = createVector(0, 0, 0);
  17154. * var v2 = createVector(100, 100, 0);
  17155. *
  17156. * var v3 = p5.Vector.lerp(v1, v2, 0.5);
  17157. * // v3 has components [50,50,0]
  17158. * </code>
  17159. * </div>
  17160. */
  17161. p5.Vector.prototype.lerp = function (x, y, z, amt) {
  17162. if (x instanceof p5.Vector) {
  17163. return this.lerp(x.x, x.y, x.z, y);
  17164. }
  17165. this.x += (x - this.x) * amt || 0;
  17166. this.y += (y - this.y) * amt || 0;
  17167. this.z += (z - this.z) * amt || 0;
  17168. return this;
  17169. };
  17170. /**
  17171. * Return a representation of this vector as a float array. This is only
  17172. * for temporary use. If used in any other fashion, the contents should be
  17173. * copied by using the <b>p5.Vector.copy()</b> method to copy into your own
  17174. * array.
  17175. *
  17176. * @method array
  17177. * @return {Array} an Array with the 3 values
  17178. * @example
  17179. * <div class = "norender"><code>
  17180. * function setup() {
  17181. * var v = createVector(20,30);
  17182. * print(v.array()); // Prints : Array [20, 30, 0]
  17183. * }
  17184. * </div></code>
  17185. * <div class="norender">
  17186. * <code>
  17187. * var v = createVector(10.0, 20.0, 30.0);
  17188. * var f = v.array();
  17189. * print(f[0]); // Prints "10.0"
  17190. * print(f[1]); // Prints "20.0"
  17191. * print(f[2]); // Prints "30.0"
  17192. * </code>
  17193. * </div>
  17194. */
  17195. p5.Vector.prototype.array = function () {
  17196. return [this.x || 0, this.y || 0, this.z || 0];
  17197. };
  17198. /**
  17199. * Equality check against a p5.Vector
  17200. *
  17201. * @method equals
  17202. * @param {Number|p5.Vector|Array} [x] the x component of the vector or a
  17203. * p5.Vector or an Array
  17204. * @param {Number} [y] the y component of the vector
  17205. * @param {Number} [z] the z component of the vector
  17206. * @return {Boolean} whether the vectors are equals
  17207. * @example
  17208. * <div class = "norender"><code>
  17209. * v1 = createVector(5,10,20);
  17210. * v2 = createVector(5,10,20);
  17211. * v3 = createVector(13,10,19);
  17212. *
  17213. * print(v1.equals(v2.x,v2.y,v2.z)); // true
  17214. * print(v1.equals(v3.x,v3.y,v3.z)); // false
  17215. * </div></code>
  17216. * <div class="norender">
  17217. * <code>
  17218. * var v1 = createVector(10.0, 20.0, 30.0);
  17219. * var v2 = createVector(10.0, 20.0, 30.0);
  17220. * var v3 = createVector(0.0, 0.0, 0.0);
  17221. * print (v1.equals(v2)) // true
  17222. * print (v1.equals(v3)) // false
  17223. * </code>
  17224. * </div>
  17225. */
  17226. p5.Vector.prototype.equals = function (x, y, z) {
  17227. var a, b, c;
  17228. if (x instanceof p5.Vector) {
  17229. a = x.x || 0;
  17230. b = x.y || 0;
  17231. c = x.z || 0;
  17232. } else if (x instanceof Array) {
  17233. a = x[0] || 0;
  17234. b = x[1] || 0;
  17235. c = x[2] || 0;
  17236. } else {
  17237. a = x || 0;
  17238. b = y || 0;
  17239. c = z || 0;
  17240. }
  17241. return this.x === a && this.y === b && this.z === c;
  17242. };
  17243. // Static Methods
  17244. /**
  17245. * Make a new 2D unit vector from an angle
  17246. *
  17247. * @method fromAngle
  17248. * @static
  17249. * @param {Number} angle the desired angle
  17250. * @return {p5.Vector} the new p5.Vector object
  17251. * @example
  17252. * <div>
  17253. * <code>
  17254. * function draw() {
  17255. * background (200);
  17256. *
  17257. * // Create a variable, proportional to the mouseX,
  17258. * // varying from 0-360, to represent an angle in degrees.
  17259. * angleMode(DEGREES);
  17260. * var myDegrees = map(mouseX, 0,width, 0,360);
  17261. *
  17262. * // Display that variable in an onscreen text.
  17263. * // (Note the nfc() function to truncate additional decimal places,
  17264. * // and the "\xB0" character for the degree symbol.)
  17265. * var readout = "angle = " + nfc(myDegrees,1,1) + "\xB0"
  17266. * noStroke();
  17267. * fill (0);
  17268. * text (readout, 5, 15);
  17269. *
  17270. * // Create a p5.Vector using the fromAngle function,
  17271. * // and extract its x and y components.
  17272. * var v = p5.Vector.fromAngle(radians(myDegrees));
  17273. * var vx = v.x;
  17274. * var vy = v.y;
  17275. *
  17276. * push();
  17277. * translate (width/2, height/2);
  17278. * noFill();
  17279. * stroke (150);
  17280. * line (0,0, 30,0);
  17281. * stroke (0);
  17282. * line (0,0, 30*vx, 30*vy);
  17283. * pop()
  17284. * }
  17285. * </code>
  17286. * </div>
  17287. */
  17288. p5.Vector.fromAngle = function(angle) {
  17289. if (this.p5) {
  17290. if (this.p5._angleMode === constants.DEGREES) {
  17291. angle = polarGeometry.degreesToRadians(angle);
  17292. }
  17293. }
  17294. if (this.p5) {
  17295. return new p5.Vector(this.p5,[Math.cos(angle),Math.sin(angle),0]);
  17296. } else {
  17297. return new p5.Vector(Math.cos(angle),Math.sin(angle),0);
  17298. }
  17299. };
  17300. /**
  17301. * Make a new 2D unit vector from a random angle
  17302. *
  17303. * @method random2D
  17304. * @static
  17305. * @return {p5.Vector} the new p5.Vector object
  17306. * @example
  17307. * <div class="norender">
  17308. * <code>
  17309. * var v = p5.Vector.random2D();
  17310. * // May make v's attributes something like:
  17311. * // [0.61554617, -0.51195765, 0.0] or
  17312. * // [-0.4695841, -0.14366731, 0.0] or
  17313. * // [0.6091097, -0.22805278, 0.0]
  17314. * </code>
  17315. * </div>
  17316. */
  17317. p5.Vector.random2D = function () {
  17318. var angle;
  17319. // A lot of nonsense to determine if we know about a
  17320. // p5 sketch and whether we should make a random angle in degrees or radians
  17321. if (this.p5) {
  17322. if (this.p5._angleMode === constants.DEGREES) {
  17323. angle = this.p5.random(360);
  17324. } else {
  17325. angle = this.p5.random(constants.TWO_PI);
  17326. }
  17327. } else {
  17328. angle = Math.random()*Math.PI*2;
  17329. }
  17330. return this.fromAngle(angle);
  17331. };
  17332. /**
  17333. * Make a new random 3D unit vector.
  17334. *
  17335. * @method random3D
  17336. * @static
  17337. * @return {p5.Vector} the new p5.Vector object
  17338. * @example
  17339. * <div class="norender">
  17340. * <code>
  17341. * var v = p5.Vector.random3D();
  17342. * // May make v's attributes something like:
  17343. * // [0.61554617, -0.51195765, 0.599168] or
  17344. * // [-0.4695841, -0.14366731, -0.8711202] or
  17345. * // [0.6091097, -0.22805278, -0.7595902]
  17346. * </code>
  17347. * </div>
  17348. */
  17349. p5.Vector.random3D = function () {
  17350. var angle,vz;
  17351. // If we know about p5
  17352. if (this.p5) {
  17353. angle = this.p5.random(0,constants.TWO_PI);
  17354. vz = this.p5.random(-1,1);
  17355. } else {
  17356. angle = Math.random()*Math.PI*2;
  17357. vz = Math.random()*2-1;
  17358. }
  17359. var vx = Math.sqrt(1-vz*vz)*Math.cos(angle);
  17360. var vy = Math.sqrt(1-vz*vz)*Math.sin(angle);
  17361. if (this.p5) {
  17362. return new p5.Vector(this.p5,[vx,vy,vz]);
  17363. } else {
  17364. return new p5.Vector(vx,vy,vz);
  17365. }
  17366. };
  17367. /**
  17368. * Adds two vectors together and returns a new one.
  17369. *
  17370. * @static
  17371. * @param {p5.Vector} v1 a p5.Vector to add
  17372. * @param {p5.Vector} v2 a p5.Vector to add
  17373. * @param {p5.Vector} target if undefined a new vector will be created
  17374. * @return {p5.Vector} the resulting p5.Vector
  17375. *
  17376. */
  17377. p5.Vector.add = function (v1, v2, target) {
  17378. if (!target) {
  17379. target = v1.copy();
  17380. } else {
  17381. target.set(v1);
  17382. }
  17383. target.add(v2);
  17384. return target;
  17385. };
  17386. /**
  17387. * Subtracts one p5.Vector from another and returns a new one. The second
  17388. * vector (v2) is subtracted from the first (v1), resulting in v1-v2.
  17389. *
  17390. * @static
  17391. * @param {p5.Vector} v1 a p5.Vector to subtract from
  17392. * @param {p5.Vector} v2 a p5.Vector to subtract
  17393. * @param {p5.Vector} target if undefined a new vector will be created
  17394. * @return {p5.Vector} the resulting p5.Vector
  17395. */
  17396. p5.Vector.sub = function (v1, v2, target) {
  17397. if (!target) {
  17398. target = v1.copy();
  17399. } else {
  17400. target.set(v1);
  17401. }
  17402. target.sub(v2);
  17403. return target;
  17404. };
  17405. /**
  17406. * Multiplies a vector by a scalar and returns a new vector.
  17407. *
  17408. * @static
  17409. * @param {p5.Vector} v the p5.Vector to multiply
  17410. * @param {Number} n the scalar
  17411. * @param {p5.Vector} target if undefined a new vector will be created
  17412. * @return {p5.Vector} the resulting new p5.Vector
  17413. */
  17414. p5.Vector.mult = function (v, n, target) {
  17415. if (!target) {
  17416. target = v.copy();
  17417. } else {
  17418. target.set(v);
  17419. }
  17420. target.mult(n);
  17421. return target;
  17422. };
  17423. /**
  17424. * Divides a vector by a scalar and returns a new vector.
  17425. *
  17426. * @static
  17427. * @param {p5.Vector} v the p5.Vector to divide
  17428. * @param {Number} n the scalar
  17429. * @param {p5.Vector} target if undefined a new vector will be created
  17430. * @return {p5.Vector} the resulting new p5.Vector
  17431. */
  17432. p5.Vector.div = function (v, n, target) {
  17433. if (!target) {
  17434. target = v.copy();
  17435. } else {
  17436. target.set(v);
  17437. }
  17438. target.div(n);
  17439. return target;
  17440. };
  17441. /**
  17442. * Calculates the dot product of two vectors.
  17443. *
  17444. * @static
  17445. * @param {p5.Vector} v1 the first p5.Vector
  17446. * @param {p5.Vector} v2 the second p5.Vector
  17447. * @return {Number} the dot product
  17448. */
  17449. p5.Vector.dot = function (v1, v2) {
  17450. return v1.dot(v2);
  17451. };
  17452. /**
  17453. * Calculates the cross product of two vectors.
  17454. *
  17455. * @static
  17456. * @param {p5.Vector} v1 the first p5.Vector
  17457. * @param {p5.Vector} v2 the second p5.Vector
  17458. * @return {Number} the cross product
  17459. */
  17460. p5.Vector.cross = function (v1, v2) {
  17461. return v1.cross(v2);
  17462. };
  17463. /**
  17464. * Calculates the Euclidean distance between two points (considering a
  17465. * point as a vector object).
  17466. *
  17467. * @static
  17468. * @param {p5.Vector} v1 the first p5.Vector
  17469. * @param {p5.Vector} v2 the second p5.Vector
  17470. * @return {Number} the distance
  17471. */
  17472. p5.Vector.dist = function (v1,v2) {
  17473. return v1.dist(v2);
  17474. };
  17475. /**
  17476. * Linear interpolate a vector to another vector and return the result as a
  17477. * new vector.
  17478. *
  17479. * @static
  17480. * @param {p5.Vector} v1 a starting p5.Vector
  17481. * @param {p5.Vector} v2 the p5.Vector to lerp to
  17482. * @param {Number} the amount of interpolation; some value between 0.0
  17483. * (old vector) and 1.0 (new vector). 0.1 is very near
  17484. * the new vector. 0.5 is halfway in between.
  17485. */
  17486. p5.Vector.lerp = function (v1, v2, amt, target) {
  17487. if (!target) {
  17488. target = v1.copy();
  17489. } else {
  17490. target.set(v1);
  17491. }
  17492. target.lerp(v2, amt);
  17493. return target;
  17494. };
  17495. /**
  17496. * Calculates and returns the angle (in radians) between two vectors.
  17497. * @method angleBetween
  17498. * @static
  17499. * @param {p5.Vector} v1 the x, y, and z components of a p5.Vector
  17500. * @param {p5.Vector} v2 the x, y, and z components of a p5.Vector
  17501. * @return {Number} the angle between (in radians)
  17502. * @example
  17503. * <div class="norender">
  17504. * <code>
  17505. * var v1 = createVector(1, 0, 0);
  17506. * var v2 = createVector(0, 1, 0);
  17507. *
  17508. * var angle = p5.Vector.angleBetween(v1, v2);
  17509. * // angle is PI/2
  17510. * </code>
  17511. * </div>
  17512. */
  17513. p5.Vector.angleBetween = function (v1, v2) {
  17514. var angle = Math.acos(v1.dot(v2) / (v1.mag() * v2.mag()));
  17515. if (this.p5) {
  17516. if (this.p5._angleMode === constants.DEGREES) {
  17517. angle = polarGeometry.radiansToDegrees(angle);
  17518. }
  17519. }
  17520. return angle;
  17521. };
  17522. module.exports = p5.Vector;
  17523. },{"../core/constants":16,"../core/core":17,"./polargeometry":46}],46:[function(require,module,exports){
  17524. module.exports = {
  17525. degreesToRadians: function(x) {
  17526. return 2 * Math.PI * x / 360;
  17527. },
  17528. radiansToDegrees: function(x) {
  17529. return 360 * x / (2 * Math.PI);
  17530. }
  17531. };
  17532. },{}],47:[function(require,module,exports){
  17533. /**
  17534. * @module Math
  17535. * @submodule Random
  17536. * @for p5
  17537. * @requires core
  17538. */
  17539. 'use strict';
  17540. var p5 = require('../core/core');
  17541. var seeded = false;
  17542. // Linear Congruential Generator
  17543. // Variant of a Lehman Generator
  17544. var lcg = (function() {
  17545. // Set to values from http://en.wikipedia.org/wiki/Numerical_Recipes
  17546. // m is basically chosen to be large (as it is the max period)
  17547. // and for its relationships to a and c
  17548. var m = 4294967296,
  17549. // a - 1 should be divisible by m's prime factors
  17550. a = 1664525,
  17551. // c and m should be co-prime
  17552. c = 1013904223,
  17553. seed, z;
  17554. return {
  17555. setSeed : function(val) {
  17556. // pick a random seed if val is undefined or null
  17557. // the >>> 0 casts the seed to an unsigned 32-bit integer
  17558. z = seed = (val == null ? Math.random() * m : val) >>> 0;
  17559. },
  17560. getSeed : function() {
  17561. return seed;
  17562. },
  17563. rand : function() {
  17564. // define the recurrence relationship
  17565. z = (a * z + c) % m;
  17566. // return a float in [0, 1)
  17567. // if z = m then z / m = 0 therefore (z % m) / m < 1 always
  17568. return z / m;
  17569. }
  17570. };
  17571. }());
  17572. /**
  17573. * Sets the seed value for random().
  17574. *
  17575. * By default, random() produces different results each time the program
  17576. * is run. Set the seed parameter to a constant to return the same
  17577. * pseudo-random numbers each time the software is run.
  17578. *
  17579. * @method randomSeed
  17580. * @param {Number} seed the seed value
  17581. * @example
  17582. * <div>
  17583. * <code>
  17584. * randomSeed(99);
  17585. * for (var i=0; i < 100; i++) {
  17586. * var r = random(0, 255);
  17587. * stroke(r);
  17588. * line(i, 0, i, 100);
  17589. * }
  17590. * </code>
  17591. * </div>
  17592. */
  17593. p5.prototype.randomSeed = function(seed) {
  17594. lcg.setSeed(seed);
  17595. seeded = true;
  17596. };
  17597. /**
  17598. * Return a random number.
  17599. *
  17600. * Takes either 0, 1 or 2 arguments.
  17601. * If no argument is given, returns a random number between 0 and 1.
  17602. * If one argument is given, returns a random number between 0 and the number.
  17603. * If two arguments are given, returns a random number between them,
  17604. * inclusive.
  17605. *
  17606. * @method random
  17607. * @param {Number} min the lower bound
  17608. * @param {Number} max the upper bound
  17609. * @return {Number} the random number
  17610. * @example
  17611. * <div>
  17612. * <code>
  17613. * for (var i = 0; i < 100; i++) {
  17614. * var r = random(50);
  17615. * stroke(r*5);
  17616. * line(50, i, 50+r, i);
  17617. * }
  17618. * </code>
  17619. * </div>
  17620. * <div>
  17621. * <code>
  17622. * for (var i = 0; i < 100; i++) {
  17623. * var r = random(-50, 50);
  17624. * line(50,i,50+r,i);
  17625. * }
  17626. * </code>
  17627. * </div>
  17628. * <div>
  17629. * <code>
  17630. * // Get a random element from an array
  17631. * var words = [ "apple", "bear", "cat", "dog" ];
  17632. * var index = floor(random(words.length)); // Convert to integer
  17633. * text(words[index],10,50); // Displays one of the four words
  17634. * </code>
  17635. * </div>
  17636. */
  17637. p5.prototype.random = function (min, max) {
  17638. var rand;
  17639. if (seeded) {
  17640. rand = lcg.rand();
  17641. } else {
  17642. rand = Math.random();
  17643. }
  17644. if (arguments.length === 0) {
  17645. return rand;
  17646. } else
  17647. if (arguments.length === 1) {
  17648. return rand * min;
  17649. } else {
  17650. if (min > max) {
  17651. var tmp = min;
  17652. min = max;
  17653. max = tmp;
  17654. }
  17655. return rand * (max-min) + min;
  17656. }
  17657. };
  17658. /**
  17659. *
  17660. * Returns a random number fitting a Gaussian, or
  17661. * normal, distribution. There is theoretically no minimum or maximum
  17662. * value that <b>randomGaussian()</b> might return. Rather, there is
  17663. * just a very low probability that values far from the mean will be
  17664. * returned; and a higher probability that numbers near the mean will
  17665. * be returned.
  17666. * Takes either 0, 1 or 2 arguments.
  17667. * If no args, returns a mean of 0 and standard deviation of 1
  17668. * If one arg, that arg is the mean (standard deviation is 1)
  17669. * If two args, first is mean, second is standard deviation
  17670. *
  17671. * @method randomGaussian
  17672. * @param {Number} mean the mean
  17673. * @param {Number} sd the standard deviation
  17674. * @return {Number} the random number
  17675. * @example
  17676. * <div>
  17677. * <code>for (var y = 0; y < 100; y++) {
  17678. * var x = randomGaussian(50,15);
  17679. * line(50, y, x, y);
  17680. *}
  17681. * </code>
  17682. * </div>
  17683. * <div>
  17684. * <code>
  17685. *var distribution = new Array(360);
  17686. *
  17687. *function setup() {
  17688. * createCanvas(100, 100);
  17689. * for (var i = 0; i < distribution.length; i++) {
  17690. * distribution[i] = floor(randomGaussian(0,15));
  17691. * }
  17692. *}
  17693. *
  17694. *function draw() {
  17695. * background(204);
  17696. *
  17697. * translate(width/2, width/2);
  17698. *
  17699. * for (var i = 0; i < distribution.length; i++) {
  17700. * rotate(TWO_PI/distribution.length);
  17701. * stroke(0);
  17702. * var dist = abs(distribution[i]);
  17703. * line(0, 0, dist, 0);
  17704. * }
  17705. *}
  17706. * </code>
  17707. * </div>
  17708. */
  17709. var y2;
  17710. var previous = false;
  17711. p5.prototype.randomGaussian = function(mean, sd) {
  17712. var y1,x1,x2,w;
  17713. if (previous) {
  17714. y1 = y2;
  17715. previous = false;
  17716. } else {
  17717. do {
  17718. x1 = this.random(2) - 1;
  17719. x2 = this.random(2) - 1;
  17720. w = x1 * x1 + x2 * x2;
  17721. } while (w >= 1);
  17722. w = Math.sqrt((-2 * Math.log(w))/w);
  17723. y1 = x1 * w;
  17724. y2 = x2 * w;
  17725. previous = true;
  17726. }
  17727. var m = mean || 0;
  17728. var s = sd || 1;
  17729. return y1*s + m;
  17730. };
  17731. module.exports = p5;
  17732. },{"../core/core":17}],48:[function(require,module,exports){
  17733. /**
  17734. * @module Math
  17735. * @submodule Trigonometry
  17736. * @for p5
  17737. * @requires core
  17738. * @requires polargeometry
  17739. * @requires constants
  17740. */
  17741. 'use strict';
  17742. var p5 = require('../core/core');
  17743. var polarGeometry = require('./polargeometry');
  17744. var constants = require('../core/constants');
  17745. p5.prototype._angleMode = constants.RADIANS;
  17746. /**
  17747. * The inverse of cos(), returns the arc cosine of a value. This function
  17748. * expects the values in the range of -1 to 1 and values are returned in
  17749. * the range 0 to PI (3.1415927).
  17750. *
  17751. * @method acos
  17752. * @param {Number} value the value whose arc cosine is to be returned
  17753. * @return {Number} the arc cosine of the given value
  17754. *
  17755. * @example
  17756. * <div class= “norender">
  17757. * <code>
  17758. * var a = PI;
  17759. * var c = cos(a);
  17760. * var ac = acos(c);
  17761. * // Prints: "3.1415927 : -1.0 : 3.1415927"
  17762. * println(a + " : " + c + " : " + ac);
  17763. * </code>
  17764. * </div>
  17765. *
  17766. * <div class= “norender">
  17767. * <code>
  17768. * var a = PI + PI/4.0;
  17769. * var c = cos(a);
  17770. * var ac = acos(c);
  17771. * // Prints: "3.926991 : -0.70710665 : 2.3561943"
  17772. * println(a + " : " + c + " : " + ac);
  17773. * </code>
  17774. * </div>
  17775. */
  17776. p5.prototype.acos = function(ratio) {
  17777. if (this._angleMode === constants.RADIANS) {
  17778. return Math.acos(ratio);
  17779. } else {
  17780. return polarGeometry.radiansToDegrees(Math.acos(ratio));
  17781. }
  17782. };
  17783. /**
  17784. * The inverse of sin(), returns the arc sine of a value. This function
  17785. * expects the values in the range of -1 to 1 and values are returned
  17786. * in the range -PI/2 to PI/2.
  17787. *
  17788. * @method asin
  17789. * @param {Number} value the value whose arc sine is to be returned
  17790. * @return {Number} the arc sine of the given value
  17791. *
  17792. * @example
  17793. * <div class= “norender">
  17794. * <code>
  17795. * var a = PI + PI/3;
  17796. * var s = sin(a);
  17797. * var as = asin(s);
  17798. * // Prints: "1.0471976 : 0.86602545 : 1.0471976"
  17799. * println(a + " : " + s + " : " + as);
  17800. * </code>
  17801. * </div>
  17802. *
  17803. * <div class= “norender">
  17804. * <code>
  17805. * var a = PI + PI/3.0;
  17806. * var s = sin(a);
  17807. * var as = asin(s);
  17808. * // Prints: "4.1887903 : -0.86602545 : -1.0471976"
  17809. * println(a + " : " + s + " : " + as);
  17810. * </code>
  17811. * </div>
  17812. *
  17813. */
  17814. p5.prototype.asin = function(ratio) {
  17815. if (this._angleMode === constants.RADIANS) {
  17816. return Math.asin(ratio);
  17817. } else {
  17818. return polarGeometry.radiansToDegrees(Math.asin(ratio));
  17819. }
  17820. };
  17821. /**
  17822. * The inverse of tan(), returns the arc tangent of a value. This function
  17823. * expects the values in the range of -Infinity to Infinity (exclusive) and
  17824. * values are returned in the range -PI/2 to PI/2.
  17825. *
  17826. * @method atan
  17827. * @param {Number} value the value whose arc tangent is to be returned
  17828. * @return {Number} the arc tangent of the given value
  17829. *
  17830. * @example
  17831. * <div class= “norender">
  17832. * <code>
  17833. * var a = PI + PI/3;
  17834. * var t = tan(a);
  17835. * var at = atan(t);
  17836. * // Prints: "1.0471976 : 1.7320509 : 1.0471976"
  17837. * println(a + " : " + t + " : " + at);
  17838. * </code>
  17839. * </div>
  17840. *
  17841. * <div class= “norender">
  17842. * <code>
  17843. * var a = PI + PI/3.0;
  17844. * var t = tan(a);
  17845. * var at = atan(t);
  17846. * // Prints: "4.1887903 : 1.7320513 : 1.0471977"
  17847. * println(a + " : " + t + " : " + at);
  17848. * </code>
  17849. * </div>
  17850. *
  17851. */
  17852. p5.prototype.atan = function(ratio) {
  17853. if (this._angleMode === constants.RADIANS) {
  17854. return Math.atan(ratio);
  17855. } else {
  17856. return polarGeometry.radiansToDegrees(Math.atan(ratio));
  17857. }
  17858. };
  17859. /**
  17860. * Calculates the angle (in radians) from a specified point to the coordinate
  17861. * origin as measured from the positive x-axis. Values are returned as a
  17862. * float in the range from PI to -PI. The atan2() function is most often used
  17863. * for orienting geometry to the position of the cursor. Note: The
  17864. * y-coordinate of the point is the first parameter, and the x-coordinate is
  17865. * the second parameter, due the the structure of calculating the tangent.
  17866. *
  17867. * @method atan2
  17868. * @param {Number} y y-coordinate of the point
  17869. * @param {Number} x x-coordinate of the point
  17870. * @return {Number} the arc tangent of the given point
  17871. *
  17872. * @example
  17873. * <div>
  17874. * <code>
  17875. * function draw() {
  17876. * background(204);
  17877. * translate(width/2, height/2);
  17878. * var a = atan2(mouseY-height/2, mouseX-width/2);
  17879. * rotate(a);
  17880. * rect(-30, -5, 60, 10);
  17881. * }
  17882. * </code>
  17883. * </div>
  17884. */
  17885. p5.prototype.atan2 = function (y, x) {
  17886. if (this._angleMode === constants.RADIANS) {
  17887. return Math.atan2(y, x);
  17888. } else {
  17889. return polarGeometry.radiansToDegrees(Math.atan2(y, x));
  17890. }
  17891. };
  17892. /**
  17893. * Calculates the cosine of an angle. This function takes into account the
  17894. * current angleMode. Values are returned in the range -1 to 1.
  17895. *
  17896. * @method cos
  17897. * @param {Number} angle the angle
  17898. * @return {Number} the cosine of the angle
  17899. *
  17900. * @example
  17901. * <div>
  17902. * <code>
  17903. * var a = 0.0;
  17904. * var inc = TWO_PI/25.0;
  17905. * for (var i = 0; i < 25; i++) {
  17906. * line(i*4, 50, i*4, 50+cos(a)*40.0);
  17907. * a = a + inc;
  17908. * }
  17909. * </code>
  17910. * </div>
  17911. *
  17912. */
  17913. p5.prototype.cos = function(angle) {
  17914. if (this._angleMode === constants.RADIANS) {
  17915. return Math.cos(angle);
  17916. } else {
  17917. return Math.cos(this.radians(angle));
  17918. }
  17919. };
  17920. /**
  17921. * Calculates the sine of an angle. This function takes into account the
  17922. * current angleMode. Values are returned in the range -1 to 1.
  17923. *
  17924. * @method sin
  17925. * @param {Number} angle the angle
  17926. * @return {Number} the sine of the angle
  17927. *
  17928. * @example
  17929. * <div>
  17930. * <code>
  17931. * var a = 0.0;
  17932. * var inc = TWO_PI/25.0;
  17933. * for (var i = 0; i < 25; i++) {
  17934. * line(i*4, 50, i*4, 50+sin(a)*40.0);
  17935. * a = a + inc;
  17936. * }
  17937. * </code>
  17938. * </div>
  17939. */
  17940. p5.prototype.sin = function(angle) {
  17941. if (this._angleMode === constants.RADIANS) {
  17942. return Math.sin(angle);
  17943. } else {
  17944. return Math.sin(this.radians(angle));
  17945. }
  17946. };
  17947. /**
  17948. * Calculates the tangent of an angle. This function takes into account
  17949. * the current angleMode. Values are returned in the range -1 to 1.
  17950. *
  17951. * @method tan
  17952. * @param {Number} angle the angle
  17953. * @return {Number} the tangent of the angle
  17954. *
  17955. * @example
  17956. * <div>
  17957. * <code>
  17958. * var a = 0.0;
  17959. * var inc = TWO_PI/50.0;
  17960. * for (var i = 0; i < 100; i = i+2) {
  17961. * line(i, 50, i, 50+tan(a)*2.0);
  17962. * a = a + inc;
  17963. * }
  17964. * </code>
  17965. * </div>
  17966. *
  17967. */
  17968. p5.prototype.tan = function(angle) {
  17969. if (this._angleMode === constants.RADIANS) {
  17970. return Math.tan(angle);
  17971. } else {
  17972. return Math.tan(this.radians(angle));
  17973. }
  17974. };
  17975. /**
  17976. * Converts a radian measurement to its corresponding value in degrees.
  17977. * Radians and degrees are two ways of measuring the same thing. There are
  17978. * 360 degrees in a circle and 2*PI radians in a circle. For example,
  17979. * 90° = PI/2 = 1.5707964.
  17980. *
  17981. * @method degrees
  17982. * @param {Number} radians the radians value to convert to degrees
  17983. * @return {Number} the converted angle
  17984. *
  17985. *
  17986. * @example
  17987. * <div class= “norender">
  17988. * <code>
  17989. * var rad = PI/4;
  17990. * var deg = degrees(rad);
  17991. * println(rad + " radians is " + deg + " degrees");
  17992. * // Prints: 45 degrees is 0.7853981633974483 radians
  17993. * </code>
  17994. * </div>
  17995. *
  17996. */
  17997. p5.prototype.degrees = function(angle) {
  17998. return polarGeometry.radiansToDegrees(angle);
  17999. };
  18000. /**
  18001. * Converts a degree measurement to its corresponding value in radians.
  18002. * Radians and degrees are two ways of measuring the same thing. There are
  18003. * 360 degrees in a circle and 2*PI radians in a circle. For example,
  18004. * 90° = PI/2 = 1.5707964.
  18005. *
  18006. * @method radians
  18007. * @param {Number} degrees the degree value to convert to radians
  18008. * @return {Number} the converted angle
  18009. *
  18010. * @example
  18011. * <div class= “norender">
  18012. * <code>
  18013. * var deg = 45.0;
  18014. * var rad = radians(deg);
  18015. * println(deg + " degrees is " + rad + " radians");
  18016. * // Prints: 45 degrees is 0.7853981633974483 radians
  18017. * </code>
  18018. * </div>
  18019. */
  18020. p5.prototype.radians = function(angle) {
  18021. return polarGeometry.degreesToRadians(angle);
  18022. };
  18023. /**
  18024. * Sets the current mode of p5 to given mode. Default mode is RADIANS.
  18025. *
  18026. * @method angleMode
  18027. * @param {Number/Constant} mode either RADIANS or DEGREES
  18028. *
  18029. * @example
  18030. * <div>
  18031. * <code>
  18032. * function draw(){
  18033. * background(204);
  18034. * angleMode(DEGREES); // Change the mode to DEGREES
  18035. * var a = atan2(mouseY-height/2, mouseX-width/2);
  18036. * translate(width/2, height/2);
  18037. * push();
  18038. * rotate(a);
  18039. * rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees
  18040. * pop();
  18041. * angleMode(RADIANS); // Change the mode to RADIANS
  18042. * rotate(a); // var a stays the same
  18043. * rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians
  18044. * }
  18045. * </code>
  18046. * </div>
  18047. *
  18048. */
  18049. p5.prototype.angleMode = function(mode) {
  18050. if (mode === constants.DEGREES || mode === constants.RADIANS) {
  18051. this._angleMode = mode;
  18052. }
  18053. };
  18054. module.exports = p5;
  18055. },{"../core/constants":16,"../core/core":17,"./polargeometry":46}],49:[function(require,module,exports){
  18056. /**
  18057. * @module Typography
  18058. * @submodule Attributes
  18059. * @for p5
  18060. * @requires core
  18061. * @requires constants
  18062. */
  18063. 'use strict';
  18064. var p5 = require('../core/core');
  18065. var constants = require('../core/constants');
  18066. p5.prototype._textSize = 12;
  18067. p5.prototype._textLeading = 15;
  18068. p5.prototype._textFont = 'sans-serif';
  18069. p5.prototype._textStyle = constants.NORMAL;
  18070. p5.prototype._textAscent = null;
  18071. p5.prototype._textDescent = null;
  18072. /**
  18073. * Sets the current alignment for drawing text. The parameters LEFT, CENTER,
  18074. * and RIGHT set the display characteristics of the letters in relation to
  18075. * the values for the x and y parameters of the text() function.
  18076. *
  18077. * @method textAlign
  18078. * @param {Number/Constant} h horizontal alignment, either LEFT,
  18079. * CENTER, or RIGHT
  18080. * @param {Number/Constant} v vertical alignment, either TOP,
  18081. * BOTTOM, CENTER, or BASELINE
  18082. * @return {Number}
  18083. * @example
  18084. * <div>
  18085. * <code>
  18086. * textSize(16);
  18087. * textAlign(RIGHT);
  18088. * text("ABCD", 50, 30);
  18089. * textAlign(CENTER);
  18090. * text("EFGH", 50, 50);
  18091. * textAlign(LEFT);
  18092. * text("IJKL", 50, 70);
  18093. * </code>
  18094. * </div>
  18095. */
  18096. p5.prototype.textAlign = function(h, v) {
  18097. return this._graphics.textAlign(h,v);
  18098. };
  18099. /**
  18100. * Sets/gets the spacing between lines of text in units of pixels. This
  18101. * setting will be used in all subsequent calls to the text() function.
  18102. *
  18103. * @method textLeading
  18104. * @param {Number} l the size in pixels for spacing between lines
  18105. * @return {Object|Number}
  18106. * @example
  18107. * <div>
  18108. * <code>
  18109. * // Text to display. The "\n" is a "new line" character
  18110. * lines = "L1\nL2\nL3";
  18111. * textSize(12);
  18112. * fill(0); // Set fill to black
  18113. *
  18114. * textLeading(10); // Set leading to 10
  18115. * text(lines, 10, 25);
  18116. *
  18117. * textLeading(20); // Set leading to 20
  18118. * text(lines, 40, 25);
  18119. *
  18120. * textLeading(30); // Set leading to 30
  18121. * text(lines, 70, 25);
  18122. * </code>
  18123. * </div>
  18124. */
  18125. p5.prototype.textLeading = function(l) {
  18126. if (arguments.length) {
  18127. this._setProperty('_textLeading', l);
  18128. return this;
  18129. }
  18130. return this._textLeading;
  18131. };
  18132. /**
  18133. * Sets/gets the current font size. This size will be used in all subsequent
  18134. * calls to the text() function. Font size is measured in units of pixels.
  18135. *
  18136. * @method textSize
  18137. * @param {Number} s the size of the letters in units of pixels
  18138. * @return {Object|Number}
  18139. * @example
  18140. * <div>
  18141. * <code>
  18142. * textSize(12);
  18143. * text("Font Size 12", 10, 30);
  18144. * textSize(14);
  18145. * text("Font Size 14", 10, 60);
  18146. * textSize(16);
  18147. * text("Font Size 16", 10, 90);
  18148. * </code>
  18149. * </div>
  18150. */
  18151. p5.prototype.textSize = function(s) {
  18152. if (arguments.length) {
  18153. this._setProperty('_textSize', s);
  18154. this._setProperty('_textLeading', s * constants._DEFAULT_LEADMULT);
  18155. return this._graphics._applyTextProperties();
  18156. }
  18157. return this._textSize;
  18158. };
  18159. /**
  18160. * Sets/gets the style of the text to NORMAL, ITALIC, or BOLD. Note this is
  18161. * overridden by CSS styling.
  18162. * (Style only apply to system font, for custom fonts, please load styled
  18163. * fonts instead.)
  18164. *
  18165. * @method textStyle
  18166. * @param {Number/Constant} s styling for text, either NORMAL,
  18167. * ITALIC, or BOLD
  18168. * @return {Object|String}
  18169. * @example
  18170. * <div>
  18171. * <code>
  18172. * fill(0);
  18173. * strokeWeight(0);
  18174. * textSize(12);
  18175. * textStyle(NORMAL);
  18176. * text("Font Style Normal", 10, 30);
  18177. * textStyle(ITALIC);
  18178. * text("Font Style Italic", 10, 60);
  18179. * textStyle(BOLD);
  18180. * text("Font Style Bold", 10, 90);
  18181. * </code>
  18182. * </div>
  18183. */
  18184. p5.prototype.textStyle = function(s) {
  18185. if (arguments.length) {
  18186. if (s === constants.NORMAL ||
  18187. s === constants.ITALIC ||
  18188. s === constants.BOLD) {
  18189. this._setProperty('_textStyle', s);
  18190. }
  18191. return this._graphics._applyTextProperties();
  18192. }
  18193. return this._textStyle;
  18194. };
  18195. /**
  18196. * Calculates and returns the width of any character or text string.
  18197. *
  18198. * @method textWidth
  18199. * @param {String} s the String of characters to measure
  18200. * @return {Number}
  18201. * @example
  18202. * <div>
  18203. * <code>
  18204. * textSize(28);
  18205. *
  18206. * var c = 'P';
  18207. * var cw = textWidth(c);
  18208. * text(c, 0, 40);
  18209. * line(cw, 0, cw, 50);
  18210. *
  18211. * var s = "p5.js";
  18212. * var sw = textWidth(s);
  18213. * text(s, 0, 85);
  18214. * line(sw, 50, sw, 100);
  18215. * </code>
  18216. * </div>
  18217. */
  18218. p5.prototype.textWidth = function(s) {
  18219. return this._graphics.textWidth(s);
  18220. };
  18221. /**
  18222. * Returns ascent of the current font at its current size.
  18223. * @return {Number}
  18224. * @example
  18225. * <div>
  18226. * <code>
  18227. * var base = height * 0.75;
  18228. * var scalar = 0.8; // Different for each font
  18229. *
  18230. * textSize(32); // Set initial text size
  18231. * var a = textAscent() * scalar; // Calc ascent
  18232. * line(0, base-a, width, base-a);
  18233. * text("dp", 0, base); // Draw text on baseline
  18234. *
  18235. * textSize(64); // Increase text size
  18236. * a = textAscent() * scalar; // Recalc ascent
  18237. * line(40, base-a, width, base-a);
  18238. * text("dp", 40, base); // Draw text on baseline
  18239. * </code>
  18240. * </div>
  18241. */
  18242. p5.prototype.textAscent = function() {
  18243. if (this._textAscent === null) {
  18244. this._updateTextMetrics();
  18245. }
  18246. return this._textAscent;
  18247. };
  18248. /*p5.prototype.fontMetrics = function(font, text, x, y, fontSize) {
  18249. var xMins = [], yMins = [], xMaxs= [], yMaxs = [], p5 = this;
  18250. //font = font || this._textFont;
  18251. fontSize = fontSize || p5._textSize;
  18252. font.forEachGlyph(text, x, y, fontSize,
  18253. {}, function(glyph, gX, gY, gFontSize) {
  18254. var gm = glyph.getMetrics();
  18255. gX = gX !== undefined ? gX : 0;
  18256. gY = gY !== undefined ? gY : 0;
  18257. fontSize = fontSize !== undefined ? fontSize : 24;
  18258. var scale = 1 / font.unitsPerEm * fontSize;
  18259. p5.noFill();
  18260. p5.rectMode(p5.CORNERS);
  18261. p5.rect(gX + (gm.xMin * scale), gY + (-gm.yMin * scale),
  18262. gX + (gm.xMax * scale), gY + (-gm.yMax * scale));
  18263. p5.rectMode(p5.CORNER);
  18264. });
  18265. return { // metrics
  18266. xMin: Math.min.apply(null, xMins),
  18267. yMin: Math.min.apply(null, yMins),
  18268. xMax: Math.max.apply(null, xMaxs),
  18269. yMax: Math.max.apply(null, yMaxs)
  18270. };
  18271. };*/
  18272. /**
  18273. * Returns descent of the current font at its current size.
  18274. * @return {Number}
  18275. * @example
  18276. * <div>
  18277. * <code>
  18278. * var base = height * 0.75;
  18279. * var scalar = 0.8; // Different for each font
  18280. *
  18281. * textSize(32); // Set initial text size
  18282. * var a = textDescent() * scalar; // Calc ascent
  18283. * line(0, base+a, width, base+a);
  18284. * text("dp", 0, base); // Draw text on baseline
  18285. *
  18286. * textSize(64); // Increase text size
  18287. * a = textDescent() * scalar; // Recalc ascent
  18288. * line(40, base+a, width, base+a);
  18289. * text("dp", 40, base); // Draw text on baseline
  18290. * </code>
  18291. * </div>
  18292. */
  18293. p5.prototype.textDescent = function() {
  18294. if (this._textDescent === null) {
  18295. this._updateTextMetrics();
  18296. }
  18297. return this._textDescent;
  18298. };
  18299. /**
  18300. * Helper fxn to check font type (system or otf)
  18301. */
  18302. p5.prototype._isOpenType = function(f) {
  18303. f = f || this._textFont;
  18304. return (typeof f === 'object' && f.font && f.font.supported);
  18305. };
  18306. /**
  18307. * Helper fxn to measure ascent and descent.
  18308. */
  18309. p5.prototype._updateTextMetrics = function() {
  18310. if (this._isOpenType()) {
  18311. this._setProperty('_textAscent', this._textFont._textAscent());
  18312. this._setProperty('_textDescent', this._textFont._textDescent());
  18313. return this;
  18314. }
  18315. // Adapted from http://stackoverflow.com/a/25355178
  18316. var text = document.createElement('span');
  18317. text.style.fontFamily = this._textFont;
  18318. text.style.fontSize = this._textSize + 'px';
  18319. text.innerHTML = 'ABCjgq|';
  18320. var block = document.createElement('div');
  18321. block.style.display = 'inline-block';
  18322. block.style.width = '1px';
  18323. block.style.height = '0px';
  18324. var container = document.createElement('div');
  18325. container.appendChild(text);
  18326. container.appendChild(block);
  18327. container.style.height = '0px';
  18328. container.style.overflow = 'hidden';
  18329. document.body.appendChild(container);
  18330. block.style.verticalAlign = 'baseline';
  18331. var blockOffset = this._calculateOffset(block);
  18332. var textOffset = this._calculateOffset(text);
  18333. var ascent = blockOffset[1] - textOffset[1];
  18334. block.style.verticalAlign = 'bottom';
  18335. blockOffset = this._calculateOffset(block);
  18336. textOffset = this._calculateOffset(text);
  18337. var height = blockOffset[1] - textOffset[1];
  18338. var descent = height - ascent;
  18339. document.body.removeChild(container);
  18340. this._setProperty('_textAscent', ascent);
  18341. this._setProperty('_textDescent', descent);
  18342. return this;
  18343. };
  18344. /**
  18345. * Helper fxn to measure ascent and descent.
  18346. * Adapted from http://stackoverflow.com/a/25355178
  18347. */
  18348. p5.prototype._calculateOffset = function(object) {
  18349. var currentLeft = 0,
  18350. currentTop = 0;
  18351. if (object.offsetParent) {
  18352. do {
  18353. currentLeft += object.offsetLeft;
  18354. currentTop += object.offsetTop;
  18355. } while (object = object.offsetParent);
  18356. } else {
  18357. currentLeft += object.offsetLeft;
  18358. currentTop += object.offsetTop;
  18359. }
  18360. return [currentLeft, currentTop];
  18361. };
  18362. module.exports = p5;
  18363. },{"../core/constants":16,"../core/core":17}],50:[function(require,module,exports){
  18364. /**
  18365. * @module Typography
  18366. * @submodule Loading & Displaying
  18367. * @for p5
  18368. * @requires core
  18369. */
  18370. 'use strict';
  18371. var p5 = require('../core/core');
  18372. var constants = require('../core/constants');
  18373. require('../core/error_helpers');
  18374. /**
  18375. * Draws text to the screen. Displays the information specified in the first
  18376. * parameter on the screen in the position specified by the additional
  18377. * parameters. A default font will be used unless a font is set with the
  18378. * textFont() function and a default size will be used unless a font is set
  18379. * with textSize(). Change the color of the text with the fill() function.
  18380. * Change the outline of the text with the stroke() and strokeWeight()
  18381. * functions.
  18382. *
  18383. * The text displays in relation to the textAlign() function, which gives the
  18384. * option to draw to the left, right, and center of the coordinates.
  18385. *
  18386. * The x2 and y2 parameters define a rectangular area to display within and
  18387. * may only be used with string data. When these parameters are specified,
  18388. * they are interpreted based on the current rectMode() setting. Text that
  18389. * does not fit completely within the rectangle specified will not be drawn
  18390. * to the screen.
  18391. *
  18392. * @method text
  18393. * @param {String} str the alphanumeric symbols to be displayed
  18394. * @param {Number} x x-coordinate of text
  18395. * @param {Number} y y-coordinate of text
  18396. * @param {Number} x2 by default, the width of the text box,
  18397. * see rectMode() for more info
  18398. * @param {Number} y2 by default, the height of the text box,
  18399. * see rectMode() for more info
  18400. * @return {Object} this
  18401. * @example
  18402. * <div>
  18403. * <code>
  18404. * textSize(32);
  18405. * text("word", 10, 30);
  18406. * fill(0, 102, 153);
  18407. * text("word", 10, 60);
  18408. * fill(0, 102, 153, 51);
  18409. * text("word", 10, 90);
  18410. * </code>
  18411. * </div>
  18412. * <div>
  18413. * <code>
  18414. * s = "The quick brown fox jumped over the lazy dog.";
  18415. * fill(50);
  18416. * text(s, 10, 10, 70, 80); // Text wraps within text box
  18417. * </code>
  18418. * </div>
  18419. */
  18420. p5.prototype.text = function(str, x, y, maxWidth, maxHeight) {
  18421. this._validateParameters(
  18422. 'text',
  18423. arguments,
  18424. [
  18425. ['*', 'Number', 'Number'],
  18426. ['*', 'Number', 'Number', 'Number', 'Number']
  18427. ]
  18428. );
  18429. return (!(this._doFill || this._doStroke)) ? this :
  18430. this._graphics.text.apply(this._graphics, arguments);
  18431. };
  18432. /**
  18433. * Sets the current font that will be drawn with the text() function.
  18434. *
  18435. * @method textFont
  18436. * @param {Object|String} f a font loaded via loadFont(), or a String
  18437. * representing a browser-based dfault font.
  18438. * @return {Object} this
  18439. * @example
  18440. * <div>
  18441. * <code>
  18442. * fill(0);
  18443. * textSize(12);
  18444. * textFont("Georgia");
  18445. * text("Georgia", 12, 30);
  18446. * textFont("Helvetica");
  18447. * text("Helvetica", 12, 60);
  18448. * </code>
  18449. * </div>
  18450. * <div>
  18451. * <code>
  18452. * var fontRegular, fontItalic, fontBold;
  18453. * function preload() {
  18454. * fontRegular = loadFont("assets/Regular.otf");
  18455. * fontItalic = loadFont("assets/Italic.ttf");
  18456. * fontBold = loadFont("assets/Bold.ttf");
  18457. * }
  18458. * function setup() {
  18459. * background(210);
  18460. * fill(0).strokeWeight(0).textSize(10);
  18461. * textFont(fontRegular);
  18462. * text("Font Style Normal", 10, 30);
  18463. * textFont(fontItalic);
  18464. * text("Font Style Italic", 10, 50);
  18465. * textFont(fontBold);
  18466. * text("Font Style Bold", 10, 70);
  18467. * }
  18468. * </code>
  18469. * </div>
  18470. */
  18471. p5.prototype.textFont = function(theFont, theSize) {
  18472. if (arguments.length) {
  18473. if (!theFont) {
  18474. throw Error('null font passed to textFont');
  18475. }
  18476. this._setProperty('_textFont', theFont);
  18477. if (theSize) {
  18478. this._setProperty('_textSize', theSize);
  18479. this._setProperty('_textLeading',
  18480. theSize * constants._DEFAULT_LEADMULT);
  18481. }
  18482. return this._graphics._applyTextProperties();
  18483. }
  18484. return this;
  18485. };
  18486. module.exports = p5;
  18487. },{"../core/constants":16,"../core/core":17,"../core/error_helpers":20}],51:[function(require,module,exports){
  18488. /**
  18489. * This module defines the p5.Font class and functions for
  18490. * drawing text to the display canvas.
  18491. * @module Typography
  18492. * @submodule Font
  18493. * @requires core
  18494. * @requires constants
  18495. */
  18496. 'use strict';
  18497. var p5 = require('../core/core');
  18498. var constants = require('../core/constants');
  18499. /*
  18500. * TODO:
  18501. *
  18502. * API:
  18503. * -- textBounds()
  18504. * -- getPath()
  18505. * -- getPoints()
  18506. *
  18507. * ===========================================
  18508. * -- PFont functions:
  18509. * PFont.list()
  18510. *
  18511. * -- kerning
  18512. * -- alignment: justified?
  18513. * -- integrate p5.dom? (later)
  18514. */
  18515. /**
  18516. * Base class for font handling
  18517. * @class p5.Font
  18518. * @constructor
  18519. * @param {Object} [pInst] pointer to p5 instance
  18520. */
  18521. p5.Font = function(p) {
  18522. this.parent = p;
  18523. this.cache = {};
  18524. /**
  18525. * Underlying opentype font implementation
  18526. * @property font
  18527. */
  18528. this.font = undefined;
  18529. };
  18530. p5.Font.prototype.list = function() {
  18531. // TODO
  18532. throw 'not yet implemented';
  18533. };
  18534. /**
  18535. * Returns a tight bounding box for the given text string using this
  18536. * font (currently only supports single lines)
  18537. *
  18538. * @method textBounds
  18539. * @param {String} line a line of text
  18540. * @param {Number} x x-position
  18541. * @param {Number} y y-position
  18542. * @param {Number} fontSize font size to use (optional)
  18543. * @param {Object} options opentype options (optional)
  18544. *
  18545. * @return {Object} a rectangle object with properties: x, y, w, h
  18546. *
  18547. * @example
  18548. * <div>
  18549. * <code>
  18550. * var font;
  18551. * var text = 'Lorem ipsum dolor sit amet.';
  18552. * function preload() {
  18553. * font = loadFont('./assets/fonts/Regular.otf');
  18554. * };
  18555. * function setup() {
  18556. * background(210);
  18557. * var bbox = font.textBounds(text, 10, 30, 12);
  18558. * fill(255);
  18559. * stroke(0);
  18560. * rect(bbox.x, bbox.y, bbox.w, bbox.h);
  18561. * fill(0);
  18562. * noStroke();
  18563. * * textFont(font);
  18564. * textSize(12);
  18565. * text(text, 10, 30);
  18566. * };
  18567. * </code>
  18568. * </div>
  18569. */
  18570. p5.Font.prototype.textBounds = function(str, x, y, fontSize, options) {
  18571. x = x !== undefined ? x : 0;
  18572. y = y !== undefined ? y : 0;
  18573. fontSize = fontSize || this.parent._textSize;
  18574. var result = this.cache[cacheKey('textBounds', str, x, y, fontSize)];
  18575. if (!result) {
  18576. var xCoords = [], yCoords = [], self = this,
  18577. scale = this._scale(fontSize), minX, minY, maxX, maxY;
  18578. this.font.forEachGlyph(str, x, y, fontSize, options,
  18579. function(glyph, gX, gY, gFontSize) {
  18580. xCoords.push(gX);
  18581. yCoords.push(gY);
  18582. if (glyph.name !== 'space') {
  18583. var gm = glyph.getMetrics();
  18584. xCoords.push(gX + (gm.xMax * scale));
  18585. yCoords.push(gY + (-gm.yMin * scale));
  18586. yCoords.push(gY + (-gm.yMax * scale));
  18587. } else {
  18588. xCoords.push(gX + self.font.charToGlyph(' ').advanceWidth *
  18589. self._scale(fontSize));
  18590. }
  18591. });
  18592. minX = Math.max(0, Math.min.apply(null, xCoords));
  18593. minY = Math.max(0, Math.min.apply(null, yCoords));
  18594. maxX = Math.max(0, Math.max.apply(null, xCoords));
  18595. maxY = Math.max(0, Math.max.apply(null, yCoords));
  18596. result = {
  18597. x: minX,
  18598. y: minY,
  18599. h: maxY - minY,
  18600. w: maxX - minX,
  18601. advance: minX - x
  18602. };
  18603. this.cache[cacheKey('textBounds', str, x, y, fontSize)] = result;
  18604. }
  18605. //else console.log('cache-hit');
  18606. return result;
  18607. };
  18608. // ----------------------------- End API ------------------------------
  18609. /**
  18610. * Returns the set of opentype glyphs for the supplied string.
  18611. *
  18612. * Note that there is not a strict one-to-one mapping between characters
  18613. * and glyphs, so the list of returned glyphs can be larger or smaller
  18614. * than the length of the given string.
  18615. *
  18616. * @param {String} str the string to be converted
  18617. * @return {array} the opentype glyphs
  18618. */
  18619. p5.Font.prototype._getGlyphs = function(str) {
  18620. return this.font.stringToGlyphs(str);
  18621. };
  18622. /**
  18623. * Returns an opentype path for the supplied string and position.
  18624. *
  18625. * @param {String} line a line of text
  18626. * @param {Number} x x-position
  18627. * @param {Number} y y-position
  18628. * @param {Object} options opentype options (optional)
  18629. * @return {Object} the opentype path
  18630. */
  18631. p5.Font.prototype._getPath = function(line, x, y, options) {
  18632. var p = this.parent,
  18633. ctx = p._graphics.drawingContext,
  18634. pos = this._handleAlignment(p, ctx, line, x, y);
  18635. return this.font.getPath(line, pos.x, pos.y, p._textSize, options);
  18636. };
  18637. /*
  18638. * Creates an SVG-formatted path-data string
  18639. * (See http://www.w3.org/TR/SVG/paths.html#PathData)
  18640. * from the given opentype path or string/position
  18641. *
  18642. * @param {Object} path an opentype path, OR the following:
  18643. *
  18644. * @param {String} line a line of text
  18645. * @param {Number} x x-position
  18646. * @param {Number} y y-position
  18647. * @param {Object} options opentype options (optional), set options.decimals
  18648. * to set the decimal precision of the path-data
  18649. *
  18650. * @return {Object} this p5.Font object
  18651. */
  18652. p5.Font.prototype._getPathData = function(line, x, y, options) {
  18653. var decimals = 3;
  18654. // create path from string/position
  18655. if (typeof line === 'string' && arguments.length > 2) {
  18656. line = this._getPath(line, x, y, options);
  18657. }
  18658. // handle options specified in 2nd arg
  18659. else if (typeof x === 'object') {
  18660. options = x;
  18661. }
  18662. // handle svg arguments
  18663. if (options && typeof options.decimals === 'number') {
  18664. decimals = options.decimals;
  18665. }
  18666. return line.toPathData(decimals);
  18667. };
  18668. /*
  18669. * Creates an SVG <path> element, as a string,
  18670. * from the given opentype path or string/position
  18671. *
  18672. * @param {Object} path an opentype path, OR the following:
  18673. *
  18674. * @param {String} line a line of text
  18675. * @param {Number} x x-position
  18676. * @param {Number} y y-position
  18677. * @param {Object} options opentype options (optional), set options.decimals
  18678. * to set the decimal precision of the path-data in the <path> element,
  18679. * options.fill to set the fill color for the <path> element,
  18680. * options.stroke to set the stroke color for the <path> element,
  18681. * options.strokeWidth to set the strokeWidth for the <path> element.
  18682. *
  18683. * @return {Object} this p5.Font object
  18684. */
  18685. p5.Font.prototype._getSVG = function(line, x, y, options) {
  18686. var decimals = 3;
  18687. // create path from string/position
  18688. if (typeof line === 'string' && arguments.length > 2) {
  18689. line = this._getPath(line, x, y, options);
  18690. }
  18691. // handle options specified in 2nd arg
  18692. else if (typeof x === 'object') {
  18693. options = x;
  18694. }
  18695. // handle svg arguments
  18696. if (options) {
  18697. if (typeof options.decimals === 'number') {
  18698. decimals = options.decimals;
  18699. }
  18700. if (typeof options.strokeWidth === 'number') {
  18701. line.strokeWidth = options.strokeWidth;
  18702. }
  18703. if (typeof options.fill !== 'undefined') {
  18704. line.fill = options.fill;
  18705. }
  18706. if (typeof options.stroke !== 'undefined') {
  18707. line.stroke = options.stroke;
  18708. }
  18709. }
  18710. return line.toSVG(decimals);
  18711. };
  18712. /*
  18713. * Renders an opentype path or string/position
  18714. * to the current graphics context
  18715. *
  18716. * @param {Object} path an opentype path, OR the following:
  18717. *
  18718. * @param {String} line a line of text
  18719. * @param {Number} x x-position
  18720. * @param {Number} y y-position
  18721. * @param {Object} options opentype options (optional)
  18722. *
  18723. * @return {Object} this p5.Font object
  18724. */
  18725. p5.Font.prototype._renderPath = function(line, x, y, options) {
  18726. // /console.log('_renderPath', typeof line);
  18727. var pdata, p = this.parent,
  18728. pg = p._graphics,
  18729. ctx = pg.drawingContext;
  18730. if (typeof line === 'object' && line.commands) {
  18731. pdata = line.commands;
  18732. } else {
  18733. //pos = handleAlignment(p, ctx, line, x, y);
  18734. pdata = this._getPath(line, x, y, p._textSize, options).commands;
  18735. }
  18736. ctx.beginPath();
  18737. for (var i = 0; i < pdata.length; i += 1) {
  18738. var cmd = pdata[i];
  18739. if (cmd.type === 'M') {
  18740. ctx.moveTo(cmd.x, cmd.y);
  18741. } else if (cmd.type === 'L') {
  18742. ctx.lineTo(cmd.x, cmd.y);
  18743. } else if (cmd.type === 'C') {
  18744. ctx.bezierCurveTo(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
  18745. } else if (cmd.type === 'Q') {
  18746. ctx.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
  18747. } else if (cmd.type === 'Z') {
  18748. ctx.closePath();
  18749. }
  18750. }
  18751. // only draw stroke if manually set by user
  18752. if (p._doStroke && p._strokeSet) {
  18753. ctx.stroke();
  18754. }
  18755. if (p._doFill) {
  18756. // if fill hasn't been set by user, use default-text-fill
  18757. ctx.fillStyle = p._fillSet ? ctx.fillStyle : constants._DEFAULT_TEXT_FILL;
  18758. ctx.fill();
  18759. }
  18760. return this;
  18761. };
  18762. p5.Font.prototype._textWidth = function(str, fontSize) {
  18763. if (str === ' ') { // special case for now
  18764. return this.font.charToGlyph(' ').advanceWidth * this._scale(fontSize);
  18765. }
  18766. var bounds = this.textBounds(str, 0, 0, fontSize);
  18767. return bounds.w + bounds.advance;
  18768. };
  18769. p5.Font.prototype._textAscent = function(fontSize) {
  18770. return this.font.ascender * this._scale(fontSize);
  18771. };
  18772. p5.Font.prototype._textDescent = function(fontSize) {
  18773. return -this.font.descender * this._scale(fontSize);
  18774. };
  18775. p5.Font.prototype._scale = function(fontSize) {
  18776. return (1 / this.font.unitsPerEm) * (fontSize || this.parent._textSize);
  18777. };
  18778. p5.Font.prototype._handleAlignment = function(p, ctx, line, x, y) {
  18779. var textWidth = this._textWidth(line),
  18780. textAscent = this._textAscent(),
  18781. textDescent = this._textDescent(),
  18782. textHeight = textAscent + textDescent;
  18783. if (ctx.textAlign === constants.CENTER) {
  18784. x -= textWidth / 2;
  18785. } else if (ctx.textAlign === constants.RIGHT) {
  18786. x -= textWidth;
  18787. }
  18788. if (ctx.textBaseline === constants.TOP) {
  18789. y += textHeight;
  18790. } else if (ctx.textBaseline === constants._CTX_MIDDLE) {
  18791. y += textHeight / 2 - textDescent;
  18792. } else if (ctx.textBaseline === constants.BOTTOM) {
  18793. y -= textDescent;
  18794. }
  18795. return { x: x, y: y };
  18796. };
  18797. function cacheKey() {
  18798. var args = Array.prototype.slice.call(arguments),
  18799. i = args.length,
  18800. hash = '';
  18801. while (i--) {
  18802. hash += (args[i] === Object(args[i])) ?
  18803. JSON.stringify(args[i]) : args[i];
  18804. }
  18805. return hash;
  18806. }
  18807. module.exports = p5.Font;
  18808. },{"../core/constants":16,"../core/core":17}],52:[function(require,module,exports){
  18809. /**
  18810. * @module Data
  18811. * @submodule Array Functions
  18812. * @for p5
  18813. * @requires core
  18814. */
  18815. 'use strict';
  18816. var p5 = require('../core/core');
  18817. /**
  18818. * Adds a value to the end of an array. Extends the length of
  18819. * the array by one. Maps to Array.push().
  18820. *
  18821. * @method append
  18822. * @param {Array} array Array to append
  18823. * @param {any} value to be added to the Array
  18824. * @example
  18825. * <div class = "norender"><code>
  18826. * function setup() {
  18827. *
  18828. * var myArray = new Array("Mango", "Apple", "Papaya")
  18829. * print(myArray) // ["Mango", "Apple", "Papaya"]
  18830. *
  18831. * append(myArray, "Peach")
  18832. * print(myArray) // ["Mango", "Apple", "Papaya", "Peach"]
  18833. *
  18834. * }
  18835. * </div></code>
  18836. */
  18837. p5.prototype.append = function(array, value) {
  18838. array.push(value);
  18839. return array;
  18840. };
  18841. /**
  18842. * Copies an array (or part of an array) to another array. The src array is
  18843. * copied to the dst array, beginning at the position specified by
  18844. * srcPosition and into the position specified by dstPosition. The number of
  18845. * elements to copy is determined by length. Note that copying values
  18846. * overwrites existing values in the destination array. To append values
  18847. * instead of overwriting them, use concat().
  18848. *
  18849. * The simplified version with only two arguments — arrayCopy(src, dst) —
  18850. * copies an entire array to another of the same size. It is equivalent to
  18851. * arrayCopy(src, 0, dst, 0, src.length).
  18852. *
  18853. * Using this function is far more efficient for copying array data than
  18854. * iterating through a for() loop and copying each element individually.
  18855. *
  18856. * @method arrayCopy
  18857. * @param {Array} src the source Array
  18858. * @param {Number} [srcPosition] starting position in the source Array
  18859. * @param {Array} dst the destination Array
  18860. * @param {Number} [dstPosition] starting position in the destination Array
  18861. * @param {Nimber} [length] number of Array elements to be copied
  18862. *
  18863. * @example
  18864. * <div class="norender"><code>
  18865. * function setup() {
  18866. *
  18867. * var src = new Array("A", "B", "C");
  18868. * var dst = new Array( 1 , 2 , 3 );
  18869. * var srcPosition = 1;
  18870. * var dstPosition = 0;
  18871. * var length = 2;
  18872. *
  18873. * print(src); // ["A", "B", "C"]
  18874. * print(dst); // [ 1 , 2 , 3 ]
  18875. *
  18876. * arrayCopy(src, srcPosition, dst, dstPosition, length);
  18877. * print(dst); // ["B", "C", 3]
  18878. *
  18879. * }
  18880. * </div></code>
  18881. */
  18882. p5.prototype.arrayCopy = function(
  18883. src,
  18884. srcPosition,
  18885. dst,
  18886. dstPosition,
  18887. length) {
  18888. // the index to begin splicing from dst array
  18889. var start,
  18890. end;
  18891. if (typeof length !== 'undefined') {
  18892. end = Math.min(length, src.length);
  18893. start = dstPosition;
  18894. src = src.slice(srcPosition, end + srcPosition);
  18895. } else {
  18896. if (typeof dst !== 'undefined') { // src, dst, length
  18897. // rename so we don't get confused
  18898. end = dst;
  18899. end = Math.min(end, src.length);
  18900. } else { // src, dst
  18901. end = src.length;
  18902. }
  18903. start = 0;
  18904. // rename so we don't get confused
  18905. dst = srcPosition;
  18906. src = src.slice(0, end);
  18907. }
  18908. // Since we are not returning the array and JavaScript is pass by reference
  18909. // we must modify the actual values of the array
  18910. // instead of reassigning arrays
  18911. Array.prototype.splice.apply(dst, [start, end].concat(src));
  18912. };
  18913. /**
  18914. * Concatenates two arrays, maps to Array.concat(). Does not modify the
  18915. * input arrays.
  18916. *
  18917. * @method concat
  18918. * @param {Array} a first Array to concatenate
  18919. * @param {Array} b second Array to concatenate
  18920. * @return {Array} concatenated array
  18921. *
  18922. * @example
  18923. * <div class = "norender"><code>
  18924. * function setup() {
  18925. * var arr1 = new Array("A", "B", "C");
  18926. * var arr2 = new Array( 1 , 2 , 3 );
  18927. *
  18928. * print(arr1); // ["A","B","C"]
  18929. * print(arr2); // [1,2,3]
  18930. *
  18931. * var arr3 = concat(arr1, arr2);
  18932. *
  18933. * print(arr1); // ["A","B","C"]
  18934. * print(arr2); // [1,2,3]
  18935. * print(arr3); // ["A","B","C",1,2,3]
  18936. *
  18937. * }
  18938. * </div></code>
  18939. */
  18940. p5.prototype.concat = function(list0, list1) {
  18941. return list0.concat(list1);
  18942. };
  18943. /**
  18944. * Reverses the order of an array, maps to Array.reverse()
  18945. *
  18946. * @method reverse
  18947. * @param {Array} list Array to reverse
  18948. * @example
  18949. * <div class="norender"><code>
  18950. * function setup() {
  18951. * var myArray = new Array("A", "B", "C");
  18952. * print(myArray); // ["A","B","C"]
  18953. *
  18954. * reverse(myArray);
  18955. * print(myArray); // ["C","B","A"]
  18956. * }
  18957. * </div></code>
  18958. */
  18959. p5.prototype.reverse = function(list) {
  18960. return list.reverse();
  18961. };
  18962. /**
  18963. * Decreases an array by one element and returns the shortened array,
  18964. * maps to Array.pop().
  18965. *
  18966. * @method shorten
  18967. * @param {Array} list Array to shorten
  18968. * @return {Array} shortened Array
  18969. * @example
  18970. * <div class = "norender"><code>
  18971. * function setup() {
  18972. * var myArray = new Array("A", "B", "C");
  18973. * print(myArray); // ["A","B","C"]
  18974. *
  18975. * var newArray = shorten(myArray);
  18976. * print(myArray); // ["A","B","C"]
  18977. * print(newArray); // ["A","B"]
  18978. * }
  18979. * </div></code>
  18980. */
  18981. p5.prototype.shorten = function(list) {
  18982. list.pop();
  18983. return list;
  18984. };
  18985. /**
  18986. * Randomizes the order of the elements of an array.
  18987. * Implements Fisher-Yates Shuffle Algorithm
  18988. * http://Bost.Ocks.org/mike/shuffle/
  18989. * http://en.Wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
  18990. *
  18991. * @method shuffle
  18992. * @param {Array} array Array to shuffle
  18993. * @param {Boolean} [bool] modify passed array
  18994. * @return {Array} shuffled Array
  18995. * @example
  18996. * <div><code>
  18997. * function setup() {
  18998. * var regularArr = ['ABC', 'def', createVector(), TAU, Math.E];
  18999. * print(regularArr);
  19000. * shuffle(regularArr, true); // force modifications to passed array
  19001. * print(regularArr);
  19002. *
  19003. * // By default shuffle() returns a shuffled cloned array:
  19004. * var newArr = shuffle(regularArr);
  19005. * print(regularArr);
  19006. * print(newArr);
  19007. * }
  19008. * </code></div>
  19009. */
  19010. p5.prototype.shuffle = function(arr, bool) {
  19011. arr = bool || ArrayBuffer.isView(arr)? arr : arr.slice();
  19012. var rnd, tmp, idx = arr.length;
  19013. while (idx > 1) {
  19014. rnd = Math.random()*idx | 0;
  19015. tmp = arr[--idx];
  19016. arr[idx] = arr[rnd];
  19017. arr[rnd] = tmp;
  19018. }
  19019. return arr;
  19020. };
  19021. /**
  19022. * Sorts an array of numbers from smallest to largest, or puts an array of
  19023. * words in alphabetical order. The original array is not modified; a
  19024. * re-ordered array is returned. The count parameter states the number of
  19025. * elements to sort. For example, if there are 12 elements in an array and
  19026. * count is set to 5, only the first 5 elements in the array will be sorted.
  19027. *
  19028. * @method sort
  19029. * @param {Array} list Array to sort
  19030. * @param {Number} [count] number of elements to sort, starting from 0
  19031. *
  19032. * @example
  19033. * <div class = "norender"><code>
  19034. * function setup() {
  19035. * var words = new Array("banana", "apple", "pear","lime");
  19036. * print(words); // ["banana", "apple", "pear", "lime"]
  19037. * var count = 4; // length of array
  19038. *
  19039. * sort(words, count);
  19040. * print(words); // ["apple", "banana", "lime", "pear"]
  19041. * }
  19042. * </div></code>
  19043. * <div class = "norender"><code>
  19044. * function setup() {
  19045. * var numbers = new Array(2,6,1,5,14,9,8,12);
  19046. * print(numbers); // [2,6,1,5,14,9,8,12]
  19047. * var count = 5; // Less than the length of the array
  19048. *
  19049. * sort(numbers, count);
  19050. * print(numbers); // [1,2,5,6,14,9,8,12]
  19051. * }
  19052. * </div></code>
  19053. */
  19054. p5.prototype.sort = function(list, count) {
  19055. var arr = count ? list.slice(0, Math.min(count, list.length)) : list;
  19056. var rest = count ? list.slice(Math.min(count, list.length)) : [];
  19057. if (typeof arr[0] === 'string') {
  19058. arr = arr.sort();
  19059. } else {
  19060. arr = arr.sort(function(a,b){return a-b;});
  19061. }
  19062. return arr.concat(rest);
  19063. };
  19064. /**
  19065. * Inserts a value or an array of values into an existing array. The first
  19066. * parameter specifies the initial array to be modified, and the second
  19067. * parameter defines the data to be inserted. The third parameter is an index
  19068. * value which specifies the array position from which to insert data.
  19069. * (Remember that array index numbering starts at zero, so the first position
  19070. * is 0, the second position is 1, and so on.)
  19071. *
  19072. * @method splice
  19073. * @param {Array} list Array to splice into
  19074. * @param {any} value value to be spliced in
  19075. * @param {Number} position in the array from which to insert data
  19076. *
  19077. * @example
  19078. * <div class = "norender"><code>
  19079. * function setup() {
  19080. * var myArray = new Array(0,1,2,3,4);
  19081. * var insArray = new Array("A","B","C");
  19082. * print(myArray); // [0,1,2,3,4]
  19083. * print(insArray); // ["A","B","C"]
  19084. *
  19085. * splice(myArray, insArray, 3);
  19086. * print(myArray); // [0,1,2,"A","B","C",3,4]
  19087. * }
  19088. * </div></code>
  19089. */
  19090. p5.prototype.splice = function(list, value, index) {
  19091. // note that splice returns spliced elements and not an array
  19092. Array.prototype.splice.apply(list, [index, 0].concat(value));
  19093. return list;
  19094. };
  19095. /**
  19096. * Extracts an array of elements from an existing array. The list parameter
  19097. * defines the array from which the elements will be copied, and the start
  19098. * and count parameters specify which elements to extract. If no count is
  19099. * given, elements will be extracted from the start to the end of the array.
  19100. * When specifying the start, remember that the first array element is 0.
  19101. * This function does not change the source array.
  19102. *
  19103. * @method subset
  19104. * @param {Array} list Array to extract from
  19105. * @param {Number} start position to begin
  19106. * @param {Number} [count] number of values to extract
  19107. * @return {Array} Array of extracted elements
  19108. *
  19109. * @example
  19110. * <div class = "norender"><code>
  19111. * function setup() {
  19112. * var myArray = new Array(1,2,3,4,5);
  19113. * print(myArray); // [1,2,3,4,5]
  19114. *
  19115. * var sub1 = subset(myArray, 0, 3);
  19116. * var sub2 = subset(myArray, 2, 2);
  19117. * print(sub1); // [1,2,3]
  19118. * print(sub2); // [3,4]
  19119. * }
  19120. * </div></code>
  19121. */
  19122. p5.prototype.subset = function(list, start, count) {
  19123. if (typeof count !== 'undefined') {
  19124. return list.slice(start, start + count);
  19125. } else {
  19126. return list.slice(start, list.length);
  19127. }
  19128. };
  19129. module.exports = p5;
  19130. },{"../core/core":17}],53:[function(require,module,exports){
  19131. /**
  19132. * @module Data
  19133. * @submodule Conversion
  19134. * @for p5
  19135. * @requires core
  19136. */
  19137. 'use strict';
  19138. var p5 = require('../core/core');
  19139. /**
  19140. * Converts a string to its floating point representation. The contents of a
  19141. * string must resemble a number, or NaN (not a number) will be returned.
  19142. * For example, float("1234.56") evaluates to 1234.56, but float("giraffe")
  19143. * will return NaN.
  19144. *
  19145. * @method float
  19146. * @param {String} str float string to parse
  19147. * @return {Number} floating point representation of string
  19148. * @example
  19149. * <div><code>
  19150. * var str = '20';
  19151. * var diameter = float(str);
  19152. * ellipse(width/2, height/2, diameter, diameter);
  19153. * </code></div>
  19154. */
  19155. p5.prototype.float = function(str) {
  19156. return parseFloat(str);
  19157. };
  19158. /**
  19159. * Converts a boolean, string, or float to its integer representation.
  19160. * When an array of values is passed in, then an int array of the same length
  19161. * is returned.
  19162. *
  19163. * @method int
  19164. * @param {String|Boolean|Number|Array} n value to parse
  19165. * @return {Number} integer representation of value
  19166. * @example
  19167. * <div class='norender'><code>
  19168. * print(int("10")); // 10
  19169. * print(int(10.31)); // 10
  19170. * print(int(-10)); // -10
  19171. * print(int(true)); // 1
  19172. * print(int(false)); // 0
  19173. * print(int([false, true, "10.3", 9.8])); // [0, 1, 10, 9]
  19174. * </code></div>
  19175. */
  19176. p5.prototype.int = function(n, radix) {
  19177. if (typeof n === 'string') {
  19178. radix = radix || 10;
  19179. return parseInt(n, radix);
  19180. } else if (typeof n === 'number') {
  19181. return n | 0;
  19182. } else if (typeof n === 'boolean') {
  19183. return n ? 1 : 0;
  19184. } else if (n instanceof Array) {
  19185. return n.map(function(n) { return p5.prototype.int(n, radix); });
  19186. }
  19187. };
  19188. /**
  19189. * Converts a boolean, string or number to its string representation.
  19190. * When an array of values is passed in, then an array of strings of the same
  19191. * length is returned.
  19192. *
  19193. * @method str
  19194. * @param {String|Boolean|Number|Array} n value to parse
  19195. * @return {String} string representation of value
  19196. * @example
  19197. * <div class='norender'><code>
  19198. * print(str("10")); // "10"
  19199. * print(str(10.31)); // "10.31"
  19200. * print(str(-10)); // "-10"
  19201. * print(str(true)); // "true"
  19202. * print(str(false)); // "false"
  19203. * print(str([true, "10.3", 9.8])); // [ "true", "10.3", "9.8" ]
  19204. * </code></div>
  19205. */
  19206. p5.prototype.str = function(n) {
  19207. if (n instanceof Array) {
  19208. return n.map(p5.prototype.str);
  19209. } else {
  19210. return String(n);
  19211. }
  19212. };
  19213. /**
  19214. * Converts a number or string to its boolean representation.
  19215. * For a number, any non-zero value (positive or negative) evaluates to true,
  19216. * while zero evaluates to false. For a string, the value "true" evaluates to
  19217. * true, while any other value evaluates to false. When an array of number or
  19218. * string values is passed in, then a array of booleans of the same length is
  19219. * returned.
  19220. *
  19221. * @method boolean
  19222. * @param {String|Boolean|Number|Array} n value to parse
  19223. * @return {Boolean} boolean representation of value
  19224. * @example
  19225. * <div class='norender'><code>
  19226. * print(boolean(0)); // false
  19227. * print(boolean(1)); // true
  19228. * print(boolean("true")); // true
  19229. * print(boolean("abcd")); // false
  19230. * print(boolean([0, 12, "true"])); // [false, true, false]
  19231. * </code></div>
  19232. */
  19233. p5.prototype.boolean = function(n) {
  19234. if (typeof n === 'number') {
  19235. return n !== 0;
  19236. } else if (typeof n === 'string') {
  19237. return n.toLowerCase() === 'true';
  19238. } else if (typeof n === 'boolean') {
  19239. return n;
  19240. } else if (n instanceof Array) {
  19241. return n.map(p5.prototype.boolean);
  19242. }
  19243. };
  19244. /**
  19245. * Converts a number, string or boolean to its byte representation.
  19246. * A byte can be only a whole number between -128 and 127, so when a value
  19247. * outside of this range is converted, it wraps around to the corresponding
  19248. * byte representation. When an array of number, string or boolean values is
  19249. * passed in, then an array of bytes the same length is returned.
  19250. *
  19251. * @method byte
  19252. * @param {String|Boolean|Number|Array} n value to parse
  19253. * @return {Number} byte representation of value
  19254. * @example
  19255. * <div class='norender'><code>
  19256. * print(byte(127)); // 127
  19257. * print(byte(128)); // -128
  19258. * print(byte(23.4)); // 23
  19259. * print(byte("23.4")); // 23
  19260. * print(byte(true)); // 1
  19261. * print(byte([0, 255, "100"])); // [0, -1, 100]
  19262. * </code></div>
  19263. */
  19264. p5.prototype.byte = function(n) {
  19265. var nn = p5.prototype.int(n, 10);
  19266. if (typeof nn === 'number') {
  19267. return ((nn + 128) % 256) - 128;
  19268. } else if (nn instanceof Array) {
  19269. return nn.map(p5.prototype.byte);
  19270. }
  19271. };
  19272. /**
  19273. * Converts a number or string to its corresponding single-character
  19274. * string representation. If a string parameter is provided, it is first
  19275. * parsed as an integer and then translated into a single-character string.
  19276. * When an array of number or string values is passed in, then an array of
  19277. * single-character strings of the same length is returned.
  19278. *
  19279. * @method char
  19280. * @param {String|Number|Array} n value to parse
  19281. * @return {String} string representation of value
  19282. * @example
  19283. * <div class='norender'><code>
  19284. * print(char(65)); // "A"
  19285. * print(char("65")); // "A"
  19286. * print(char([65, 66, 67])); // [ "A", "B", "C" ]
  19287. * print(join(char([65, 66, 67]), '')); // "ABC"
  19288. * </code></div>
  19289. */
  19290. p5.prototype.char = function(n) {
  19291. if (typeof n === 'number' && !isNaN(n)) {
  19292. return String.fromCharCode(n);
  19293. } else if (n instanceof Array) {
  19294. return n.map(p5.prototype.char);
  19295. } else if (typeof n === 'string') {
  19296. return p5.prototype.char(parseInt(n, 10));
  19297. }
  19298. };
  19299. /**
  19300. * Converts a single-character string to its corresponding integer
  19301. * representation. When an array of single-character string values is passed
  19302. * in, then an array of integers of the same length is returned.
  19303. *
  19304. * @method unchar
  19305. * @param {String|Array} n value to parse
  19306. * @return {Number} integer representation of value
  19307. * @example
  19308. * <div class='norender'><code>
  19309. * print(unchar("A")); // 65
  19310. * print(unchar(["A", "B", "C"])); // [ 65, 66, 67 ]
  19311. * print(unchar(split("ABC", ""))); // [ 65, 66, 67 ]
  19312. * </code></div>
  19313. */
  19314. p5.prototype.unchar = function(n) {
  19315. if (typeof n === 'string' && n.length === 1) {
  19316. return n.charCodeAt(0);
  19317. } else if (n instanceof Array) {
  19318. return n.map(p5.prototype.unchar);
  19319. }
  19320. };
  19321. /**
  19322. * Converts a number to a string in its equivalent hexadecimal notation. If a
  19323. * second parameter is passed, it is used to set the number of characters to
  19324. * generate in the hexadecimal notation. When an array is passed in, an
  19325. * array of strings in hexadecimal notation of the same length is returned.
  19326. *
  19327. * @method hex
  19328. * @param {Number|Array} n value to parse
  19329. * @return {String} hexadecimal string representation of value
  19330. * @example
  19331. * <div class='norender'><code>
  19332. * print(hex(255)); // "000000FF"
  19333. * print(hex(255, 6)); // "0000FF"
  19334. * print(hex([0, 127, 255], 6)); // [ "000000", "00007F", "0000FF" ]
  19335. * </code></div>
  19336. */
  19337. p5.prototype.hex = function(n, digits) {
  19338. digits = (digits === undefined || digits === null) ? digits = 8 : digits;
  19339. if (n instanceof Array) {
  19340. return n.map(function(n) { return p5.prototype.hex(n, digits); });
  19341. } else if (typeof n === 'number') {
  19342. if (n < 0) {
  19343. n = 0xFFFFFFFF + n + 1;
  19344. }
  19345. var hex = Number(n).toString(16).toUpperCase();
  19346. while (hex.length < digits) {
  19347. hex = '0' + hex;
  19348. }
  19349. if (hex.length >= digits) {
  19350. hex = hex.substring(hex.length - digits, hex.length);
  19351. }
  19352. return hex;
  19353. }
  19354. };
  19355. /**
  19356. * Converts a string representation of a hexadecimal number to its equivalent
  19357. * integer value. When an array of strings in hexadecimal notation is passed
  19358. * in, an array of integers of the same length is returned.
  19359. *
  19360. * @method unhex
  19361. * @param {String|Array} n value to parse
  19362. * @return {Number} integer representation of hexadecimal value
  19363. * @example
  19364. * <div class='norender'><code>
  19365. * print(unhex("A")); // 10
  19366. * print(unhex("FF")); // 255
  19367. * print(unhex(["FF", "AA", "00"])); // [ 255, 170, 0 ]
  19368. * </code></div>
  19369. */
  19370. p5.prototype.unhex = function(n) {
  19371. if (n instanceof Array) {
  19372. return n.map(p5.prototype.unhex);
  19373. } else {
  19374. return parseInt('0x' + n, 16);
  19375. }
  19376. };
  19377. module.exports = p5;
  19378. },{"../core/core":17}],54:[function(require,module,exports){
  19379. /**
  19380. * @module Data
  19381. * @submodule String Functions
  19382. * @for p5
  19383. * @requires core
  19384. */
  19385. 'use strict';
  19386. var p5 = require('../core/core');
  19387. //return p5; //LM is this a mistake?
  19388. /**
  19389. * Combines an array of Strings into one String, each separated by the
  19390. * character(s) used for the separator parameter. To join arrays of ints or
  19391. * floats, it's necessary to first convert them to Strings using nf() or
  19392. * nfs().
  19393. *
  19394. * @method join
  19395. * @param {Array} list array of Strings to be joined
  19396. * @param {String} separator String to be placed between each item
  19397. * @return {String} joined String
  19398. * @example
  19399. * <div>
  19400. * <code>
  19401. * var array = ["Hello", "world!"]
  19402. * var separator = " "
  19403. * var message = join(array, separator);
  19404. * text(message, 5, 50);
  19405. * </code>
  19406. * </div>
  19407. */
  19408. p5.prototype.join = function(list, separator) {
  19409. return list.join(separator);
  19410. };
  19411. /**
  19412. * This function is used to apply a regular expression to a piece of text,
  19413. * and return matching groups (elements found inside parentheses) as a
  19414. * String array. If there are no matches, a null value will be returned.
  19415. * If no groups are specified in the regular expression, but the sequence
  19416. * matches, an array of length 1 (with the matched text as the first element
  19417. * of the array) will be returned.
  19418. *
  19419. * To use the function, first check to see if the result is null. If the
  19420. * result is null, then the sequence did not match at all. If the sequence
  19421. * did match, an array is returned.
  19422. *
  19423. * If there are groups (specified by sets of parentheses) in the regular
  19424. * expression, then the contents of each will be returned in the array.
  19425. * Element [0] of a regular expression match returns the entire matching
  19426. * string, and the match groups start at element [1] (the first group is [1],
  19427. * the second [2], and so on).
  19428. *
  19429. * @method match
  19430. * @param {String} str the String to be searched
  19431. * @param {String} regexp the regexp to be used for matching
  19432. * @return {Array} Array of Strings found
  19433. * @example
  19434. * <div>
  19435. * <code>
  19436. * var string = "Hello p5js*!"
  19437. * var regexp = "p5js\\*"
  19438. * var match = match(string, regexp);
  19439. * text(match, 5, 50);
  19440. * </code>
  19441. * </div>
  19442. */
  19443. p5.prototype.match = function(str, reg) {
  19444. return str.match(reg);
  19445. };
  19446. /**
  19447. * This function is used to apply a regular expression to a piece of text,
  19448. * and return a list of matching groups (elements found inside parentheses)
  19449. * as a two-dimensional String array. If there are no matches, a null value
  19450. * will be returned. If no groups are specified in the regular expression,
  19451. * but the sequence matches, a two dimensional array is still returned, but
  19452. * the second dimension is only of length one.
  19453. *
  19454. * To use the function, first check to see if the result is null. If the
  19455. * result is null, then the sequence did not match at all. If the sequence
  19456. * did match, a 2D array is returned.
  19457. *
  19458. * If there are groups (specified by sets of parentheses) in the regular
  19459. * expression, then the contents of each will be returned in the array.
  19460. * Assuming a loop with counter variable i, element [i][0] of a regular
  19461. * expression match returns the entire matching string, and the match groups
  19462. * start at element [i][1] (the first group is [i][1], the second [i][2],
  19463. * and so on).
  19464. *
  19465. * @method matchAll
  19466. * @param {String} str the String to be searched
  19467. * @param {String} regexp the regexp to be used for matching
  19468. * @return {Array} 2d Array of Strings found
  19469. * @example
  19470. * <div class="norender">
  19471. * <code>
  19472. * var string = "Hello p5js*! Hello world!"
  19473. * var regexp = "Hello"
  19474. * matchAll(string, regexp);
  19475. * </code>
  19476. * </div>
  19477. */
  19478. p5.prototype.matchAll = function(str, reg) {
  19479. var re = new RegExp(reg, 'g');
  19480. var match = re.exec(str);
  19481. var matches = [];
  19482. while (match !== null) {
  19483. matches.push(match);
  19484. // matched text: match[0]
  19485. // match start: match.index
  19486. // capturing group n: match[n]
  19487. match = re.exec(str);
  19488. }
  19489. return matches;
  19490. };
  19491. /**
  19492. * Utility function for formatting numbers into strings. There are two
  19493. * versions: one for formatting floats, and one for formatting ints.
  19494. * The values for the digits, left, and right parameters should always
  19495. * be positive integers.
  19496. *
  19497. * @method nf
  19498. * @param {Number|Array} num the Number to format
  19499. * @param {Number} [left] number of digits to the left of the
  19500. * decimal point
  19501. * @param {Number} [right] number of digits to the right of the
  19502. * decimal point
  19503. * @return {String|Array} formatted String
  19504. * @example
  19505. * <div>
  19506. * <code>
  19507. * function setup() {
  19508. * background(200);
  19509. * var num = 112.53106115;
  19510. *
  19511. * noStroke();
  19512. * fill(0);
  19513. * textSize(14);
  19514. * // Draw formatted numbers
  19515. * text(nf(num, 5, 2), 10, 20);
  19516. *
  19517. * text(nf(num, 4, 3), 10, 55);
  19518. *
  19519. * text(nf(num, 3, 6), 10, 85);
  19520. *
  19521. * // Draw dividing lines
  19522. * stroke(120);
  19523. * line(0, 30, width, 30);
  19524. * line(0, 65, width, 65);
  19525. * }
  19526. * </code>
  19527. * </div>
  19528. */
  19529. p5.prototype.nf = function () {
  19530. if (arguments[0] instanceof Array) {
  19531. var a = arguments[1];
  19532. var b = arguments[2];
  19533. return arguments[0].map(function (x) {
  19534. return doNf(x, a, b);
  19535. });
  19536. }
  19537. else{
  19538. var typeOfFirst = Object.prototype.toString.call(arguments[0]);
  19539. if(typeOfFirst === '[object Arguments]'){
  19540. if(arguments[0].length===3){
  19541. return this.nf(arguments[0][0],arguments[0][1],arguments[0][2]);
  19542. }
  19543. else if(arguments[0].length===2){
  19544. return this.nf(arguments[0][0],arguments[0][1]);
  19545. }
  19546. else{
  19547. return this.nf(arguments[0][0]);
  19548. }
  19549. }
  19550. else {
  19551. return doNf.apply(this, arguments);
  19552. }
  19553. }
  19554. };
  19555. function doNf() {
  19556. var num = arguments[0];
  19557. var neg = num < 0;
  19558. var n = neg ? num.toString().substring(1) : num.toString();
  19559. var decimalInd = n.indexOf('.');
  19560. var intPart = decimalInd !== -1 ? n.substring(0, decimalInd) : n;
  19561. var decPart = decimalInd !== -1 ? n.substring(decimalInd + 1) : '';
  19562. var str = neg ? '-' : '';
  19563. if (arguments.length === 3) {
  19564. var decimal = '';
  19565. if(decimalInd !== -1 || arguments[2] - decPart.length > 0){
  19566. decimal = '.';
  19567. }
  19568. if (decPart.length > arguments[2]) {
  19569. decPart = decPart.substring(0, arguments[2]);
  19570. }
  19571. for (var i = 0; i < arguments[1] - intPart.length; i++) {
  19572. str += '0';
  19573. }
  19574. str += intPart;
  19575. str += decimal;
  19576. str += decPart;
  19577. for (var j = 0; j < arguments[2] - decPart.length; j++) {
  19578. str += '0';
  19579. }
  19580. return str;
  19581. }
  19582. else {
  19583. for (var k = 0; k < Math.max(arguments[1] - intPart.length, 0); k++) {
  19584. str += '0';
  19585. }
  19586. str += n;
  19587. return str;
  19588. }
  19589. }
  19590. /**
  19591. * Utility function for formatting numbers into strings and placing
  19592. * appropriate commas to mark units of 1000. There are two versions: one
  19593. * for formatting ints, and one for formatting an array of ints. The value
  19594. * for the right parameter should always be a positive integer.
  19595. *
  19596. * @method nfc
  19597. * @param {Number|Array} num the Number to format
  19598. * @param {Number} [right] number of digits to the right of the
  19599. * decimal point
  19600. * @return {String|Array} formatted String
  19601. * @example
  19602. * <div>
  19603. * <code>
  19604. * function setup() {
  19605. * background(200);
  19606. * var num = 11253106.115;
  19607. * var numArr = new Array(1,1,2);
  19608. *
  19609. * noStroke();
  19610. * fill(0);
  19611. * textSize(12);
  19612. *
  19613. * // Draw formatted numbers
  19614. * text(nfc(num, 4, 2), 10, 30);
  19615. * text(nfc(numArr, 2, 1), 10, 80);
  19616. *
  19617. * // Draw dividing line
  19618. * stroke(120);
  19619. * line(0, 50, width, 50);
  19620. * }
  19621. * </code>
  19622. * </div>
  19623. */
  19624. p5.prototype.nfc = function () {
  19625. if (arguments[0] instanceof Array) {
  19626. var a = arguments[1];
  19627. return arguments[0].map(function (x) {
  19628. return doNfc(x, a);
  19629. });
  19630. } else {
  19631. return doNfc.apply(this, arguments);
  19632. }
  19633. };
  19634. function doNfc() {
  19635. var num = arguments[0].toString();
  19636. var dec = num.indexOf('.');
  19637. var rem = dec !== -1 ? num.substring(dec) : '';
  19638. var n = dec !== -1 ? num.substring(0, dec) : num;
  19639. n = n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
  19640. if (arguments[1] === 0) {
  19641. rem = '';
  19642. }
  19643. else if(arguments[1] !== undefined){
  19644. if(arguments[1] > rem.length){
  19645. rem+= dec === -1 ? '.' : '';
  19646. var len = arguments[1] - rem.length + 1;
  19647. for(var i =0; i< len; i++){
  19648. rem += '0';
  19649. }
  19650. }
  19651. else{
  19652. rem = rem.substring(0, arguments[1] + 1);
  19653. }
  19654. }
  19655. return n + rem;
  19656. }
  19657. /**
  19658. * Utility function for formatting numbers into strings. Similar to nf() but
  19659. * puts a "+" in front of positive numbers and a "-" in front of negative
  19660. * numbers. There are two versions: one for formatting floats, and one for
  19661. * formatting ints. The values for left, and right parameters
  19662. * should always be positive integers.
  19663. *
  19664. * @method nfp
  19665. * @param {Number|Array} num the Number to format
  19666. * @param {Number} [left] number of digits to the left of the decimal
  19667. * point
  19668. * @param {Number} [right] number of digits to the right of the
  19669. * decimal point
  19670. * @return {String|Array} formatted String
  19671. * @example
  19672. * <div>
  19673. * <code>
  19674. * function setup() {
  19675. * background(200);
  19676. * var num1 = 11253106.115;
  19677. * var num2 = -11253106.115;
  19678. *
  19679. * noStroke();
  19680. * fill(0);
  19681. * textSize(12);
  19682. *
  19683. * // Draw formatted numbers
  19684. * text(nfp(num1, 4, 2), 10, 30);
  19685. * text(nfp(num2, 4, 2), 10, 80);
  19686. *
  19687. * // Draw dividing line
  19688. * stroke(120);
  19689. * line(0, 50, width, 50);
  19690. * }
  19691. * </code>
  19692. * </div>
  19693. */
  19694. p5.prototype.nfp = function() {
  19695. var nfRes = this.nf.apply(this, arguments);
  19696. if (nfRes instanceof Array) {
  19697. return nfRes.map(addNfp);
  19698. } else {
  19699. return addNfp(nfRes);
  19700. }
  19701. };
  19702. function addNfp() {
  19703. return (
  19704. parseFloat(arguments[0]) > 0) ?
  19705. '+'+arguments[0].toString() :
  19706. arguments[0].toString();
  19707. }
  19708. /**
  19709. * Utility function for formatting numbers into strings. Similar to nf() but
  19710. * puts a " " (space) in front of positive numbers and a "-" in front of
  19711. * negative numbers. There are two versions: one for formatting floats, and
  19712. * one for formatting ints. The values for the digits, left, and right
  19713. * parameters should always be positive integers.
  19714. *
  19715. * @method nfs
  19716. * @param {Number|Array} num the Number to format
  19717. * @param {Number} [left] number of digits to the left of the decimal
  19718. * point
  19719. * @param {Number} [right] number of digits to the right of the
  19720. * decimal point
  19721. * @return {String|Array} formatted String
  19722. * @example
  19723. * <div>
  19724. * <code>
  19725. * function setup() {
  19726. * background(200);
  19727. * var num1 = 11253106.115;
  19728. * var num2 = -11253106.115;
  19729. *
  19730. * noStroke();
  19731. * fill(0);
  19732. * textSize(12);
  19733. * // Draw formatted numbers
  19734. * text(nfs(num1, 4, 2), 10, 30);
  19735. *
  19736. * text(nfs(num2, 4, 2), 10, 80);
  19737. *
  19738. * // Draw dividing line
  19739. * stroke(120);
  19740. * line(0, 50, width, 50);
  19741. * }
  19742. * </code>
  19743. * </div>
  19744. */
  19745. p5.prototype.nfs = function() {
  19746. var nfRes = this.nf.apply(this, arguments);
  19747. if (nfRes instanceof Array) {
  19748. return nfRes.map(addNfs);
  19749. } else {
  19750. return addNfs(nfRes);
  19751. }
  19752. };
  19753. function addNfs() {
  19754. return (
  19755. parseFloat(arguments[0]) > 0) ?
  19756. ' '+arguments[0].toString() :
  19757. arguments[0].toString();
  19758. }
  19759. /**
  19760. * The split() function maps to String.split(), it breaks a String into
  19761. * pieces using a character or string as the delimiter. The delim parameter
  19762. * specifies the character or characters that mark the boundaries between
  19763. * each piece. A String[] array is returned that contains each of the pieces.
  19764. *
  19765. * The splitTokens() function works in a similar fashion, except that it
  19766. * splits using a range of characters instead of a specific character or
  19767. * sequence.
  19768. *
  19769. * @method split
  19770. * @param {String} value the String to be split
  19771. * @param {String} delim the String used to separate the data
  19772. * @return {Array} Array of Strings
  19773. * @example
  19774. * <div>
  19775. * <code>
  19776. *var names = "Pat,Xio,Alex"
  19777. * var splitString = split(names, ",");
  19778. * text(splitString[0], 5, 30);
  19779. * text(splitString[1], 5, 50);
  19780. * text(splitString[2], 5, 70);
  19781. * </code>
  19782. * </div>
  19783. */
  19784. p5.prototype.split = function(str, delim) {
  19785. return str.split(delim);
  19786. };
  19787. /**
  19788. * The splitTokens() function splits a String at one or many character
  19789. * delimiters or "tokens." The delim parameter specifies the character or
  19790. * characters to be used as a boundary.
  19791. *
  19792. * If no delim characters are specified, any whitespace character is used to
  19793. * split. Whitespace characters include tab (\t), line feed (\n), carriage
  19794. * return (\r), form feed (\f), and space.
  19795. *
  19796. * @method splitTokens
  19797. * @param {String} value the String to be split
  19798. * @param {String} [delim] list of individual Strings that will be used as
  19799. * separators
  19800. * @return {Array} Array of Strings
  19801. * @example
  19802. * <div class = "norender">
  19803. * <code>
  19804. * function setup() {
  19805. * var myStr = "Mango, Banana, Lime";
  19806. * var myStrArr = splitTokens(myStr, ",");
  19807. *
  19808. * print(myStrArr); // prints : ["Mango"," Banana"," Lime"]
  19809. * }
  19810. * </div>
  19811. * </code>
  19812. */
  19813. p5.prototype.splitTokens = function() {
  19814. var d = (arguments.length > 0) ? arguments[1] : /\s/g;
  19815. return arguments[0].split(d).filter(function(n){return n;});
  19816. };
  19817. /**
  19818. * Removes whitespace characters from the beginning and end of a String. In
  19819. * addition to standard whitespace characters such as space, carriage return,
  19820. * and tab, this function also removes the Unicode "nbsp" character.
  19821. *
  19822. * @method trim
  19823. * @param {String|Array} [str] a String or Array of Strings to be trimmed
  19824. * @return {String|Array} a trimmed String or Array of Strings
  19825. * @example
  19826. * <div>
  19827. * <code>
  19828. * var string = trim(" No new lines\n ");
  19829. * text(string +" here", 2, 50);
  19830. * </code>
  19831. * </div>
  19832. */
  19833. p5.prototype.trim = function(str) {
  19834. if (str instanceof Array) {
  19835. return str.map(this.trim);
  19836. } else {
  19837. return str.trim();
  19838. }
  19839. };
  19840. module.exports = p5;
  19841. },{"../core/core":17}],55:[function(require,module,exports){
  19842. /**
  19843. * @module Input
  19844. * @submodule Time & Date
  19845. * @for p5
  19846. * @requires core
  19847. */
  19848. 'use strict';
  19849. var p5 = require('../core/core');
  19850. /**
  19851. * p5.js communicates with the clock on your computer. The day() function
  19852. * returns the current day as a value from 1 - 31.
  19853. *
  19854. * @method day
  19855. * @return {Number} the current day
  19856. * @example
  19857. * <div>
  19858. * <code>
  19859. * var day = day();
  19860. * text("Current day: \n"+day, 5, 50);
  19861. * </code>
  19862. * </div>
  19863. */
  19864. p5.prototype.day = function() {
  19865. return new Date().getDate();
  19866. };
  19867. /**
  19868. * p5.js communicates with the clock on your computer. The hour() function
  19869. * returns the current hour as a value from 0 - 23.
  19870. *
  19871. * @method hour
  19872. * @return {Number} the current hour
  19873. * @example
  19874. * <div>
  19875. * <code>
  19876. * var hour = hour();
  19877. * text("Current hour:\n"+hour, 5, 50);
  19878. * </code>
  19879. * </div>
  19880. */
  19881. p5.prototype.hour = function() {
  19882. return new Date().getHours();
  19883. };
  19884. /**
  19885. * p5.js communicates with the clock on your computer. The minute() function
  19886. * returns the current minute as a value from 0 - 59.
  19887. *
  19888. * @method minute
  19889. * @return {Number} the current minute
  19890. * @example
  19891. * <div>
  19892. * <code>
  19893. * var minute = minute();
  19894. * text("Current minute: \n:"+minute, 5, 50);
  19895. * </code>
  19896. * </div>
  19897. */
  19898. p5.prototype.minute = function() {
  19899. return new Date().getMinutes();
  19900. };
  19901. /**
  19902. * Returns the number of milliseconds (thousandths of a second) since
  19903. * starting the program. This information is often used for timing events and
  19904. * animation sequences.
  19905. *
  19906. * @method millis
  19907. * @return {Number} the number of milliseconds since starting the program
  19908. * @example
  19909. * <div>
  19910. * <code>
  19911. * var millisecond = millis();
  19912. * text("Milliseconds \nrunning: "+millisecond, 5, 50);
  19913. * </code>
  19914. * </div>
  19915. */
  19916. p5.prototype.millis = function() {
  19917. return window.performance.now();
  19918. };
  19919. /**
  19920. * p5.js communicates with the clock on your computer. The month() function
  19921. * returns the current month as a value from 1 - 12.
  19922. *
  19923. * @method month
  19924. * @return {Number} the current month
  19925. * @example
  19926. * <div>
  19927. * <code>
  19928. * var month = month();
  19929. * text("Current month: \n"+month, 5, 50);
  19930. * </code>
  19931. * </div>
  19932. */
  19933. p5.prototype.month = function() {
  19934. return new Date().getMonth() + 1; //January is 0!
  19935. };
  19936. /**
  19937. * p5.js communicates with the clock on your computer. The second() function
  19938. * returns the current second as a value from 0 - 59.
  19939. *
  19940. * @method second
  19941. * @return {Number} the current second
  19942. * @example
  19943. * <div>
  19944. * <code>
  19945. * var second = second();
  19946. * text("Current second: \n" +second, 5, 50);
  19947. * </code>
  19948. * </div>
  19949. */
  19950. p5.prototype.second = function() {
  19951. return new Date().getSeconds();
  19952. };
  19953. /**
  19954. * p5.js communicates with the clock on your computer. The year() function
  19955. * returns the current year as an integer (2014, 2015, 2016, etc).
  19956. *
  19957. * @method year
  19958. * @return {Number} the current year
  19959. * @example
  19960. * <div>
  19961. * <code>
  19962. * var year = year();
  19963. * text("Current year: \n" +year, 5, 50);
  19964. * </code>
  19965. * </div>
  19966. */
  19967. p5.prototype.year = function() {
  19968. return new Date().getFullYear();
  19969. };
  19970. module.exports = p5;
  19971. },{"../core/core":17}]},{},[8])(8)
  19972. });
  19973. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.opentype = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  19974. "use strict";exports.argument=function(r,t){if(!r)throw new Error(t)},exports.assert=exports.argument;
  19975. },{}],2:[function(require,module,exports){
  19976. "use strict";function line(e,i,n,o,t){e.beginPath(),e.moveTo(i,n),e.lineTo(o,t),e.stroke()}exports.line=line;
  19977. },{}],3:[function(require,module,exports){
  19978. "use strict";function DefaultEncoding(e){this.font=e}function CmapEncoding(e){this.cmap=e}function CffEncoding(e,l){this.encoding=e,this.charset=l}function GlyphNames(e){var l;switch(e.version){case 1:this.names=exports.standardNames.slice();break;case 2:for(this.names=new Array(e.numberOfGlyphs),l=0;l<e.numberOfGlyphs;l++)this.names[l]=e.glyphNameIndex[l]<exports.standardNames.length?exports.standardNames[e.glyphNameIndex[l]]:e.names[e.glyphNameIndex[l]-exports.standardNames.length];break;case 2.5:for(this.names=new Array(e.numberOfGlyphs),l=0;l<e.numberOfGlyphs;l++)this.names[l]=exports.standardNames[l+e.glyphNameIndex[l]];break;case 3:this.names=[]}}function addGlyphNames(e){for(var l,r=e.tables.cmap.glyphIndexMap,a=Object.keys(r),s=0;s<a.length;s+=1){var i=a[s],o=r[i];l=e.glyphs[o],l.addUnicode(parseInt(i))}for(s=0;s<e.glyphs.length;s+=1)l=e.glyphs[s],l.name=e.cffEncoding?e.cffEncoding.charset[s]:e.glyphNames.glyphIndexToName(s)}var cffStandardStrings=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","266 ff","onedotenleader","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003","Black","Bold","Book","Light","Medium","Regular","Roman","Semibold"],cffStandardEncoding=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","","endash","dagger","daggerdbl","periodcentered","","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","","questiondown","","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","","ring","cedilla","","hungarumlaut","ogonek","caron","emdash","","","","","","","","","","","","","","","","","AE","","ordfeminine","","","","","Lslash","Oslash","OE","ordmasculine","","","","","","ae","","","","dotlessi","","","lslash","oslash","oe","germandbls"],cffExpertEncoding=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","","asuperior","bsuperior","centsuperior","dsuperior","esuperior","","","isuperior","","","lsuperior","msuperior","nsuperior","osuperior","","","rsuperior","ssuperior","tsuperior","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdownsmall","centoldstyle","Lslashsmall","","","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","","Dotaccentsmall","","","Macronsmall","","","figuredash","hypheninferior","","","Ogoneksmall","Ringsmall","Cedillasmall","","","","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"],standardNames=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft","backslash","bracketright","asciicircum","underscore","grave","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"];DefaultEncoding.prototype.charToGlyphIndex=function(e){var l=e.charCodeAt(0),r=this.font.glyphs;if(!r)return null;for(var a=0;a<r.length;a+=1)for(var s=r[a],i=0;i<s.unicodes.length;i+=1)if(s.unicodes[i]===l)return a},CmapEncoding.prototype.charToGlyphIndex=function(e){return this.cmap.glyphIndexMap[e.charCodeAt(0)]||0},CffEncoding.prototype.charToGlyphIndex=function(e){var l=e.charCodeAt(0),r=this.encoding[l];return this.charset.indexOf(r)},GlyphNames.prototype.nameToGlyphIndex=function(e){return this.names.indexOf(e)},GlyphNames.prototype.glyphIndexToName=function(e){return this.names[e]},exports.cffStandardStrings=cffStandardStrings,exports.cffStandardEncoding=cffStandardEncoding,exports.cffExpertEncoding=cffExpertEncoding,exports.standardNames=standardNames,exports.DefaultEncoding=DefaultEncoding,exports.CmapEncoding=CmapEncoding,exports.CffEncoding=CffEncoding,exports.GlyphNames=GlyphNames,exports.addGlyphNames=addGlyphNames;
  19979. },{}],4:[function(require,module,exports){
  19980. "use strict";function Font(t){t=t||{},this.familyName=t.familyName||" ",this.styleName=t.styleName||" ",this.designer=t.designer||" ",this.designerURL=t.designerURL||" ",this.manufacturer=t.manufacturer||" ",this.manufacturerURL=t.manufacturerURL||" ",this.license=t.license||" ",this.licenseURL=t.licenseURL||" ",this.version=t.version||"Version 0.1",this.description=t.description||" ",this.copyright=t.copyright||" ",this.trademark=t.trademark||" ",this.unitsPerEm=t.unitsPerEm||1e3,this.ascender=t.ascender,this.descender=t.descender,this.supported=!0,this.glyphs=t.glyphs||[],this.encoding=new encoding.DefaultEncoding(this),this.tables={}}var path=require("./path"),sfnt=require("./tables/sfnt"),encoding=require("./encoding");Font.prototype.hasChar=function(t){return null!==this.encoding.charToGlyphIndex(t)},Font.prototype.charToGlyphIndex=function(t){return this.encoding.charToGlyphIndex(t)},Font.prototype.charToGlyph=function(t){var e=this.charToGlyphIndex(t),n=this.glyphs[e];return n||(n=this.glyphs[0]),n},Font.prototype.stringToGlyphs=function(t){for(var e=[],n=0;n<t.length;n+=1){var i=t[n];e.push(this.charToGlyph(i))}return e},Font.prototype.nameToGlyphIndex=function(t){return this.glyphNames.nameToGlyphIndex(t)},Font.prototype.nameToGlyph=function(t){var e=this.nametoGlyphIndex(t),n=this.glyphs[e];return n||(n=this.glyphs[0]),n},Font.prototype.glyphIndexToName=function(t){return this.glyphNames.glyphIndexToName?this.glyphNames.glyphIndexToName(t):""},Font.prototype.getKerningValue=function(t,e){t=t.index||t,e=e.index||e;var n=this.getGposKerningValue;return n?n(t,e):this.kerningPairs[t+","+e]||0},Font.prototype.forEachGlyph=function(t,e,n,i,o,r){if(this.supported){e=void 0!==e?e:0,n=void 0!==n?n:0,i=void 0!==i?i:72,o=o||{};for(var s=void 0===o.kerning?!0:o.kerning,h=1/this.unitsPerEm*i,a=this.stringToGlyphs(t),p=0;p<a.length;p+=1){var c=a[p];if(r(c,e,n,i,o),c.advanceWidth&&(e+=c.advanceWidth*h),s&&p<a.length-1){var u=this.getKerningValue(c,a[p+1]);e+=u*h}}}},Font.prototype.getPath=function(t,e,n,i,o){var r=new path.Path;return this.forEachGlyph(t,e,n,i,o,function(t,e,n,i){var o=t.getPath(e,n,i);r.extend(o)}),r},Font.prototype.draw=function(t,e,n,i,o,r){this.getPath(e,n,i,o,r).draw(t)},Font.prototype.drawPoints=function(t,e,n,i,o,r){this.forEachGlyph(e,n,i,o,r,function(e,n,i,o){e.drawPoints(t,n,i,o)})},Font.prototype.drawMetrics=function(t,e,n,i,o,r){this.forEachGlyph(e,n,i,o,r,function(e,n,i,o){e.drawMetrics(t,n,i,o)})},Font.prototype.validate=function(){function t(t,e){t||n.push(e)}function e(e){t(i[e]&&i[e].trim().length>0,"No "+e+" specified.")}var n=[],i=this;e("familyName"),e("weightName"),e("manufacturer"),e("copyright"),e("version"),t(this.unitsPerEm>0,"No unitsPerEm specified.")},Font.prototype.toTables=function(){return sfnt.fontToTable(this)},Font.prototype.toBuffer=function(){for(var t=this.toTables(),e=t.encode(),n=new ArrayBuffer(e.length),i=new Uint8Array(n),o=0;o<e.length;o++)i[o]=e[o];return n},Font.prototype.download=function(){var t=this.familyName.replace(/\s/g,"")+"-"+this.styleName+".otf",e=this.toBuffer();window.requestFileSystem=window.requestFileSystem||window.webkitRequestFileSystem,window.requestFileSystem(window.TEMPORARY,e.byteLength,function(n){n.root.getFile(t,{create:!0},function(t){t.createWriter(function(n){var i=new DataView(e),o=new Blob([i],{type:"font/opentype"});n.write(o),n.addEventListener("writeend",function(){location.href=t.toURL()},!1)})})},function(t){throw t})},exports.Font=Font;
  19981. },{"./encoding":3,"./path":8,"./tables/sfnt":23}],5:[function(require,module,exports){
  19982. "use strict";function Glyph(t){this.font=t.font||null,this.index=t.index||0,this.name=t.name||null,this.unicode=t.unicode||void 0,this.unicodes=t.unicodes||void 0!==t.unicode?[t.unicode]:[],this.xMin=t.xMin||0,this.yMin=t.yMin||0,this.xMax=t.xMax||0,this.yMax=t.yMax||0,this.advanceWidth=t.advanceWidth||0,this.path=t.path||null}var check=require("./check"),draw=require("./draw"),path=require("./path");Glyph.prototype.addUnicode=function(t){0===this.unicodes.length&&(this.unicode=t),this.unicodes.push(t)},Glyph.prototype.getPath=function(t,i,e){t=void 0!==t?t:0,i=void 0!==i?i:0,e=void 0!==e?e:72;for(var n=1/this.font.unitsPerEm*e,h=new path.Path,a=this.path.commands,o=0;o<a.length;o+=1){var r=a[o];"M"===r.type?h.moveTo(t+r.x*n,i+-r.y*n):"L"===r.type?h.lineTo(t+r.x*n,i+-r.y*n):"Q"===r.type?h.quadraticCurveTo(t+r.x1*n,i+-r.y1*n,t+r.x*n,i+-r.y*n):"C"===r.type?h.curveTo(t+r.x1*n,i+-r.y1*n,t+r.x2*n,i+-r.y2*n,t+r.x*n,i+-r.y*n):"Z"===r.type&&h.closePath()}return h},Glyph.prototype.getContours=function(){if(void 0===this.points)return[];for(var t=[],i=[],e=0;e<this.points.length;e+=1){var n=this.points[e];i.push(n),n.lastPointOfContour&&(t.push(i),i=[])}return check.argument(0===i.length,"There are still points left in the current contour."),t},Glyph.prototype.getMetrics=function(){for(var t=this.path.commands,i=[],e=[],n=0;n<t.length;n+=1){var h=t[n];"Z"!==h.type&&(i.push(h.x),e.push(h.y)),("Q"===h.type||"C"===h.type)&&(i.push(h.x1),e.push(h.y1)),"C"===h.type&&(i.push(h.x2),e.push(h.y2))}var a={xMin:Math.min.apply(null,i),yMin:Math.min.apply(null,e),xMax:Math.max.apply(null,i),yMax:Math.max.apply(null,e),leftSideBearing:0};return a.rightSideBearing=this.advanceWidth-a.leftSideBearing-(a.xMax-a.xMin),a},Glyph.prototype.draw=function(t,i,e,n){this.getPath(i,e,n).draw(t)},Glyph.prototype.drawPoints=function(t,i,e,n){function h(i,e,n,h){var a=2*Math.PI;t.beginPath();for(var o=0;o<i.length;o+=1)t.moveTo(e+i[o].x*h,n+i[o].y*h),t.arc(e+i[o].x*h,n+i[o].y*h,2,0,a,!1);t.closePath(),t.fill()}i=void 0!==i?i:0,e=void 0!==e?e:0,n=void 0!==n?n:24;for(var a=1/this.font.unitsPerEm*n,o=[],r=[],s=this.path,l=0;l<s.commands.length;l+=1){var p=s.commands[l];void 0!==p.x&&o.push({x:p.x,y:-p.y}),void 0!==p.x1&&r.push({x:p.x1,y:-p.y1}),void 0!==p.x2&&r.push({x:p.x2,y:-p.y2})}t.fillStyle="blue",h(o,i,e,a),t.fillStyle="red",h(r,i,e,a)},Glyph.prototype.drawMetrics=function(t,i,e,n){var h;i=void 0!==i?i:0,e=void 0!==e?e:0,n=void 0!==n?n:24,h=1/this.font.unitsPerEm*n,t.lineWidth=1,t.strokeStyle="black",draw.line(t,i,-1e4,i,1e4),draw.line(t,-1e4,e,1e4,e),t.strokeStyle="blue",draw.line(t,i+this.xMin*h,-1e4,i+this.xMin*h,1e4),draw.line(t,i+this.xMax*h,-1e4,i+this.xMax*h,1e4),draw.line(t,-1e4,e+-this.yMin*h,1e4,e+-this.yMin*h),draw.line(t,-1e4,e+-this.yMax*h,1e4,e+-this.yMax*h),t.strokeStyle="green",draw.line(t,i+this.advanceWidth*h,-1e4,i+this.advanceWidth*h,1e4)},exports.Glyph=Glyph;
  19983. },{"./check":1,"./draw":2,"./path":8}],6:[function(require,module,exports){
  19984. "use strict";function toArrayBuffer(e){for(var a=new ArrayBuffer(e.length),r=new Uint8Array(a),s=0;s<e.length;s+=1)r[s]=e[s];return a}function loadFromFile(e,a){var r=require("fs");r.readFile(e,function(e,r){return e?a(e.message):void a(null,toArrayBuffer(r))})}function loadFromUrl(e,a){var r=new XMLHttpRequest;r.open("get",e,!0),r.responseType="arraybuffer",r.onload=function(){return 200!==r.status?a("Font could not be loaded: "+r.statusText):a(null,r.response)},r.send()}function parseBuffer(e){var a,r,s,t,n,o,p,l=new _font.Font,i=new DataView(e,0),u=parse.getFixed(i,0);if(1===u)l.outlinesFormat="truetype";else{if(u=parse.getTag(i,0),"OTTO"!==u)throw new Error("Unsupported OpenType version "+u);l.outlinesFormat="cff"}for(var c=parse.getUShort(i,4),f=12,h=0;c>h;h+=1){var d=parse.getTag(i,f),m=parse.getULong(i,f+8);switch(d){case"cmap":l.tables.cmap=cmap.parse(i,m),l.encoding=new encoding.CmapEncoding(l.tables.cmap),l.encoding||(l.supported=!1);break;case"head":l.tables.head=head.parse(i,m),l.unitsPerEm=l.tables.head.unitsPerEm,a=l.tables.head.indexToLocFormat;break;case"hhea":l.tables.hhea=hhea.parse(i,m),l.ascender=l.tables.hhea.ascender,l.descender=l.tables.hhea.descender,l.numberOfHMetrics=l.tables.hhea.numberOfHMetrics;break;case"hmtx":r=m;break;case"maxp":l.tables.maxp=maxp.parse(i,m),l.numGlyphs=l.tables.maxp.numGlyphs;break;case"name":l.tables.name=_name.parse(i,m),l.familyName=l.tables.name.fontFamily,l.styleName=l.tables.name.fontSubfamily;break;case"OS/2":l.tables.os2=os2.parse(i,m);break;case"post":l.tables.post=post.parse(i,m),l.glyphNames=new encoding.GlyphNames(l.tables.post);break;case"glyf":s=m;break;case"loca":t=m;break;case"CFF ":n=m;break;case"kern":o=m;break;case"GPOS":p=m}f+=16}if(s&&t){var b=0===a,g=loca.parse(i,t,l.numGlyphs,b);l.glyphs=glyf.parse(i,s,g,l),hmtx.parse(i,r,l.numberOfHMetrics,l.numGlyphs,l.glyphs),encoding.addGlyphNames(l)}else n?(cff.parse(i,n,l),encoding.addGlyphNames(l)):l.supported=!1;return l.supported&&(l.kerningPairs=o?kern.parse(i,o):{},p&&gpos.parse(i,p,l)),l}function load(e,a){var r="undefined"==typeof window,s=r?loadFromFile:loadFromUrl;s(e,function(e,r){if(e)return a(e);var s=parseBuffer(r);return s.supported?a(null,s):a("Font is not supported (is this a Postscript font?)")})}var encoding=require("./encoding"),_font=require("./font"),glyph=require("./glyph"),parse=require("./parse"),path=require("./path"),cmap=require("./tables/cmap"),cff=require("./tables/cff"),glyf=require("./tables/glyf"),gpos=require("./tables/gpos"),head=require("./tables/head"),hhea=require("./tables/hhea"),hmtx=require("./tables/hmtx"),kern=require("./tables/kern"),loca=require("./tables/loca"),maxp=require("./tables/maxp"),_name=require("./tables/name"),os2=require("./tables/os2"),post=require("./tables/post");exports._parse=parse,exports.Font=_font.Font,exports.Glyph=glyph.Glyph,exports.Path=path.Path,exports.parse=parseBuffer,exports.load=load;
  19985. },{"./encoding":3,"./font":4,"./glyph":5,"./parse":7,"./path":8,"./tables/cff":10,"./tables/cmap":11,"./tables/glyf":12,"./tables/gpos":13,"./tables/head":14,"./tables/hhea":15,"./tables/hmtx":16,"./tables/kern":17,"./tables/loca":18,"./tables/maxp":19,"./tables/name":20,"./tables/os2":21,"./tables/post":22,"fs":undefined}],7:[function(require,module,exports){
  19986. "use strict";function Parser(t,e){this.data=t,this.offset=e,this.relativeOffset=0}exports.getByte=function(t,e){return t.getUint8(e)},exports.getCard8=exports.getByte,exports.getUShort=function(t,e){return t.getUint16(e,!1)},exports.getCard16=exports.getUShort,exports.getShort=function(t,e){return t.getInt16(e,!1)},exports.getULong=function(t,e){return t.getUint32(e,!1)},exports.getFixed=function(t,e){var r=t.getInt16(e,!1),s=t.getUint16(e+2,!1);return r+s/65535},exports.getTag=function(t,e){for(var r="",s=e;e+4>s;s+=1)r+=String.fromCharCode(t.getInt8(s));return r},exports.getOffset=function(t,e,r){for(var s=0,o=0;r>o;o+=1)s<<=8,s+=t.getUint8(e+o);return s},exports.getBytes=function(t,e,r){for(var s=[],o=e;r>o;o+=1)s.push(t.getUint8(o));return s},exports.bytesToString=function(t){for(var e="",r=0;r<t.length;r+=1)e+=String.fromCharCode(t[r]);return e};var typeOffsets={"byte":1,uShort:2,"short":2,uLong:4,fixed:4,longDateTime:8,tag:4};Parser.prototype.parseByte=function(){var t=this.data.getUint8(this.offset+this.relativeOffset);return this.relativeOffset+=1,t},Parser.prototype.parseChar=function(){var t=this.data.getInt8(this.offset+this.relativeOffset);return this.relativeOffset+=1,t},Parser.prototype.parseCard8=Parser.prototype.parseByte,Parser.prototype.parseUShort=function(){var t=this.data.getUint16(this.offset+this.relativeOffset);return this.relativeOffset+=2,t},Parser.prototype.parseCard16=Parser.prototype.parseUShort,Parser.prototype.parseSID=Parser.prototype.parseUShort,Parser.prototype.parseOffset16=Parser.prototype.parseUShort,Parser.prototype.parseShort=function(){var t=this.data.getInt16(this.offset+this.relativeOffset);return this.relativeOffset+=2,t},Parser.prototype.parseF2Dot14=function(){var t=this.data.getInt16(this.offset+this.relativeOffset)/16384;return this.relativeOffset+=2,t},Parser.prototype.parseULong=function(){var t=exports.getULong(this.data,this.offset+this.relativeOffset);return this.relativeOffset+=4,t},Parser.prototype.parseFixed=function(){var t=exports.getFixed(this.data,this.offset+this.relativeOffset);return this.relativeOffset+=4,t},Parser.prototype.parseOffset16List=Parser.prototype.parseUShortList=function(t){for(var e=new Array(t),r=this.data,s=this.offset+this.relativeOffset,o=0;t>o;o++)e[o]=exports.getUShort(r,s),s+=2;return this.relativeOffset+=2*t,e},Parser.prototype.parseString=function(t){var e=this.data,r=this.offset+this.relativeOffset,s="";this.relativeOffset+=t;for(var o=0;t>o;o++)s+=String.fromCharCode(e.getUint8(r+o));return s},Parser.prototype.parseTag=function(){return this.parseString(4)},Parser.prototype.parseLongDateTime=function(){var t=exports.getULong(this.data,this.offset+this.relativeOffset+4);return this.relativeOffset+=8,t},Parser.prototype.parseFixed=function(){var t=exports.getULong(this.data,this.offset+this.relativeOffset);return this.relativeOffset+=4,t/65536},Parser.prototype.parseVersion=function(){var t=exports.getUShort(this.data,this.offset+this.relativeOffset),e=exports.getUShort(this.data,this.offset+this.relativeOffset+2);return this.relativeOffset+=4,t+e/4096/10},Parser.prototype.skip=function(t,e){void 0===e&&(e=1),this.relativeOffset+=typeOffsets[t]*e},exports.Parser=Parser;
  19987. },{}],8:[function(require,module,exports){
  19988. "use strict";function Path(){this.commands=[],this.fill="black",this.stroke=null,this.strokeWidth=1}Path.prototype.moveTo=function(t,o){this.commands.push({type:"M",x:t,y:o})},Path.prototype.lineTo=function(t,o){this.commands.push({type:"L",x:t,y:o})},Path.prototype.curveTo=Path.prototype.bezierCurveTo=function(t,o,e,i,s,h){this.commands.push({type:"C",x1:t,y1:o,x2:e,y2:i,x:s,y:h})},Path.prototype.quadTo=Path.prototype.quadraticCurveTo=function(t,o,e,i){this.commands.push({type:"Q",x1:t,y1:o,x:e,y:i})},Path.prototype.close=Path.prototype.closePath=function(){this.commands.push({type:"Z"})},Path.prototype.extend=function(t){t.commands&&(t=t.commands),Array.prototype.push.apply(this.commands,t)},Path.prototype.draw=function(t){t.beginPath();for(var o=0;o<this.commands.length;o+=1){var e=this.commands[o];"M"===e.type?t.moveTo(e.x,e.y):"L"===e.type?t.lineTo(e.x,e.y):"C"===e.type?t.bezierCurveTo(e.x1,e.y1,e.x2,e.y2,e.x,e.y):"Q"===e.type?t.quadraticCurveTo(e.x1,e.y1,e.x,e.y):"Z"===e.type&&t.closePath()}this.fill&&(t.fillStyle=this.fill,t.fill()),this.stroke&&(t.strokeStyle=this.stroke,t.lineWidth=this.strokeWidth,t.stroke())},Path.prototype.toPathData=function(t){function o(o){return Math.round(o)===o?""+Math.round(o):o.toFixed(t)}function e(){for(var t="",e=0;e<arguments.length;e+=1){var i=arguments[e];i>=0&&e>0&&(t+=" "),t+=o(i)}return t}t=void 0!==t?t:2;for(var i="",s=0;s<this.commands.length;s+=1){var h=this.commands[s];"M"===h.type?i+="M"+e(h.x,h.y):"L"===h.type?i+="L"+e(h.x,h.y):"C"===h.type?i+="C"+e(h.x1,h.y1,h.x2,h.y2,h.x,h.y):"Q"===h.type?i+="Q"+e(h.x1,h.y1,h.x,h.y):"Z"===h.type&&(i+="Z")}return i},Path.prototype.toSVG=function(t){var o='<path d="';return o+=this.toPathData(t),o+='"',this.fill&&"black"!==this.fill&&(o+=null===this.fill?' fill="none"':' fill="'+this.fill+'"'),this.stroke&&(o+=' stroke="'+this.stroke+'" stroke-width="'+this.strokeWidth+'"'),o+="/>"},exports.Path=Path;
  19989. },{}],9:[function(require,module,exports){
  19990. "use strict";function Table(e,t,i){var s;for(s=0;s<t.length;s+=1){var r=t[s];this[r.name]=r.value}if(this.tableName=e,this.fields=t,i){var f=Object.keys(i);for(s=0;s<f.length;s+=1){var n=f[s],o=i[n];void 0!==this[n]&&(this[n]=o)}}}var check=require("./check"),encode=require("./types").encode,sizeOf=require("./types").sizeOf;Table.prototype.sizeOf=function(){for(var e=0,t=0;t<this.fields.length;t+=1){var i=this.fields[t],s=this[i.name];if(void 0===s&&(s=i.value),"function"==typeof s.sizeOf)e+=s.sizeOf();else{var r=sizeOf[i.type];check.assert("function"==typeof r,"Could not find sizeOf function for field"+i.name),e+=r(s)}}return e},Table.prototype.encode=function(){return encode.TABLE(this)},exports.Table=Table;
  19991. },{"./check":1,"./types":24}],10:[function(require,module,exports){
  19992. "use strict";function equals(e,t){if(e===t)return!0;if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return!1;for(var a=0;a<e.length;a+=1)if(!equals(e[a],t[a]))return!1;return!0}return!1}function parseCFFIndex(e,t,a){var r,n,s,i=[],h=[],o=parse.getCard16(e,t);if(0!==o){var f=parse.getByte(e,t+2);n=t+(o+1)*f+2;var p=t+3;for(r=0;o+1>r;r+=1)i.push(parse.getOffset(e,p,f)),p+=f;s=n+i[o]}else s=t+2;for(r=0;r<i.length-1;r+=1){var u=parse.getBytes(e,n+i[r],n+i[r+1]);a&&(u=a(u)),h.push(u)}return{objects:h,startOffset:t,endOffset:s}}function parseFloatOperand(e){for(var t="",a=15,r=["0","1","2","3","4","5","6","7","8","9",".","E","E-",null,"-"];;){var n=e.parseByte(),s=n>>4,i=15&n;if(s===a)break;if(t+=r[s],i===a)break;t+=r[i]}return parseFloat(t)}function parseOperand(e,t){var a,r,n,s;if(28===t)return a=e.parseByte(),r=e.parseByte(),a<<8|r;if(29===t)return a=e.parseByte(),r=e.parseByte(),n=e.parseByte(),s=e.parseByte(),a<<24|r<<16|n<<8|s;if(30===t)return parseFloatOperand(e);if(t>=32&&246>=t)return t-139;if(t>=247&&250>=t)return a=e.parseByte(),256*(t-247)+a+108;if(t>=251&&254>=t)return a=e.parseByte(),256*-(t-251)-a-108;throw new Error("Invalid b0 "+t)}function entriesToObject(e){for(var t={},a=0;a<e.length;a+=1){var r,n=e[a][0],s=e[a][1];if(r=1===s.length?s[0]:s,t.hasOwnProperty(n))throw new Error("Object "+t+" already has key "+n);t[n]=r}return t}function parseCFFDict(e,t,a){t=void 0!==t?t:0;var r=new parse.Parser(e,t),n=[],s=[];for(a=void 0!==a?a:e.length;r.relativeOffset<a;){var i=r.parseByte();21>=i?(12===i&&(i=1200+r.parseByte()),n.push([i,s]),s=[]):s.push(parseOperand(r,i))}return entriesToObject(n)}function getCFFString(e,t){return t=390>=t?encoding.cffStandardStrings[t]:e[t-391]}function interpretDict(e,t,a){for(var r={},n=0;n<t.length;n+=1){var s=t[n],i=e[s.op];void 0===i&&(i=void 0!==s.value?s.value:null),"SID"===s.type&&(i=getCFFString(a,i)),r[s.name]=i}return r}function parseCFFHeader(e,t){var a={};return a.formatMajor=parse.getCard8(e,t),a.formatMinor=parse.getCard8(e,t+1),a.size=parse.getCard8(e,t+2),a.offsetSize=parse.getCard8(e,t+3),a.startOffset=t,a.endOffset=t+4,a}function parseCFFTopDict(e,t){var a=parseCFFDict(e,0,e.byteLength);return interpretDict(a,TOP_DICT_META,t)}function parseCFFPrivateDict(e,t,a,r){var n=parseCFFDict(e,t,a);return interpretDict(n,PRIVATE_DICT_META,r)}function parseCFFCharset(e,t,a,r){var n,s,i,h=new parse.Parser(e,t);a-=1;var o=[".notdef"],f=h.parseCard8();if(0===f)for(n=0;a>n;n+=1)s=h.parseSID(),o.push(getCFFString(r,s));else if(1===f)for(;o.length<=a;)for(s=h.parseSID(),i=h.parseCard8(),n=0;i>=n;n+=1)o.push(getCFFString(r,s)),s+=1;else{if(2!==f)throw new Error("Unknown charset format "+f);for(;o.length<=a;)for(s=h.parseSID(),i=h.parseCard16(),n=0;i>=n;n+=1)o.push(getCFFString(r,s)),s+=1}return o}function parseCFFEncoding(e,t,a){var r,n,s={},i=new parse.Parser(e,t),h=i.parseCard8();if(0===h){var o=i.parseCard8();for(r=0;o>r;r+=1)n=i.parseCard8(),s[n]=r}else{if(1!==h)throw new Error("Unknown encoding format "+h);var f=i.parseCard8();for(n=1,r=0;f>r;r+=1)for(var p=i.parseCard8(),u=i.parseCard8(),l=p;p+u>=l;l+=1)s[l]=n,n+=1}return new encoding.CffEncoding(s,a)}function parseCFFCharstring(e,t,a){function r(e,t){v&&p.closePath(),p.moveTo(e,t),v=!0}function n(){var e;e=u.length%2!==0,e&&!c&&(d=u.shift()+t.nominalWidthX),l+=u.length>>1,u.length=0,c=!0}function s(e){for(var y,b,T,C,I,F,D,x,k,S,E,B,w=0;w<e.length;){var M=e[w];switch(w+=1,M){case 1:n();break;case 3:n();break;case 4:u.length>1&&!c&&(d=u.shift()+t.nominalWidthX,c=!0),m+=u.pop(),r(g,m);break;case 5:for(;u.length>0;)g+=u.shift(),m+=u.shift(),p.lineTo(g,m);break;case 6:for(;u.length>0&&(g+=u.shift(),p.lineTo(g,m),0!==u.length);)m+=u.shift(),p.lineTo(g,m);break;case 7:for(;u.length>0&&(m+=u.shift(),p.lineTo(g,m),0!==u.length);)g+=u.shift(),p.lineTo(g,m);break;case 8:for(;u.length>0;)i=g+u.shift(),h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),g=o+u.shift(),m=f+u.shift(),p.curveTo(i,h,o,f,g,m);break;case 10:I=u.pop()+t.subrsBias,F=t.subrs[I],F&&s(F);break;case 11:return;case 12:switch(M=e[w],w+=1,M){case 35:i=g+u.shift(),h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),D=o+u.shift(),x=f+u.shift(),k=D+u.shift(),S=x+u.shift(),E=k+u.shift(),B=S+u.shift(),g=E+u.shift(),m=B+u.shift(),u.shift(),p.curveTo(i,h,o,f,D,x),p.curveTo(k,S,E,B,g,m);break;case 34:i=g+u.shift(),h=m,o=i+u.shift(),f=h+u.shift(),D=o+u.shift(),x=f,k=D+u.shift(),S=f,E=k+u.shift(),B=m,g=E+u.shift(),p.curveTo(i,h,o,f,D,x),p.curveTo(k,S,E,B,g,m);break;case 36:i=g+u.shift(),h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),D=o+u.shift(),x=f,k=D+u.shift(),S=f,E=k+u.shift(),B=S+u.shift(),g=E+u.shift(),p.curveTo(i,h,o,f,D,x),p.curveTo(k,S,E,B,g,m);break;case 37:i=g+u.shift(),h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),D=o+u.shift(),x=f+u.shift(),k=D+u.shift(),S=x+u.shift(),E=k+u.shift(),B=S+u.shift(),Math.abs(E-g)>Math.abs(B-m)?g=E+u.shift():m=B+u.shift(),p.curveTo(i,h,o,f,D,x),p.curveTo(k,S,E,B,g,m);break;default:console.log("Glyph "+a+": unknown operator 1200"+M),u.length=0}break;case 14:u.length>0&&!c&&(d=u.shift()+t.nominalWidthX,c=!0),v&&(p.closePath(),v=!1);break;case 18:n();break;case 19:case 20:n(),w+=l+7>>3;break;case 21:u.length>2&&!c&&(d=u.shift()+t.nominalWidthX,c=!0),m+=u.pop(),g+=u.pop(),r(g,m);break;case 22:u.length>1&&!c&&(d=u.shift()+t.nominalWidthX,c=!0),g+=u.pop(),r(g,m);break;case 23:n();break;case 24:for(;u.length>2;)i=g+u.shift(),h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),g=o+u.shift(),m=f+u.shift(),p.curveTo(i,h,o,f,g,m);g+=u.shift(),m+=u.shift(),p.lineTo(g,m);break;case 25:for(;u.length>6;)g+=u.shift(),m+=u.shift(),p.lineTo(g,m);i=g+u.shift(),h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),g=o+u.shift(),m=f+u.shift(),p.curveTo(i,h,o,f,g,m);break;case 26:for(u.length%2&&(g+=u.shift());u.length>0;)i=g,h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),g=o,m=f+u.shift(),p.curveTo(i,h,o,f,g,m);break;case 27:for(u.length%2&&(m+=u.shift());u.length>0;)i=g+u.shift(),h=m,o=i+u.shift(),f=h+u.shift(),g=o+u.shift(),m=f,p.curveTo(i,h,o,f,g,m);break;case 28:y=e[w],b=e[w+1],u.push((y<<24|b<<16)>>16),w+=2;break;case 29:I=u.pop()+t.gsubrsBias,F=t.gsubrs[I],F&&s(F);break;case 30:for(;u.length>0&&(i=g,h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),g=o+u.shift(),m=f+(1===u.length?u.shift():0),p.curveTo(i,h,o,f,g,m),0!==u.length);)i=g+u.shift(),h=m,o=i+u.shift(),f=h+u.shift(),m=f+u.shift(),g=o+(1===u.length?u.shift():0),p.curveTo(i,h,o,f,g,m);break;case 31:for(;u.length>0&&(i=g+u.shift(),h=m,o=i+u.shift(),f=h+u.shift(),m=f+u.shift(),g=o+(1===u.length?u.shift():0),p.curveTo(i,h,o,f,g,m),0!==u.length);)i=g,h=m+u.shift(),o=i+u.shift(),f=h+u.shift(),g=o+u.shift(),m=f+(1===u.length?u.shift():0),p.curveTo(i,h,o,f,g,m);break;default:32>M?console.log("Glyph "+a+": unknown operator "+M):247>M?u.push(M-139):251>M?(y=e[w],w+=1,u.push(256*(M-247)+y+108)):255>M?(y=e[w],w+=1,u.push(256*-(M-251)-y-108)):(y=e[w],b=e[w+1],T=e[w+2],C=e[w+3],w+=4,u.push((y<<24|b<<16|T<<8|C)/65536))}}}var i,h,o,f,p=new path.Path,u=[],l=0,c=!1,d=t.defaultWidthX,v=!1,g=0,m=0;s(e);var y=new _glyph.Glyph({font:t,index:a});return y.path=p,y.advanceWidth=d,y}function calcCFFSubroutineBias(e){var t;return t=e.length<1240?107:e.length<33900?1131:32768}function parseCFFTable(e,t,a){a.tables.cff={};var r=parseCFFHeader(e,t),n=parseCFFIndex(e,r.endOffset,parse.bytesToString),s=parseCFFIndex(e,n.endOffset),i=parseCFFIndex(e,s.endOffset,parse.bytesToString),h=parseCFFIndex(e,i.endOffset);a.gsubrs=h.objects,a.gsubrsBias=calcCFFSubroutineBias(a.gsubrs);var o=new DataView(new Uint8Array(s.objects[0]).buffer),f=parseCFFTopDict(o,i.objects);a.tables.cff.topDict=f;var p=t+f["private"][1],u=parseCFFPrivateDict(e,p,f["private"][0],i.objects);if(a.defaultWidthX=u.defaultWidthX,a.nominalWidthX=u.nominalWidthX,0!==u.subrs){var l=p+u.subrs,c=parseCFFIndex(e,l);a.subrs=c.objects,a.subrsBias=calcCFFSubroutineBias(a.subrs)}else a.subrs=[],a.subrsBias=0;var d=parseCFFIndex(e,t+f.charStrings);a.nGlyphs=d.objects.length;var v=parseCFFCharset(e,t+f.charset,a.nGlyphs,i.objects);a.cffEncoding=0===f.encoding?new encoding.CffEncoding(encoding.cffStandardEncoding,v):1===f.encoding?new encoding.CffEncoding(encoding.cffExpertEncoding,v):parseCFFEncoding(e,t+f.encoding,v),a.encoding=a.encoding||a.cffEncoding,a.glyphs=[];for(var g=0;g<a.nGlyphs;g+=1){var m=d.objects[g];a.glyphs.push(parseCFFCharstring(m,a,g))}}function encodeString(e,t){var a,r=encoding.cffStandardStrings.indexOf(e);return r>=0&&(a=r),r=t.indexOf(e),r>=0?a=r+encoding.cffStandardStrings.length:(a=encoding.cffStandardStrings.length+t.length,t.push(e)),a}function makeHeader(){return new table.Table("Header",[{name:"major",type:"Card8",value:1},{name:"minor",type:"Card8",value:0},{name:"hdrSize",type:"Card8",value:4},{name:"major",type:"Card8",value:1}])}function makeNameIndex(e){var t=new table.Table("Name INDEX",[{name:"names",type:"INDEX",value:[]}]);t.names=[];for(var a=0;a<e.length;a+=1)t.names.push({name:"name_"+a,type:"NAME",value:e[a]});return t}function makeDict(e,t,a){for(var r={},n=0;n<e.length;n+=1){var s=e[n],i=t[s.name];void 0===i||equals(i,s.value)||("SID"===s.type&&(i=encodeString(i,a)),r[s.op]={name:s.name,type:s.type,value:i})}return r}function makeTopDict(e,t){var a=new table.Table("Top DICT",[{name:"dict",type:"DICT",value:{}}]);return a.dict=makeDict(TOP_DICT_META,e,t),a}function makeTopDictIndex(e){var t=new table.Table("Top DICT INDEX",[{name:"topDicts",type:"INDEX",value:[]}]);return t.topDicts=[{name:"topDict_0",type:"TABLE",value:e}],t}function makeStringIndex(e){var t=new table.Table("String INDEX",[{name:"strings",type:"INDEX",value:[]}]);t.strings=[];for(var a=0;a<e.length;a+=1)t.strings.push({name:"string_"+a,type:"STRING",value:e[a]});return t}function makeGlobalSubrIndex(){return new table.Table("Global Subr INDEX",[{name:"subrs",type:"INDEX",value:[]}])}function makeCharsets(e,t){for(var a=new table.Table("Charsets",[{name:"format",type:"Card8",value:0}]),r=0;r<e.length;r+=1){var n=e[r],s=encodeString(n,t);a.fields.push({name:"glyph_"+r,type:"SID",value:s})}return a}function glyphToOps(e){var t=[],a=e.path;t.push({name:"width",type:"NUMBER",value:e.advanceWidth});for(var r=0,n=0,s=0;s<a.commands.length;s+=1){var i,h,o=a.commands[s];if("Q"===o.type){var f=1/3,p=2/3;o={type:"C",x:o.x,y:o.y,x1:f*r+p*o.x1,y1:f*n+p*o.y1,x2:f*o.x+p*o.x1,y2:f*o.y+p*o.y1}}if("M"===o.type)i=Math.round(o.x-r),h=Math.round(o.y-n),t.push({name:"dx",type:"NUMBER",value:i}),t.push({name:"dy",type:"NUMBER",value:h}),t.push({name:"rmoveto",type:"OP",value:21}),r=Math.round(o.x),n=Math.round(o.y);else if("L"===o.type)i=Math.round(o.x-r),h=Math.round(o.y-n),t.push({name:"dx",type:"NUMBER",value:i}),t.push({name:"dy",type:"NUMBER",value:h}),t.push({name:"rlineto",type:"OP",value:5}),r=Math.round(o.x),n=Math.round(o.y);else if("C"===o.type){var u=Math.round(o.x1-r),l=Math.round(o.y1-n),c=Math.round(o.x2-o.x1),d=Math.round(o.y2-o.y1);i=Math.round(o.x-o.x2),h=Math.round(o.y-o.y2),t.push({name:"dx1",type:"NUMBER",value:u}),t.push({name:"dy1",type:"NUMBER",value:l}),t.push({name:"dx2",type:"NUMBER",value:c}),t.push({name:"dy2",type:"NUMBER",value:d}),t.push({name:"dx",type:"NUMBER",value:i}),t.push({name:"dy",type:"NUMBER",value:h}),t.push({name:"rrcurveto",type:"OP",value:8}),r=Math.round(o.x),n=Math.round(o.y)}}return t.push({name:"endchar",type:"OP",value:14}),t}function makeCharStringsIndex(e){for(var t=new table.Table("CharStrings INDEX",[{name:"charStrings",type:"INDEX",value:[]}]),a=0;a<e.length;a+=1){var r=e[a],n=glyphToOps(r);t.charStrings.push({name:r.name,type:"CHARSTRING",value:n})}return t}function makePrivateDict(e,t){var a=new table.Table("Private DICT",[{name:"dict",type:"DICT",value:{}}]);return a.dict=makeDict(PRIVATE_DICT_META,e,t),a}function makePrivateDictIndex(e){var t=new table.Table("Private DICT INDEX",[{name:"privateDicts",type:"INDEX",value:[]}]);return t.privateDicts=[{name:"privateDict_0",type:"TABLE",value:e}],t}function makeCFFTable(e,t){for(var a=new table.Table("CFF ",[{name:"header",type:"TABLE"},{name:"nameIndex",type:"TABLE"},{name:"topDictIndex",type:"TABLE"},{name:"stringIndex",type:"TABLE"},{name:"globalSubrIndex",type:"TABLE"},{name:"charsets",type:"TABLE"},{name:"charStringsIndex",type:"TABLE"},{name:"privateDictIndex",type:"TABLE"}]),r={version:t.version,fullName:t.fullName,familyName:t.familyName,weight:t.weightName,charset:999,encoding:0,charStrings:999,"private":[0,999]},n={},s=[],i=1;i<e.length;i+=1)s.push(e[i].name);var h=[];a.header=makeHeader(),a.nameIndex=makeNameIndex([t.postScriptName]);var o=makeTopDict(r,h);a.topDictIndex=makeTopDictIndex(o),a.globalSubrIndex=makeGlobalSubrIndex(),a.charsets=makeCharsets(s,h),a.charStringsIndex=makeCharStringsIndex(e);var f=makePrivateDict(n,h);a.privateDictIndex=makePrivateDictIndex(f),a.stringIndex=makeStringIndex(h);var p=a.header.sizeOf()+a.nameIndex.sizeOf()+a.topDictIndex.sizeOf()+a.stringIndex.sizeOf()+a.globalSubrIndex.sizeOf();return r.charset=p,r.encoding=0,r.charStrings=r.charset+a.charsets.sizeOf(),r.private[1]=r.charStrings+a.charStringsIndex.sizeOf(),o=makeTopDict(r,h),a.topDictIndex=makeTopDictIndex(o),a}var encoding=require("../encoding"),_glyph=require("../glyph"),parse=require("../parse"),path=require("../path"),table=require("../table"),TOP_DICT_META=[{name:"version",op:0,type:"SID"},{name:"notice",op:1,type:"SID"},{name:"copyright",op:1200,type:"SID"},{name:"fullName",op:2,type:"SID"},{name:"familyName",op:3,type:"SID"},{name:"weight",op:4,type:"SID"},{name:"isFixedPitch",op:1201,type:"number",value:0},{name:"italicAngle",op:1202,type:"number",value:0},{name:"underlinePosition",op:1203,type:"number",value:-100},{name:"underlineThickness",op:1204,type:"number",value:50},{name:"paintType",op:1205,type:"number",value:0},{name:"charstringType",op:1206,type:"number",value:2},{name:"fontMatrix",op:1207,type:["real","real","real","real","real","real"],value:[.001,0,0,.001,0,0]},{name:"uniqueId",op:13,type:"number"},{name:"fontBBox",op:5,type:["number","number","number","number"],value:[0,0,0,0]},{name:"strokeWidth",op:1208,type:"number",value:0},{name:"xuid",op:14,type:[],value:null},{name:"charset",op:15,type:"offset",value:0},{name:"encoding",op:16,type:"offset",value:0},{name:"charStrings",op:17,type:"offset",value:0},{name:"private",op:18,type:["number","offset"],value:[0,0]}],PRIVATE_DICT_META=[{name:"subrs",op:19,type:"offset",value:0},{name:"defaultWidthX",op:20,type:"number",value:0},{name:"nominalWidthX",op:21,type:"number",value:0}];exports.parse=parseCFFTable,exports.make=makeCFFTable;
  19993. },{"../encoding":3,"../glyph":5,"../parse":7,"../path":8,"../table":9}],11:[function(require,module,exports){
  19994. "use strict";function parseCmapTable(e,a){var t,r={};r.version=parse.getUShort(e,a),check.argument(0===r.version,"cmap table version should be 0."),r.numTables=parse.getUShort(e,a+2);var n=-1;for(t=0;t<r.numTables;t+=1){var s=parse.getUShort(e,a+4+8*t),l=parse.getUShort(e,a+4+8*t+2);if(3===s&&(1===l||0===l)){n=parse.getULong(e,a+4+8*t+4);break}}if(-1===n)return null;var o=new parse.Parser(e,a+n);r.format=o.parseUShort(),check.argument(4===r.format,"Only format 4 cmap tables are supported."),r.length=o.parseUShort(),r.language=o.parseUShort();var p;r.segCount=p=o.parseUShort()>>1,o.skip("uShort",3),r.glyphIndexMap={};var g=new parse.Parser(e,a+n+14),m=new parse.Parser(e,a+n+16+2*p),u=new parse.Parser(e,a+n+16+4*p),h=new parse.Parser(e,a+n+16+6*p),c=a+n+16+8*p;for(t=0;p-1>t;t+=1)for(var f,d=g.parseUShort(),S=m.parseUShort(),i=u.parseShort(),v=h.parseUShort(),U=S;d>=U;U+=1)0!==v?(c=h.offset+h.relativeOffset-2,c+=v,c+=2*(U-S),f=parse.getUShort(e,c),0!==f&&(f=f+i&65535)):f=U+i&65535,r.glyphIndexMap[U]=f;return r}function addSegment(e,a,t){e.segments.push({end:a,start:a,delta:-(a-t),offset:0})}function addTerminatorSegment(e){e.segments.push({end:65535,start:65535,delta:1,offset:0})}function makeCmapTable(e){var a,t=new table.Table("cmap",[{name:"version",type:"USHORT",value:0},{name:"numTables",type:"USHORT",value:1},{name:"platformID",type:"USHORT",value:3},{name:"encodingID",type:"USHORT",value:1},{name:"offset",type:"ULONG",value:12},{name:"format",type:"USHORT",value:4},{name:"length",type:"USHORT",value:0},{name:"language",type:"USHORT",value:0},{name:"segCountX2",type:"USHORT",value:0},{name:"searchRange",type:"USHORT",value:0},{name:"entrySelector",type:"USHORT",value:0},{name:"rangeShift",type:"USHORT",value:0}]);for(t.segments=[],a=0;a<e.length;a+=1){for(var r=e[a],n=0;n<r.unicodes.length;n+=1)addSegment(t,r.unicodes[n],a);t.segments=t.segments.sort(function(e,a){return e.start-a.start})}addTerminatorSegment(t);var s;s=t.segments.length,t.segCountX2=2*s,t.searchRange=2*Math.pow(2,Math.floor(Math.log(s)/Math.log(2))),t.entrySelector=Math.log(t.searchRange/2)/Math.log(2),t.rangeShift=t.segCountX2-t.searchRange;var l=[],o=[],p=[],g=[],m=[];for(a=0;s>a;a+=1){var u=t.segments[a];l=l.concat({name:"end_"+a,type:"USHORT",value:u.end}),o=o.concat({name:"start_"+a,type:"USHORT",value:u.start}),p=p.concat({name:"idDelta_"+a,type:"SHORT",value:u.delta}),g=g.concat({name:"idRangeOffset_"+a,type:"USHORT",value:u.offset}),void 0!==u.glyphId&&(m=m.concat({name:"glyph_"+a,type:"USHORT",value:u.glyphId}))}return t.fields=t.fields.concat(l),t.fields.push({name:"reservedPad",type:"USHORT",value:0}),t.fields=t.fields.concat(o),t.fields=t.fields.concat(p),t.fields=t.fields.concat(g),t.fields=t.fields.concat(m),t.length=14+2*l.length+2+2*o.length+2*p.length+2*g.length+2*m.length,t}var check=require("../check"),parse=require("../parse"),table=require("../table");exports.parse=parseCmapTable,exports.make=makeCmapTable;
  19995. },{"../check":1,"../parse":7,"../table":9}],12:[function(require,module,exports){
  19996. "use strict";function parseGlyphCoordinate(r,e,t,o,n){var a;return(e&o)>0?(a=r.parseByte(),0===(e&n)&&(a=-a),a=t+a):a=(e&n)>0?t:t+r.parseShort(),a}function parseGlyph(r,e,t,o){var n=new parse.Parser(r,e),a=new _glyph.Glyph({font:o,index:t});a.numberOfContours=n.parseShort(),a.xMin=n.parseShort(),a.yMin=n.parseShort(),a.xMax=n.parseShort(),a.yMax=n.parseShort();var s,p;if(a.numberOfContours>0){var u,i=a.endPointIndices=[];for(u=0;u<a.numberOfContours;u+=1)i.push(n.parseUShort());for(a.instructionLength=n.parseUShort(),a.instructions=[],u=0;u<a.instructionLength;u+=1)a.instructions.push(n.parseByte());var l=i[i.length-1]+1;for(s=[],u=0;l>u;u+=1)if(p=n.parseByte(),s.push(p),(8&p)>0)for(var h=n.parseByte(),f=0;h>f;f+=1)s.push(p),u+=1;if(check.argument(s.length===l,"Bad flags."),i.length>0){var y,c=[];if(l>0){for(u=0;l>u;u+=1)p=s[u],y={},y.onCurve=!!(1&p),y.lastPointOfContour=i.indexOf(u)>=0,c.push(y);var v=0;for(u=0;l>u;u+=1)p=s[u],y=c[u],y.x=parseGlyphCoordinate(n,p,v,2,16),v=y.x;var x=0;for(u=0;l>u;u+=1)p=s[u],y=c[u],y.y=parseGlyphCoordinate(n,p,x,4,32),x=y.y}a.points=c}else a.points=[]}else if(0===a.numberOfContours)a.points=[];else{a.isComposite=!0,a.points=[],a.components=[];for(var C=!0;C;){s=n.parseUShort();var g={glyphIndex:n.parseUShort(),xScale:1,scale01:0,scale10:0,yScale:1,dx:0,dy:0};(1&s)>0?(g.dx=n.parseShort(),g.dy=n.parseShort()):(g.dx=n.parseChar(),g.dy=n.parseChar()),(8&s)>0?g.xScale=g.yScale=n.parseF2Dot14():(64&s)>0?(g.xScale=n.parseF2Dot14(),g.yScale=n.parseF2Dot14()):(128&s)>0&&(g.xScale=n.parseF2Dot14(),g.scale01=n.parseF2Dot14(),g.scale10=n.parseF2Dot14(),g.yScale=n.parseF2Dot14()),a.components.push(g),C=!!(32&s)}}return a}function transformPoints(r,e){for(var t=[],o=0;o<r.length;o+=1){var n=r[o],a={x:e.xScale*n.x+e.scale01*n.y+e.dx,y:e.scale10*n.x+e.yScale*n.y+e.dy,onCurve:n.onCurve,lastPointOfContour:n.lastPointOfContour};t.push(a)}return t}function getContours(r){for(var e=[],t=[],o=0;o<r.length;o+=1){var n=r[o];t.push(n),n.lastPointOfContour&&(e.push(t),t=[])}return check.argument(0===t.length,"There are still points left in the current contour."),e}function getPath(r){var e=new path.Path;if(!r)return e;for(var t=getContours(r),o=0;o<t.length;o+=1){var n,a,s=t[o],p=s[0],u=s[s.length-1];p.onCurve?(n=null,a=!0):(p=u.onCurve?u:{x:(p.x+u.x)/2,y:(p.y+u.y)/2},n=p,a=!1),e.moveTo(p.x,p.y);for(var i=a?1:0;i<s.length;i+=1){var l=s[i],h=0===i?p:s[i-1];if(h.onCurve&&l.onCurve)e.lineTo(l.x,l.y);else if(h.onCurve&&!l.onCurve)n=l;else if(h.onCurve||l.onCurve){if(h.onCurve||!l.onCurve)throw new Error("Invalid state.");e.quadraticCurveTo(n.x,n.y,l.x,l.y),n=null}else{var f={x:(h.x+l.x)/2,y:(h.y+l.y)/2};e.quadraticCurveTo(h.x,h.y,f.x,f.y),n=l}}p!==u&&(n?e.quadraticCurveTo(n.x,n.y,p.x,p.y):e.lineTo(p.x,p.y))}return e.closePath(),e}function parseGlyfTable(r,e,t,o){var n,a=[];for(n=0;n<t.length-1;n+=1){var s=t[n],p=t[n+1];a.push(s!==p?parseGlyph(r,e+s,n,o):new _glyph.Glyph({font:o,index:n}))}for(n=0;n<a.length;n+=1){var u=a[n];if(u.isComposite)for(var i=0;i<u.components.length;i+=1){var l=u.components[i],h=a[l.glyphIndex];if(h.points){var f=transformPoints(h.points,l);u.points=u.points.concat(f)}}u.path=getPath(u.points)}return a}var check=require("../check"),_glyph=require("../glyph"),parse=require("../parse"),path=require("../path");exports.parse=parseGlyfTable;
  19997. },{"../check":1,"../glyph":5,"../parse":7,"../path":8}],13:[function(require,module,exports){
  19998. "use strict";function parseTaggedListTable(r,e){for(var a=new parse.Parser(r,e),s=a.parseUShort(),t=[],o=0;s>o;o++)t[a.parseTag()]={offset:a.parseUShort()};return t}function parseCoverageTable(r,e){var a=new parse.Parser(r,e),s=a.parseUShort(),t=a.parseUShort();if(1===s)return a.parseUShortList(t);if(2===s){for(var o=[];t--;)for(var p=a.parseUShort(),n=a.parseUShort(),f=a.parseUShort(),i=p;n>=i;i++)o[f++]=i;return o}}function parseClassDefTable(r,e){var a=new parse.Parser(r,e),s=a.parseUShort();if(1===s){var t=a.parseUShort(),o=a.parseUShort(),p=a.parseUShortList(o);return function(r){return p[r-t]||0}}if(2===s){for(var n=a.parseUShort(),f=[],i=[],h=[],S=0;n>S;S++)f[S]=a.parseUShort(),i[S]=a.parseUShort(),h[S]=a.parseUShort();return function(r){for(var e=0,a=f.length-1;a>e;){var s=e+a+1>>1;r<f[s]?a=s-1:e=s}return f[e]<=r&&r<=i[e]?h[e]||0:0}}}function parsePairPosSubTable(r,e){var a,s,t=new parse.Parser(r,e),o=t.parseUShort(),p=t.parseUShort(),n=parseCoverageTable(r,e+p),f=t.parseUShort(),i=t.parseUShort();if(4===f&&0===i){var h={};if(1===o){for(var S=t.parseUShort(),u=[],v=t.parseOffset16List(S),U=0;S>U;U++){var l=v[U],g=h[l];if(!g){g={},t.relativeOffset=l;for(var T=t.parseUShort();T--;){var c=t.parseUShort();f&&(a=t.parseShort()),i&&(s=t.parseShort()),g[c]=a}}u[n[U]]=g}return function(r,e){var a=u[r];return a?a[e]:void 0}}if(2===o){for(var b=t.parseUShort(),P=t.parseUShort(),L=t.parseUShort(),k=t.parseUShort(),d=parseClassDefTable(r,e+b),w=parseClassDefTable(r,e+P),O=[],C=0;L>C;C++)for(var G=O[C]=[],K=0;k>K;K++)f&&(a=t.parseShort()),i&&(s=t.parseShort()),G[K]=a;var V={};for(C=0;C<n.length;C++)V[n[C]]=1;return function(r,e){if(V[r]){var a=d(r),s=w(e),t=O[a];return t?t[s]:void 0}}}}}function parseLookupTable(r,e){var a=new parse.Parser(r,e),s=a.parseUShort(),t=a.parseUShort(),o=16&t,p=a.parseUShort(),n=a.parseOffset16List(p),f={lookupType:s,lookupFlag:t,markFilteringSet:o?a.parseUShort():-1};if(2===s){for(var i=[],h=0;p>h;h++)i.push(parsePairPosSubTable(r,e+n[h]));f.getKerningValue=function(r,e){for(var a=i.length;a--;){var s=i[a](r,e);if(void 0!==s)return s}return 0}}return f}function parseGposTable(r,e,a){var s=new parse.Parser(r,e),t=s.parseFixed();check.argument(1===t,"Unsupported GPOS table version."),parseTaggedListTable(r,e+s.parseUShort()),parseTaggedListTable(r,e+s.parseUShort());var o=s.parseUShort();s.relativeOffset=o;for(var p=s.parseUShort(),n=s.parseOffset16List(p),f=e+o,i=0;p>i;i++){var h=parseLookupTable(r,f+n[i]);2!==h.lookupType||a.getGposKerningValue||(a.getGposKerningValue=h.getKerningValue)}}var check=require("../check"),parse=require("../parse");exports.parse=parseGposTable;
  19999. },{"../check":1,"../parse":7}],14:[function(require,module,exports){
  20000. "use strict";function parseHeadTable(e,a){var r={},t=new parse.Parser(e,a);return r.version=t.parseVersion(),r.fontRevision=Math.round(1e3*t.parseFixed())/1e3,r.checkSumAdjustment=t.parseULong(),r.magicNumber=t.parseULong(),check.argument(1594834165===r.magicNumber,"Font header has wrong magic number."),r.flags=t.parseUShort(),r.unitsPerEm=t.parseUShort(),r.created=t.parseLongDateTime(),r.modified=t.parseLongDateTime(),r.xMin=t.parseShort(),r.yMin=t.parseShort(),r.xMax=t.parseShort(),r.yMax=t.parseShort(),r.macStyle=t.parseUShort(),r.lowestRecPPEM=t.parseUShort(),r.fontDirectionHint=t.parseShort(),r.indexToLocFormat=t.parseShort(),r.glyphDataFormat=t.parseShort(),r}function makeHeadTable(e){return new table.Table("head",[{name:"version",type:"FIXED",value:65536},{name:"fontRevision",type:"FIXED",value:65536},{name:"checkSumAdjustment",type:"ULONG",value:0},{name:"magicNumber",type:"ULONG",value:1594834165},{name:"flags",type:"USHORT",value:0},{name:"unitsPerEm",type:"USHORT",value:1e3},{name:"created",type:"LONGDATETIME",value:0},{name:"modified",type:"LONGDATETIME",value:0},{name:"xMin",type:"SHORT",value:0},{name:"yMin",type:"SHORT",value:0},{name:"xMax",type:"SHORT",value:0},{name:"yMax",type:"SHORT",value:0},{name:"macStyle",type:"USHORT",value:0},{name:"lowestRecPPEM",type:"USHORT",value:0},{name:"fontDirectionHint",type:"SHORT",value:2},{name:"indexToLocFormat",type:"SHORT",value:0},{name:"glyphDataFormat",type:"SHORT",value:0}],e)}var check=require("../check"),parse=require("../parse"),table=require("../table");exports.parse=parseHeadTable,exports.make=makeHeadTable;
  20001. },{"../check":1,"../parse":7,"../table":9}],15:[function(require,module,exports){
  20002. "use strict";function parseHheaTable(e,a){var r={},t=new parse.Parser(e,a);return r.version=t.parseVersion(),r.ascender=t.parseShort(),r.descender=t.parseShort(),r.lineGap=t.parseShort(),r.advanceWidthMax=t.parseUShort(),r.minLeftSideBearing=t.parseShort(),r.minRightSideBearing=t.parseShort(),r.xMaxExtent=t.parseShort(),r.caretSlopeRise=t.parseShort(),r.caretSlopeRun=t.parseShort(),r.caretOffset=t.parseShort(),t.relativeOffset+=8,r.metricDataFormat=t.parseShort(),r.numberOfHMetrics=t.parseUShort(),r}function makeHheaTable(e){return new table.Table("hhea",[{name:"version",type:"FIXED",value:65536},{name:"ascender",type:"FWORD",value:0},{name:"descender",type:"FWORD",value:0},{name:"lineGap",type:"FWORD",value:0},{name:"advanceWidthMax",type:"UFWORD",value:0},{name:"minLeftSideBearing",type:"FWORD",value:0},{name:"minRightSideBearing",type:"FWORD",value:0},{name:"xMaxExtent",type:"FWORD",value:0},{name:"caretSlopeRise",type:"SHORT",value:1},{name:"caretSlopeRun",type:"SHORT",value:0},{name:"caretOffset",type:"SHORT",value:0},{name:"reserved1",type:"SHORT",value:0},{name:"reserved2",type:"SHORT",value:0},{name:"reserved3",type:"SHORT",value:0},{name:"reserved4",type:"SHORT",value:0},{name:"metricDataFormat",type:"SHORT",value:0},{name:"numberOfHMetrics",type:"USHORT",value:0}],e)}var parse=require("../parse"),table=require("../table");exports.parse=parseHheaTable,exports.make=makeHheaTable;
  20003. },{"../parse":7,"../table":9}],16:[function(require,module,exports){
  20004. "use strict";function parseHmtxTable(e,a,r,t,s){for(var i,l,n=new parse.Parser(e,a),p=0;t>p;p+=1){r>p&&(i=n.parseUShort(),l=n.parseShort());var d=s[p];d.advanceWidth=i,d.leftSideBearing=l}}function makeHmtxTable(e){for(var a=new table.Table("hmtx",[]),r=0;r<e.length;r+=1){var t=e[r],s=t.advanceWidth||0,i=t.leftSideBearing||0;a.fields.push({name:"advanceWidth_"+r,type:"USHORT",value:s}),a.fields.push({name:"leftSideBearing_"+r,type:"SHORT",value:i})}return a}var parse=require("../parse"),table=require("../table");exports.parse=parseHmtxTable,exports.make=makeHmtxTable;
  20005. },{"../parse":7,"../table":9}],17:[function(require,module,exports){
  20006. "use strict";function parseKernTable(r,e){var a={},s=new parse.Parser(r,e),p=s.parseUShort();check.argument(0===p,"Unsupported kern table version."),s.skip("uShort",1);var t=s.parseUShort();check.argument(0===t,"Unsupported kern sub-table version."),s.skip("uShort",2);var o=s.parseUShort();s.skip("uShort",3);for(var n=0;o>n;n+=1){var h=s.parseUShort(),u=s.parseUShort(),c=s.parseShort();a[h+","+u]=c}return a}var check=require("../check"),parse=require("../parse");exports.parse=parseKernTable;
  20007. },{"../check":1,"../parse":7}],18:[function(require,module,exports){
  20008. "use strict";function parseLocaTable(r,a,e,s){for(var p=new parse.Parser(r,a),o=s?p.parseUShort:p.parseULong,t=[],c=0;e+1>c;c+=1){var n=o.call(p);s&&(n*=2),t.push(n)}return t}var parse=require("../parse");exports.parse=parseLocaTable;
  20009. },{"../parse":7}],19:[function(require,module,exports){
  20010. "use strict";function parseMaxpTable(e,a){var r={},s=new parse.Parser(e,a);return r.version=s.parseVersion(),r.numGlyphs=s.parseUShort(),1===r.version&&(r.maxPoints=s.parseUShort(),r.maxContours=s.parseUShort(),r.maxCompositePoints=s.parseUShort(),r.maxCompositeContours=s.parseUShort(),r.maxZones=s.parseUShort(),r.maxTwilightPoints=s.parseUShort(),r.maxStorage=s.parseUShort(),r.maxFunctionDefs=s.parseUShort(),r.maxInstructionDefs=s.parseUShort(),r.maxStackElements=s.parseUShort(),r.maxSizeOfInstructions=s.parseUShort(),r.maxComponentElements=s.parseUShort(),r.maxComponentDepth=s.parseUShort()),r}function makeMaxpTable(e){return new table.Table("maxp",[{name:"version",type:"FIXED",value:20480},{name:"numGlyphs",type:"USHORT",value:e}])}var parse=require("../parse"),table=require("../table");exports.parse=parseMaxpTable,exports.make=makeMaxpTable;
  20011. },{"../parse":7,"../table":9}],20:[function(require,module,exports){
  20012. "use strict";function parseNameTable(e,a){var r={},n=new parse.Parser(e,a);r.format=n.parseUShort();for(var t=n.parseUShort(),s=n.offset+n.parseUShort(),o=0,m=0;t>m;m++){var l=n.parseUShort(),p=n.parseUShort(),u=n.parseUShort(),i=n.parseUShort(),d=nameTableNames[i],c=n.parseUShort(),f=n.parseUShort();if(3===l&&1===p&&1033===u){for(var h=[],T=c/2,g=0;T>g;g++,f+=2)h[g]=parse.getShort(e,s+f);var S=String.fromCharCode.apply(null,h);d?r[d]=S:(o++,r["unknown"+o]=S)}}return 1===r.format&&(r.langTagCount=n.parseUShort()),r}function makeNameRecord(e,a,r,n,t,s){return new table.Table("NameRecord",[{name:"platformID",type:"USHORT",value:e},{name:"encodingID",type:"USHORT",value:a},{name:"languageID",type:"USHORT",value:r},{name:"nameID",type:"USHORT",value:n},{name:"length",type:"USHORT",value:t},{name:"offset",type:"USHORT",value:s}])}function addMacintoshNameRecord(e,a,r,n){var t=encode.STRING(r);return e.records.push(makeNameRecord(1,0,0,a,t.length,n)),e.strings.push(t),n+=t.length}function addWindowsNameRecord(e,a,r,n){var t=encode.UTF16(r);return e.records.push(makeNameRecord(3,1,1033,a,t.length,n)),e.strings.push(t),n+=t.length}function makeNameTable(e){var a=new table.Table("name",[{name:"format",type:"USHORT",value:0},{name:"count",type:"USHORT",value:0},{name:"stringOffset",type:"USHORT",value:0}]);a.records=[],a.strings=[];var r,n,t=0;for(r=0;r<nameTableNames.length;r+=1)void 0!==e[nameTableNames[r]]&&(n=e[nameTableNames[r]],t=addMacintoshNameRecord(a,r,n,t));for(r=0;r<nameTableNames.length;r+=1)void 0!==e[nameTableNames[r]]&&(n=e[nameTableNames[r]],t=addWindowsNameRecord(a,r,n,t));for(a.count=a.records.length,a.stringOffset=6+12*a.count,r=0;r<a.records.length;r+=1)a.fields.push({name:"record_"+r,type:"TABLE",value:a.records[r]});for(r=0;r<a.strings.length;r+=1)a.fields.push({name:"string_"+r,type:"LITERAL",value:a.strings[r]});return a}var encode=require("../types").encode,parse=require("../parse"),table=require("../table"),nameTableNames=["copyright","fontFamily","fontSubfamily","uniqueID","fullName","version","postScriptName","trademark","manufacturer","designer","description","manufacturerURL","designerURL","licence","licenceURL","reserved","preferredFamily","preferredSubfamily","compatibleFullName","sampleText","postScriptFindFontName","wwsFamily","wwsSubfamily"];exports.parse=parseNameTable,exports.make=makeNameTable;
  20013. },{"../parse":7,"../table":9,"../types":24}],21:[function(require,module,exports){
  20014. "use strict";function getUnicodeRange(e){for(var n=0;n<unicodeRanges.length;n+=1){var a=unicodeRanges[n];if(e>=a.begin&&e<a.end)return n}return-1}function parseOS2Table(e,n){var a={},i=new parse.Parser(e,n);a.version=i.parseUShort(),a.xAvgCharWidth=i.parseShort(),a.usWeightClass=i.parseUShort(),a.usWidthClass=i.parseUShort(),a.fsType=i.parseUShort(),a.ySubscriptXSize=i.parseShort(),a.ySubscriptYSize=i.parseShort(),a.ySubscriptXOffset=i.parseShort(),a.ySubscriptYOffset=i.parseShort(),a.ySuperscriptXSize=i.parseShort(),a.ySuperscriptYSize=i.parseShort(),a.ySuperscriptXOffset=i.parseShort(),a.ySuperscriptYOffset=i.parseShort(),a.yStrikeoutSize=i.parseShort(),a.yStrikeoutPosition=i.parseShort(),a.sFamilyClass=i.parseShort(),a.panose=[];for(var t=0;10>t;t++)a.panose[t]=i.parseByte();return a.ulUnicodeRange1=i.parseULong(),a.ulUnicodeRange2=i.parseULong(),a.ulUnicodeRange3=i.parseULong(),a.ulUnicodeRange4=i.parseULong(),a.achVendID=String.fromCharCode(i.parseByte(),i.parseByte(),i.parseByte(),i.parseByte()),a.fsSelection=i.parseUShort(),a.usFirstCharIndex=i.parseUShort(),a.usLastCharIndex=i.parseUShort(),a.sTypoAscender=i.parseShort(),a.sTypoDescender=i.parseShort(),a.sTypoLineGap=i.parseShort(),a.usWinAscent=i.parseUShort(),a.usWinDescent=i.parseUShort(),a.version>=1&&(a.ulCodePageRange1=i.parseULong(),a.ulCodePageRange2=i.parseULong()),a.version>=2&&(a.sxHeight=i.parseShort(),a.sCapHeight=i.parseShort(),a.usDefaultChar=i.parseUShort(),a.usBreakChar=i.parseUShort(),a.usMaxContent=i.parseUShort()),a}function makeOS2Table(e){return new table.Table("OS/2",[{name:"version",type:"USHORT",value:3},{name:"xAvgCharWidth",type:"SHORT",value:0},{name:"usWeightClass",type:"USHORT",value:0},{name:"usWidthClass",type:"USHORT",value:0},{name:"fsType",type:"USHORT",value:0},{name:"ySubscriptXSize",type:"SHORT",value:650},{name:"ySubscriptYSize",type:"SHORT",value:699},{name:"ySubscriptXOffset",type:"SHORT",value:0},{name:"ySubscriptYOffset",type:"SHORT",value:140},{name:"ySuperscriptXSize",type:"SHORT",value:650},{name:"ySuperscriptYSize",type:"SHORT",value:699},{name:"ySuperscriptXOffset",type:"SHORT",value:0},{name:"ySuperscriptYOffset",type:"SHORT",value:479},{name:"yStrikeoutSize",type:"SHORT",value:49},{name:"yStrikeoutPosition",type:"SHORT",value:258},{name:"sFamilyClass",type:"SHORT",value:0},{name:"bFamilyType",type:"BYTE",value:0},{name:"bSerifStyle",type:"BYTE",value:0},{name:"bWeight",type:"BYTE",value:0},{name:"bProportion",type:"BYTE",value:0},{name:"bContrast",type:"BYTE",value:0},{name:"bStrokeVariation",type:"BYTE",value:0},{name:"bArmStyle",type:"BYTE",value:0},{name:"bLetterform",type:"BYTE",value:0},{name:"bMidline",type:"BYTE",value:0},{name:"bXHeight",type:"BYTE",value:0},{name:"ulUnicodeRange1",type:"ULONG",value:0},{name:"ulUnicodeRange2",type:"ULONG",value:0},{name:"ulUnicodeRange3",type:"ULONG",value:0},{name:"ulUnicodeRange4",type:"ULONG",value:0},{name:"achVendID",type:"CHARARRAY",value:"XXXX"},{name:"fsSelection",type:"USHORT",value:0},{name:"usFirstCharIndex",type:"USHORT",value:0},{name:"usLastCharIndex",type:"USHORT",value:0},{name:"sTypoAscender",type:"SHORT",value:0},{name:"sTypoDescender",type:"SHORT",value:0},{name:"sTypoLineGap",type:"SHORT",value:0},{name:"usWinAscent",type:"USHORT",value:0},{name:"usWinDescent",type:"USHORT",value:0},{name:"ulCodePageRange1",type:"ULONG",value:0},{name:"ulCodePageRange2",type:"ULONG",value:0},{name:"sxHeight",type:"SHORT",value:0},{name:"sCapHeight",type:"SHORT",value:0},{name:"usDefaultChar",type:"USHORT",value:0},{name:"usBreakChar",type:"USHORT",value:0},{name:"usMaxContext",type:"USHORT",value:0}],e)}var parse=require("../parse"),table=require("../table"),unicodeRanges=[{begin:0,end:127},{begin:128,end:255},{begin:256,end:383},{begin:384,end:591},{begin:592,end:687},{begin:688,end:767},{begin:768,end:879},{begin:880,end:1023},{begin:11392,end:11519},{begin:1024,end:1279},{begin:1328,end:1423},{begin:1424,end:1535},{begin:42240,end:42559},{begin:1536,end:1791},{begin:1984,end:2047},{begin:2304,end:2431},{begin:2432,end:2559},{begin:2560,end:2687},{begin:2688,end:2815},{begin:2816,end:2943},{begin:2944,end:3071},{begin:3072,end:3199},{begin:3200,end:3327},{begin:3328,end:3455},{begin:3584,end:3711},{begin:3712,end:3839},{begin:4256,end:4351},{begin:6912,end:7039},{begin:4352,end:4607},{begin:7680,end:7935},{begin:7936,end:8191},{begin:8192,end:8303},{begin:8304,end:8351},{begin:8352,end:8399},{begin:8400,end:8447},{begin:8448,end:8527},{begin:8528,end:8591},{begin:8592,end:8703},{begin:8704,end:8959},{begin:8960,end:9215},{begin:9216,end:9279},{begin:9280,end:9311},{begin:9312,end:9471},{begin:9472,end:9599},{begin:9600,end:9631},{begin:9632,end:9727},{begin:9728,end:9983},{begin:9984,end:10175},{begin:12288,end:12351},{begin:12352,end:12447},{begin:12448,end:12543},{begin:12544,end:12591},{begin:12592,end:12687},{begin:43072,end:43135},{begin:12800,end:13055},{begin:13056,end:13311},{begin:44032,end:55215},{begin:55296,end:57343},{begin:67840,end:67871},{begin:19968,end:40959},{begin:57344,end:63743},{begin:12736,end:12783},{begin:64256,end:64335},{begin:64336,end:65023},{begin:65056,end:65071},{begin:65040,end:65055},{begin:65104,end:65135},{begin:65136,end:65279},{begin:65280,end:65519},{begin:65520,end:65535},{begin:3840,end:4095},{begin:1792,end:1871},{begin:1920,end:1983},{begin:3456,end:3583},{begin:4096,end:4255},{begin:4608,end:4991},{begin:5024,end:5119},{begin:5120,end:5759},{begin:5760,end:5791},{begin:5792,end:5887},{begin:6016,end:6143},{begin:6144,end:6319},{begin:10240,end:10495},{begin:40960,end:42127},{begin:5888,end:5919},{begin:66304,end:66351},{begin:66352,end:66383},{begin:66560,end:66639},{begin:118784,end:119039},{begin:119808,end:120831},{begin:1044480,end:1048573},{begin:65024,end:65039},{begin:917504,end:917631},{begin:6400,end:6479},{begin:6480,end:6527},{begin:6528,end:6623},{begin:6656,end:6687},{begin:11264,end:11359},{begin:11568,end:11647},{begin:19904,end:19967},{begin:43008,end:43055},{begin:65536,end:65663},{begin:65856,end:65935},{begin:66432,end:66463},{begin:66464,end:66527},{begin:66640,end:66687},{begin:66688,end:66735},{begin:67584,end:67647},{begin:68096,end:68191},{begin:119552,end:119647},{begin:73728,end:74751},{begin:119648,end:119679},{begin:7040,end:7103},{begin:7168,end:7247},{begin:7248,end:7295},{begin:43136,end:43231},{begin:43264,end:43311},{begin:43312,end:43359},{begin:43520,end:43615},{begin:65936,end:65999},{begin:66e3,end:66047},{begin:66208,end:66271},{begin:127024,end:127135}];exports.unicodeRanges=unicodeRanges,exports.getUnicodeRange=getUnicodeRange,exports.parse=parseOS2Table,exports.make=makeOS2Table;
  20015. },{"../parse":7,"../table":9}],22:[function(require,module,exports){
  20016. "use strict";function parsePostTable(e,a){var r,n={},s=new parse.Parser(e,a);switch(n.version=s.parseVersion(),n.italicAngle=s.parseFixed(),n.underlinePosition=s.parseShort(),n.underlineThickness=s.parseShort(),n.isFixedPitch=s.parseULong(),n.minMemType42=s.parseULong(),n.maxMemType42=s.parseULong(),n.minMemType1=s.parseULong(),n.maxMemType1=s.parseULong(),n.version){case 1:n.names=encoding.standardNames.slice();break;case 2:for(n.numberOfGlyphs=s.parseUShort(),n.glyphNameIndex=new Array(n.numberOfGlyphs),r=0;r<n.numberOfGlyphs;r++)n.glyphNameIndex[r]=s.parseUShort();for(n.names=[],r=0;r<n.numberOfGlyphs;r++)if(n.glyphNameIndex[r]>=encoding.standardNames.length){var p=s.parseChar();n.names.push(s.parseString(p))}break;case 2.5:for(n.numberOfGlyphs=s.parseUShort(),n.offset=new Array(n.numberOfGlyphs),r=0;r<n.numberOfGlyphs;r++)n.offset[r]=s.parseChar()}return n}function makePostTable(){return new table.Table("post",[{name:"version",type:"FIXED",value:196608},{name:"italicAngle",type:"FIXED",value:0},{name:"underlinePosition",type:"FWORD",value:0},{name:"underlineThickness",type:"FWORD",value:0},{name:"isFixedPitch",type:"ULONG",value:0},{name:"minMemType42",type:"ULONG",value:0},{name:"maxMemType42",type:"ULONG",value:0},{name:"minMemType1",type:"ULONG",value:0},{name:"maxMemType1",type:"ULONG",value:0}])}var encoding=require("../encoding"),parse=require("../parse"),table=require("../table");exports.parse=parsePostTable,exports.make=makePostTable;
  20017. },{"../encoding":3,"../parse":7,"../table":9}],23:[function(require,module,exports){
  20018. "use strict";function log2(e){return Math.log(e)/Math.log(2)|0}function computeCheckSum(e){for(;e.length%4!==0;)e.push(0);for(var a=0,n=0;n<e.length;n+=4)a+=(e[n]<<24)+(e[n+1]<<16)+(e[n+2]<<8)+e[n+3];return a%=Math.pow(2,32)}function makeTableRecord(e,a,n,r){return new table.Table("Table Record",[{name:"tag",type:"TAG",value:void 0!==e?e:""},{name:"checkSum",type:"ULONG",value:void 0!==a?a:0},{name:"offset",type:"ULONG",value:void 0!==n?n:0},{name:"length",type:"ULONG",value:void 0!==r?r:0}])}function makeSfntTable(e){var a=new table.Table("sfnt",[{name:"version",type:"TAG",value:"OTTO"},{name:"numTables",type:"USHORT",value:0},{name:"searchRange",type:"USHORT",value:0},{name:"entrySelector",type:"USHORT",value:0},{name:"rangeShift",type:"USHORT",value:0}]);a.tables=e,a.numTables=e.length;var n=Math.pow(2,log2(a.numTables));a.searchRange=16*n,a.entrySelector=log2(n),a.rangeShift=16*a.numTables-a.searchRange;for(var r=[],t=[],i=a.sizeOf()+makeTableRecord().sizeOf()*a.numTables;i%4!==0;)i+=1,t.push({name:"padding",type:"BYTE",value:0});for(var l=0;l<e.length;l+=1){var s=e[l];check.argument(4===s.tableName.length,"Table name"+s.tableName+" is invalid.");var m=s.sizeOf(),u=makeTableRecord(s.tableName,computeCheckSum(s.encode()),i,m);for(r.push({name:u.tag+" Table Record",type:"TABLE",value:u}),t.push({name:s.tableName+" table",type:"TABLE",value:s}),i+=m,check.argument(!isNaN(i),"Something went wrong calculating the offset.");i%4!==0;)i+=1,t.push({name:"padding",type:"BYTE",value:0})}return r.sort(function(e,a){return e.value.tag>a.value.tag?1:-1}),a.fields=a.fields.concat(r),a.fields=a.fields.concat(t),a}function metricsForChar(e,a,n){for(var r=0;r<a.length;r+=1){var t=e.charToGlyphIndex(a[r]);if(t>0){var i=e.glyphs[t];return i.getMetrics()}}return n}function average(e){for(var a=0,n=0;n<e.length;n+=1)a+=e[n];return a/e.length}function fontToSfntTable(e){for(var a=[],n=[],r=[],t=[],i=[],l=[],s=[],m=null,u=0,c=0,h=0,o=0,d=0,p=0;p<e.glyphs.length;p+=1){var f=e.glyphs[p],g=0|f.unicode;(m>g||null===m)&&(m=g),g>u&&(u=g);var y=os2.getUnicodeRange(g);if(32>y)c|=1<<y;else if(64>y)h|=1<<y-32;else if(96>y)o|=1<<y-64;else{if(!(123>y))throw new Error("Unicode ranges bits > 123 are reserved for internal usage");d|=1<<y-96}if(".notdef"!==f.name){var v=f.getMetrics();a.push(v.xMin),n.push(v.yMin),r.push(v.xMax),t.push(v.yMax),l.push(v.leftSideBearing),s.push(v.rightSideBearing),i.push(f.advanceWidth)}}var x={xMin:Math.min.apply(null,a),yMin:Math.min.apply(null,n),xMax:Math.max.apply(null,r),yMax:Math.max.apply(null,t),advanceWidthMax:Math.max.apply(null,i),advanceWidthAvg:average(i),minLeftSideBearing:Math.min.apply(null,l),maxLeftSideBearing:Math.max.apply(null,l),minRightSideBearing:Math.min.apply(null,s)};x.ascender=void 0!==e.ascender?e.ascender:x.yMax,x.descender=void 0!==e.descender?e.descender:x.yMin;var M=head.make({unitsPerEm:e.unitsPerEm,xMin:x.xMin,yMin:x.yMin,xMax:x.xMax,yMax:x.yMax}),T=hhea.make({ascender:x.ascender,descender:x.descender,advanceWidthMax:x.advanceWidthMax,minLeftSideBearing:x.minLeftSideBearing,minRightSideBearing:x.minRightSideBearing,xMaxExtent:x.maxLeftSideBearing+(x.xMax-x.xMin),numberOfHMetrics:e.glyphs.length}),S=maxp.make(e.glyphs.length),b=os2.make({xAvgCharWidth:Math.round(x.advanceWidthAvg),usWeightClass:500,usWidthClass:5,usFirstCharIndex:m,usLastCharIndex:u,ulUnicodeRange1:c,ulUnicodeRange2:h,ulUnicodeRange3:o,ulUnicodeRange4:d,sTypoAscender:x.ascender,sTypoDescender:x.descender,sTypoLineGap:0,usWinAscent:x.ascender,usWinDescent:-x.descender,sxHeight:metricsForChar(e,"xyvw",{yMax:0}).yMax,sCapHeight:metricsForChar(e,"HIKLEFJMNTZBDPRAGOQSUVWXY",x).yMax,usBreakChar:e.hasChar(" ")?32:0}),k=hmtx.make(e.glyphs),R=cmap.make(e.glyphs),N=e.familyName+" "+e.styleName,U=e.familyName.replace(/\s/g,"")+"-"+e.styleName,L=_name.make({copyright:e.copyright,fontFamily:e.familyName,fontSubfamily:e.styleName,uniqueID:e.manufacturer+":"+N,fullName:N,version:e.version,postScriptName:U,trademark:e.trademark,manufacturer:e.manufacturer,designer:e.designer,description:e.description,manufacturerURL:e.manufacturerURL,designerURL:e.designerURL,license:e.license,licenseURL:e.licenseURL,preferredFamily:e.familyName,preferredSubfamily:e.styleName}),C=post.make(),B=cff.make(e.glyphs,{version:e.version,fullName:N,familyName:e.familyName,weightName:e.styleName,postScriptName:U}),O=[M,T,S,b,L,R,C,B,k],w=makeSfntTable(O),q=w.encode(),W=computeCheckSum(q),A=w.fields,E=!1;for(p=0;p<A.length;p+=1)if("head table"===A[p].name){A[p].value.checkSumAdjustment=2981146554-W,E=!0;break}if(!E)throw new Error("Could not find head table with checkSum to adjust.");return w}var check=require("../check"),table=require("../table"),cmap=require("./cmap"),cff=require("./cff"),head=require("./head"),hhea=require("./hhea"),hmtx=require("./hmtx"),maxp=require("./maxp"),_name=require("./name"),os2=require("./os2"),post=require("./post");exports.computeCheckSum=computeCheckSum,exports.make=makeSfntTable,exports.fontToTable=fontToSfntTable;
  20019. },{"../check":1,"../table":9,"./cff":10,"./cmap":11,"./head":14,"./hhea":15,"./hmtx":16,"./maxp":19,"./name":20,"./os2":21,"./post":22}],24:[function(require,module,exports){
  20020. "use strict";function constant(e){return function(){return e}}var check=require("./check"),LIMIT16=32768,LIMIT32=2147483648,decode={},encode={},sizeOf={};encode.BYTE=function(e){return check.argument(e>=0&&255>=e,"Byte value should be between 0 and 255."),[e]},sizeOf.BYTE=constant(1),encode.CHAR=function(e){return[e.charCodeAt(0)]},sizeOf.BYTE=constant(1),encode.CHARARRAY=function(e){for(var n=[],o=0;o<e.length;o+=1)n.push(e.charCodeAt(o));return n},sizeOf.CHARARRAY=function(e){return e.length},encode.USHORT=function(e){return[e>>8&255,255&e]},sizeOf.USHORT=constant(2),encode.SHORT=function(e){return e>=LIMIT16&&(e=-(2*LIMIT16-e)),[e>>8&255,255&e]},sizeOf.SHORT=constant(2),encode.UINT24=function(e){return[e>>16&255,e>>8&255,255&e]},sizeOf.UINT24=constant(3),encode.ULONG=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]},sizeOf.ULONG=constant(4),encode.LONG=function(e){return e>=LIMIT32&&(e=-(2*LIMIT32-e)),[e>>24&255,e>>16&255,e>>8&255,255&e]},sizeOf.LONG=constant(4),encode.FIXED=encode.ULONG,sizeOf.FIXED=sizeOf.ULONG,encode.FWORD=encode.SHORT,sizeOf.FWORD=sizeOf.SHORT,encode.UFWORD=encode.USHORT,sizeOf.UFWORD=sizeOf.USHORT,encode.LONGDATETIME=function(){return[0,0,0,0,0,0,0,0]},sizeOf.LONGDATETIME=constant(8),encode.TAG=function(e){return check.argument(4===e.length,"Tag should be exactly 4 ASCII characters."),[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]},sizeOf.TAG=constant(4),encode.Card8=encode.BYTE,sizeOf.Card8=sizeOf.BYTE,encode.Card16=encode.USHORT,sizeOf.Card16=sizeOf.USHORT,encode.OffSize=encode.BYTE,sizeOf.OffSize=sizeOf.BYTE,encode.SID=encode.USHORT,sizeOf.SID=sizeOf.USHORT,encode.NUMBER=function(e){return e>=-107&&107>=e?[e+139]:e>=108&&1131>=e?(e-=108,[(e>>8)+247,255&e]):e>=-1131&&-108>=e?(e=-e-108,[(e>>8)+251,255&e]):e>=-32768&&32767>=e?encode.NUMBER16(e):encode.NUMBER32(e)},sizeOf.NUMBER=function(e){return encode.NUMBER(e).length},encode.NUMBER16=function(e){return[28,e>>8&255,255&e]},sizeOf.NUMBER16=constant(2),encode.NUMBER32=function(e){return[29,e>>24&255,e>>16&255,e>>8&255,255&e]},sizeOf.NUMBER32=constant(4),encode.NAME=encode.CHARARRAY,sizeOf.NAME=sizeOf.CHARARRAY,encode.STRING=encode.CHARARRAY,sizeOf.STRING=sizeOf.CHARARRAY,encode.UTF16=function(e){for(var n=[],o=0;o<e.length;o+=1)n.push(0),n.push(e.charCodeAt(o));return n},sizeOf.UTF16=function(e){return 2*e.length},encode.INDEX=function(e){var n,o=1,t=[o],c=[],r=0;for(n=0;n<e.length;n+=1){var f=encode.OBJECT(e[n]);Array.prototype.push.apply(c,f),r+=f.length,o+=f.length,t.push(o)}if(0===c.length)return[0,0];var d=[],i=1+Math.floor(Math.log(r)/Math.log(2))/8|0,u=[void 0,encode.BYTE,encode.USHORT,encode.UINT24,encode.ULONG][i];for(n=0;n<t.length;n+=1){var a=u(t[n]);Array.prototype.push.apply(d,a)}return Array.prototype.concat(encode.Card16(e.length),encode.OffSize(i),d,c)},sizeOf.INDEX=function(e){return encode.INDEX(e).length},encode.DICT=function(e){for(var n=[],o=Object.keys(e),t=o.length,c=0;t>c;c+=1){var r=parseInt(o[c],0),f=e[r];n=n.concat(encode.OPERAND(f.value,f.type)),n=n.concat(encode.OPERATOR(r))}return n},sizeOf.DICT=function(e){return encode.DICT(e).length},encode.OPERATOR=function(e){return 1200>e?[e]:[12,e-1200]},encode.OPERAND=function(e,n){var o=[];if(Array.isArray(n))for(var t=0;t<n.length;t+=1)check.argument(e.length===n.length,"Not enough arguments given for type"+n),o=o.concat(encode.OPERAND(e[t],n[t]));else o=o.concat("SID"===n?encode.NUMBER(e):"offset"===n?encode.NUMBER32(e):encode.NUMBER(e));return o},encode.OP=encode.BYTE,sizeOf.OP=sizeOf.BYTE;var wmm="function"==typeof WeakMap&&new WeakMap;encode.CHARSTRING=function(e){if(wmm&&wmm.has(e))return wmm.get(e);for(var n=[],o=e.length,t=0;o>t;t+=1){var c=e[t];n=n.concat(encode[c.type](c.value))}return wmm&&wmm.set(e,n),n},sizeOf.CHARSTRING=function(e){return encode.CHARSTRING(e).length},encode.OBJECT=function(e){var n=encode[e.type];return check.argument(void 0!==n,"No encoding function for type "+e.type),n(e.value)},encode.TABLE=function(e){for(var n=[],o=e.fields.length,t=0;o>t;t+=1){var c=e.fields[t],r=encode[c.type];check.argument(void 0!==r,"No encoding function for field type "+c.type);var f=e[c.name];void 0===f&&(f=c.value);var d=r(f);n=n.concat(d)}return n},encode.LITERAL=function(e){return e},sizeOf.LITERAL=function(e){return e.length},exports.decode=decode,exports.encode=encode,exports.sizeOf=sizeOf;
  20021. },{"./check":1}]},{},[6])(6)
  20022. });