kity_all.js 302 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573
  1. /*!
  2. * ====================================================
  3. * kity - v2.0.5 - 2015-11-12
  4. * https://github.com/fex-team/kity
  5. * GitHub: https://github.com/fex-team/kity.git
  6. * Copyright (c) 2015 Baidu FEX; Licensed BSD
  7. * ====================================================
  8. */
  9. (function () {
  10. var _p = {
  11. r: function(index) {
  12. if (_p[index].inited) {
  13. return _p[index].value;
  14. }
  15. if (typeof _p[index].value === "function") {
  16. var module = {
  17. exports: {}
  18. }, returnValue = _p[index].value(null, module.exports, module);
  19. _p[index].inited = true;
  20. _p[index].value = returnValue;
  21. if (returnValue !== undefined) {
  22. return returnValue;
  23. } else {
  24. for (var key in module.exports) {
  25. if (module.exports.hasOwnProperty(key)) {
  26. _p[index].inited = true;
  27. _p[index].value = module.exports;
  28. return module.exports;
  29. }
  30. }
  31. }
  32. } else {
  33. _p[index].inited = true;
  34. return _p[index].value;
  35. }
  36. }
  37. };
  38. //src/animate/animator.js
  39. /**
  40. * @fileOverview
  41. *
  42. * 提供基本的动画支持
  43. */
  44. _p[0] = {
  45. value: function(require) {
  46. function parseTime(str) {
  47. var value = parseFloat(str, 10);
  48. if (/ms/.test(str)) {
  49. return value;
  50. }
  51. if (/s/.test(str)) {
  52. return value * 1e3;
  53. }
  54. if (/min/.test(str)) {
  55. return value * 60 * 1e3;
  56. }
  57. return value;
  58. }
  59. var Timeline = _p.r(8);
  60. var easingTable = _p.r(1);
  61. /**
  62. * @class kity.Animator
  63. * @catalog animate
  64. * @description 表示一个动画启动器,可以作用于不同的对象进行动画
  65. */
  66. var Animator = _p.r(11).createClass("Animator", {
  67. /**
  68. * @constructor
  69. * @for kity.Animator
  70. * @catalog animate
  71. *
  72. * @grammar new kity.Animator(beginValue, finishValue, setter)
  73. * @grammar new kity.Animator(option)
  74. *
  75. * @param {any} beginValue|opt.beginValue
  76. * 动画的起始值,允许的类型有数字、数组、字面量、kity.Point、kity.Vector、kity.Box、kity.Matrix
  77. *
  78. * @param {any} finishValue|opt.beginValue
  79. * 动画的结束值,类型应于起始值相同
  80. *
  81. * @param {Function} setter|opt.setter
  82. * 值的使用函数,接受三个参数: function(target, value, timeline)
  83. * target {object} 动画的目标
  84. * value {any} 动画的当前值
  85. * timeline {kity.Timeline} 动画当前的时间线对象
  86. */
  87. constructor: function(beginValue, finishValue, setter) {
  88. if (arguments.length == 1) {
  89. var opt = arguments[0];
  90. this.beginValue = opt.beginValue;
  91. this.finishValue = opt.finishValue;
  92. this.setter = opt.setter;
  93. } else {
  94. this.beginValue = beginValue;
  95. this.finishValue = finishValue;
  96. this.setter = setter;
  97. }
  98. },
  99. /**
  100. * @method start()
  101. * @for kity.Animator
  102. * @description 使用当前的动画器启动在指定目标上启动动画
  103. *
  104. * @grammar start(target, duration, easing, delay, callback) => {kity.Timeline}
  105. * @grammar start(target, option) => {kity.Timeline}
  106. *
  107. * @param {object} target
  108. * 启动动画的目标
  109. *
  110. * @param {Number|String} duration|option.duration
  111. * [Optional] 动画的持续时间,如 300、"300ms"、"1.5min"
  112. *
  113. * @param {String|Function} easing|option.easing
  114. * [Optional] 动画使用的缓动函数,如 "ease"、"linear"、"swing"
  115. *
  116. * @param {Number|String} delay|option.delay
  117. * [Optional] 动画的播放延迟时间
  118. *
  119. * @param {Function} callback|option.callback
  120. * [Optional] 动画结束后的回调函数
  121. *
  122. * @example
  123. *
  124. * ```js
  125. * var turnRed = new kity.Animator(
  126. * new kity.Color('yellow'),
  127. * new kity.Color('red'),
  128. * function(target, value) {
  129. * target.fill(value);
  130. * });
  131. *
  132. * turnRed.start(rect, 300, 'ease', function() {
  133. * console.log('I am red!');
  134. * });
  135. * ```
  136. */
  137. start: function(target, duration, easing, delay, callback) {
  138. if (arguments.length === 2 && typeof duration == "object") {
  139. easing = duration.easing;
  140. delay = duration.delay;
  141. callback = duration.callback;
  142. duration = duration.duration;
  143. }
  144. if (arguments.length === 4 && typeof delay == "function") {
  145. callback = delay;
  146. delay = 0;
  147. }
  148. var timeline = this.create(target, duration, easing, callback);
  149. delay = parseTime(delay);
  150. if (delay > 0) {
  151. setTimeout(function() {
  152. timeline.play();
  153. }, delay);
  154. } else {
  155. timeline.play();
  156. }
  157. return timeline;
  158. },
  159. /**
  160. * @method create()
  161. * @for kity.Animator
  162. * @description 使用当前的动画器为指定目标创建时间线
  163. *
  164. * @grammar create(target, duration, easing, callback) => {kity.Timeline}
  165. *
  166. * @param {object} target 要创建的时间线的目标
  167. * @param {Number|String} duration 要创建的时间线的长度,如 300、"5s"、"0.5min"
  168. * @param {String|Function} easing 要创建的时间线的缓动函数,如 'ease'、'linear'、'swing'
  169. * @param {Function} callback 时间线播放结束之后的回调函数
  170. *
  171. * @example
  172. *
  173. * ```js
  174. * var expand = new kity.Animator({
  175. * beginValue: function(target) {
  176. * return target.getBox();
  177. * },
  178. * finishValue: function(target) {
  179. * return target.getBox().expand(100, 100, 100, 100);
  180. * },
  181. * setter: function(target, value) {
  182. * target.setBox(value)
  183. * }
  184. * });
  185. *
  186. * var timeline = expand.create(rect, 300);
  187. * timeline.repeat(3).play();
  188. * ```
  189. */
  190. create: function(target, duration, easing, callback) {
  191. var timeline;
  192. duration = duration && parseTime(duration) || Animator.DEFAULT_DURATION;
  193. easing = easing || Animator.DEFAULT_EASING;
  194. if (typeof easing == "string") {
  195. easing = easingTable[easing];
  196. }
  197. timeline = new Timeline(this, target, duration, easing);
  198. if (typeof callback == "function") {
  199. timeline.on("finish", callback);
  200. }
  201. return timeline;
  202. },
  203. /**
  204. * @method reverse()
  205. * @for kity.Animator
  206. * @grammar reverse() => {kity.Animator}
  207. * @description 创建一个与当前动画器相反的动画器
  208. *
  209. * @example
  210. *
  211. * ```js
  212. * var turnYellow = turnRed.reverse();
  213. * ```
  214. */
  215. reverse: function() {
  216. return new Animator(this.finishValue, this.beginValue, this.setter);
  217. }
  218. });
  219. Animator.DEFAULT_DURATION = 300;
  220. Animator.DEFAULT_EASING = "linear";
  221. var Shape = _p.r(60);
  222. _p.r(11).extendClass(Shape, {
  223. /**
  224. * @method animate()
  225. * @for kity.Shape
  226. * @description 在图形上播放使用指定的动画器播放动画,如果图形当前有动画正在播放,则会加入播放队列
  227. *
  228. * @grammar animate(animator, duration, easing, delay, callback)
  229. *
  230. * @param {object} animator 播放动画使用的动画器
  231. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  232. * @param {Number|String} delay 动画播放前的延时
  233. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  234. * @param {Function} callback 播放结束之后的回调函数
  235. *
  236. * @example
  237. *
  238. * ```js
  239. * rect.animate(turnRed, 300); // turnRect 是一个动画器
  240. * rect.animate(expand, 500); // turnRect 播放结束后播放 expand
  241. * ```
  242. */
  243. animate: function(animator, duration, easing, delay, callback) {
  244. var queue = this._KityAnimateQueue = this._KityAnimateQueue || [];
  245. var timeline = animator.create(this, duration, easing, callback);
  246. function dequeue() {
  247. queue.shift();
  248. if (queue.length) {
  249. setTimeout(queue[0].t.play.bind(queue[0].t), queue[0].d);
  250. }
  251. }
  252. timeline.on("finish", dequeue);
  253. queue.push({
  254. t: timeline,
  255. d: delay
  256. });
  257. if (queue.length == 1) {
  258. setTimeout(timeline.play.bind(timeline), delay);
  259. }
  260. return this;
  261. },
  262. /**
  263. * @method timeline()
  264. * @for kity.Shape
  265. * @description 获得当前正在播放的动画的时间线
  266. *
  267. * @grammar timeline() => {kity.Timeline}
  268. *
  269. * @example
  270. *
  271. * ```js
  272. * rect.timeline().repeat(2);
  273. * ```
  274. */
  275. timeline: function() {
  276. return this._KityAnimateQueue[0].t;
  277. },
  278. /**
  279. * @method stop()
  280. * @for kity.Shape
  281. * @description 停止当前正在播放的动画
  282. *
  283. * @grammar stop() => {this}
  284. *
  285. * @example
  286. *
  287. * ```js
  288. * rect.stop(); // 停止 rect 上的动画
  289. * ```
  290. */
  291. stop: function() {
  292. var queue = this._KityAnimateQueue;
  293. if (queue) {
  294. while (queue.length) {
  295. queue.shift().t.stop();
  296. }
  297. }
  298. return this;
  299. }
  300. });
  301. return Animator;
  302. }
  303. };
  304. //src/animate/easing.js
  305. /**
  306. * Kity Animate Easing modified from jQuery Easing
  307. * Author: techird
  308. * Changes:
  309. * 1. make easing functions standalone
  310. * 2. remove the 'x' parameter
  311. */
  312. /* ============================================================
  313. * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
  314. *
  315. * Open source under the BSD License.
  316. *
  317. * Copyright © 2008 George McGinley Smith
  318. * All rights reserved.
  319. * https://raw.github.com/danro/jquery-easing/master/LICENSE
  320. * ======================================================== */
  321. _p[1] = {
  322. value: function(require, exports, module) {
  323. var easings = {
  324. // t: current_time, b: begin_value, c: change_value, d: duration
  325. linear: function(t, b, c, d) {
  326. return c * (t / d) + b;
  327. },
  328. swing: function(t, b, c, d) {
  329. return easings.easeOutQuad(t, b, c, d);
  330. },
  331. ease: function(t, b, c, d) {
  332. return easings.easeInOutCubic(t, b, c, d);
  333. },
  334. easeInQuad: function(t, b, c, d) {
  335. return c * (t /= d) * t + b;
  336. },
  337. easeOutQuad: function(t, b, c, d) {
  338. return -c * (t /= d) * (t - 2) + b;
  339. },
  340. easeInOutQuad: function(t, b, c, d) {
  341. if ((t /= d / 2) < 1) return c / 2 * t * t + b;
  342. return -c / 2 * (--t * (t - 2) - 1) + b;
  343. },
  344. easeInCubic: function(t, b, c, d) {
  345. return c * (t /= d) * t * t + b;
  346. },
  347. easeOutCubic: function(t, b, c, d) {
  348. return c * ((t = t / d - 1) * t * t + 1) + b;
  349. },
  350. easeInOutCubic: function(t, b, c, d) {
  351. if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
  352. return c / 2 * ((t -= 2) * t * t + 2) + b;
  353. },
  354. easeInQuart: function(t, b, c, d) {
  355. return c * (t /= d) * t * t * t + b;
  356. },
  357. easeOutQuart: function(t, b, c, d) {
  358. return -c * ((t = t / d - 1) * t * t * t - 1) + b;
  359. },
  360. easeInOutQuart: function(t, b, c, d) {
  361. if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
  362. return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
  363. },
  364. easeInQuint: function(t, b, c, d) {
  365. return c * (t /= d) * t * t * t * t + b;
  366. },
  367. easeOutQuint: function(t, b, c, d) {
  368. return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
  369. },
  370. easeInOutQuint: function(t, b, c, d) {
  371. if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
  372. return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
  373. },
  374. easeInSine: function(t, b, c, d) {
  375. return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
  376. },
  377. easeOutSine: function(t, b, c, d) {
  378. return c * Math.sin(t / d * (Math.PI / 2)) + b;
  379. },
  380. easeInOutSine: function(t, b, c, d) {
  381. return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
  382. },
  383. easeInExpo: function(t, b, c, d) {
  384. return t === 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
  385. },
  386. easeOutExpo: function(t, b, c, d) {
  387. return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
  388. },
  389. easeInOutExpo: function(t, b, c, d) {
  390. if (t === 0) return b;
  391. if (t == d) return b + c;
  392. if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
  393. return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
  394. },
  395. easeInCirc: function(t, b, c, d) {
  396. return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
  397. },
  398. easeOutCirc: function(t, b, c, d) {
  399. return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
  400. },
  401. easeInOutCirc: function(t, b, c, d) {
  402. if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
  403. return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
  404. },
  405. easeInElastic: function(t, b, c, d) {
  406. var s = 1.70158;
  407. var p = 0;
  408. var a = c;
  409. if (t === 0) return b;
  410. if ((t /= d) == 1) return b + c;
  411. if (!p) p = d * .3;
  412. if (a < Math.abs(c)) {
  413. a = c;
  414. s = p / 4;
  415. } else s = p / (2 * Math.PI) * Math.asin(c / a);
  416. return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
  417. },
  418. easeOutElastic: function(t, b, c, d) {
  419. var s = 1.70158;
  420. var p = 0;
  421. var a = c;
  422. if (t === 0) return b;
  423. if ((t /= d) == 1) return b + c;
  424. if (!p) p = d * .3;
  425. if (a < Math.abs(c)) {
  426. a = c;
  427. s = p / 4;
  428. } else s = p / (2 * Math.PI) * Math.asin(c / a);
  429. return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
  430. },
  431. easeInOutElastic: function(t, b, c, d) {
  432. var s = 1.70158;
  433. var p = 0;
  434. var a = c;
  435. if (t === 0) return b;
  436. if ((t /= d / 2) == 2) return b + c;
  437. if (!p) p = d * (.3 * 1.5);
  438. if (a < Math.abs(c)) {
  439. a = c;
  440. var s = p / 4;
  441. } else var s = p / (2 * Math.PI) * Math.asin(c / a);
  442. if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
  443. return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
  444. },
  445. easeInBack: function(t, b, c, d, s) {
  446. if (s == undefined) s = 1.70158;
  447. return c * (t /= d) * t * ((s + 1) * t - s) + b;
  448. },
  449. easeOutBack: function(t, b, c, d, s) {
  450. if (s == undefined) s = 1.70158;
  451. return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
  452. },
  453. easeInOutBack: function(t, b, c, d, s) {
  454. if (s == undefined) s = 1.70158;
  455. if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b;
  456. return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;
  457. },
  458. easeInBounce: function(t, b, c, d) {
  459. return c - easings.easeOutBounce(d - t, 0, c, d) + b;
  460. },
  461. easeOutBounce: function(t, b, c, d) {
  462. if ((t /= d) < 1 / 2.75) {
  463. return c * (7.5625 * t * t) + b;
  464. } else if (t < 2 / 2.75) {
  465. return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b;
  466. } else if (t < 2.5 / 2.75) {
  467. return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b;
  468. } else {
  469. return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b;
  470. }
  471. },
  472. easeInOutBounce: function(t, b, c, d) {
  473. if (t < d / 2) return easings.easeInBounce(t * 2, 0, c, d) * .5 + b;
  474. return easings.easeOutBounce(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
  475. }
  476. };
  477. return easings;
  478. }
  479. };
  480. /*
  481. *
  482. * TERMS OF USE - EASING EQUATIONS
  483. *
  484. * Open source under the BSD License.
  485. *
  486. * Copyright © 2001 Robert Penner
  487. * All rights reserved.
  488. *
  489. * Redistribution and use in source and binary forms, with or without modification,
  490. * are permitted provided that the following conditions are met:
  491. *
  492. * Redistributions of source code must retain the above copyright notice, this list of
  493. * conditions and the following disclaimer.
  494. * Redistributions in binary form must reproduce the above copyright notice, this list
  495. * of conditions and the following disclaimer in the documentation and/or other materials
  496. * provided with the distribution.
  497. *
  498. * Neither the name of the author nor the names of contributors may be used to endorse
  499. * or promote products derived from this software without specific prior written permission.
  500. *
  501. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  502. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  503. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  504. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  505. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  506. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  507. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  508. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  509. * OF THE POSSIBILITY OF SUCH DAMAGE.
  510. *
  511. */
  512. //src/animate/frame.js
  513. /**
  514. * @fileOverview
  515. *
  516. * 提供动画帧的基本支持
  517. */
  518. _p[2] = {
  519. value: function(require, exports) {
  520. // 原生动画帧方法 polyfill
  521. var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(fn) {
  522. return setTimeout(fn, 1e3 / 60);
  523. };
  524. var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame || window.clearTimeout;
  525. // 上一个请求的原生动画帧 id
  526. var frameRequestId;
  527. // 等待执行的帧动作的集合,这些帧的方法将在下个原生动画帧同步执行
  528. var pendingFrames = [];
  529. /**
  530. * 添加一个帧到等待集合中
  531. *
  532. * 如果添加的帧是序列的第一个,至少有一个帧需要被执行,则会请求一个原生动画帧来执行
  533. */
  534. function pushFrame(frame) {
  535. if (pendingFrames.push(frame) === 1) {
  536. frameRequestId = requestAnimationFrame(executePendingFrames);
  537. }
  538. }
  539. /**
  540. * 执行所有等待帧
  541. */
  542. function executePendingFrames() {
  543. var frames = pendingFrames;
  544. pendingFrames = [];
  545. while (frames.length) {
  546. executeFrame(frames.pop());
  547. }
  548. frameRequestId = 0;
  549. }
  550. /**
  551. * @method kity.requestFrame
  552. * @catalog animate
  553. * @grammar kity.requestFrame(action) => {frame}
  554. * @description 请求一个帧,执行指定的动作。动作回调提供一些有用的信息
  555. *
  556. * @param {Function} action
  557. *
  558. * 要执行的动作,该动作回调有一个参数 frame,其中:
  559. *
  560. * frame.time {Number}
  561. * 动作执行时的时间戳(ms)
  562. *
  563. * frame.index {Number}
  564. * 当前执行的帧的编号(首帧为 0)
  565. *
  566. * frame.dur {Number}
  567. * 上一帧至当前帧经过的时间,单位 ms
  568. *
  569. * frame.elapsed {Number}
  570. * 从首帧开始到当前帧经过的时间,单位 ms
  571. *
  572. * frame.action {Number}
  573. * 指向当前的帧处理函数
  574. *
  575. * frame.next()
  576. * 表示下一帧继续执行。如果不调用该方法,将不会执行下一帧。
  577. *
  578. * @example
  579. *
  580. * ```js
  581. * kity.requestFrame(function(frame) {
  582. * console.log('平均帧率:' + frame.elapsed / (frame.index + 1));
  583. *
  584. * // 更新或渲染动作
  585. *
  586. * frame.next(); //继续执行下一帧
  587. * });
  588. * ```
  589. */
  590. function requestFrame(action) {
  591. var frame = initFrame(action);
  592. pushFrame(frame);
  593. return frame;
  594. }
  595. /**
  596. * @method kity.releaseFrame
  597. * @catalog animate
  598. * @grammar kity.releaseFrame(frame)
  599. * @description 释放一个已经请求过的帧,如果该帧在等待集合里,将移除,下个动画帧不会执行释放的帧
  600. *
  601. * @param {frame} frame 使用 kity.requestFrame() 返回的帧
  602. *
  603. * @example
  604. *
  605. * ```js
  606. * var frame = kity.requestFrame(function() {....});
  607. * kity.releaseFrame(frame);
  608. * ```
  609. */
  610. function releaseFrame(frame) {
  611. var index = pendingFrames.indexOf(frame);
  612. if (~index) {
  613. pendingFrames.splice(index, 1);
  614. }
  615. if (pendingFrames.length === 0) {
  616. cancelAnimationFrame(frameRequestId);
  617. }
  618. }
  619. /**
  620. * 初始化一个帧,主要用于后续计算
  621. */
  622. function initFrame(action) {
  623. var frame = {
  624. index: 0,
  625. time: +new Date(),
  626. elapsed: 0,
  627. action: action,
  628. next: function() {
  629. pushFrame(frame);
  630. }
  631. };
  632. return frame;
  633. }
  634. /**
  635. * 执行一个帧动作
  636. */
  637. function executeFrame(frame) {
  638. // 当前帧时间错
  639. var time = +new Date();
  640. // 当上一帧到当前帧经过的时间
  641. var dur = time - frame.time;
  642. //
  643. // http://stackoverflow.com/questions/13133434/requestanimationframe-detect-stop
  644. // 浏览器最小化或切换标签,requestAnimationFrame 不会执行。
  645. // 检测时间超过 200 ms(频率小于 5Hz ) 判定为计时器暂停,重置为一帧长度
  646. //
  647. if (dur > 200) {
  648. dur = 1e3 / 60;
  649. }
  650. frame.dur = dur;
  651. frame.elapsed += dur;
  652. frame.time = time;
  653. frame.action.call(null, frame);
  654. frame.index++;
  655. }
  656. // 暴露
  657. exports.requestFrame = requestFrame;
  658. exports.releaseFrame = releaseFrame;
  659. }
  660. };
  661. //src/animate/motionanimator.js
  662. /**
  663. * @fileOverview
  664. *
  665. * 路径动画器,可以让一个物体沿着某个轨迹运动
  666. */
  667. _p[3] = {
  668. value: function(require) {
  669. var Animator = _p.r(0);
  670. var g = _p.r(34);
  671. var Path = _p.r(46);
  672. var Shape = _p.r(60);
  673. /**
  674. * @class kity.MotionAnimator
  675. * @catalog animate
  676. * @base kity.Animator
  677. * @description 路径动画器,可以让一个物体沿着某个轨迹运动
  678. *
  679. * @example
  680. *
  681. * ```js
  682. * var motionAnimator = new MotionAnimator('M0,0C100,0,100,0,100,100L200,200');
  683. * motionAnimator.start(rect, 3000);
  684. * ```
  685. */
  686. var MotionAnimator = _p.r(11).createClass("MotionAnimator", {
  687. base: Animator,
  688. /**
  689. * @constructor
  690. * @for kity.MotionAnimator
  691. * @grammar new kity.MotionAnimator(path, doRotate)
  692. * @param {kity.Path|String|PathSegment} path 运动的轨迹,或者是 kity.Path 对象
  693. * @param {boolean} doRotate 是否让运动的目标沿着路径的切线方向旋转
  694. */
  695. constructor: function(path, doRotate) {
  696. var me = this;
  697. this.callBase({
  698. beginValue: 0,
  699. finishValue: 1,
  700. setter: function(target, value) {
  701. var path = me.motionPath instanceof Path ? me.motionPath.getPathData() : me.motionPath;
  702. var point = g.pointAtPath(path, value);
  703. target.setTranslate(point.x, point.y);
  704. if (this.doRotate) target.setRotate(point.tan.getAngle());
  705. }
  706. });
  707. /**
  708. * @property doRotate
  709. * @for kity.MotionAnimator
  710. * @type {boolean}
  711. * @description 是否让运动的目标沿着路径的切线方向旋转
  712. *
  713. * @example
  714. *
  715. * ```js
  716. * motionAnimator.doRotate = true; // 目标沿着切线方向旋转
  717. * ```
  718. */
  719. this.doRotate = doRotate;
  720. /**
  721. * @property motionPath
  722. * @for kity.MotionAnimator
  723. * @type {kity.Path|String|PathSegment}
  724. * @description 运动沿着的路径,可以在动画过程中更新
  725. */
  726. this.motionPath = path;
  727. }
  728. });
  729. _p.r(11).extendClass(Shape, {
  730. /**
  731. * @method motion()
  732. * @catalog animate
  733. * @for kity.Shape
  734. * @description 让图形沿着指定的路径运动
  735. *
  736. * @grammar motion(path, duration, easing, delay, callback) => this
  737. *
  738. * @param {kity.Path|String|PathSegment} path 运动的轨迹,或者是 kity.Path 对象
  739. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  740. * @param {Number|String} delay 动画播放前的延时
  741. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  742. * @param {Function} callback 播放结束之后的回调函数
  743. */
  744. motion: function(path, duration, easing, delay, callback) {
  745. return this.animate(new MotionAnimator(path), duration, easing, delay, callback);
  746. }
  747. });
  748. return MotionAnimator;
  749. }
  750. };
  751. //src/animate/opacityanimator.js
  752. /**
  753. * @fileOverview
  754. *
  755. * 透明度动画器,让图形动画过度到指定的透明度。
  756. */
  757. _p[4] = {
  758. value: function(require) {
  759. var Animator = _p.r(0);
  760. /**
  761. * @class kity.OpacityAnimator
  762. * @catalog animate
  763. * @base kity.Animator
  764. * @description 透明度动画器,让图形动画过度到指定的透明度
  765. */
  766. var OpacityAnimator = _p.r(11).createClass("OpacityAnimator", {
  767. base: Animator,
  768. /**
  769. * @constructor
  770. * @for kity.OpacityAnimator
  771. * @grammar new kity.OpacityAnimator(opacity)
  772. *
  773. * @param {Number} opacity 目标透明度,取值范围 0 - 1
  774. */
  775. constructor: function(opacity) {
  776. this.callBase({
  777. beginValue: function(target) {
  778. return target.getOpacity();
  779. },
  780. finishValue: opacity,
  781. setter: function(target, value) {
  782. target.setOpacity(value);
  783. }
  784. });
  785. }
  786. });
  787. var Shape = _p.r(60);
  788. _p.r(11).extendClass(Shape, {
  789. /**
  790. * @method fxOpacity()
  791. * @catalog animate
  792. * @for kity.Shape
  793. * @description 让图形的透明度以动画的形式过渡到指定的值
  794. *
  795. * @grammar fxOpacity(opacity, duration, easing, delay, callback) => {this}
  796. *
  797. * @param {Number} opacity 动画的目标透明度
  798. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  799. * @param {Number|String} delay 动画播放前的延时
  800. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  801. * @param {Function} callback 播放结束之后的回调函数
  802. */
  803. fxOpacity: function(opacity, duration, easing, delay, callback) {
  804. return this.animate(new OpacityAnimator(opacity), duration, easing, delay, callback);
  805. },
  806. /**
  807. * @method fadeTo()
  808. * @catalog animate
  809. * @for kity.Shape
  810. * @description 让图形的透明度以动画的形式过渡到指定的值
  811. *
  812. * @grammar fadeTo(opacity, duration, easing, delay, callback) => {this}
  813. *
  814. * @param {Number} opacity 动画的目标透明度
  815. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  816. * @param {Number|String} delay 动画播放前的延时
  817. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  818. * @param {Function} callback 播放结束之后的回调函数
  819. */
  820. fadeTo: function() {
  821. return this.fxOpacity.apply(this, arguments);
  822. },
  823. /**
  824. * @method fadeIn()
  825. * @catalog animate
  826. * @for kity.Shape
  827. * @description 让图形淡入
  828. *
  829. * @grammar fadeIn(duration, easing, delay, callback) => {this}
  830. *
  831. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  832. * @param {Number|String} delay 动画播放前的延时
  833. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  834. * @param {Function} callback 播放结束之后的回调函数
  835. */
  836. fadeIn: function() {
  837. return this.fxOpacity.apply(this, [ 1 ].concat([].slice.call(arguments)));
  838. },
  839. /**
  840. * @method fadeOut()
  841. * @catalog animate
  842. * @for kity.Shape
  843. * @description 让图形淡出
  844. *
  845. * @grammar fadeIn(duration, easing, delay, callback) => {this}
  846. *
  847. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  848. * @param {Number|String} delay 动画播放前的延时
  849. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  850. * @param {Function} callback 播放结束之后的回调函数
  851. */
  852. fadeOut: function() {
  853. return this.fxOpacity.apply(this, [ 0 ].concat([].slice.call(arguments)));
  854. }
  855. });
  856. return OpacityAnimator;
  857. }
  858. };
  859. //src/animate/pathanimator.js
  860. /**
  861. * @fileOverview
  862. *
  863. * 路径补间动画器,让图形从一个形状变为另一个形状
  864. */
  865. _p[5] = {
  866. value: function(require) {
  867. var Animator = _p.r(0);
  868. var g = _p.r(34);
  869. /**
  870. * @catalog animate
  871. *
  872. * @class kity.PathAnimator
  873. * @base kity.Animator
  874. * @description 路径补间动画器,让图形从一个形状变为另一个形状
  875. *
  876. * @example
  877. *
  878. * ```js
  879. * var path = new kity.Path('M0,0L0,100');
  880. * var pa = new kity.PathAnimator('M0,0C100,0,100,0,100,100');
  881. * pa.start(path, 300);
  882. * ```
  883. */
  884. var PathAnimator = _p.r(11).createClass("OpacityAnimator", {
  885. base: Animator,
  886. /**
  887. * @constructor
  888. * @for kity.PathAnimator
  889. *
  890. * @grammar new kity.Path.Animator(path)
  891. *
  892. * @param {String|PathSegment} path 目标形状的路径数据
  893. *
  894. */
  895. constructor: function(path) {
  896. this.callBase({
  897. beginValue: function(target) {
  898. this.beginPath = target.getPathData();
  899. return 0;
  900. },
  901. finishValue: 1,
  902. setter: function(target, value) {
  903. target.setPathData(g.pathTween(this.beginPath, path, value));
  904. }
  905. });
  906. }
  907. });
  908. var Path = _p.r(46);
  909. _p.r(11).extendClass(Path, {
  910. /**
  911. * @catalog animate
  912. *
  913. * @method fxPath()
  914. * @for kity.Shape
  915. * @description 以动画的形式把路径变换为新路径
  916. *
  917. * @grammar fxPath(path, duration, easing, delay, callback) => {this}
  918. *
  919. * @param {String|PathSegment} path 要变换新路径
  920. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  921. * @param {Number|String} delay 动画播放前的延时
  922. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  923. * @param {Function} callback 播放结束之后的回调函数
  924. */
  925. fxPath: function(path, duration, easing, delay, callback) {
  926. return this.animate(new PathAnimator(path), duration, easing, delay, callback);
  927. }
  928. });
  929. return PathAnimator;
  930. }
  931. };
  932. //src/animate/rotateanimator.js
  933. /**
  934. * @fileOverview
  935. *
  936. * 提供支持目标旋转的动画器
  937. */
  938. _p[6] = {
  939. value: function(require) {
  940. var Animator = _p.r(0);
  941. /**
  942. * @class kity.RotateAnimator
  943. * @base Animator
  944. * @description 提供支持目标旋转的动画器
  945. */
  946. var RotateAnimator = _p.r(11).createClass("RotateAnimator", {
  947. base: Animator,
  948. /**
  949. * @constructor
  950. * @for kity.RotateAnimator
  951. *
  952. * @grammar new kity.RotateAnimator(deg, ax, ay)
  953. *
  954. * @param {Number} deg 要旋转的角度
  955. */
  956. constructor: function(deg) {
  957. this.callBase({
  958. beginValue: 0,
  959. finishValue: deg,
  960. setter: function(target, value, timeline) {
  961. var delta = timeline.getDelta();
  962. target.rotate(delta, ax, ay);
  963. }
  964. });
  965. }
  966. });
  967. var Shape = _p.r(60);
  968. _p.r(11).extendClass(Shape, {
  969. /**
  970. * @method fxRotate()
  971. * @for kity.Shape
  972. * @description 让目标以动画旋转指定的角度
  973. *
  974. * @grammar fxRotate(deg, duration, easing, delay) => {this}
  975. *
  976. * @param {Number} deg 要旋转的角度
  977. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  978. * @param {Number|String} delay 动画播放前的延时
  979. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  980. * @param {Function} callback 播放结束之后的回调函数
  981. */
  982. fxRotate: function(deg, duration, easing, delay, callback) {
  983. return this.animate(new RotateAnimator(deg), duration, easing, delay, callback);
  984. }
  985. });
  986. return RotateAnimator;
  987. }
  988. };
  989. //src/animate/scaleanimator.js
  990. /**
  991. * @fileOverview
  992. *
  993. * 提供支持目标缩放的动画器
  994. */
  995. _p[7] = {
  996. value: function(require) {
  997. var Animator = _p.r(0);
  998. /**
  999. * @class kity.ScaleAnimator
  1000. * @base kity.Animator
  1001. * @description 提供支持目标缩放的动画器
  1002. */
  1003. var ScaleAnimator = _p.r(11).createClass("ScaleAnimator", {
  1004. base: Animator,
  1005. /**
  1006. * @constructor
  1007. * @for kity.ScaleAnimator
  1008. *
  1009. * @grammar new kity.ScaleAnimator(sx, sy)
  1010. * @param {Number} sx x 轴的缩放比例
  1011. * @param {Number} sy y 轴的缩放比例
  1012. */
  1013. constructor: function(sx, sy) {
  1014. this.callBase({
  1015. beginValue: 0,
  1016. finishValue: 1,
  1017. setter: function(target, value, timeline) {
  1018. var delta = timeline.getDelta();
  1019. var kx = Math.pow(sx, delta);
  1020. var ky = Math.pow(sy, delta);
  1021. target.scale(ky, kx);
  1022. }
  1023. });
  1024. }
  1025. });
  1026. var Shape = _p.r(60);
  1027. _p.r(11).extendClass(Shape, {
  1028. /**
  1029. * @method fxScale
  1030. * @for kity.Shape
  1031. * @description 动画缩放当前的图形
  1032. *
  1033. * @grammar fxScale(sx, sy, duration, easing, delay, callback) => {this}
  1034. *
  1035. * @param {Number} sx x 轴的缩放比例
  1036. * @param {Number} sy y 轴的缩放比例
  1037. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  1038. * @param {Number|String} delay 动画播放前的延时
  1039. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  1040. * @param {Function} callback 播放结束之后的回调函数
  1041. */
  1042. fxScale: function(sx, sy, duration, easing, delay, callback) {
  1043. return this.animate(new ScaleAnimator(sx, sy), duration, easing, delay, callback);
  1044. }
  1045. });
  1046. return ScaleAnimator;
  1047. }
  1048. };
  1049. //src/animate/timeline.js
  1050. /**
  1051. * @fileOverview
  1052. *
  1053. * 动画时间线的实现
  1054. */
  1055. _p[8] = {
  1056. value: function(require) {
  1057. var EventHandler = _p.r(33);
  1058. var utils = _p.r(12);
  1059. var frame = _p.r(2);
  1060. function getPercentValue(b, f, p) {
  1061. return utils.paralle(b, f, function(b, f) {
  1062. return b + (f - b) * p;
  1063. });
  1064. }
  1065. function getDelta(v1, v2) {
  1066. return utils.paralle(v1, v2, function(v1, v2) {
  1067. return v2 - v1;
  1068. });
  1069. }
  1070. function TimelineEvent(timeline, type, param) {
  1071. this.timeline = timeline;
  1072. this.target = timeline.target;
  1073. this.type = type;
  1074. for (var name in param) {
  1075. if (param.hasOwnProperty(name)) {
  1076. this[name] = param[name];
  1077. }
  1078. }
  1079. }
  1080. /**
  1081. * @class kity.Timeline
  1082. * @catalog animate
  1083. * @mixins EventHandler
  1084. * @description 动画时间线
  1085. */
  1086. var Timeline = _p.r(11).createClass("Timeline", {
  1087. mixins: [ EventHandler ],
  1088. /**
  1089. * @constructor
  1090. * @for kity.Timeline
  1091. * @private
  1092. * @description 时间线应该由动画器进行构造,不应手动创建
  1093. *
  1094. */
  1095. constructor: function(animator, target, duration, easing) {
  1096. this.callMixin();
  1097. this.target = target;
  1098. this.time = 0;
  1099. this.duration = duration;
  1100. this.easing = easing;
  1101. this.animator = animator;
  1102. this.beginValue = animator.beginValue;
  1103. this.finishValue = animator.finishValue;
  1104. this.setter = animator.setter;
  1105. this.status = "ready";
  1106. },
  1107. /**
  1108. * @private
  1109. *
  1110. * 让时间线进入下一帧
  1111. */
  1112. nextFrame: function(frame) {
  1113. if (this.status != "playing") {
  1114. return;
  1115. }
  1116. this.time += frame.dur;
  1117. this.setValue(this.getValue());
  1118. if (this.time >= this.duration) {
  1119. this.timeUp();
  1120. }
  1121. frame.next();
  1122. },
  1123. /**
  1124. * @method getPlayTime()
  1125. * @for kity.Timeline
  1126. * @grammar getPlayTime() => {Number}
  1127. * @description 获得当前播放的时间,取值区间为 [0, duration]
  1128. */
  1129. getPlayTime: function() {
  1130. return this.rollbacking ? this.duration - this.time : this.time;
  1131. },
  1132. /**
  1133. * @method getTimeProportion()
  1134. * @for kity.Timeline
  1135. * @grammar getTimeProportion() => {Number}
  1136. * @description 获得当前播放时间的比例,取值区间为 [0, 1]
  1137. */
  1138. getTimeProportion: function() {
  1139. return this.getPlayTime() / this.duration;
  1140. },
  1141. /**
  1142. * @method getValueProportion()
  1143. * @for kity.Timeline
  1144. * @grammar getValueProportion() => {Number}
  1145. * @description 获得当前播放时间对应值的比例,取值区间为 [0, 1];该值实际上是时间比例值经过缓动函数计算之后的值。
  1146. */
  1147. getValueProportion: function() {
  1148. return this.easing(this.getPlayTime(), 0, 1, this.duration);
  1149. },
  1150. /**
  1151. * @method getValue()
  1152. * @for kity.Timeline
  1153. * @grammar getValue() => {any}
  1154. * @description 返回当前播放时间对应的值。
  1155. */
  1156. getValue: function() {
  1157. var b = this.beginValue;
  1158. var f = this.finishValue;
  1159. var p = this.getValueProportion();
  1160. return getPercentValue(b, f, p);
  1161. },
  1162. /**
  1163. * @private
  1164. *
  1165. * 把值通过动画器的 setter 设置到目标上
  1166. */
  1167. setValue: function(value) {
  1168. this.lastValue = this.currentValue;
  1169. this.currentValue = value;
  1170. this.setter.call(this.target, this.target, value, this);
  1171. },
  1172. /**
  1173. * @method getDelta()
  1174. * @for kity.Timeline
  1175. * @grammar getDelta() => {any}
  1176. * @description 返回当前值和上一帧的值的差值
  1177. */
  1178. getDelta: function() {
  1179. this.lastValue = this.lastValue === undefined ? this.beginValue : this.lastValue;
  1180. return getDelta(this.lastValue, this.currentValue);
  1181. },
  1182. /**
  1183. * @method play()
  1184. * @for kity.Timeline
  1185. * @grammar play() => {this}
  1186. * @description 让时间线播放,如果时间线还没开始,或者已停止、已结束,则重头播放;如果是已暂停,从暂停的位置继续播放
  1187. */
  1188. play: function() {
  1189. var lastStatus = this.status;
  1190. this.status = "playing";
  1191. switch (lastStatus) {
  1192. case "ready":
  1193. if (utils.isFunction(this.beginValue)) {
  1194. this.beginValue = this.beginValue.call(this.target, this.target);
  1195. }
  1196. if (utils.isFunction(this.finishValue)) {
  1197. this.finishValue = this.finishValue.call(this.target, this.target);
  1198. }
  1199. this.time = 0;
  1200. this.setValue(this.beginValue);
  1201. this.frame = frame.requestFrame(this.nextFrame.bind(this));
  1202. break;
  1203. case "finished":
  1204. case "stoped":
  1205. this.time = 0;
  1206. this.frame = frame.requestFrame(this.nextFrame.bind(this));
  1207. break;
  1208. case "paused":
  1209. this.frame.next();
  1210. }
  1211. /**
  1212. * @event play
  1213. * @for kity.Timeline
  1214. * @description 在时间线播放后触发
  1215. *
  1216. * @param {String} event.lastStatus
  1217. * 表示播放前的上一个状态,可能取值为 'ready'、'finished'、'stoped'、'paused'
  1218. */
  1219. this.fire("play", new TimelineEvent(this, "play", {
  1220. lastStatus: lastStatus
  1221. }));
  1222. return this;
  1223. },
  1224. /**
  1225. * @method pause()
  1226. * @for kity.Timeline
  1227. * @description 暂停当前的时间线
  1228. *
  1229. * @grammar pause() => {this}
  1230. */
  1231. pause: function() {
  1232. this.status = "paused";
  1233. /**
  1234. * @event pause
  1235. * @for kity.Timeline
  1236. * @description 暂停事件,在时间线暂停时触发
  1237. */
  1238. this.fire("pause", new TimelineEvent(this, "pause"));
  1239. frame.releaseFrame(this.frame);
  1240. return this;
  1241. },
  1242. /**
  1243. * @method stop()
  1244. * @for kity.Timeline
  1245. * @description 停止当前时间线
  1246. *
  1247. * @grammar stop() => {this}
  1248. */
  1249. stop: function() {
  1250. this.status = "stoped";
  1251. this.setValue(this.finishValue);
  1252. this.rollbacking = false;
  1253. /**
  1254. * @event stop
  1255. * @for kity.Timeline
  1256. * @description 停止时间,在时间线停止时触发
  1257. */
  1258. this.fire("stop", new TimelineEvent(this, "stop"));
  1259. frame.releaseFrame(this.frame);
  1260. return this;
  1261. },
  1262. /**
  1263. * @private
  1264. *
  1265. * 播放结束之后的处理
  1266. */
  1267. timeUp: function() {
  1268. if (this.repeatOption) {
  1269. this.time = 0;
  1270. if (this.rollback) {
  1271. if (this.rollbacking) {
  1272. this.decreaseRepeat();
  1273. this.rollbacking = false;
  1274. } else {
  1275. this.rollbacking = true;
  1276. /**
  1277. * @event rollback
  1278. * @for kity.Timeline
  1279. * @description 回滚事件,在时间线回滚播放开始的时候触发
  1280. */
  1281. this.fire("rollback", new TimelineEvent(this, "rollback"));
  1282. }
  1283. } else {
  1284. this.decreaseRepeat();
  1285. }
  1286. if (!this.repeatOption) {
  1287. this.finish();
  1288. } else {
  1289. /**
  1290. * @event repeat
  1291. * @for kity.Timeline
  1292. * @description 循环事件,在时间线循环播放开始的时候触发
  1293. */
  1294. this.fire("repeat", new TimelineEvent(this, "repeat"));
  1295. }
  1296. } else {
  1297. this.finish();
  1298. }
  1299. },
  1300. /**
  1301. * @private
  1302. *
  1303. * 决定播放结束的处理
  1304. */
  1305. finish: function() {
  1306. this.setValue(this.finishValue);
  1307. this.status = "finished";
  1308. /**
  1309. * @event finish
  1310. * @for kity.Timeline
  1311. * @description 结束事件,在时间线播放结束后触发(包括重复和回滚都结束)
  1312. */
  1313. this.fire("finish", new TimelineEvent(this, "finish"));
  1314. frame.releaseFrame(this.frame);
  1315. },
  1316. /**
  1317. * @private
  1318. *
  1319. * 循环次数递减
  1320. */
  1321. decreaseRepeat: function() {
  1322. if (this.repeatOption !== true) {
  1323. this.repeatOption--;
  1324. }
  1325. },
  1326. /**
  1327. * @method repeat()
  1328. * @for kity.Timeline
  1329. * @description 设置时间线的重复选项
  1330. *
  1331. * @grammar repeat(repeat, rollback) => {this}
  1332. *
  1333. * @param {Number|Boolean} repeat
  1334. * 是否重复播放,设置为 true 无限循环播放,设置数值则循环指定的次数
  1335. * @param {Boolean} rollback
  1336. * 指示是否要回滚播放。
  1337. * 如果设置为真,一次事件到 duration 则一个来回算一次循环次数,否则播放完成一次算一次循环次数
  1338. *
  1339. */
  1340. repeat: function(repeat, rollback) {
  1341. this.repeatOption = repeat;
  1342. this.rollback = rollback;
  1343. return this;
  1344. }
  1345. });
  1346. Timeline.requestFrame = frame.requestFrame;
  1347. Timeline.releaseFrame = frame.releaseFrame;
  1348. return Timeline;
  1349. }
  1350. };
  1351. //src/animate/translateanimator.js
  1352. /**
  1353. * @fileOverview
  1354. *
  1355. * 提供让图形移动的动画器
  1356. */
  1357. _p[9] = {
  1358. value: function(require) {
  1359. var Animator = _p.r(0);
  1360. /**
  1361. * @class kity.TranslateAnimator
  1362. * @base kity.Animator
  1363. * @description 提供让图形移动的动画器
  1364. */
  1365. var TranslateAnimator = _p.r(11).createClass("TranslateAnimator", {
  1366. base: Animator,
  1367. /**
  1368. * @constructor
  1369. * @for kity.TranslateAnimator
  1370. * @grammar new kity.TranslateAnimator(x, y)
  1371. * @param {Number} x x 方向上需要移动的距离
  1372. * @param {Number} y y 方向上需要移动的距离
  1373. */
  1374. constructor: function(x, y) {
  1375. this.callBase({
  1376. x: 0,
  1377. y: 0
  1378. }, {
  1379. x: x,
  1380. y: y
  1381. }, function(target, value, timeline) {
  1382. var delta = timeline.getDelta();
  1383. target.translate(delta.x, delta.y);
  1384. });
  1385. }
  1386. });
  1387. var Shape = _p.r(60);
  1388. _p.r(11).extendClass(Shape, {
  1389. /**
  1390. * @method fxTranslate()
  1391. * @for kity.Shape
  1392. * @description 让目标以动画平移指定的距离
  1393. *
  1394. * @grammar fxTranslate(x, y, duration, easing, delay, callback) => {this}
  1395. *
  1396. * @param {Number} x x 方向上需要移动的距离
  1397. * @param {Number} y y 方向上需要移动的距离
  1398. * @param {Number|String} duration 动画的播放长度,如 300、"5s"、"0.5min"
  1399. * @param {Number|String} delay 动画播放前的延时
  1400. * @param {String|Function} easing 动画播放使用的缓动函数,如 'ease'、'linear'、'swing'
  1401. * @param {Function} callback 播放结束之后的回调函数
  1402. */
  1403. fxTranslate: function(x, y, duration, easing, delay, callback) {
  1404. return this.animate(new TranslateAnimator(x, y), duration, easing, delay, callback);
  1405. }
  1406. });
  1407. return TranslateAnimator;
  1408. }
  1409. };
  1410. //src/core/browser.js
  1411. /**
  1412. * @fileOverview
  1413. *
  1414. * 提供浏览器判断的一些字段
  1415. */
  1416. _p[10] = {
  1417. value: function() {
  1418. /**
  1419. * @class kity.Browser
  1420. * @catalog core
  1421. * @static
  1422. * @description 提供浏览器信息
  1423. */
  1424. var browser = function() {
  1425. var agent = navigator.userAgent.toLowerCase(), opera = window.opera, browser;
  1426. // 浏览器对象
  1427. browser = {
  1428. /**
  1429. * @property platform
  1430. * @description 获取浏览器所在系统,"Win"->Windows;"Mac"->Mac;"Lux"->Linux
  1431. * @type {String}
  1432. */
  1433. platform: function(navigator) {
  1434. var _p = {
  1435. win32: "Win",
  1436. macintel: "Mac"
  1437. };
  1438. return _p[navigator.platform.toLowerCase()] || "Lux";
  1439. }(navigator),
  1440. /**
  1441. * 猎豹,区分两种不同内核
  1442. */
  1443. lb: function(agent) {
  1444. if (~agent.indexOf("lbbrowser")) {
  1445. return ~agent.indexOf("msie") ? "ie" : "chrome";
  1446. }
  1447. return false;
  1448. }(agent),
  1449. /**
  1450. * 搜狗
  1451. */
  1452. sg: /se[\s\S]+metasr/.test(agent),
  1453. /**
  1454. * 百度
  1455. */
  1456. bd: !!~agent.indexOf("bidubrowser"),
  1457. /**
  1458. * edge浏览器
  1459. */
  1460. edge: !!~agent.indexOf("edge"),
  1461. /**
  1462. * chrome初始化为false
  1463. * @type {Boolean}
  1464. */
  1465. chrome: false,
  1466. /**
  1467. * @property opera
  1468. * @for kity.Browser
  1469. * @description 判断是否为 Opera 浏览器
  1470. * @type {boolean}
  1471. */
  1472. opera: !!opera && opera.version,
  1473. /**
  1474. * @property webkit
  1475. * @for kity.Browser
  1476. * @description 判断是否为 Webkit 内核的浏览器
  1477. * @type {boolean}
  1478. */
  1479. webkit: agent.indexOf(" applewebkit/") > -1,
  1480. /**
  1481. * @property mac
  1482. * @for kity.Browser
  1483. * @description 判断是否为 Mac 下的浏览器
  1484. * @type {boolean}
  1485. */
  1486. mac: agent.indexOf("macintosh") > -1
  1487. };
  1488. /**
  1489. * @property ie
  1490. * @for kity.Browser
  1491. * @description 判断是否为 IE 浏览器
  1492. * @type {boolean}
  1493. */
  1494. browser.ie = !browser.lb && /(msie\s|trident.*rv:)([\w.]+)/.test(agent);
  1495. browser.gecko = navigator.product == "Gecko" && !browser.webkit && !browser.opera && !browser.ie;
  1496. var version = 0;
  1497. // Internet Explorer 6.0+
  1498. if (browser.ie) {
  1499. version = (agent.match(/(msie\s|trident.*rv:)([\w.]+)/)[2] || 0) * 1;
  1500. browser.ie11Compat = document.documentMode == 11;
  1501. browser.ie9Compat = document.documentMode == 9;
  1502. }
  1503. // Gecko.
  1504. if (browser.gecko) {
  1505. var geckoRelease = agent.match(/rv:([\d\.]+)/);
  1506. if (geckoRelease) {
  1507. geckoRelease = geckoRelease[1].split(".");
  1508. version = geckoRelease[0] * 1e4 + (geckoRelease[1] || 0) * 100 + (geckoRelease[2] || 0) * 1;
  1509. }
  1510. }
  1511. // 排除其他chrome内核的浏览器的干扰
  1512. if (/chrome\/(\d+\.\d)/i.test(agent) && !browser.bd && !browser.opera && !browser.lb && !browser.sg && !browser.edge) {
  1513. /**
  1514. * @property chrome
  1515. * @for kity.Browser
  1516. * @description 判断是否为 Chrome 浏览器
  1517. * @type {boolean}
  1518. */
  1519. browser.chrome = +RegExp["$1"];
  1520. }
  1521. if (/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)) {
  1522. browser.safari = +(RegExp["$1"] || RegExp["$2"]);
  1523. }
  1524. // Opera 9.50+
  1525. if (browser.opera) version = parseFloat(opera.version());
  1526. // WebKit 522+ (Safari 3+)
  1527. if (browser.webkit) version = parseFloat(agent.match(/ applewebkit\/(\d+)/)[1]);
  1528. // 搜狗版本号无从得知
  1529. // 猎豹版本号无从得知
  1530. // 百度
  1531. if (browser.bd) version = parseFloat(agent.match(/bidubrowser\/(\d+)/)[1]);
  1532. // Opera 9.50+
  1533. if (browser.opera) version = parseFloat(agent.match(/opr\/(\d+)/)[1]);
  1534. // edge
  1535. if (browser.edge) version = parseFloat(agent.match(/edge\/(\d+)/)[1]);
  1536. /**
  1537. * @property version
  1538. * @for kity.Browser
  1539. * @description 获取当前浏览器的版本
  1540. * @type {Number}
  1541. */
  1542. browser.version = version;
  1543. browser.isCompatible = !browser.mobile && (browser.ie && version >= 6 || browser.gecko && version >= 10801 || browser.opera && version >= 9.5 || browser.air && version >= 1 || browser.webkit && version >= 522 || false);
  1544. return browser;
  1545. }();
  1546. return browser;
  1547. }
  1548. };
  1549. //src/core/class.js
  1550. /**
  1551. * @fileOverview
  1552. *
  1553. * 提供 Kity 的 OOP 支持
  1554. */
  1555. _p[11] = {
  1556. value: function(require, exports) {
  1557. /**
  1558. * @class kity.Class
  1559. * @catalog core
  1560. * @description 所有 kity 类的基类
  1561. * @abstract
  1562. */
  1563. function Class() {}
  1564. exports.Class = Class;
  1565. Class.__KityClassName = "Class";
  1566. /**
  1567. * @method base()
  1568. * @for kity.Class
  1569. * @protected
  1570. * @grammar base(name, args...) => {any}
  1571. * @description 调用父类指定名称的函数
  1572. * @param {string} name 函数的名称
  1573. * @param {parameter} args... 传递给父类函数的参数
  1574. *
  1575. * @example
  1576. *
  1577. * ```js
  1578. * var Person = kity.createClass('Person', {
  1579. * toString: function() {
  1580. * return 'I am a person';
  1581. * }
  1582. * });
  1583. *
  1584. * var Male = kity.createClass('Male', {
  1585. * base: Person,
  1586. *
  1587. * toString: function() {
  1588. * return 'I am a man';
  1589. * },
  1590. *
  1591. * speak: function() {
  1592. * return this.base('toString') + ',' + this.toString();
  1593. * }
  1594. * })
  1595. * ```
  1596. */
  1597. Class.prototype.base = function(name) {
  1598. var caller = arguments.callee.caller;
  1599. var method = caller.__KityMethodClass.__KityBaseClass.prototype[name];
  1600. return method.apply(this, Array.prototype.slice.call(arguments, 1));
  1601. };
  1602. /**
  1603. * @method callBase()
  1604. * @for kity.Class
  1605. * @protected
  1606. * @grammar callBase(args...) => {any}
  1607. * @description 调用父类同名函数
  1608. * @param {parameter} args... 传递到父类同名函数的参数
  1609. *
  1610. * @example
  1611. *
  1612. * ```js
  1613. * var Animal = kity.createClass('Animal', {
  1614. * constructor: function(name) {
  1615. * this.name = name;
  1616. * },
  1617. * toString: function() {
  1618. * return 'I am an animal name ' + this.name;
  1619. * }
  1620. * });
  1621. *
  1622. * var Dog = kity.createClass('Dog', {
  1623. * constructor: function(name) {
  1624. * this.callBase(name);
  1625. * },
  1626. * toString: function() {
  1627. * return this.callBase() + ', a dog';
  1628. * }
  1629. * });
  1630. *
  1631. * var dog = new Dog('Dummy');
  1632. * console.log(dog.toString()); // "I am an animal name Dummy, a dog";
  1633. * ```
  1634. */
  1635. Class.prototype.callBase = function() {
  1636. var caller = arguments.callee.caller;
  1637. var method = caller.__KityMethodClass.__KityBaseClass.prototype[caller.__KityMethodName];
  1638. return method.apply(this, arguments);
  1639. };
  1640. Class.prototype.mixin = function(name) {
  1641. var caller = arguments.callee.caller;
  1642. var mixins = caller.__KityMethodClass.__KityMixins;
  1643. if (!mixins) {
  1644. return this;
  1645. }
  1646. var method = mixins[name];
  1647. return method.apply(this, Array.prototype.slice.call(arguments, 1));
  1648. };
  1649. Class.prototype.callMixin = function() {
  1650. var caller = arguments.callee.caller;
  1651. var methodName = caller.__KityMethodName;
  1652. var mixins = caller.__KityMethodClass.__KityMixins;
  1653. if (!mixins) {
  1654. return this;
  1655. }
  1656. var method = mixins[methodName];
  1657. if (methodName == "constructor") {
  1658. for (var i = 0, l = method.length; i < l; i++) {
  1659. method[i].call(this);
  1660. }
  1661. return this;
  1662. } else {
  1663. return method.apply(this, arguments);
  1664. }
  1665. };
  1666. /**
  1667. * @method pipe()
  1668. * @for kity.Class
  1669. * @grammar pipe() => {this}
  1670. * @description 以当前对象为上线文以及管道函数的第一个参数,执行一个管道函数
  1671. * @param {Function} fn 进行管道操作的函数
  1672. *
  1673. * @example
  1674. *
  1675. * ```js
  1676. * var rect = new kity.Rect().pipe(function() {
  1677. * this.setWidth(500);
  1678. * this.setHeight(300);
  1679. * });
  1680. * ```
  1681. */
  1682. Class.prototype.pipe = function(fn) {
  1683. if (typeof fn == "function") {
  1684. fn.call(this, this);
  1685. }
  1686. return this;
  1687. };
  1688. /**
  1689. * @method getType()
  1690. * @for kity.Class
  1691. * @grammar getType() => {string}
  1692. * @description 获得对象的类型
  1693. *
  1694. * @example
  1695. *
  1696. * ```js
  1697. * var rect = new kity.Rect();
  1698. * var circle = new kity.Circle();
  1699. *
  1700. * console.log(rect.getType()); // "Rect"
  1701. * console.log(rect.getType()); // "Circle"
  1702. * ```
  1703. */
  1704. Class.prototype.getType = function() {
  1705. return this.__KityClassName;
  1706. };
  1707. /**
  1708. * @method getClass()
  1709. * @for kity.Class
  1710. * @grammar getClass() => {Class}
  1711. * @description 获得对象的类
  1712. *
  1713. * @example
  1714. *
  1715. * ```js
  1716. * var rect = new kity.Rect();
  1717. *
  1718. * console.log(rect.getClass() === kity.Rect); // true
  1719. * console.log(rect instanceof kity.Rect); // true
  1720. * ```
  1721. */
  1722. Class.prototype.getClass = function() {
  1723. return this.constructor;
  1724. };
  1725. // 检查基类是否调用了父类的构造函数
  1726. // 该检查是弱检查,假如调用的代码被注释了,同样能检查成功(这个特性可用于知道建议调用,但是出于某些原因不想调用的情况)
  1727. function checkBaseConstructorCall(targetClass, classname) {
  1728. var code = targetClass.toString();
  1729. if (!/this\.callBase/.test(code)) {
  1730. throw new Error(classname + " : 类构造函数没有调用父类的构造函数!为了安全,请调用父类的构造函数");
  1731. }
  1732. }
  1733. var KITY_INHERIT_FLAG = "__KITY_INHERIT_FLAG_" + +new Date();
  1734. function inherit(constructor, BaseClass, classname) {
  1735. var KityClass = eval("(function " + classname + "( __inherit__flag ) {" + "if( __inherit__flag != KITY_INHERIT_FLAG ) {" + "KityClass.__KityConstructor.apply(this, arguments);" + "}" + "this.__KityClassName = KityClass.__KityClassName;" + "})");
  1736. KityClass.__KityConstructor = constructor;
  1737. KityClass.prototype = new BaseClass(KITY_INHERIT_FLAG);
  1738. for (var methodName in BaseClass.prototype) {
  1739. if (BaseClass.prototype.hasOwnProperty(methodName) && methodName.indexOf("__Kity") !== 0) {
  1740. KityClass.prototype[methodName] = BaseClass.prototype[methodName];
  1741. }
  1742. }
  1743. KityClass.prototype.constructor = KityClass;
  1744. return KityClass;
  1745. }
  1746. function mixin(NewClass, mixins) {
  1747. if (false === mixins instanceof Array) {
  1748. return NewClass;
  1749. }
  1750. var i, length = mixins.length, proto, method;
  1751. NewClass.__KityMixins = {
  1752. constructor: []
  1753. };
  1754. for (i = 0; i < length; i++) {
  1755. proto = mixins[i].prototype;
  1756. for (method in proto) {
  1757. if (false === proto.hasOwnProperty(method) || method.indexOf("__Kity") === 0) {
  1758. continue;
  1759. }
  1760. if (method === "constructor") {
  1761. // constructor 特殊处理
  1762. NewClass.__KityMixins.constructor.push(proto[method]);
  1763. } else {
  1764. NewClass.prototype[method] = NewClass.__KityMixins[method] = proto[method];
  1765. }
  1766. }
  1767. }
  1768. return NewClass;
  1769. }
  1770. function extend(BaseClass, extension) {
  1771. if (extension.__KityClassName) {
  1772. extension = extension.prototype;
  1773. }
  1774. for (var methodName in extension) {
  1775. if (extension.hasOwnProperty(methodName) && methodName.indexOf("__Kity") && methodName != "constructor") {
  1776. var method = BaseClass.prototype[methodName] = extension[methodName];
  1777. method.__KityMethodClass = BaseClass;
  1778. method.__KityMethodName = methodName;
  1779. }
  1780. }
  1781. return BaseClass;
  1782. }
  1783. /**
  1784. * @method kity.createClass()
  1785. * @grammar kity.createClass(classname, defines) => {Class}
  1786. * @description 创建一个类
  1787. * @param {string} classname 类名,用于调试的时候查看,可选
  1788. * @param {object} defines 类定义
  1789. * defines.base {Class}
  1790. * 定义的类的基类,如果不配置,则表示基类为 kity.Class
  1791. * defines.mixins {Class[]}
  1792. * 定义的类要融合的类列表
  1793. * defines.constructor {Function}
  1794. * 定义类的构造函数,如果父类显式定义了构造函数,需要在构造函数中使用 callBase() 方法调用父类的构造函数
  1795. * defines.* {Function}
  1796. * 定义类的其它函数
  1797. *
  1798. * @example 创建一个类
  1799. *
  1800. * ```js
  1801. * var Animal = kity.createClass('Animal', {
  1802. * constructor: function(name) {
  1803. * this.name = name;
  1804. * },
  1805. * toString: function() {
  1806. * return this.name;
  1807. * }
  1808. * });
  1809. *
  1810. * var a = new Animal('kity');
  1811. * console.log(a.toString()); // "kity"
  1812. * ```
  1813. *
  1814. * @example 继承一个类
  1815. *
  1816. * ```js
  1817. * var Cat = kity.createClass('Cat', {
  1818. * base: Animal,
  1819. * constructor: function(name, color) {
  1820. * // 调用父类构造函数
  1821. * this.callBase(name);
  1822. * },
  1823. * toString: function() {
  1824. * return 'A ' + this.color + ' cat, ' + this.callBase();
  1825. * }
  1826. * });
  1827. *
  1828. * var cat = new Cat('kity', 'black');
  1829. * console.log(cat.toString()); // "A black cat, kity"
  1830. * ```
  1831. *
  1832. * @example 混合类的能力
  1833. * ```js
  1834. * var Walkable = kity.createClass('Walkable', {
  1835. * constructor: function() {
  1836. * this.speed = 'fast';
  1837. * },
  1838. * walk: function() {
  1839. * console.log('I am walking ' + this.speed);
  1840. * }
  1841. * });
  1842. *
  1843. * var Dog = kity.createClass('Dog', {
  1844. * base: Animal,
  1845. * mixins: [Walkable],
  1846. * constructor: function(name) {
  1847. * this.callBase(name);
  1848. * this.callMixins();
  1849. * }
  1850. * });
  1851. *
  1852. * var dog = new Dog('doggy');
  1853. * console.log(dog.toString() + ' say:');
  1854. * dog.walk();
  1855. * ```
  1856. */
  1857. exports.createClass = function(classname, defines) {
  1858. var constructor, NewClass, BaseClass;
  1859. if (arguments.length === 1) {
  1860. defines = arguments[0];
  1861. classname = "AnonymousClass";
  1862. }
  1863. BaseClass = defines.base || Class;
  1864. if (defines.hasOwnProperty("constructor")) {
  1865. constructor = defines.constructor;
  1866. if (BaseClass != Class) {
  1867. checkBaseConstructorCall(constructor, classname);
  1868. }
  1869. } else {
  1870. constructor = function() {
  1871. this.callBase.apply(this, arguments);
  1872. this.callMixin.apply(this, arguments);
  1873. };
  1874. }
  1875. NewClass = inherit(constructor, BaseClass, classname);
  1876. NewClass = mixin(NewClass, defines.mixins);
  1877. NewClass.__KityClassName = constructor.__KityClassName = classname;
  1878. NewClass.__KityBaseClass = constructor.__KityBaseClass = BaseClass;
  1879. NewClass.__KityMethodName = constructor.__KityMethodName = "constructor";
  1880. NewClass.__KityMethodClass = constructor.__KityMethodClass = NewClass;
  1881. // 下面这些不需要拷贝到原型链上
  1882. delete defines.mixins;
  1883. delete defines.constructor;
  1884. delete defines.base;
  1885. NewClass = extend(NewClass, defines);
  1886. return NewClass;
  1887. };
  1888. /**
  1889. * @method kity.extendClass()
  1890. * @grammar kity.extendClass(clazz, extension) => {Class}
  1891. * @description 拓展一个已有的类
  1892. *
  1893. * @example
  1894. *
  1895. * ```js
  1896. * kity.extendClass(Dog, {
  1897. * spark: function() {
  1898. * console.log('wao wao wao!');
  1899. * }
  1900. * });
  1901. *
  1902. * new Dog().spark(); // "wao wao wao!";
  1903. * ```
  1904. */
  1905. exports.extendClass = extend;
  1906. }
  1907. };
  1908. //src/core/utils.js
  1909. /**
  1910. * @fileOverview
  1911. *
  1912. * 一些常用的工具方法
  1913. */
  1914. _p[12] = {
  1915. value: function() {
  1916. /**
  1917. * @class kity.Utils
  1918. * @catalog core
  1919. * @static
  1920. * @description 提供常用的工具方法
  1921. */
  1922. var utils = {
  1923. /**
  1924. * @method each()
  1925. * @for kity.Utils
  1926. * @grammar each(obj, interator, context)
  1927. * @param {Object|Array} obj 要迭代的对象或数组
  1928. * @param {Function} iterator 迭代函数
  1929. * @param {Any} context 迭代函数的上下文
  1930. *
  1931. * @example 迭代数组
  1932. *
  1933. * ```js
  1934. * kity.Utils.each([1, 2, 3, 4, 5], function(value, index, array) {
  1935. * console.log(value, index);
  1936. * });
  1937. * // 1, 0
  1938. * // 2, 1
  1939. * // 3, 2
  1940. * // 4, 3
  1941. * // 5, 4
  1942. * ```
  1943. *
  1944. * @example 迭代对象
  1945. *
  1946. * ```js
  1947. * var obj = {
  1948. * name: 'kity',
  1949. * version: '1.2.1'
  1950. * };
  1951. * var param = [];
  1952. * kity.Utils.each(obj, function(value, key, obj) {
  1953. * param.push(key + '=' + value);
  1954. * });
  1955. * console.log(param.join('&')); // "name=kity&version=1.2.1"
  1956. * ```
  1957. */
  1958. each: function each(obj, iterator, context) {
  1959. if (obj === null) {
  1960. return;
  1961. }
  1962. if (obj.length === +obj.length) {
  1963. for (var i = 0, l = obj.length; i < l; i++) {
  1964. if (iterator.call(context, obj[i], i, obj) === false) {
  1965. return false;
  1966. }
  1967. }
  1968. } else {
  1969. for (var key in obj) {
  1970. if (obj.hasOwnProperty(key)) {
  1971. if (iterator.call(context, obj[key], key, obj) === false) {
  1972. return false;
  1973. }
  1974. }
  1975. }
  1976. }
  1977. },
  1978. /**
  1979. * @method extend()
  1980. * @for kity.Utils
  1981. * @grammar extend(target, sources..., notCover) => {object}
  1982. * @description 把源对象的属性合并到目标对象上
  1983. * @param {object} target 目标对象
  1984. * @param {parameter} sources 源对象
  1985. * @param {boolean} notCover 是否不要覆盖源对象已有的属性
  1986. *
  1987. * @example
  1988. *
  1989. * ```js
  1990. * var a = {
  1991. * key1: 'a1',
  1992. * key2: 'a2'
  1993. * };
  1994. *
  1995. * var b = {
  1996. * key2: 'b2',
  1997. * key3: 'b3'
  1998. * };
  1999. *
  2000. * var c = {
  2001. * key4: 'c4'
  2002. * };
  2003. *
  2004. * var d = kity.extend(a, b, c);
  2005. *
  2006. * console.log(d === a); // true
  2007. * console.log(a); // {key1: 'a1', key2: 'b2', key3: 'b3', key4: 'c4'}
  2008. * ```
  2009. */
  2010. extend: function extend(t) {
  2011. var a = arguments, notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;
  2012. for (var i = 1; i < len; i++) {
  2013. var x = a[i];
  2014. for (var k in x) {
  2015. if (!notCover || !t.hasOwnProperty(k)) {
  2016. t[k] = x[k];
  2017. }
  2018. }
  2019. }
  2020. return t;
  2021. },
  2022. /**
  2023. * @method deepExtend()
  2024. * @for kity.Utils
  2025. * @grammar deepExtend(target, sources..., notCover)
  2026. * @description 把源对象的属性合并到目标对象上,如果属性是对象,会递归合并
  2027. * @param {object} target 目标对象
  2028. * @param {parameter} sources 源对象
  2029. * @param {boolean} notCover 是否不要覆盖源对象已有的属性
  2030. */
  2031. deepExtend: function(t, s) {
  2032. var a = arguments, notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;
  2033. for (var i = 1; i < len; i++) {
  2034. var x = a[i];
  2035. for (var k in x) {
  2036. if (!notCover || !t.hasOwnProperty(k)) {
  2037. if (this.isObject(t[k]) && this.isObject(x[k])) {
  2038. this.deepExtend(t[k], x[k], notCover);
  2039. } else {
  2040. t[k] = x[k];
  2041. }
  2042. }
  2043. }
  2044. }
  2045. return t;
  2046. },
  2047. /**
  2048. * @method clone()
  2049. * @for kity.Utils
  2050. * @grammar clone(obj) => {object}
  2051. * @description 返回一个对象的克隆副本(非深度复制)
  2052. * @param {object} obj 要克隆的对象
  2053. *
  2054. * @example
  2055. *
  2056. * ```js
  2057. * var source = {
  2058. * key1: {
  2059. * key2: 'value2'
  2060. * },
  2061. * key3: 'value3'
  2062. * };
  2063. *
  2064. * var target = kity.Utils.clone(source);
  2065. *
  2066. * console.log(target === source); // false
  2067. * console.log(target.key1 === source.key1); // true
  2068. * console.log(target.key3 === source.key3); // true
  2069. * ```
  2070. */
  2071. clone: function clone(obj) {
  2072. var cloned = {};
  2073. for (var m in obj) {
  2074. if (obj.hasOwnProperty(m)) {
  2075. cloned[m] = obj[m];
  2076. }
  2077. }
  2078. return cloned;
  2079. },
  2080. /**
  2081. * @method copy()
  2082. * @for kity.Utils
  2083. * @grammar copy(obj) => {object}
  2084. * @description 返回一个对象的拷贝副本(深度复制)
  2085. * @param {object} obj 要拷贝的对象
  2086. *
  2087. * @example
  2088. *
  2089. * ```js
  2090. * var source = {
  2091. * key1: {
  2092. * key2: 'value2'
  2093. * },
  2094. * key3: 'value3'
  2095. * };
  2096. *
  2097. * var target = kity.Utils.copy(source);
  2098. *
  2099. * console.log(target === source); // false
  2100. * console.log(target.key1 === source.key1); // false
  2101. * console.log(target.key3 === source.key3); // true,因为是值类型
  2102. * ```
  2103. */
  2104. copy: function copy(obj) {
  2105. if (typeof obj !== "object") return obj;
  2106. if (typeof obj === "function") return null;
  2107. return JSON.parse(JSON.stringify(obj));
  2108. },
  2109. queryPath: function(path, obj) {
  2110. var arr = path.split(".");
  2111. var i = 0, tmp = obj, l = arr.length;
  2112. while (i < l) {
  2113. if (arr[i] in tmp) {
  2114. tmp = tmp[arr[i]];
  2115. i++;
  2116. if (i >= l || tmp === undefined) {
  2117. return tmp;
  2118. }
  2119. } else {
  2120. return undefined;
  2121. }
  2122. }
  2123. },
  2124. getValue: function(value, defaultValue) {
  2125. return value !== undefined ? value : defaultValue;
  2126. },
  2127. /**
  2128. * @method flatten()
  2129. * @for kity.Utils
  2130. * @grammar flatten(arr) => {Array}
  2131. * @description 返回给定数组的扁平化版本
  2132. * @param {Array} arr 要扁平化的数组
  2133. *
  2134. * @example
  2135. *
  2136. * ```js
  2137. * var flattened = kity.Utils.flatten([[1, 2], [2, 3], [[4, 5], [6, 7]]]);
  2138. * console.log(flattened); // [1, 2, 3, 4, 5, 6, 7];
  2139. * ```
  2140. */
  2141. flatten: function flatten(arr) {
  2142. var result = [], length = arr.length, i;
  2143. for (i = 0; i < length; i++) {
  2144. if (arr[i] instanceof Array) {
  2145. result = result.concat(utils.flatten(arr[i]));
  2146. } else {
  2147. result.push(arr[i]);
  2148. }
  2149. }
  2150. return result;
  2151. },
  2152. /**
  2153. * @method paralle()
  2154. * @for kity.Utils
  2155. * @grammar paralle() => {Any}
  2156. *
  2157. * @description 平行地对 v1 和 v2 进行指定的操作
  2158. *
  2159. * 如果 v1 是数字,那么直接进行 op 操作
  2160. * 如果 v1 是对象,那么返回一个对象,其元素是 v1 和 v2 同键值的每个元素平行地进行 op 操作的结果
  2161. * 如果 v1 是数组,那么返回一个数组,其元素是 v1 和 v2 同索引的每个元素平行地进行 op 操作的结果
  2162. *
  2163. * @param {Number|Object|Array} v1 第一个操作数
  2164. * @param {Number|Object|Array} v2 第二个操作数
  2165. * @param {Function} op 操作函数
  2166. *
  2167. *
  2168. *
  2169. * @example
  2170. *
  2171. * ```js
  2172. * var a = {
  2173. * value1: 1,
  2174. * value2: 2,
  2175. * value3: [3, 4, 5]
  2176. * };
  2177. *
  2178. * var b = {
  2179. * value1: 2,
  2180. * value2: 3,
  2181. * value3: [4, 5, 6]
  2182. * };
  2183. *
  2184. * var c = kity.Utils.paralle(a, b, function(v1, v2) {
  2185. * return v1 + v2;
  2186. * });
  2187. *
  2188. * console.log(c.value1); // 3
  2189. * console.log(c.value2); // 5
  2190. * console.log(c.value3); // [7, 9, 11]
  2191. *
  2192. * ```
  2193. */
  2194. paralle: function paralle(v1, v2, op) {
  2195. var Class, field, index, name, value;
  2196. // 数组
  2197. if (v1 instanceof Array) {
  2198. value = [];
  2199. for (index = 0; index < v1.length; index++) {
  2200. value.push(utils.paralle(v1[index], v2[index], op));
  2201. }
  2202. return value;
  2203. }
  2204. // 对象
  2205. if (v1 instanceof Object) {
  2206. // 如果值是一个支持原始表示的实例,获取其原始表示
  2207. Class = v1.getClass && v1.getClass();
  2208. if (Class && Class.parse) {
  2209. v1 = v1.valueOf();
  2210. v2 = v2.valueOf();
  2211. value = utils.paralle(v1, v2, op);
  2212. value = Class.parse(value);
  2213. } else {
  2214. value = {};
  2215. for (name in v1) {
  2216. if (v1.hasOwnProperty(name) && v2.hasOwnProperty(name)) {
  2217. value[name] = utils.paralle(v1[name], v2[name], op);
  2218. }
  2219. }
  2220. }
  2221. return value;
  2222. }
  2223. // 是否数字
  2224. if (false === isNaN(parseFloat(v1))) {
  2225. return op(v1, v2);
  2226. }
  2227. return value;
  2228. },
  2229. /**
  2230. * 创建 op 操作的一个平行化版本
  2231. */
  2232. parallelize: function parallelize(op) {
  2233. return function(v1, v2) {
  2234. return utils.paralle(v1, v2, op);
  2235. };
  2236. }
  2237. };
  2238. /**
  2239. * @method isString()
  2240. * @for kity.Utils
  2241. * @grammar isString(unknown) => {boolean}
  2242. * @description 判断一个值是否为字符串类型
  2243. * @param {any} unknown 要判断的值
  2244. */
  2245. /**
  2246. * @method isFunction()
  2247. * @for kity.Utils
  2248. * @grammar isFunction(unknown) => {boolean}
  2249. * @description 判断一个值是否为函数类型
  2250. * @param {any} unknown 要判断的值
  2251. */
  2252. /**
  2253. * @method isArray()
  2254. * @for kity.Utils
  2255. * @grammar isArray(unknown) => {boolean}
  2256. * @description 判断一个值是否为数组类型
  2257. * @param {any} unknown 要判断的值
  2258. */
  2259. /**
  2260. * @method isNumber()
  2261. * @for kity.Utils
  2262. * @grammar isNumber(unknown) => {boolean}
  2263. * @description 判断一个值是否为数字类型
  2264. * @param {any} unknown 要判断的值
  2265. */
  2266. /**
  2267. * @method isRegExp()
  2268. * @for kity.Utils
  2269. * @grammar isRegExp(unknown) => {boolean}
  2270. * @description 判断一个值是否为正则表达式类型
  2271. * @param {any} unknown 要判断的值
  2272. */
  2273. /**
  2274. * @method isObject()
  2275. * @for kity.Utils
  2276. * @grammar isObject(unknown) => {boolean}
  2277. * @description 判断一个值是否为对象类型
  2278. * @param {any} unknown 要判断的值
  2279. */
  2280. /**
  2281. * @method isBoolean()
  2282. * @for kity.Utils
  2283. * @grammar isBoolean(unknown) => {boolean}
  2284. * @description 判断一个值是否为布尔类型
  2285. * @param {any} unknown 要判断的值
  2286. */
  2287. utils.each([ "String", "Function", "Array", "Number", "RegExp", "Object", "Boolean" ], function(v) {
  2288. utils["is" + v] = function typeCheck(obj) {
  2289. return Object.prototype.toString.apply(obj) == "[object " + v + "]";
  2290. };
  2291. });
  2292. return utils;
  2293. }
  2294. };
  2295. //src/filter/effect/colormatrixeffect.js
  2296. /**
  2297. * 颜色矩阵运算效果封装
  2298. */
  2299. _p[13] = {
  2300. value: function(require, exports, module) {
  2301. var Effect = _p.r(16), Utils = _p.r(12);
  2302. var ColorMatrixEffect = _p.r(11).createClass("ColorMatrixEffect", {
  2303. base: Effect,
  2304. constructor: function(type, input) {
  2305. this.callBase(Effect.NAME_COLOR_MATRIX);
  2306. this.set("type", Utils.getValue(type, ColorMatrixEffect.TYPE_MATRIX));
  2307. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  2308. }
  2309. });
  2310. Utils.extend(ColorMatrixEffect, {
  2311. // 类型常量
  2312. TYPE_MATRIX: "matrix",
  2313. TYPE_SATURATE: "saturate",
  2314. TYPE_HUE_ROTATE: "hueRotate",
  2315. TYPE_LUMINANCE_TO_ALPHA: "luminanceToAlpha",
  2316. // 矩阵常量
  2317. MATRIX_ORIGINAL: "10000010000010000010".split("").join(" "),
  2318. MATRIX_EMPTY: "00000000000000000000".split("").join(" ")
  2319. });
  2320. return ColorMatrixEffect;
  2321. }
  2322. };
  2323. //src/filter/effect/compositeeffect.js
  2324. /**
  2325. * 高斯模糊效果封装
  2326. */
  2327. _p[14] = {
  2328. value: function(require, exports, module) {
  2329. var Effect = _p.r(16), Utils = _p.r(12);
  2330. var CompositeEffect = _p.r(11).createClass("CompositeEffect", {
  2331. base: Effect,
  2332. constructor: function(operator, input, input2) {
  2333. this.callBase(Effect.NAME_COMPOSITE);
  2334. this.set("operator", Utils.getValue(operator, CompositeEffect.OPERATOR_OVER));
  2335. if (input) {
  2336. this.set("in", input);
  2337. }
  2338. if (input2) {
  2339. this.set("in2", input2);
  2340. }
  2341. }
  2342. });
  2343. Utils.extend(CompositeEffect, {
  2344. // operator 常量
  2345. OPERATOR_OVER: "over",
  2346. OPERATOR_IN: "in",
  2347. OPERATOR_OUT: "out",
  2348. OPERATOR_ATOP: "atop",
  2349. OPERATOR_XOR: "xor",
  2350. OPERATOR_ARITHMETIC: "arithmetic"
  2351. });
  2352. return CompositeEffect;
  2353. }
  2354. };
  2355. //src/filter/effect/convolvematrixeffect.js
  2356. /**
  2357. * 像素级别的矩阵卷积运算效果封装
  2358. */
  2359. _p[15] = {
  2360. value: function(require, exports, module) {
  2361. var Effect = _p.r(16), Utils = _p.r(12);
  2362. var ConvolveMatrixEffect = _p.r(11).createClass("ConvolveMatrixEffect", {
  2363. base: Effect,
  2364. constructor: function(edgeMode, input) {
  2365. this.callBase(Effect.NAME_CONVOLVE_MATRIX);
  2366. this.set("edgeMode", Utils.getValue(edgeMode, ConvolveMatrixEffect.MODE_DUPLICATE));
  2367. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  2368. }
  2369. });
  2370. Utils.extend(ConvolveMatrixEffect, {
  2371. MODE_DUPLICATE: "duplicate",
  2372. MODE_WRAP: "wrap",
  2373. MODE_NONE: "none"
  2374. });
  2375. return ConvolveMatrixEffect;
  2376. }
  2377. };
  2378. //src/filter/effect/effect.js
  2379. /*
  2380. * 效果类
  2381. * 该类型的对象不存储任何内部属性, 所有操作都是针对该类对象所维护的节点进行的
  2382. */
  2383. _p[16] = {
  2384. value: function(require, exports, module) {
  2385. var svg = _p.r(67), Effect = _p.r(11).createClass("Effect", {
  2386. constructor: function(type) {
  2387. this.node = svg.createNode(type);
  2388. },
  2389. getId: function() {
  2390. return this.node.id;
  2391. },
  2392. setId: function(id) {
  2393. this.node.id = id;
  2394. return this;
  2395. },
  2396. set: function(key, value) {
  2397. this.node.setAttribute(key, value);
  2398. return this;
  2399. },
  2400. get: function(key) {
  2401. return this.node.getAttribute(key);
  2402. },
  2403. getNode: function() {
  2404. return this.node;
  2405. },
  2406. // 返回该效果的result
  2407. toString: function() {
  2408. return this.node.getAttribute("result") || "";
  2409. }
  2410. });
  2411. _p.r(12).extend(Effect, {
  2412. // 特效名称常量
  2413. NAME_GAUSSIAN_BLUR: "feGaussianBlur",
  2414. NAME_OFFSET: "feOffset",
  2415. NAME_COMPOSITE: "feComposite",
  2416. NAME_COLOR_MATRIX: "feColorMatrix",
  2417. NAME_CONVOLVE_MATRIX: "feConvolveMatrix",
  2418. // 输入常量
  2419. INPUT_SOURCE_GRAPHIC: "SourceGraphic",
  2420. INPUT_SOURCE_ALPHA: "SourceAlpha",
  2421. INPUT_BACKGROUND_IMAGE: "BackgroundImage",
  2422. INPUT_BACKGROUND_ALPHA: "BackgroundAlpha",
  2423. INPUT_FILL_PAINT: "FillPaint",
  2424. INPUT_STROKE_PAINT: "StrokePaint"
  2425. });
  2426. return Effect;
  2427. }
  2428. };
  2429. //src/filter/effect/gaussianblureffect.js
  2430. /**
  2431. * 高斯模糊效果封装
  2432. */
  2433. _p[17] = {
  2434. value: function(require, exports, module) {
  2435. var Effect = _p.r(16), Utils = _p.r(12);
  2436. return _p.r(11).createClass("GaussianblurEffect", {
  2437. base: Effect,
  2438. constructor: function(stdDeviation, input) {
  2439. this.callBase(Effect.NAME_GAUSSIAN_BLUR);
  2440. this.set("stdDeviation", Utils.getValue(stdDeviation, 1));
  2441. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  2442. }
  2443. });
  2444. }
  2445. };
  2446. //src/filter/effect/offseteffect.js
  2447. /**
  2448. * 偏移效果封装
  2449. */
  2450. _p[18] = {
  2451. value: function(require, exports, module) {
  2452. var Effect = _p.r(16), Utils = _p.r(12);
  2453. return _p.r(11).createClass("OffsetEffect", {
  2454. base: Effect,
  2455. constructor: function(dx, dy, input) {
  2456. this.callBase(Effect.NAME_OFFSET);
  2457. this.set("dx", Utils.getValue(dx, 0));
  2458. this.set("dy", Utils.getValue(dy, 0));
  2459. this.set("in", Utils.getValue(input, Effect.INPUT_SOURCE_GRAPHIC));
  2460. }
  2461. });
  2462. }
  2463. };
  2464. //src/filter/effectcontainer.js
  2465. /*
  2466. * Effect所用的container
  2467. */
  2468. _p[19] = {
  2469. value: function(require) {
  2470. return _p.r(11).createClass("EffectContainer", {
  2471. base: _p.r(29),
  2472. addEffect: function(point, pos) {
  2473. return this.addItem.apply(this, arguments);
  2474. },
  2475. prependEffect: function() {
  2476. return this.prependItem.apply(this, arguments);
  2477. },
  2478. appendEffect: function() {
  2479. return this.appendItem.apply(this, arguments);
  2480. },
  2481. removeEffect: function(pos) {
  2482. return this.removeItem.apply(this, arguments);
  2483. },
  2484. addEffects: function() {
  2485. return this.addItems.apply(this, arguments);
  2486. },
  2487. setEffects: function() {
  2488. return this.setItems.apply(this, arguments);
  2489. },
  2490. getEffect: function() {
  2491. return this.getItem.apply(this, arguments);
  2492. },
  2493. getEffects: function() {
  2494. return this.getItems.apply(this, arguments);
  2495. },
  2496. getFirstEffect: function() {
  2497. return this.getFirstItem.apply(this, arguments);
  2498. },
  2499. getLastEffect: function() {
  2500. return this.getLastItem.apply(this, arguments);
  2501. },
  2502. handleAdd: function(effectItem, pos) {
  2503. var count = this.getEffects().length, nextEffectItem = this.getItem(pos + 1);
  2504. // 最后一个节点, 直接追加
  2505. if (count === pos + 1) {
  2506. this.node.appendChild(effectItem.getNode());
  2507. return;
  2508. }
  2509. this.node.insertBefore(effectItem.getNode(), nextEffectItem.getNode());
  2510. }
  2511. });
  2512. }
  2513. };
  2514. //src/filter/filter.js
  2515. /**
  2516. * Filter 基类
  2517. */
  2518. _p[20] = {
  2519. value: function(require, exports, module) {
  2520. var svg = _p.r(67);
  2521. var Class = _p.r(11);
  2522. var Filter = Class.createClass("Filter", {
  2523. mixins: [ _p.r(19) ],
  2524. constructor: function(x, y, width, height) {
  2525. this.node = svg.createNode("filter");
  2526. if (x !== undefined) {
  2527. this.set("x", x);
  2528. }
  2529. if (y !== undefined) {
  2530. this.set("y", y);
  2531. }
  2532. if (width !== undefined) {
  2533. this.set("width", width);
  2534. }
  2535. if (height !== undefined) {
  2536. this.set("height", height);
  2537. }
  2538. },
  2539. getId: function() {
  2540. return this.id;
  2541. },
  2542. setId: function(id) {
  2543. this.node.id = id;
  2544. return this;
  2545. },
  2546. set: function(key, value) {
  2547. this.node.setAttribute(key, value);
  2548. return this;
  2549. },
  2550. get: function(key) {
  2551. return this.node.getAttribute(key);
  2552. },
  2553. getNode: function() {
  2554. return this.node;
  2555. }
  2556. });
  2557. var Shape = _p.r(60);
  2558. Class.extendClass(Shape, {
  2559. applyFilter: function(filter) {
  2560. var filterId = filter.get("id");
  2561. if (filterId) {
  2562. this.node.setAttribute("filter", "url(#" + filterId + ")");
  2563. }
  2564. return this;
  2565. }
  2566. });
  2567. return Filter;
  2568. }
  2569. };
  2570. //src/filter/gaussianblurfilter.js
  2571. /*
  2572. * 高斯模糊滤镜
  2573. */
  2574. _p[21] = {
  2575. value: function(require, exports, module) {
  2576. var GaussianblurEffect = _p.r(17);
  2577. return _p.r(11).createClass("GaussianblurFilter", {
  2578. base: _p.r(20),
  2579. constructor: function(stdDeviation) {
  2580. this.callBase();
  2581. this.addEffect(new GaussianblurEffect(stdDeviation));
  2582. }
  2583. });
  2584. }
  2585. };
  2586. //src/filter/projectionfilter.js
  2587. /*
  2588. * 投影滤镜
  2589. */
  2590. _p[22] = {
  2591. value: function(require, exports, module) {
  2592. var GaussianblurEffect = _p.r(17), Effect = _p.r(16), ColorMatrixEffect = _p.r(13), Color = _p.r(28), Utils = _p.r(12), CompositeEffect = _p.r(14), OffsetEffect = _p.r(18);
  2593. return _p.r(11).createClass("ProjectionFilter", {
  2594. base: _p.r(20),
  2595. constructor: function(stdDeviation, dx, dy) {
  2596. this.callBase();
  2597. this.gaussianblurEffect = new GaussianblurEffect(stdDeviation, Effect.INPUT_SOURCE_ALPHA);
  2598. this.gaussianblurEffect.set("result", "gaussianblur");
  2599. this.addEffect(this.gaussianblurEffect);
  2600. this.offsetEffect = new OffsetEffect(dx, dy, this.gaussianblurEffect);
  2601. this.offsetEffect.set("result", "offsetBlur");
  2602. this.addEffect(this.offsetEffect);
  2603. this.colorMatrixEffect = new ColorMatrixEffect(ColorMatrixEffect.TYPE_MATRIX, this.offsetEffect);
  2604. this.colorMatrixEffect.set("values", ColorMatrixEffect.MATRIX_ORIGINAL);
  2605. this.colorMatrixEffect.set("result", "colorOffsetBlur");
  2606. this.addEffect(this.colorMatrixEffect);
  2607. this.compositeEffect = new CompositeEffect(CompositeEffect.OPERATOR_OVER, Effect.INPUT_SOURCE_GRAPHIC, this.colorMatrixEffect);
  2608. this.addEffect(this.compositeEffect);
  2609. },
  2610. // 设置投影颜色
  2611. setColor: function(color) {
  2612. var matrix = null, originMatrix = null, colorValue = [];
  2613. if (Utils.isString(color)) {
  2614. color = Color.parse(color);
  2615. }
  2616. if (!color) {
  2617. return this;
  2618. }
  2619. matrix = ColorMatrixEffect.MATRIX_EMPTY.split(" ");
  2620. colorValue.push(color.get("r"));
  2621. colorValue.push(color.get("g"));
  2622. colorValue.push(color.get("b"));
  2623. // rgb 分量更改
  2624. for (var i = 0, len = colorValue.length; i < len; i++) {
  2625. matrix[i * 5 + 3] = colorValue[i] / 255;
  2626. }
  2627. // alpha 分量更改
  2628. matrix[18] = color.get("a");
  2629. this.colorMatrixEffect.set("values", matrix.join(" "));
  2630. return this;
  2631. },
  2632. // 设置投影透明度
  2633. setOpacity: function(opacity) {
  2634. var matrix = this.colorMatrixEffect.get("values").split(" ");
  2635. matrix[18] = opacity;
  2636. this.colorMatrixEffect.set("values", matrix.join(" "));
  2637. return this;
  2638. },
  2639. // 设置阴影偏移量
  2640. setOffset: function(dx, dy) {
  2641. this.setOffsetX(dx);
  2642. this.setOffsetY(dy);
  2643. },
  2644. setOffsetX: function(dx) {
  2645. this.offsetEffect.set("dx", dx);
  2646. },
  2647. setOffsetY: function(dy) {
  2648. this.offsetEffect.set("dy", dy);
  2649. },
  2650. setDeviation: function(deviation) {
  2651. this.gaussianblurEffect.set("stdDeviation", deviation);
  2652. }
  2653. });
  2654. }
  2655. };
  2656. //src/graphic/bezier.js
  2657. /**
  2658. * @fileOverview
  2659. *
  2660. * 贝塞尔曲线
  2661. */
  2662. _p[23] = {
  2663. value: function(require, exports, module) {
  2664. /**
  2665. * @class kity.Bezier
  2666. * @mixins kity.PointContainer
  2667. * @base kity.Path
  2668. * @description 绘制和使用贝塞尔曲线。贝塞尔曲线作为一个贝塞尔点的容器,任何贝塞尔点的改变都会更改贝塞尔曲线的外观
  2669. */
  2670. return _p.r(11).createClass("Bezier", {
  2671. mixins: [ _p.r(51) ],
  2672. base: _p.r(46),
  2673. /**
  2674. * @constructor
  2675. * @for kity.Bezier
  2676. *
  2677. * @grammar new kity.Bezier(bezierPoints)
  2678. *
  2679. * @param {kity.BezierPoints[]} bezierPoints 贝塞尔点集合,每个元素应该是 {kity.BezierPoint} 类型
  2680. *
  2681. * @example
  2682. *
  2683. * ```js
  2684. * var bezier = new kity.Bezier([
  2685. * new kity.BezierPoint(0, 0).setForward(100, 0),
  2686. * new kity.BezierPoint(100, 100).setBackward(100, 0)
  2687. * ]);
  2688. * ```
  2689. */
  2690. constructor: function(bezierPoints) {
  2691. this.callBase();
  2692. bezierPoints = bezierPoints || [];
  2693. this.changeable = true;
  2694. this.setBezierPoints(bezierPoints);
  2695. },
  2696. /**
  2697. * @method getBezierPoints()
  2698. * @for kity.Bezier
  2699. * @description 返回当前贝塞尔曲线的贝塞尔点集合
  2700. *
  2701. * @grammar getBezierPoints() => {kity.BezierPoints[]}
  2702. *
  2703. */
  2704. getBezierPoints: function() {
  2705. return this.getPoints();
  2706. },
  2707. /**
  2708. * @method setBezierPoints()
  2709. * @for kity.Bezier
  2710. * @description 设置当前贝塞尔曲线的贝塞尔点集合
  2711. *
  2712. * @grammar setBeizerPoints(bezierPoints) => {this}
  2713. *
  2714. * @param {kity.BezierPoint[]} bezierPoints 贝塞尔点集合
  2715. */
  2716. setBezierPoints: function(bezierPoints) {
  2717. return this.setPoints(bezierPoints);
  2718. },
  2719. //当点集合发生变化时采取的动作
  2720. onContainerChanged: function() {
  2721. if (this.changeable) {
  2722. this.update();
  2723. }
  2724. },
  2725. update: function() {
  2726. var drawer = null, bezierPoints = this.getBezierPoints();
  2727. //单独的一个点不画任何图形
  2728. if (bezierPoints.length < 2) {
  2729. return;
  2730. }
  2731. drawer = this.getDrawer();
  2732. drawer.clear();
  2733. var vertex = bezierPoints[0].getVertex(), forward = null, backward = null;
  2734. drawer.moveTo(vertex.x, vertex.y);
  2735. for (var i = 1, len = bezierPoints.length; i < len; i++) {
  2736. vertex = bezierPoints[i].getVertex();
  2737. backward = bezierPoints[i].getBackward();
  2738. forward = bezierPoints[i - 1].getForward();
  2739. drawer.bezierTo(forward.x, forward.y, backward.x, backward.y, vertex.x, vertex.y);
  2740. }
  2741. return this;
  2742. }
  2743. });
  2744. }
  2745. };
  2746. //src/graphic/bezierpoint.js
  2747. /**
  2748. * @fileOverview
  2749. *
  2750. * 表示一个贝塞尔点
  2751. */
  2752. _p[24] = {
  2753. value: function(require, exports, module) {
  2754. var ShapePoint = _p.r(63);
  2755. var Vector = _p.r(73);
  2756. /**
  2757. * @class kity.BezierPoint
  2758. *
  2759. * @description 表示一个贝塞尔点
  2760. * 一个贝塞尔点由顶点坐标(曲线经过的点)、前方控制点、后方控制点表示
  2761. */
  2762. var BezierPoint = _p.r(11).createClass("BezierPoint", {
  2763. /**
  2764. * @constructor
  2765. * @for kity.BezierPoint
  2766. *
  2767. * @description 创建一个具有默认顶点坐标的贝塞尔点,两个控制点的坐标和顶点一致
  2768. *
  2769. * @param {Number} x 顶点的 x 坐标
  2770. * @param {Number} y 顶点的 y 坐标
  2771. * @param {Boolean} isSmooth 指示当前贝塞尔点是否光滑,光滑会约束顶点和两个控制点共线
  2772. */
  2773. constructor: function(x, y, isSmooth) {
  2774. //顶点
  2775. this.vertex = new ShapePoint(x, y);
  2776. //控制点
  2777. this.forward = new ShapePoint(x, y);
  2778. this.backward = new ShapePoint(x, y);
  2779. //是否平滑
  2780. this.setSmooth(isSmooth === undefined || isSmooth);
  2781. this.setSymReflaction(true);
  2782. },
  2783. /**
  2784. * @method clone()
  2785. * @for kity.BezierPoint
  2786. * @description 返回贝塞尔点的一份拷贝
  2787. *
  2788. * @grammar clone() => {kity.BezierPoint}
  2789. */
  2790. clone: function() {
  2791. var newPoint = new BezierPoint(), tmp = null;
  2792. tmp = this.getVertex();
  2793. newPoint.setVertex(tmp.x, tmp.y);
  2794. tmp = this.getForward();
  2795. newPoint.setForward(tmp.x, tmp.y);
  2796. tmp = this.getBackward();
  2797. newPoint.setBackward(tmp.x, tmp.y);
  2798. newPoint.setSymReflaction(this.isSymReflaction);
  2799. newPoint.setSmooth(this.isSmooth());
  2800. return newPoint;
  2801. },
  2802. /**
  2803. * @method setVertex()
  2804. * @for kity.BezierPoint
  2805. * @description 设置贝塞尔点的顶点坐标,注意,控制点的坐标不会跟着变化。希望控制点的坐标跟着变化,请用 moveTo() 方法
  2806. *
  2807. * @grammar setVertex(x, y) => {this}
  2808. *
  2809. * @param {Number} x 顶点的 x 坐标
  2810. * @param {Number} y 顶点的 y 坐标
  2811. */
  2812. setVertex: function(x, y) {
  2813. this.vertex.setPoint(x, y);
  2814. this.update();
  2815. return this;
  2816. },
  2817. /**
  2818. * @method moveTo()
  2819. * @for kity.BezierPoint
  2820. * @description 同步移动整个贝塞尔点,使顶点的移动到指定的坐标中。控制点的位置相对顶点坐标固定。
  2821. *
  2822. * @grammar moveTo() => {this}
  2823. *
  2824. * @param {Number} x 顶点的目标 x 坐标
  2825. * @param {Number} y 顶点的目标 y 坐标
  2826. *
  2827. */
  2828. moveTo: function(x, y) {
  2829. var oldForward = this.forward.getPoint(), oldBackward = this.backward.getPoint(), oldVertex = this.vertex.getPoint(), //移动距离
  2830. distance = {
  2831. left: x - oldVertex.x,
  2832. top: y - oldVertex.y
  2833. };
  2834. // 更新
  2835. this.forward.setPoint(oldForward.x + distance.left, oldForward.y + distance.top);
  2836. this.backward.setPoint(oldBackward.x + distance.left, oldBackward.y + distance.top);
  2837. this.vertex.setPoint(x, y);
  2838. this.update();
  2839. },
  2840. /**
  2841. * @method setForward()
  2842. * @for kity.BezierPoint
  2843. * @description 设置前方控制点的位置,如果贝塞尔点光滑,后方控制点会跟着联动
  2844. *
  2845. * @grammar setForward(x, y) => {this}
  2846. *
  2847. * @param {Number} x 前方控制点的 x 坐标
  2848. * @param {Number} y 前方控制点的 y 坐标
  2849. */
  2850. setForward: function(x, y) {
  2851. this.forward.setPoint(x, y);
  2852. //更新后置点
  2853. if (this.smooth) {
  2854. this.updateAnother(this.forward, this.backward);
  2855. }
  2856. this.update();
  2857. this.lastControlPointSet = this.forward;
  2858. return this;
  2859. },
  2860. /**
  2861. * @method setBackward()
  2862. * @for kity.BezierPoint
  2863. * @description 设置后方控制点的位置,如果贝塞尔点光滑,前方控制点会跟着联动
  2864. *
  2865. * @grammar setBackward(x, y) => {this}
  2866. *
  2867. * @param {Number} x 后方控制点的 x 坐标
  2868. * @param {Number} y 后方控制点的 y 坐标
  2869. */
  2870. setBackward: function(x, y) {
  2871. this.backward.setPoint(x, y);
  2872. //更新前置点
  2873. if (this.smooth) {
  2874. this.updateAnother(this.backward, this.forward);
  2875. }
  2876. this.update();
  2877. this.lastControlPointSet = this.backward;
  2878. return this;
  2879. },
  2880. /**
  2881. * @method setSymReflaction()
  2882. * @for kity.BezierPoint
  2883. * @description 设定是否镜像两个控制点的位置
  2884. *
  2885. * @grammar setSymReflaction(value) => {this}
  2886. *
  2887. * @param {boolean} value 如果设置为 true,且贝塞尔点光滑,两个控制点离顶点的距离相等
  2888. */
  2889. setSymReflaction: function(value) {
  2890. this.symReflaction = value;
  2891. if (this.smooth) this.setSmooth(true);
  2892. return this;
  2893. },
  2894. /**
  2895. * @method isSymReflaction()
  2896. * @for kity.BezierPoint
  2897. * @description 当前贝塞尔点的两个控制点是否被镜像约束
  2898. *
  2899. * @grammar isSymReflaction() => {boolean}
  2900. */
  2901. isSymReflaction: function() {
  2902. return this.symReflaction;
  2903. },
  2904. /**
  2905. * @private
  2906. *
  2907. * 根据前方控制点或后方控制点更新另一方
  2908. */
  2909. updateAnother: function(p, q) {
  2910. var v = this.getVertex(), pv = Vector.fromPoints(p.getPoint(), v), vq = Vector.fromPoints(v, q.getPoint());
  2911. vq = pv.normalize(this.isSymReflaction() ? pv.length() : vq.length());
  2912. q.setPoint(v.x + vq.x, v.y + vq.y);
  2913. return this;
  2914. },
  2915. /**
  2916. * @method setSmooth()
  2917. * @for kity.BezierPoint
  2918. * @description 设置贝塞尔点是否光滑,光滑会约束顶点和两个控制点共线
  2919. *
  2920. * @param {Boolean} isSmooth 设置为 true 让贝塞尔点光滑
  2921. */
  2922. setSmooth: function(isSmooth) {
  2923. var lc;
  2924. this.smooth = !!isSmooth;
  2925. if (this.smooth && (lc = this.lastControlPointSet)) {
  2926. this.updateAnother(lc, lc == this.forward ? this.backward : this.forward);
  2927. }
  2928. return this;
  2929. },
  2930. /**
  2931. * @method isSmooth()
  2932. * @for kity.BezierPoint
  2933. * @description 判断贝塞尔点是否光滑
  2934. *
  2935. * @grammar isSmooth() => {boolean}
  2936. */
  2937. isSmooth: function() {
  2938. return this.smooth;
  2939. },
  2940. /**
  2941. * @method getVertex()
  2942. * @for kity.BezierPoint
  2943. * @description 获得当前贝塞尔点的顶点
  2944. *
  2945. * @grammar getVertex() => {kity.ShapePoint}
  2946. */
  2947. getVertex: function() {
  2948. return this.vertex.getPoint();
  2949. },
  2950. /**
  2951. * @method getForward()
  2952. * @for kity.BezierPoint
  2953. * @description 获得当前贝塞尔点的前方控制点
  2954. *
  2955. * @grammar getForward() => {kity.ShapePoint}
  2956. */
  2957. getForward: function() {
  2958. return this.forward.getPoint();
  2959. },
  2960. /**
  2961. * @method getBackward()
  2962. * @for kity.BezierPoint
  2963. * @description 获得当前贝塞尔点的后方控制点
  2964. *
  2965. * @grammar getBackward() => {kity.ShapePoint}
  2966. */
  2967. getBackward: function() {
  2968. return this.backward.getPoint();
  2969. },
  2970. /**
  2971. * @private
  2972. *
  2973. * 联动更新相关的贝塞尔曲线
  2974. */
  2975. update: function() {
  2976. if (!this.container) {
  2977. return this;
  2978. }
  2979. //新增参数 this, 把当前引起变化的点传递过去, 以便有需要的地方可以获取到引起变化的源
  2980. if (this.container.update) this.container.update(this);
  2981. }
  2982. });
  2983. return BezierPoint;
  2984. }
  2985. };
  2986. //src/graphic/box.js
  2987. /**
  2988. * @fileOverview
  2989. *
  2990. * 表示一个矩形区域
  2991. */
  2992. _p[25] = {
  2993. value: function(require, exports, module) {
  2994. /**
  2995. * @class kity.Box
  2996. * @description 表示一个矩形区域
  2997. */
  2998. var Box = _p.r(11).createClass("Box", {
  2999. /**
  3000. * @constructor
  3001. * @for kity.Box
  3002. *
  3003. * @grammar new kity.Box(x, y, width, height)
  3004. * @grammar new kity.Box(box)
  3005. *
  3006. * @param {Number} x|box.x 矩形区域的 x 坐标
  3007. * @param {Number} y|box.y 矩形区域的 y 坐标
  3008. * @param {Number} width|box.width 矩形区域的宽度
  3009. * @param {Number} height|box.height 矩形区域的高度
  3010. *
  3011. * @example
  3012. *
  3013. * ```js
  3014. * var box = new kity.Box(10, 20, 50, 50);
  3015. * var box2 = new kity.Box({x: 10, y: 20, width: 50, height: 50});
  3016. * ```
  3017. */
  3018. constructor: function(x, y, width, height) {
  3019. var box = arguments[0];
  3020. if (box && typeof box === "object") {
  3021. x = box.x;
  3022. y = box.y;
  3023. width = box.width;
  3024. height = box.height;
  3025. }
  3026. if (width < 0) {
  3027. x -= width = -width;
  3028. }
  3029. if (height < 0) {
  3030. y -= height = -height;
  3031. }
  3032. /**
  3033. * @property x
  3034. * @for kity.Box
  3035. * @type {Number}
  3036. * @readOnly
  3037. * @description 矩形区域的 x 坐标
  3038. */
  3039. this.x = x || 0;
  3040. /**
  3041. * @property y
  3042. * @for kity.Box
  3043. * @type {Number}
  3044. * @readOnly
  3045. * @description 矩形区域的 y 坐标
  3046. */
  3047. this.y = y || 0;
  3048. /**
  3049. * @property width
  3050. * @for kity.Box
  3051. * @type {Number}
  3052. * @readOnly
  3053. * @description 矩形区域的宽度
  3054. */
  3055. this.width = width || 0;
  3056. /**
  3057. * @property height
  3058. * @for kity.Box
  3059. * @type {Number}
  3060. * @readOnly
  3061. * @description 矩形区域的高度
  3062. */
  3063. this.height = height || 0;
  3064. /**
  3065. * @property left
  3066. * @for kity.Box
  3067. * @type {Number}
  3068. * @readOnly
  3069. * @description 矩形区域的最左侧坐标,等价于 x 的值
  3070. */
  3071. this.left = this.x;
  3072. /**
  3073. * @property right
  3074. * @for kity.Box
  3075. * @type {Number}
  3076. * @readOnly
  3077. * @description 矩形区域的最右侧坐标,等价于 x + width 的值
  3078. */
  3079. this.right = this.x + this.width;
  3080. /**
  3081. * @property top
  3082. * @for kity.Box
  3083. * @type {Number}
  3084. * @readOnly
  3085. * @description 矩形区域的最上侧坐标,等价于 y 的值
  3086. */
  3087. this.top = this.y;
  3088. /**
  3089. * @property bottom
  3090. * @for kity.Box
  3091. * @type {Number}
  3092. * @readOnly
  3093. * @description 矩形区域的最下侧坐标,等价于 y + height 的值
  3094. */
  3095. this.bottom = this.y + this.height;
  3096. /**
  3097. * @property cx
  3098. * @for kity.Box
  3099. * @type {Number}
  3100. * @readOnly
  3101. * @description 矩形区域的中心 x 坐标
  3102. */
  3103. this.cx = this.x + this.width / 2;
  3104. /**
  3105. * @property cy
  3106. * @for kity.Box
  3107. * @type {Number}
  3108. * @readOnly
  3109. * @description 矩形区域的中心 y 坐标
  3110. */
  3111. this.cy = this.y + this.height / 2;
  3112. },
  3113. /**
  3114. * @method getRangeX()
  3115. * @for kity.Box
  3116. * @description 获得矩形区域的 x 值域
  3117. *
  3118. * @grammar getRangeX() => {Number[]}
  3119. *
  3120. * @example
  3121. *
  3122. * var box = new kity.Box(10, 10, 30, 50);
  3123. * console.log(box.getRangeX()); // [10, 40]
  3124. */
  3125. getRangeX: function() {
  3126. return [ this.left, this.right ];
  3127. },
  3128. /**
  3129. * @method getRangeY()
  3130. * @for kity.Box
  3131. * @description 获得矩形区域的 y 值域
  3132. *
  3133. * @grammar getRangeY() => {Number[]}
  3134. *
  3135. * @example
  3136. *
  3137. * var box = new kity.Box(10, 10, 30, 50);
  3138. * console.log(box.getRangeY()); // [10, 60]
  3139. */
  3140. getRangeY: function() {
  3141. return [ this.top, this.bottom ];
  3142. },
  3143. /**
  3144. * @method merge()
  3145. * @for kity.Box
  3146. * @description 把当前矩形区域和指定的矩形区域合并,返回一个新的矩形区域(即包含两个源矩形区域的最小矩形区域)
  3147. *
  3148. * @grammar merge(another) => {kity.Box}
  3149. * @param {kity.Box} another 要合并的矩形区域
  3150. *
  3151. * @example
  3152. *
  3153. * ```js
  3154. * var box1 = new kity.Box(10, 10, 50, 50);
  3155. * var box2 = new kity.Box(30, 30, 50, 50);
  3156. * var box3 = box1.merge(box2);
  3157. * console.log(box3.valueOf()); // [10, 10, 70, 70]
  3158. * ```
  3159. */
  3160. merge: function(another) {
  3161. if (this.isEmpty()) {
  3162. return new Box(another.x, another.y, another.width, another.height);
  3163. }
  3164. var left = Math.min(this.left, another.left), right = Math.max(this.right, another.right), top = Math.min(this.top, another.top), bottom = Math.max(this.bottom, another.bottom);
  3165. return new Box(left, top, right - left, bottom - top);
  3166. },
  3167. /**
  3168. * @method intersect()
  3169. * @for kity.Box
  3170. * @description 求当前矩形区域和指定的矩形区域重叠的矩形区域
  3171. *
  3172. * @grammar intersect(another) => {kity.Box}
  3173. * @param {kity.Box} another 要求重叠的矩形区域
  3174. *
  3175. * @example
  3176. *
  3177. * ```js
  3178. * var box1 = new kity.Box(10, 10, 50, 50);
  3179. * var box2 = new kity.Box(30, 30, 50, 50);
  3180. * var box3 = box1.intersect(box2);
  3181. * console.log(box3.valueOf()); // [30, 30, 20, 20]
  3182. * ```
  3183. */
  3184. intersect: function(another) {
  3185. if (!another instanceof Box) {
  3186. another = new Box(another);
  3187. }
  3188. var left = Math.max(this.left, another.left), right = Math.min(this.right, another.right), top = Math.max(this.top, another.top), bottom = Math.min(this.bottom, another.bottom);
  3189. if (left > right || top > bottom) return new Box();
  3190. return new Box(left, top, right - left, bottom - top);
  3191. },
  3192. /**
  3193. * @method expand()
  3194. * @for kity.Box
  3195. * @description 扩展(或收缩)当前的盒子,返回新的盒子
  3196. *
  3197. * @param {Number} top
  3198. * 矩形区域的上边界往上扩展的值;如果是负数,则上边界往下收缩
  3199. *
  3200. * @param {Number} right
  3201. * [Optional] 矩形区域的右边界往右拓展的值;
  3202. * 如果是负数,则右边界往左收缩;
  3203. * 如果不设置该值,使用和 top 同样的值。
  3204. *
  3205. * @param {Number} bottom
  3206. * [Optional] 矩形区域的下边界往下拓展的值;
  3207. * 如果是负数,则下边界往上收缩;
  3208. * 如果不设置该值,使用和 top 同样的值。
  3209. *
  3210. * @param {Number} left
  3211. * [Optional] 矩形区域的左边界往左拓展的值;
  3212. * 如果是负数,则左边界往右收缩;
  3213. * 如果不设置该值,使用和 right 同样的值。
  3214. *
  3215. * @example
  3216. *
  3217. * ```js
  3218. * var box = new kity.Box(10, 10, 20, 20);
  3219. * var box1 = box.expand(10); // [0, 0, 40, 40]
  3220. * var box2 = box.expand(10, 20); // [0, -10, 40, 60]
  3221. * var box3 = box.expand(1, 2, 3, 4); // [9, 8, 24, 26]
  3222. * ```
  3223. */
  3224. expand: function(top, right, bottom, left) {
  3225. if (arguments.length < 1) {
  3226. return new Box(this);
  3227. }
  3228. if (arguments.length < 2) {
  3229. right = top;
  3230. }
  3231. if (arguments.length < 3) {
  3232. bottom = top;
  3233. }
  3234. if (arguments.length < 4) {
  3235. left = right;
  3236. }
  3237. var x = this.left - left, y = this.top - top, width = this.width + right, height = this.height + top;
  3238. return new Box(x, y, width, height);
  3239. },
  3240. /**
  3241. * @method valueOf()
  3242. * @for kity.Box
  3243. * @description 返回当前盒子的数组表示
  3244. *
  3245. * @grammar valueOf() => {Number[]}
  3246. *
  3247. * @example
  3248. *
  3249. * ```js
  3250. * var box = new kity.Box(0, 0, 200, 50);
  3251. * console.log(box.valueOf()); // [0, 0, 200, 50]
  3252. * ```
  3253. */
  3254. valueOf: function() {
  3255. return [ this.x, this.y, this.width, this.height ];
  3256. },
  3257. /**
  3258. * @method toString()
  3259. * @for kity.Box
  3260. * @description 返回当前盒子的字符串表示
  3261. *
  3262. * @grammar toString() => {String}
  3263. *
  3264. * @example
  3265. *
  3266. * ```js
  3267. * var box = new kity.Box(0, 0, 200, 50);
  3268. * console.log(box.toString()); // "0 0 200 50"
  3269. */
  3270. toString: function() {
  3271. return this.valueOf().join(" ");
  3272. },
  3273. /**
  3274. * @method isEmpty()
  3275. * @for kity.Box
  3276. * @description 判断当前盒子是否具有尺寸(面积大
  3277. *
  3278. * @grammar isEmpty() => {boolean}
  3279. *
  3280. * @example
  3281. * ```js
  3282. * var box = new kity.Box(0, 0, 0, 100000);
  3283. * console.log(box.isEmpty()); // true
  3284. * ```
  3285. */
  3286. isEmpty: function() {
  3287. return !this.width || !this.height;
  3288. }
  3289. });
  3290. /**
  3291. * @method parse()
  3292. * @static
  3293. * @for kity.Box
  3294. * @description 解析一个字符串或数组为 kity.Box 对象
  3295. *
  3296. * @grammar kity.Box.parse(any) => {kity.Box}
  3297. *
  3298. * @param {Number[]|String} any 要解析的字符串或数组
  3299. *
  3300. * @example
  3301. *
  3302. * ```js
  3303. * console.log(kity.Box.parse('0 0 100 200'));
  3304. * console.log(kity.Box.parse([0, 0, 100, 200]));
  3305. * ```
  3306. */
  3307. Box.parse = function(any) {
  3308. if (typeof any == "string") {
  3309. return Box.parse(any.split(/[\s,]+/).map(parseFloat));
  3310. }
  3311. if (any instanceof Array) {
  3312. return new Box(any[0], any[1], any[2], any[3]);
  3313. }
  3314. if ("x" in any) return new Box(any);
  3315. return null;
  3316. };
  3317. return Box;
  3318. }
  3319. };
  3320. //src/graphic/circle.js
  3321. /**
  3322. * @fileOverview
  3323. *
  3324. * 绘制和使用圆形
  3325. */
  3326. _p[26] = {
  3327. value: function(require, exports, module) {
  3328. /**
  3329. * @class kity.Circle
  3330. * @base kity.Ellipse
  3331. * @description 表示一个圆形
  3332. */
  3333. return _p.r(11).createClass("Circle", {
  3334. base: _p.r(32),
  3335. /**
  3336. * @constructor
  3337. * @for kity.Circle
  3338. *
  3339. * @grammar new kity.Circle(radius, cx, cy)
  3340. *
  3341. * @param {Number} radius 半径
  3342. * @param {Number} cx 圆心 x 坐标
  3343. * @param {Number} cy 圆心 y 坐标
  3344. */
  3345. constructor: function(radius, cx, cy) {
  3346. this.callBase(radius, radius, cx, cy);
  3347. },
  3348. /**
  3349. * @method
  3350. * @for kity.Circle
  3351. * @description 获取圆形的半径
  3352. *
  3353. * @grammar getRadius() => {Number}
  3354. */
  3355. getRadius: function() {
  3356. return this.getRadiusX();
  3357. },
  3358. /**
  3359. * @method
  3360. * @for kity.Circle
  3361. * @description 设置圆形的半径
  3362. *
  3363. * @grammar setRadius() => {this}
  3364. *
  3365. * @param {Number} radius 半径大小
  3366. */
  3367. setRadius: function(radius) {
  3368. return this.callBase(radius, radius);
  3369. }
  3370. });
  3371. }
  3372. };
  3373. //src/graphic/clip.js
  3374. /**
  3375. * @fileOverview
  3376. *
  3377. * 支持图形裁切
  3378. */
  3379. _p[27] = {
  3380. value: function(require, exports, module) {
  3381. var Class = _p.r(11);
  3382. var Shape = _p.r(60);
  3383. /**
  3384. * @class kity.Clip
  3385. * @base kity.Resource
  3386. * @mixins kity.ShapeContainer
  3387. *
  3388. * @description 创建图形裁切,用于裁切目标图形
  3389. */
  3390. var Clip = Class.createClass("Clip", {
  3391. base: Shape,
  3392. mixins: [ _p.r(61) ],
  3393. /**
  3394. * @constructor
  3395. * @for kity.Clip
  3396. *
  3397. * @grammar new kity.Clip(paper)
  3398. *
  3399. * @param {kity.Paper} paper 资源所属的文档
  3400. *
  3401. * @example
  3402. *
  3403. * ```js
  3404. * var circle = paper.put(new kity.Circle(100).fill('yellow'));
  3405. * var clip = new kity.Clip(paper);
  3406. * clip.addShape(new kity.Circle(100, 50, 0));
  3407. * clip.clip(circle);
  3408. * ```
  3409. */
  3410. constructor: function(paper) {
  3411. this.callBase("clipPath", paper);
  3412. },
  3413. /**
  3414. * @method clip()
  3415. * @for kity.Clip
  3416. * @description 将裁切应用到指定的图形上,应用之后,目标图形将显示与裁切形状重合的部分
  3417. *
  3418. * @grammar clip(shape) => {this}
  3419. *
  3420. * @param {kity.Shape} shape 要应用裁切的图形
  3421. */
  3422. clip: function(shape) {
  3423. shape.getNode().setAttribute("clip-path", this);
  3424. return this;
  3425. }
  3426. });
  3427. Class.extendClass(Shape, {
  3428. /**
  3429. * @method clipWidth()
  3430. * @for kity.Shape
  3431. *
  3432. * @grammar clipWidth(clip) => {this}
  3433. *
  3434. * @param {kity.Clip|kity.Shape} clip 要用于裁切当前图形的图形;
  3435. * 如果 clip 本身是一个裁切对象(kity.Clip 类型),则直接裁切;
  3436. * 否则将创建新的裁切包含给定的图形,然后对当前图形进行裁切
  3437. *
  3438. * @example
  3439. *
  3440. * ```js
  3441. * var circle = paper.put(new kity.Circle(100));
  3442. * var rect = paper.put(new kity.Rect(100, 100, -100, 0));
  3443. *
  3444. * circle.clipWidth(rect);
  3445. * ```
  3446. */
  3447. clipWith: function(clip) {
  3448. if (clip instanceof Shape) {
  3449. clip = new Clip(clip.getPaper()).addShape(clip);
  3450. }
  3451. clip.clip(this);
  3452. return this;
  3453. }
  3454. });
  3455. return Clip;
  3456. }
  3457. };
  3458. //src/graphic/color.js
  3459. /**
  3460. * @fileOverview
  3461. *
  3462. * 提供颜色支持
  3463. */
  3464. _p[28] = {
  3465. value: function(require, exports, module) {
  3466. var Utils = _p.r(12), StandardColor = _p.r(64), ColorUtils = {}, /**
  3467. * @class kity.Color
  3468. * @description 表示一个颜色
  3469. */
  3470. Color = _p.r(11).createClass("Color", {
  3471. /**
  3472. * @constructor
  3473. * @for kity.Color
  3474. *
  3475. * @grammar new kity.Color(r, g, b)
  3476. * @grammar new kity.Color(r, g, b, a)
  3477. * @grammar new kity.Color(colorString)
  3478. *
  3479. * @param {Number} r 红色分量,取值 0 - 255
  3480. * @param {Number} g 绿色分量,取值 0 - 255
  3481. * @param {Number} b 蓝色分量,取值 0 - 255
  3482. * @param {Number} a 透明度(可选),取值 0 - 100
  3483. * @param {String} colorString 一个代表颜色的字符串,可以是:
  3484. * 熟知颜色表:如 'red', 'yellow'
  3485. * HEX 表示:如 '#368', '#123456'
  3486. * RGB 表示:如 'RGB(200, 200, 0)', 'RGBA(200, 200, 200, .5)'
  3487. * HSL 表示:如 'HSL(100, 60%, 80%)', 'HSLA(100, 60%, 80%, .5)'
  3488. */
  3489. constructor: function() {
  3490. var colorValue = null;
  3491. //parse构造
  3492. if (typeof arguments[0] === "string") {
  3493. colorValue = ColorUtils.parseToValue(arguments[0]);
  3494. //解析失败
  3495. if (colorValue === null) {
  3496. colorValue = {
  3497. r: 0,
  3498. g: 0,
  3499. b: 0,
  3500. h: 0,
  3501. s: 0,
  3502. l: 0,
  3503. a: 1
  3504. };
  3505. }
  3506. } else {
  3507. colorValue = {
  3508. r: arguments[0] | 0,
  3509. g: arguments[1] | 0,
  3510. b: arguments[2] | 0,
  3511. //alpha 默认为1
  3512. a: arguments[3] === undefined ? 1 : parseFloat(arguments[3])
  3513. };
  3514. colorValue = ColorUtils.overflowFormat(colorValue);
  3515. //获取hsl分量
  3516. colorValue = Utils.extend(colorValue, ColorUtils.rgbValueToHslValue(colorValue));
  3517. }
  3518. this._color = colorValue;
  3519. },
  3520. /**
  3521. * @method set()
  3522. * @for kity.Color
  3523. *
  3524. * @description 设置当前颜色某个分量的值
  3525. *
  3526. * @grammar set(name, value) => {this}
  3527. *
  3528. * @param {string} name 要设置的颜色通道的名称
  3529. * r: 红色(Red),取值范围 [0, 255]
  3530. * g: 绿色(Green),取值范围 [0, 255]
  3531. * b: 蓝色(Blue),取值范围 [0, 255]
  3532. * a: 透明度(Alpha),取值范围 [0, 1]
  3533. * h: 色环角度(Hue),取值范围 [0, 359]
  3534. * s: 饱和度(Saturation),取值范围 [0, 100]
  3535. * l: 亮度(Lightness),取值范围 [0, 100]
  3536. * r、g、b 值和 h、s、l 值会联动修改
  3537. * @param {number} value 要设置的值
  3538. */
  3539. set: function(name, value) {
  3540. var values = null;
  3541. //设置的值非法
  3542. if (!Color._MAX_VALUE[name]) {
  3543. throw new Error("Color set(): Illegal parameter");
  3544. }
  3545. if (name !== "a") {
  3546. value = Math.floor(value);
  3547. }
  3548. if (name == "h") {
  3549. value = (value + 360) % 360;
  3550. }
  3551. this._color[name] = Math.max(Color._MIN_VALUE[name], Math.min(Color._MAX_VALUE[name], value));
  3552. if ("rgb".indexOf(name) !== -1) {
  3553. this._color = Utils.extend(this._color, ColorUtils.rgbValueToHslValue(this._color));
  3554. } else if ("hsl".indexOf(name) !== -1) {
  3555. this._color = Utils.extend(this._color, ColorUtils.hslValueToRGBValue(this._color));
  3556. }
  3557. return this;
  3558. },
  3559. /**
  3560. * @method inc()
  3561. *
  3562. * @description 返回新的颜色,表示当前颜色增加指定通道的值之后的颜色
  3563. *
  3564. * @grammar inc(name, value) => {this}
  3565. *
  3566. * @param {string} name 要增加的通道的名称,具体含义请查看 set 方法
  3567. * @param {number} value 增量值
  3568. */
  3569. inc: function(name, value) {
  3570. value = this.get(name) + value;
  3571. if (name == "h") {
  3572. value = (value + 360) % 360;
  3573. } else {
  3574. value = Math.min(Color._MAX_VALUE[name], value);
  3575. value = Math.max(Color._MIN_VALUE[name], value);
  3576. }
  3577. return this.clone().set(name, value);
  3578. },
  3579. /**
  3580. * @method dec()
  3581. * @for kity.Color
  3582. *
  3583. * @description 返回新的颜色,表示当前颜色减少指定通道的值之后的颜色
  3584. *
  3585. * @grammar dec(name, value) => {this}
  3586. *
  3587. * @param {string} name 要减少值的通道的名称,具体含义请查看 set 方法
  3588. * @param {number} value 减量值
  3589. */
  3590. dec: function(name, value) {
  3591. return this.inc(name, -value);
  3592. },
  3593. /**
  3594. * @method clone()
  3595. * @for kity.Color
  3596. *
  3597. * @description 返回当前颜色的一个拷贝
  3598. *
  3599. * @grammar clone() => {kity.Color}
  3600. */
  3601. clone: function() {
  3602. return new Color(this.toRGBA());
  3603. },
  3604. /**
  3605. * @method get()
  3606. * @for kity.Color
  3607. *
  3608. * @description 返回当前颜色指定的分量
  3609. *
  3610. * @grammar get() => {number}
  3611. */
  3612. get: function(name) {
  3613. if (!Color._MAX_VALUE[name]) {
  3614. return null;
  3615. }
  3616. return this._color[name];
  3617. },
  3618. getValues: function() {
  3619. return Utils.clone(this._color);
  3620. },
  3621. /**
  3622. * @method valueOf()
  3623. * @for kity.Color
  3624. *
  3625. * @description 返回当前颜色的一个字面量表示
  3626. *
  3627. * @return {plain} 颜色字面量,其结构为:
  3628. * {
  3629. * r: 0,
  3630. * g: 0,
  3631. * b: 0,
  3632. * a: 0,
  3633. * h: 0,
  3634. * s: 0,
  3635. * l: 0
  3636. * }
  3637. */
  3638. valueOf: function() {
  3639. return this.getValues();
  3640. },
  3641. /**
  3642. * @method toRGB()
  3643. * @for kity.Color
  3644. *
  3645. * @description 返回当前颜色的 RGB 表示,如果颜色有透明度,将抛弃透明度属性(想要保留请使用 toRGBA())方法。
  3646. *
  3647. * @grammar toRGB() => {string}
  3648. */
  3649. toRGB: function() {
  3650. return ColorUtils.toString(this._color, "rgb");
  3651. },
  3652. /**
  3653. * @method toRGBA()
  3654. * @for kity.Color
  3655. *
  3656. * @description 返回当前颜色的 RGBA 表示
  3657. *
  3658. * @grammar toRGBA() => {string}
  3659. */
  3660. toRGBA: function() {
  3661. return ColorUtils.toString(this._color, "rgba");
  3662. },
  3663. /**
  3664. * @method toHEX()
  3665. * @for kity.Color
  3666. *
  3667. * @description 返回当前颜色的 HEX 表示,如果颜色有透明度,将抛弃透明度属性(想要保留请使用 toRGBA())方法。
  3668. *
  3669. * @grammar toHEX() => {string}
  3670. */
  3671. toHEX: function() {
  3672. return ColorUtils.toString(this._color, "hex");
  3673. },
  3674. /**
  3675. * @method toHSL()
  3676. * @for kity.Color
  3677. *
  3678. * @description 返回当前颜色的 HSL 表示,如果颜色有透明度,将抛弃透明度属性(想要保留请使用 toHSLA())方法。
  3679. *
  3680. * @grammar toHSL() => {string}
  3681. */
  3682. toHSL: function() {
  3683. return ColorUtils.toString(this._color, "hsl");
  3684. },
  3685. /**
  3686. * @method toHSLA()
  3687. * @for kity.Color
  3688. *
  3689. * @description 返回当前颜色的 HSLA 表示
  3690. *
  3691. * @grammar toHSLA() => {string}
  3692. */
  3693. toHSLA: function() {
  3694. return ColorUtils.toString(this._color, "hsla");
  3695. },
  3696. /**
  3697. * @method toString()
  3698. * @for kity.Color
  3699. *
  3700. * @description 返回当前颜色的 RGB 或 RGBA 表示,如果颜色有透明度,将使用 RGBA 形式,否则是 RGB 形式
  3701. * @grammar toString() => {string}
  3702. */
  3703. toString: function() {
  3704. if (this._color.a === 1) {
  3705. return this.toRGB();
  3706. }
  3707. return this.toRGBA();
  3708. }
  3709. });
  3710. //Color 静态方法
  3711. Utils.extend(Color, {
  3712. //各分量可表示的最大值
  3713. _MAX_VALUE: {
  3714. r: 255,
  3715. g: 255,
  3716. b: 255,
  3717. h: 360,
  3718. s: 100,
  3719. l: 100,
  3720. a: 1
  3721. },
  3722. //各分量最小值
  3723. _MIN_VALUE: {
  3724. r: 0,
  3725. g: 0,
  3726. b: 0,
  3727. h: 0,
  3728. s: 0,
  3729. l: 0,
  3730. a: 0
  3731. },
  3732. //分量常量
  3733. R: "r",
  3734. G: "g",
  3735. B: "b",
  3736. H: "h",
  3737. S: "s",
  3738. L: "l",
  3739. A: "a",
  3740. /**
  3741. * @method parse()
  3742. * @static
  3743. * @for kity.Color
  3744. *
  3745. * @description 解析一个颜色字符串为 kity.Color 对象
  3746. *
  3747. * @grammar kity.Color.parse(valStr)
  3748. *
  3749. * @param {string} valStr 一个代表颜色的字符串,可以是:
  3750. * 熟知颜色表:如 'red', 'yellow'
  3751. * HEX 表示:如 '#368', '#123456'
  3752. * RGB 表示:如 'RGB(200, 200, 0)', 'RGBA(200, 200, 200, .5)'
  3753. * HSL 表示:如 'HSL(100, 60%, 80%)', 'HSLA(100, 60%, 80%, .5)'
  3754. */
  3755. parse: function(valStr) {
  3756. var rgbValue;
  3757. if (Utils.isString(valStr)) {
  3758. rgbValue = ColorUtils.parseToValue(valStr);
  3759. }
  3760. if (Utils.isObject(valStr) && "r" in valStr) {
  3761. rgbValue = valStr;
  3762. }
  3763. //解析失败, 返回一个默认color实例
  3764. if (rgbValue === null) {
  3765. return new Color();
  3766. }
  3767. return new Color(rgbValue.r, rgbValue.g, rgbValue.b, rgbValue.a);
  3768. },
  3769. /**
  3770. * @method createHSL()
  3771. * @for kity.Color
  3772. * @static
  3773. *
  3774. * @description 创建一个 HSL 颜色
  3775. *
  3776. * @grammar kity.Color.createHSL(h, s, l) => {kity.Color}
  3777. *
  3778. * @param {number} h 色环(Hue)分量值,取值范围 [0, 359]
  3779. * @param {number} s 饱和度(Saturation)分量值,取值范围 [0, 100]
  3780. * @param {number} l 亮度(Lighteness)分量值,取值范围 [0, 100]
  3781. */
  3782. createHSL: function(h, s, l) {
  3783. return Color.createHSLA(h, s, l, 1);
  3784. },
  3785. /**
  3786. * @method createHSLA()
  3787. * @for kity.Color
  3788. * @static
  3789. *
  3790. * @description 创建一个 HSLA 颜色
  3791. *
  3792. * @grammar kity.Color.createHSLA(h, s, l, a) => {kity.Color}
  3793. *
  3794. * @param {number} h 色环(Hue)分量值,取值范围 [0, 359]
  3795. * @param {number} s 饱和度(Saturation)分量值,取值范围 [0, 100]
  3796. * @param {number} l 亮度(Lighteness)分量值,取值范围 [0, 100]
  3797. * @param {number} a 透明度(Alpha)分量值,取值范围 [0, 1]
  3798. */
  3799. createHSLA: function(h, s, l, a) {
  3800. var colorValue = null;
  3801. s += "%";
  3802. l += "%";
  3803. colorValue = [ "hsla(" + h, s, l, a + ")" ];
  3804. return Color.parse(colorValue.join(", "));
  3805. },
  3806. /**
  3807. * @method createRGB()
  3808. * @for kity.Color
  3809. * @static
  3810. *
  3811. * @description 创建一个 RGB 颜色
  3812. *
  3813. * @grammar kity.Color.createRGB(r, g, b) => {kity.Color}
  3814. *
  3815. * @param {number} r 红色(Red)分量值,取值范围 [0, 255]
  3816. * @param {number} g 绿色(Green)分量值,取值范围 [0, 255]
  3817. * @param {number} b 蓝色(Blue)分量值,取值范围 [0, 255]
  3818. */
  3819. createRGB: function(r, g, b) {
  3820. return Color.createRGBA(r, g, b, 1);
  3821. },
  3822. /**
  3823. * @method createRGBA()
  3824. * @for kity.Color
  3825. * @static
  3826. *
  3827. * @description 创建一个 RGBA 颜色
  3828. *
  3829. * @grammar kity.Color.createRGBA(r, g, b, a) => {kity.Color}
  3830. *
  3831. * @param {number} r 红色(Red)分量值,取值范围 [0, 255]
  3832. * @param {number} g 绿色(Green)分量值,取值范围 [0, 255]
  3833. * @param {number} b 蓝色(Blue)分量值,取值范围 [0, 255]
  3834. * @param {number} a 透明度(Alpha)分量值,取值范围 [0, 1]
  3835. */
  3836. createRGBA: function(r, g, b, a) {
  3837. return new Color(r, g, b, a);
  3838. }
  3839. });
  3840. //内部工具对象
  3841. Utils.extend(ColorUtils, {
  3842. parseToValue: function(valStr) {
  3843. var rgbaValue = {};
  3844. /* 优先检测在调色板中是否有对应的颜色 */
  3845. valStr = StandardColor.EXTEND_STANDARD[valStr] || StandardColor.COLOR_STANDARD[valStr] || valStr;
  3846. /* 颜色转换 */
  3847. //hex格式
  3848. if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(valStr)) {
  3849. rgbaValue = ColorUtils.hexToValue(valStr);
  3850. } else if (/^(rgba?)/i.test(valStr)) {
  3851. rgbaValue = ColorUtils.rgbaToValue(valStr);
  3852. } else if (/^(hsla?)/i.test(valStr)) {
  3853. rgbaValue = ColorUtils.hslaToValue(valStr);
  3854. } else {
  3855. return null;
  3856. }
  3857. return ColorUtils.overflowFormat(rgbaValue);
  3858. },
  3859. hexToValue: function(hexStr) {
  3860. var result = {}, keys = [ "r", "g", "b" ];
  3861. if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(hexStr)) {
  3862. hexStr = RegExp.$1.split("");
  3863. Utils.each(keys, function(key, index) {
  3864. if (hexStr.length === 3) {
  3865. result[key] = ColorUtils.toNumber(hexStr[index] + hexStr[index]);
  3866. } else {
  3867. result[key] = ColorUtils.toNumber(hexStr[index * 2] + hexStr[index * 2 + 1]);
  3868. }
  3869. });
  3870. //转换出hsl值
  3871. result = Utils.extend(result, ColorUtils.rgbValueToHslValue(result));
  3872. result.a = 1;
  3873. return result;
  3874. }
  3875. return null;
  3876. },
  3877. rgbaToValue: function(rgbaStr) {
  3878. var result = {}, hasAlpha = false, keys = [ "r", "g", "b" ];
  3879. if (/^(rgba?)/i.test(rgbaStr)) {
  3880. hasAlpha = RegExp.$1.length === 4;
  3881. rgbaStr = rgbaStr.replace(/^rgba?/i, "").replace(/\s+/g, "").replace(/[^0-9,.]/g, "").split(",");
  3882. Utils.each(keys, function(key, index) {
  3883. result[key] = rgbaStr[index] | 0;
  3884. });
  3885. //转换出hsl值
  3886. result = Utils.extend(result, ColorUtils.rgbValueToHslValue(result));
  3887. result.a = hasAlpha ? parseFloat(rgbaStr[3]) : 1;
  3888. return result;
  3889. }
  3890. return null;
  3891. },
  3892. hslaToValue: function(hslaStr) {
  3893. var result = {}, hasAlpha = false;
  3894. if (/^(hsla?)/i.test(hslaStr)) {
  3895. hasAlpha = RegExp.$1.length === 4;
  3896. hslaStr = hslaStr.replace(/^hsla?/i, "").replace(/\s+/g, "").replace(/[^0-9,.]/g, "").split(",");
  3897. //记录hsl值
  3898. result.h = hslaStr[0] | 0;
  3899. result.s = hslaStr[1] | 0;
  3900. result.l = hslaStr[2] | 0;
  3901. //转换出rgb值
  3902. result = Utils.extend(result, ColorUtils.hslValueToRGBValue(result));
  3903. //hsl值转换为rgb值
  3904. result = ColorUtils.hslValueToRGBValue(result);
  3905. result.a = hasAlpha ? parseFloat(hslaStr[3]) : 1;
  3906. return result;
  3907. }
  3908. return null;
  3909. },
  3910. //hsl值对象转换为rgb值对象
  3911. hslValueToRGBValue: function(hslValue) {
  3912. function trans(v1, v2, vH) {
  3913. if (vH < 0) {
  3914. vH += 1;
  3915. } else if (vH > 1) {
  3916. vH -= 1;
  3917. }
  3918. if (6 * vH < 1) {
  3919. return v1 + (v2 - v1) * 6 * vH;
  3920. } else if (2 * vH < 1) {
  3921. return v2;
  3922. } else if (3 * vH < 2) {
  3923. return v1 + (v2 - v1) * ((2 / 3 - vH) * 6);
  3924. }
  3925. return v1;
  3926. }
  3927. var q = null, p = null, result = {};
  3928. hslValue = Utils.extend({}, hslValue);
  3929. hslValue.h = hslValue.h / 360;
  3930. hslValue.s = hslValue.s / 100;
  3931. hslValue.l = hslValue.l / 100;
  3932. //分量计算
  3933. if (hslValue.s === 0) {
  3934. result.r = result.g = result.b = hslValue.l;
  3935. } else {
  3936. if (hslValue.l < .5) {
  3937. q = hslValue.l * (1 + hslValue.s);
  3938. } else {
  3939. q = hslValue.l + hslValue.s - hslValue.l * hslValue.s;
  3940. }
  3941. p = 2 * hslValue.l - q;
  3942. result.r = trans(p, q, hslValue.h + 1 / 3);
  3943. result.g = trans(p, q, hslValue.h);
  3944. result.b = trans(p, q, hslValue.h - 1 / 3);
  3945. }
  3946. result.r = Math.min(Math.round(result.r * 255), 255);
  3947. result.g = Math.min(Math.round(result.g * 255), 255);
  3948. result.b = Math.min(Math.round(result.b * 255), 255);
  3949. return result;
  3950. },
  3951. //rgb值对象转换为hsl值对象
  3952. rgbValueToHslValue: function(rgbValue) {
  3953. var max = null, min = null, result = {};
  3954. rgbValue = Utils.extend({}, rgbValue);
  3955. rgbValue.r = rgbValue.r / 255;
  3956. rgbValue.g = rgbValue.g / 255;
  3957. rgbValue.b = rgbValue.b / 255;
  3958. max = Math.max(rgbValue.r, rgbValue.g, rgbValue.b);
  3959. min = Math.min(rgbValue.r, rgbValue.g, rgbValue.b);
  3960. //h分量计算
  3961. if (max === min) {
  3962. result.h = 0;
  3963. } else if (max === rgbValue.r) {
  3964. if (rgbValue.g >= rgbValue.b) {
  3965. result.h = 60 * (rgbValue.g - rgbValue.b) / (max - min);
  3966. } else {
  3967. result.h = 60 * (rgbValue.g - rgbValue.b) / (max - min) + 360;
  3968. }
  3969. } else if (max === rgbValue.g) {
  3970. result.h = 60 * (rgbValue.b - rgbValue.r) / (max - min) + 120;
  3971. } else if (max === rgbValue.b) {
  3972. result.h = 60 * (rgbValue.r - rgbValue.g) / (max - min) + 240;
  3973. }
  3974. //l分量计算
  3975. result.l = (max + min) / 2;
  3976. //s分量计算
  3977. if (result.l === 0 || max === min) {
  3978. result.s = 0;
  3979. } else if (result.l > 0 && result.l <= .5) {
  3980. result.s = (max - min) / (max + min);
  3981. } else {
  3982. result.s = (max - min) / (2 - max - min);
  3983. }
  3984. //格式化hsl结果
  3985. result.h = Math.round(result.h);
  3986. result.s = Math.round(result.s * 100);
  3987. result.l = Math.round(result.l * 100);
  3988. return result;
  3989. },
  3990. toString: function(colorValue, type) {
  3991. var vals = [];
  3992. colorValue = Utils.extend({}, colorValue);
  3993. if (type.indexOf("hsl") !== -1) {
  3994. colorValue.s += "%";
  3995. colorValue.l += "%";
  3996. }
  3997. if (type !== "hex") {
  3998. Utils.each(type.split(""), function(key) {
  3999. vals.push(colorValue[key]);
  4000. });
  4001. return (type + "(" + vals.join(", ") + ")").toLowerCase();
  4002. } else {
  4003. vals.push(ColorUtils.toHexValue(+colorValue.r));
  4004. vals.push(ColorUtils.toHexValue(+colorValue.g));
  4005. vals.push(ColorUtils.toHexValue(+colorValue.b));
  4006. return ("#" + vals.join("")).toLowerCase();
  4007. }
  4008. },
  4009. //16进制的2个数字转化为10进制, 如果转化失败, 返回0
  4010. toNumber: function(value) {
  4011. return Number("0x" + value) | 0;
  4012. },
  4013. toHexValue: function(value) {
  4014. var result = value.toString(16);
  4015. return result.length === 1 ? "0" + result : result;
  4016. },
  4017. //溢出控制
  4018. overflowFormat: function(value) {
  4019. var tmpValue = Utils.extend({}, value), keys = "rgba";
  4020. Utils.each(keys.split(""), function(key) {
  4021. if (!tmpValue.hasOwnProperty(key)) {
  4022. return;
  4023. }
  4024. //上溢出
  4025. tmpValue[key] = Math.min(Color._MAX_VALUE[key], tmpValue[key]);
  4026. //下溢出
  4027. tmpValue[key] = Math.max(Color._MIN_VALUE[key], tmpValue[key]);
  4028. });
  4029. return tmpValue;
  4030. }
  4031. });
  4032. return Color;
  4033. }
  4034. };
  4035. //src/graphic/container.js
  4036. _p[29] = {
  4037. value: function(require, exports, module) {
  4038. function itemRemove() {
  4039. this.container.removeItem(this);
  4040. return this;
  4041. }
  4042. return _p.r(11).createClass("Container", {
  4043. getItems: function() {
  4044. return this.items || (this.items = []);
  4045. },
  4046. getItem: function(index) {
  4047. return this.getItems()[index];
  4048. },
  4049. getFirstItem: function() {
  4050. return this.getItem(0);
  4051. },
  4052. getLastItem: function() {
  4053. return this.getItem(this.getItems().length - 1);
  4054. },
  4055. indexOf: function(item) {
  4056. return this.getItems().indexOf(item);
  4057. },
  4058. eachItem: function(fn) {
  4059. var items = this.getItems(), length = items.length, i;
  4060. for (i = 0; i < length; i++) {
  4061. fn.call(this, i, items[i]);
  4062. }
  4063. return this;
  4064. },
  4065. addItem: function(item, pos, noEvent) {
  4066. var items = this.getItems(), length = items.length;
  4067. if (~items.indexOf(item)) {
  4068. return this;
  4069. }
  4070. if (!(pos >= 0 && pos < length)) {
  4071. pos = length;
  4072. }
  4073. items.splice(pos, 0, item);
  4074. if (typeof item === "object") {
  4075. item.container = this;
  4076. item.remove = itemRemove;
  4077. }
  4078. this.handleAdd(item, pos);
  4079. if (!noEvent) {
  4080. this.onContainerChanged("add", [ item ]);
  4081. }
  4082. return this;
  4083. },
  4084. addItems: function(items) {
  4085. for (var i = 0, l = items.length; i < l; i++) {
  4086. this.addItem(items[i], -1, true);
  4087. }
  4088. this.onContainerChanged("add", items);
  4089. return this;
  4090. },
  4091. setItems: function(items) {
  4092. return this.clear().addItems(items);
  4093. },
  4094. appendItem: function(item) {
  4095. return this.addItem(item);
  4096. },
  4097. prependItem: function(item) {
  4098. return this.addItem(item, 0);
  4099. },
  4100. removeItem: function(pos, noEvent) {
  4101. if (typeof pos !== "number") {
  4102. return this.removeItem(this.indexOf(pos));
  4103. }
  4104. var items = this.getItems(), length = items.length, item = items[pos];
  4105. if (item === undefined) {
  4106. return this;
  4107. }
  4108. items.splice(pos, 1);
  4109. if (item.container) {
  4110. delete item.container;
  4111. }
  4112. if (item.remove) {
  4113. delete item.remove;
  4114. }
  4115. this.handleRemove(item, pos);
  4116. if (!noEvent) {
  4117. this.onContainerChanged("remove", [ item ]);
  4118. }
  4119. return this;
  4120. },
  4121. clear: function() {
  4122. var removed = [];
  4123. var item;
  4124. while (item = this.getFirstItem()) {
  4125. removed.push(item);
  4126. this.removeItem(0, true);
  4127. }
  4128. this.onContainerChanged("remove", removed);
  4129. return this;
  4130. },
  4131. onContainerChanged: function(type, items) {},
  4132. handleAdd: function(item, index) {},
  4133. handleRemove: function(item, index) {}
  4134. });
  4135. }
  4136. };
  4137. //src/graphic/curve.js
  4138. /*
  4139. * 曲线
  4140. * */
  4141. _p[30] = {
  4142. value: function(require, exports, module) {
  4143. var Utils = _p.r(12), CurveUtil = {
  4144. /*
  4145. * 获取由两个以上的点组成的曲线的平移线
  4146. * @param points 曲线上的点的集合, 集合中的点的数量必须大于2
  4147. * @return 平移线数组
  4148. */
  4149. getCurvePanLines: function(points, smoothFactor) {
  4150. //计算原始点的中点坐标
  4151. var centerPoints = CurveUtil.getCenterPoints(points), //注意:计算中点连线的中点坐标, 得出平移线
  4152. panLines = CurveUtil.getPanLine(points.length, centerPoints);
  4153. //平移线移动到顶点
  4154. return CurveUtil.getMovedPanLines(points, panLines, smoothFactor);
  4155. },
  4156. /*
  4157. * 计算给定点集合的连线的中点
  4158. * @param points
  4159. */
  4160. getCenterPoints: function(points) {
  4161. var centerPoints = {}, key = null;
  4162. for (var i = 0, j = 0, len = points.length; i < len; i++) {
  4163. //j是下一个点的索引
  4164. j = i === len - 1 ? 0 : i + 1;
  4165. key = i + "," + j;
  4166. //计算中点坐标
  4167. centerPoints[key] = {
  4168. x: (points[i].x + points[j].y) / 2,
  4169. y: (points[i].x + points[j].y) / 2
  4170. };
  4171. }
  4172. return centerPoints;
  4173. },
  4174. /*
  4175. * 对getCenterPoints()接口获取到的数据做处理, 计算出各个顶点对应的平移线数据
  4176. * @param length 集合中点的个数
  4177. * @param points 点集合, 该集合应该是getCenterPoints()接口返回的数据
  4178. */
  4179. getPanLine: function(length, points) {
  4180. var result = {}, //顶点索引
  4181. pointIndex = null;
  4182. for (var i = 0, j; i < length; i++) {
  4183. var point1 = null, point2 = null;
  4184. //计算当前点
  4185. j = (i + 1) % length;
  4186. //保存当前处理的顶点索引
  4187. pointIndex = j;
  4188. point1 = points[i + "," + j];
  4189. //计算下一个点
  4190. i = j;
  4191. j = (i + 1) % length;
  4192. point2 = points[i + "," + j];
  4193. result[pointIndex] = {
  4194. points: [ {
  4195. x: point1.x,
  4196. y: point1.y
  4197. }, {
  4198. x: point2.x,
  4199. y: point2.y
  4200. } ],
  4201. center: {
  4202. x: (point1.x + point2.x) / 2,
  4203. y: (point1.y + point2.y) / 2
  4204. }
  4205. };
  4206. //还原i值
  4207. i = (pointIndex + length - 1) % length;
  4208. }
  4209. return result;
  4210. },
  4211. /*
  4212. * 计算平移线移动到顶点后的位置
  4213. * @param points 顶点集合
  4214. * @param panLines 平移线集合
  4215. */
  4216. getMovedPanLines: function(points, panLines, smoothFactor) {
  4217. var result = {};
  4218. Utils.each(points, function(point, index) {
  4219. //当前平移线
  4220. var currentPanLine = panLines[index], //平移线中点
  4221. center = currentPanLine.center, //移动距离
  4222. distance = {
  4223. x: center.x - point.x,
  4224. y: center.y - point.y
  4225. };
  4226. var currentResult = result[index] = {
  4227. points: [],
  4228. center: {
  4229. x: point.x,
  4230. y: point.y
  4231. }
  4232. };
  4233. //计算控制点到顶点的距离, 并且应用平滑系数到距离上
  4234. Utils.each(currentPanLine.points, function(controlPoint, index) {
  4235. var moved = {
  4236. x: controlPoint.x - distance.x,
  4237. y: controlPoint.y - distance.y
  4238. };
  4239. var vertex = currentResult.center;
  4240. var dx = moved.x - vertex.x;
  4241. var dy = moved.y - vertex.y;
  4242. moved.x = vertex.x + smoothFactor * dx;
  4243. moved.y = vertex.y + smoothFactor * dy;
  4244. currentResult.points.push(moved);
  4245. });
  4246. });
  4247. return result;
  4248. }
  4249. };
  4250. return _p.r(11).createClass("Curve", {
  4251. base: _p.r(46),
  4252. mixins: [ _p.r(51) ],
  4253. constructor: function(points, isColse) {
  4254. this.callBase();
  4255. this.setPoints(points || []);
  4256. this.closeState = !!isColse;
  4257. this.changeable = true;
  4258. this.smoothFactor = 1;
  4259. this.update();
  4260. },
  4261. //当点集合发生变化时采取的动作
  4262. onContainerChanged: function() {
  4263. if (this.changeable) {
  4264. this.update();
  4265. }
  4266. },
  4267. setSmoothFactor: function(factor) {
  4268. this.smoothFactor = factor < 0 ? 0 : factor;
  4269. this.update();
  4270. return this;
  4271. },
  4272. getSmoothFactor: function() {
  4273. return this.smoothFactor;
  4274. },
  4275. update: function() {
  4276. var points = this.getPoints(), withControlPoints = null, drawer = this.getDrawer(), curPoint = null, curControlPoint = null, prevControlPoint = null;
  4277. drawer.clear();
  4278. if (points.length === 0) {
  4279. return this;
  4280. } else {
  4281. drawer.moveTo(points[0]);
  4282. }
  4283. if (points.length === 1) {
  4284. return this;
  4285. }
  4286. if (points.length === 2) {
  4287. drawer.lineTo(points[1]);
  4288. return this;
  4289. }
  4290. //获取已转换过后的带控制点的所有点
  4291. withControlPoints = CurveUtil.getCurvePanLines(points, this.getSmoothFactor());
  4292. for (var i = 1, len = points.length; i < len; i++) {
  4293. //当前顶点
  4294. curPoint = withControlPoints[i].center;
  4295. //当前控制点
  4296. if (this.closeState || i != len - 1) {
  4297. curControlPoint = withControlPoints[i].points[0];
  4298. } else {
  4299. //非闭合状态下最后一个点的处理
  4300. curControlPoint = withControlPoints[i].center;
  4301. }
  4302. if (this.closeState || i != 1) {
  4303. prevControlPoint = withControlPoints[i - 1].points[1];
  4304. } else {
  4305. //非闭合状态下第一个点的处理
  4306. prevControlPoint = withControlPoints[i - 1].center;
  4307. }
  4308. drawer.bezierTo(prevControlPoint.x, prevControlPoint.y, curControlPoint.x, curControlPoint.y, curPoint.x, curPoint.y);
  4309. }
  4310. //处理闭合
  4311. if (this.closeState) {
  4312. curPoint = withControlPoints[0].center;
  4313. curControlPoint = withControlPoints[0].points[0];
  4314. prevControlPoint = withControlPoints[points.length - 1].points[1];
  4315. drawer.bezierTo(prevControlPoint.x, prevControlPoint.y, curControlPoint.x, curControlPoint.y, curPoint.x, curPoint.y);
  4316. }
  4317. return this;
  4318. },
  4319. close: function() {
  4320. this.closeState = true;
  4321. return this.update();
  4322. },
  4323. open: function() {
  4324. this.closeState = false;
  4325. return this.update();
  4326. },
  4327. isClose: function() {
  4328. return !!this.closeState;
  4329. }
  4330. });
  4331. }
  4332. };
  4333. //src/graphic/data.js
  4334. _p[31] = {
  4335. value: function(require, exports, module) {
  4336. return _p.r(11).createClass("Data", {
  4337. constructor: function() {
  4338. this._data = {};
  4339. },
  4340. setData: function(name, value) {
  4341. this._data[name] = value;
  4342. return this;
  4343. },
  4344. getData: function(name) {
  4345. return this._data[name];
  4346. },
  4347. removeData: function(name) {
  4348. delete this._data[name];
  4349. return this;
  4350. }
  4351. });
  4352. }
  4353. };
  4354. //src/graphic/ellipse.js
  4355. _p[32] = {
  4356. value: function(require, exports, module) {
  4357. var Utils = _p.r(12), Point = _p.r(50);
  4358. return _p.r(11).createClass("Ellipse", {
  4359. base: _p.r(46),
  4360. constructor: function(rx, ry, cx, cy) {
  4361. this.callBase();
  4362. this.rx = rx || 0;
  4363. this.ry = ry || 0;
  4364. this.cx = cx || 0;
  4365. this.cy = cy || 0;
  4366. this.update();
  4367. },
  4368. update: function() {
  4369. var rx = this.rx, ry = this.ry, x1 = this.cx + rx, x2 = this.cx - rx, y = this.cy;
  4370. var drawer = this.getDrawer();
  4371. drawer.clear();
  4372. drawer.moveTo(x1, y);
  4373. drawer.arcTo(rx, ry, 0, 1, 1, x2, y);
  4374. drawer.arcTo(rx, ry, 0, 1, 1, x1, y);
  4375. return this;
  4376. },
  4377. getRadius: function() {
  4378. return {
  4379. x: this.rx,
  4380. y: this.ry
  4381. };
  4382. },
  4383. getRadiusX: function() {
  4384. return this.rx;
  4385. },
  4386. getRadiusY: function() {
  4387. return this.ry;
  4388. },
  4389. getCenter: function() {
  4390. return new Point(this.cx, this.cy);
  4391. },
  4392. getCenterX: function() {
  4393. return this.cx;
  4394. },
  4395. getCenterY: function() {
  4396. return this.cy;
  4397. },
  4398. setRadius: function(rx, ry) {
  4399. this.rx = rx;
  4400. this.ry = ry;
  4401. return this.update();
  4402. },
  4403. setRadiusX: function(rx) {
  4404. this.rx = rx;
  4405. return this.update();
  4406. },
  4407. setRadiusY: function(ry) {
  4408. this.ry = ry;
  4409. return this.update();
  4410. },
  4411. setCenter: function(cx, cy) {
  4412. if (arguments.length == 1) {
  4413. var p = Point.parse(arguments[0]);
  4414. cx = p.x;
  4415. cy = p.y;
  4416. }
  4417. this.cx = cx;
  4418. this.cy = cy;
  4419. return this.update();
  4420. },
  4421. setCenterX: function(cx) {
  4422. this.cx = cx;
  4423. return this.update();
  4424. },
  4425. setCenterY: function(cy) {
  4426. this.cy = cy;
  4427. return this.update();
  4428. }
  4429. });
  4430. }
  4431. };
  4432. //src/graphic/eventhandler.js
  4433. /*
  4434. * kity event 实现
  4435. */
  4436. _p[33] = {
  4437. value: function(require, exports, module) {
  4438. // polyfill
  4439. (function() {
  4440. function CustomEvent(event, params) {
  4441. params = params || {
  4442. bubbles: false,
  4443. cancelable: false,
  4444. detail: undefined
  4445. };
  4446. var evt = document.createEvent("CustomEvent");
  4447. evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
  4448. return evt;
  4449. }
  4450. CustomEvent.prototype = window.Event.prototype;
  4451. window.CustomEvent = CustomEvent;
  4452. })();
  4453. var Utils = _p.r(12), ShapeEvent = _p.r(62);
  4454. // 内部处理器缓存
  4455. var INNER_HANDLER_CACHE = {}, // 用户处理器缓存
  4456. USER_HANDLER_CACHE = {}, guid = 0;
  4457. // 添加事件统一入口
  4458. function _addEvent(type, handler, isOnce) {
  4459. isOnce = !!isOnce;
  4460. if (Utils.isString(type)) {
  4461. type = type.match(/\S+/g);
  4462. }
  4463. Utils.each(type, function(currentType) {
  4464. listen.call(this, this.node, currentType, handler, isOnce);
  4465. }, this);
  4466. return this;
  4467. }
  4468. // 移除事件统一入口
  4469. function _removeEvent(type, handler) {
  4470. var userHandlerList = null, eventId = this._EVNET_UID, isRemoveAll = handler === undefined;
  4471. userHandlerList = USER_HANDLER_CACHE[eventId][type];
  4472. //移除指定的监听器
  4473. if (!isRemoveAll) {
  4474. isRemoveAll = true;
  4475. Utils.each(userHandlerList, function removeKityEvent(fn, index) {
  4476. if (fn === handler) {
  4477. // 不能结束, 需要查找完整个list, 避免丢失移除多次绑定同一个处理器的情况
  4478. delete userHandlerList[index];
  4479. } else {
  4480. isRemoveAll = false;
  4481. }
  4482. });
  4483. }
  4484. //删除所有监听器
  4485. if (isRemoveAll) {
  4486. deleteDomEvent(this.node, type, INNER_HANDLER_CACHE[eventId][type]);
  4487. delete USER_HANDLER_CACHE[eventId][type];
  4488. delete INNER_HANDLER_CACHE[eventId][type];
  4489. }
  4490. return this;
  4491. }
  4492. // 执行绑定, 该方法context为shape或者mixin了eventhandler的对象
  4493. function listen(node, type, handler, isOnce) {
  4494. var eid = this._EVNET_UID, targetObject = this;
  4495. // 初始化内部监听器
  4496. if (!INNER_HANDLER_CACHE[eid]) {
  4497. INNER_HANDLER_CACHE[eid] = {};
  4498. }
  4499. if (!INNER_HANDLER_CACHE[eid][type]) {
  4500. // 内部监听器
  4501. INNER_HANDLER_CACHE[eid][type] = function kityEventHandler(e) {
  4502. e = new ShapeEvent(e || window.event);
  4503. Utils.each(USER_HANDLER_CACHE[eid][type], function executeKityEvent(fn) {
  4504. var result;
  4505. if (fn) {
  4506. result = fn.call(targetObject, e);
  4507. //once 绑定, 执行完后删除
  4508. if (isOnce) {
  4509. targetObject.off(type, fn);
  4510. }
  4511. }
  4512. // 如果用户handler里return了false, 则该节点上的此后的同类型事件将不再执行
  4513. return result;
  4514. }, targetObject);
  4515. };
  4516. }
  4517. // 初始化用户监听器列表
  4518. if (!USER_HANDLER_CACHE[eid]) {
  4519. USER_HANDLER_CACHE[eid] = {};
  4520. }
  4521. if (!USER_HANDLER_CACHE[eid][type]) {
  4522. USER_HANDLER_CACHE[eid][type] = [ handler ];
  4523. // 绑定对应类型的事件
  4524. // dom对象利用dom event进行处理, 非dom对象, 由消息分发机制处理
  4525. if (!!node && "on" + type in node) {
  4526. bindDomEvent(node, type, INNER_HANDLER_CACHE[eid][type]);
  4527. }
  4528. } else {
  4529. USER_HANDLER_CACHE[eid][type].push(handler);
  4530. }
  4531. }
  4532. // 绑定dom事件
  4533. function bindDomEvent(node, type, handler) {
  4534. if (node.addEventListener) {
  4535. node.addEventListener(type, handler, false);
  4536. } else {
  4537. node.attachEvent("on" + type, handler);
  4538. }
  4539. }
  4540. // 删除dom事件
  4541. function deleteDomEvent(node, type, handler) {
  4542. if (node.removeEventListener) {
  4543. node.removeEventListener(type, handler, false);
  4544. } else {
  4545. node.detachEvent(type, handler);
  4546. }
  4547. }
  4548. // 触发dom事件
  4549. function triggerDomEvent(node, type, params) {
  4550. var event = new CustomEvent(type, {
  4551. bubbles: true,
  4552. cancelable: true
  4553. });
  4554. event._kityParam = params;
  4555. node.dispatchEvent(event);
  4556. }
  4557. // 发送消息
  4558. function sendMessage(messageObj, type, msg) {
  4559. var event = null, handler = null;
  4560. var handlers = INNER_HANDLER_CACHE[messageObj._EVNET_UID];
  4561. if (!handlers) return;
  4562. handler = handlers[type];
  4563. if (!handler) {
  4564. return;
  4565. }
  4566. event = Utils.extend({
  4567. type: type,
  4568. target: messageObj
  4569. }, msg || {});
  4570. handler.call(messageObj, event);
  4571. }
  4572. // 对外接口
  4573. return _p.r(11).createClass("EventHandler", {
  4574. constructor: function() {
  4575. this._EVNET_UID = ++guid;
  4576. },
  4577. addEventListener: function(type, handler) {
  4578. return _addEvent.call(this, type, handler, false);
  4579. },
  4580. addOnceEventListener: function(type, handler) {
  4581. return _addEvent.call(this, type, handler, true);
  4582. },
  4583. removeEventListener: function(type, handler) {
  4584. return _removeEvent.call(this, type, handler);
  4585. },
  4586. on: function(type, handler) {
  4587. return this.addEventListener.apply(this, arguments);
  4588. },
  4589. once: function(type, handler) {
  4590. return this.addOnceEventListener.apply(this, arguments);
  4591. },
  4592. off: function() {
  4593. return this.removeEventListener.apply(this, arguments);
  4594. },
  4595. fire: function(type, params) {
  4596. return this.trigger.apply(this, arguments);
  4597. },
  4598. trigger: function(type, params) {
  4599. sendMessage(this, type, params);
  4600. return this;
  4601. }
  4602. });
  4603. }
  4604. };
  4605. //src/graphic/geometry.js
  4606. _p[34] = {
  4607. value: function(require) {
  4608. var utils = _p.r(12);
  4609. var Point = _p.r(50);
  4610. var Vector = _p.r(73);
  4611. var Matrix = _p.r(43);
  4612. var g = {};
  4613. var pathCommand = /([achlmrqstvz])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?\s*)+)/gi, pathValues = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)\s*,?\s*/gi, paramCounts = {
  4614. a: 7,
  4615. c: 6,
  4616. h: 1,
  4617. l: 2,
  4618. m: 2,
  4619. q: 4,
  4620. s: 4,
  4621. t: 2,
  4622. v: 1,
  4623. z: 0
  4624. };
  4625. function pathClone(path) {
  4626. var result, i, j, segment, segmentCopy;
  4627. result = [];
  4628. for (i = 0; i < path.length; i++) {
  4629. segment = path[i];
  4630. result.push(segmentCopy = []);
  4631. for (j = 0; j < segment.length; j++) {
  4632. segmentCopy.push(segment[j]);
  4633. }
  4634. }
  4635. if (path.isUniform) result.isUniform = true;
  4636. if (path.isAbsolute) result.isAbsolute = true;
  4637. if (path.isCurve) result.isCurve = true;
  4638. return result;
  4639. }
  4640. // 缓存函数
  4641. // from raphael.js
  4642. function cacher(f, scope, postprocessor) {
  4643. function repush(array, item) {
  4644. for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) {
  4645. return array.push(array.splice(i, 1)[0]);
  4646. }
  4647. }
  4648. function newf() {
  4649. var arg = Array.prototype.slice.call(arguments, 0), args = arg.join("␀"), cache = newf.cache = newf.cache || {}, count = newf.count = newf.count || [];
  4650. if (cache.hasOwnProperty(args)) {
  4651. repush(count, args);
  4652. return postprocessor ? postprocessor(cache[args]) : cache[args];
  4653. }
  4654. if (count.length >= 1e3) {
  4655. delete cache[count.shift()];
  4656. }
  4657. count.push(args);
  4658. cache[args] = f.apply(scope, arg);
  4659. return postprocessor ? postprocessor(cache[args]) : cache[args];
  4660. }
  4661. return newf;
  4662. }
  4663. /**
  4664. *
  4665. * kity.g.pathToString(pathSegment)
  4666. *
  4667. * 返回表示 PathSegment 的字符串
  4668. *
  4669. * @param {Array} pathSegment
  4670. * 要表示的 Path Segment
  4671. *
  4672. * @return {String} 表示该 Path 的字符串
  4673. *
  4674. * @example
  4675. *
  4676. * var pathSegment = [['M', 0, 0], ['L', 10, 10]]
  4677. * var pathString = kity.g.pathToString(pathSegment);
  4678. * // 返回 'M0,0L10,10'
  4679. */
  4680. g.pathToString = function(pathSegment) {
  4681. pathSegment = pathSegment || this;
  4682. if (typeof pathSegment == "string") return pathSegment;
  4683. if (pathSegment instanceof Array) {
  4684. pathSegment = utils.flatten(pathSegment);
  4685. return pathSegment.join(",").replace(/,?([achlmqrstvxz]),?/gi, "$1");
  4686. }
  4687. };
  4688. /**
  4689. * kity.g.parsePathString(pathString)
  4690. *
  4691. * 解析 Path 字符串成 PathSegment
  4692. *
  4693. * @copyright rapheal.js
  4694. *
  4695. * @example
  4696. *
  4697. * var seg = kity.g.parsePathString('M10,12l21-23-21.5,11z');
  4698. * // 返回: [['M', 10, 12], ['l', 21, -23], ['l', -21.5, 11], ['z']]
  4699. *
  4700. * @param {String} pathString Path 字符串
  4701. * @return {Array}
  4702. */
  4703. g.parsePathString = cacher(function(pathString) {
  4704. var data = [];
  4705. pathString.replace(pathCommand, function(a, b, c) {
  4706. var params = [], name = b.toLowerCase();
  4707. c.replace(pathValues, function(a, b) {
  4708. if (b) params.push(+b);
  4709. });
  4710. if (name == "m" && params.length > 2) {
  4711. data.push([ b ].concat(params.splice(0, 2)));
  4712. name = "l";
  4713. b = b == "m" ? "l" : "L";
  4714. }
  4715. if (name == "r") {
  4716. data.push([ b ].concat(params));
  4717. } else {
  4718. while (params.length >= paramCounts[name]) {
  4719. data.push([ b ].concat(params.splice(0, paramCounts[name])));
  4720. if (!paramCounts[name]) {
  4721. break;
  4722. }
  4723. }
  4724. }
  4725. });
  4726. data.isUniform = true;
  4727. data.toString = g.pathToString;
  4728. return data;
  4729. });
  4730. /**
  4731. * kity.g.pathToAbsolute(path)
  4732. *
  4733. * 把路径转换为绝对路径的形式
  4734. *
  4735. * @param {Array|String} path
  4736. * 要转换的 path 路径或者数组
  4737. *
  4738. * @return {Array}
  4739. * 转换后的 Path Segment
  4740. *
  4741. * @example
  4742. *
  4743. * var path = 'M10,10l50,50';
  4744. * var absPath = kity.g.pathToAbsolute(path);
  4745. * // 返回 [['M', 10, 10], ['L', 60, 60]]
  4746. */
  4747. g.pathToAbsolute = cacher(function(path) {
  4748. var pathArray = path.isUniform ? path : g.parsePathString(g.pathToString(path));
  4749. var res = [], x = 0, y = 0, mx = 0, my = 0, start = 0;
  4750. var r, pa, i, j, k, ii, jj, kk;
  4751. if (pathArray[0][0] == "M") {
  4752. x = +pathArray[0][1];
  4753. y = +pathArray[0][2];
  4754. mx = x;
  4755. my = y;
  4756. start++;
  4757. res[0] = [ "M", x, y ];
  4758. }
  4759. for (r, pa, i = start, ii = pathArray.length; i < ii; i++) {
  4760. res.push(r = []);
  4761. pa = pathArray[i];
  4762. if (pa[0] != pa[0].toUpperCase()) {
  4763. r[0] = pa[0].toUpperCase();
  4764. switch (r[0]) {
  4765. case "A":
  4766. r[1] = pa[1];
  4767. r[2] = pa[2];
  4768. r[3] = pa[3];
  4769. r[4] = pa[4];
  4770. r[5] = pa[5];
  4771. r[6] = +(pa[6] + x);
  4772. r[7] = +(pa[7] + y);
  4773. break;
  4774. case "V":
  4775. r[1] = +pa[1] + y;
  4776. break;
  4777. case "H":
  4778. r[1] = +pa[1] + x;
  4779. break;
  4780. case "M":
  4781. mx = +pa[1] + x;
  4782. my = +pa[2] + y;
  4783. break;
  4784. default:
  4785. for (j = 1, jj = pa.length; j < jj; j++) {
  4786. r[j] = +pa[j] + (j % 2 ? x : y);
  4787. }
  4788. }
  4789. } else {
  4790. for (k = 0, kk = pa.length; k < kk; k++) {
  4791. r[k] = pa[k];
  4792. }
  4793. }
  4794. switch (r[0]) {
  4795. case "Z":
  4796. x = mx;
  4797. y = my;
  4798. break;
  4799. case "H":
  4800. x = r[1];
  4801. break;
  4802. case "V":
  4803. y = r[1];
  4804. break;
  4805. case "M":
  4806. mx = r[r.length - 2];
  4807. my = r[r.length - 1];
  4808. break;
  4809. default:
  4810. x = r[r.length - 2];
  4811. y = r[r.length - 1];
  4812. }
  4813. }
  4814. res.isUniform = true;
  4815. res.isAbsolute = true;
  4816. res.toString = g.pathToString;
  4817. return res;
  4818. });
  4819. // 把圆弧绘制的曲线转化为对应的三次贝塞尔形式
  4820. function a2c(x1, y1, rx, ry, angle, laf, sf, x2, y2, recursive) {
  4821. // copy from raphael.js
  4822. // for more information of where this math came from visit:
  4823. // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
  4824. var math = Math, PI = math.PI, abs = Math.abs, _120 = PI * 120 / 180, rad = PI / 180 * (+angle || 0), res = [], xy, rotate = function(x, y, rad) {
  4825. var X = x * math.cos(rad) - y * math.sin(rad), Y = x * math.sin(rad) + y * math.cos(rad);
  4826. return {
  4827. x: X,
  4828. y: Y
  4829. };
  4830. };
  4831. var cos, sin, h, x, y, rx2, ry2, k, cx, cy, f1, f2, df, f2old, x2old, y2old, c1, s1, c2, s2, t, hx, hy, m1, m2, m3, m4, newres, i, ii;
  4832. if (!recursive) {
  4833. xy = rotate(x1, y1, -rad);
  4834. x1 = xy.x;
  4835. y1 = xy.y;
  4836. xy = rotate(x2, y2, -rad);
  4837. x2 = xy.x;
  4838. y2 = xy.y;
  4839. cos = math.cos(PI / 180 * angle);
  4840. sin = math.sin(PI / 180 * angle);
  4841. x = (x1 - x2) / 2;
  4842. y = (y1 - y2) / 2;
  4843. h = x * x / (rx * rx) + y * y / (ry * ry);
  4844. if (h > 1) {
  4845. h = math.sqrt(h);
  4846. rx = h * rx;
  4847. ry = h * ry;
  4848. }
  4849. rx2 = rx * rx;
  4850. ry2 = ry * ry;
  4851. k = (laf == sf ? -1 : 1) * math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x)));
  4852. cx = k * rx * y / ry + (x1 + x2) / 2;
  4853. cy = k * -ry * x / rx + (y1 + y2) / 2;
  4854. f1 = math.asin(((y1 - cy) / ry).toFixed(9));
  4855. f2 = math.asin(((y2 - cy) / ry).toFixed(9));
  4856. f1 = x1 < cx ? PI - f1 : f1;
  4857. f2 = x2 < cx ? PI - f2 : f2;
  4858. if (f1 < 0) f1 = PI * 2 + f1;
  4859. if (f2 < 0) f2 = PI * 2 + f2;
  4860. if (sf && f1 > f2) {
  4861. f1 = f1 - PI * 2;
  4862. }
  4863. if (!sf && f2 > f1) {
  4864. f2 = f2 - PI * 2;
  4865. }
  4866. } else {
  4867. f1 = recursive[0];
  4868. f2 = recursive[1];
  4869. cx = recursive[2];
  4870. cy = recursive[3];
  4871. }
  4872. df = f2 - f1;
  4873. if (abs(df) > _120) {
  4874. f2old = f2;
  4875. x2old = x2;
  4876. y2old = y2;
  4877. f2 = f1 + _120 * (sf && f2 > f1 ? 1 : -1);
  4878. x2 = cx + rx * math.cos(f2);
  4879. y2 = cy + ry * math.sin(f2);
  4880. res = a2c(x2, y2, rx, ry, angle, 0, sf, x2old, y2old, [ f2, f2old, cx, cy ]);
  4881. }
  4882. df = f2 - f1;
  4883. c1 = math.cos(f1);
  4884. s1 = math.sin(f1);
  4885. c2 = math.cos(f2);
  4886. s2 = math.sin(f2);
  4887. t = math.tan(df / 4);
  4888. hx = 4 / 3 * rx * t;
  4889. hy = 4 / 3 * ry * t;
  4890. m1 = [ x1, y1 ];
  4891. m2 = [ x1 + hx * s1, y1 - hy * c1 ];
  4892. m3 = [ x2 + hx * s2, y2 - hy * c2 ];
  4893. m4 = [ x2, y2 ];
  4894. m2[0] = 2 * m1[0] - m2[0];
  4895. m2[1] = 2 * m1[1] - m2[1];
  4896. if (recursive) {
  4897. return [ m2, m3, m4 ].concat(res);
  4898. } else {
  4899. res = [ m2, m3, m4 ].concat(res).join().split(",");
  4900. newres = [];
  4901. for (i = 0, ii = res.length; i < ii; i++) {
  4902. newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x;
  4903. }
  4904. return newres;
  4905. }
  4906. }
  4907. // 把二次贝塞尔曲线参数转化为三次贝塞尔曲线参数
  4908. function q2c(x1, y1, ax, ay, x2, y2) {
  4909. // copy from raphael.js
  4910. var _13 = 1 / 3, _23 = 2 / 3;
  4911. return [ _13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2 ];
  4912. }
  4913. /**
  4914. * kity.g.pathToCurve(path)
  4915. *
  4916. * 把路径转换为贝塞尔路径
  4917. *
  4918. * @param {Array|String} path
  4919. * 要转换的 path 路径或数组
  4920. *
  4921. * @return {Array}
  4922. * 转换后的 PathSegment,每一段都是 'C'
  4923. */
  4924. g.pathToCurve = cacher(function(path) {
  4925. var i, j, command, param;
  4926. var initPoint, currentPoint, endPoint, shouldClose, lastControlPoint, aussumedControlPoint;
  4927. var controlPoint1, controlPoint2;
  4928. var res = [];
  4929. // 处理的路径要求是一个绝对路径
  4930. if (!path.isAbsolute) path = g.pathToAbsolute(path);
  4931. for (i = 0; i < path.length; i++) {
  4932. command = path[i][0];
  4933. param = path[i].slice(1);
  4934. // 画笔移动
  4935. if (command == "M") {
  4936. initPoint = lastControlPoint = currentPoint = param;
  4937. res.push(path[i]);
  4938. continue;
  4939. }
  4940. // 路径闭合
  4941. if (command == "Z") {
  4942. shouldClose = true;
  4943. command = "L";
  4944. param = initPoint;
  4945. }
  4946. // 绘制命令的目的位置
  4947. endPoint = param.slice(param.length - 2);
  4948. // 对 'H' 命令的修正
  4949. if (command == "H") {
  4950. endPoint = [ param[0], currentPoint[1] ];
  4951. command = "L";
  4952. }
  4953. // 对 'V' 命令的修正
  4954. if (command == "V") {
  4955. endPoint = [ currentPoint[0], param[0] ];
  4956. command = "L";
  4957. }
  4958. // 对 'S' 命令求出隐含的控制点位置
  4959. if (command == "S" || command == "T") {
  4960. // 隐含控制点是上一个控制点关于当前位置的镜像
  4961. aussumedControlPoint = [ currentPoint[0] + (currentPoint[0] - lastControlPoint[0]), currentPoint[1] + (currentPoint[1] - lastControlPoint[1]) ];
  4962. }
  4963. // 针对不同的命令求控制点
  4964. switch (command) {
  4965. case "L":
  4966. controlPoint1 = currentPoint;
  4967. controlPoint2 = endPoint;
  4968. break;
  4969. case "C":
  4970. controlPoint1 = param.slice(0, 2);
  4971. controlPoint2 = param.slice(2, 4);
  4972. break;
  4973. case "S":
  4974. controlPoint1 = aussumedControlPoint.slice();
  4975. controlPoint2 = param.slice(0, 2);
  4976. break;
  4977. case "Q":
  4978. lastControlPoint = param.slice(0, 2);
  4979. param = q2c.apply(null, currentPoint.concat(param));
  4980. controlPoint1 = param.slice(0, 2);
  4981. controlPoint2 = param.slice(2, 4);
  4982. break;
  4983. case "T":
  4984. param = q2c.apply(null, currentPoint.concat(aussumedControlPoint).concat(param));
  4985. controlPoint1 = param.slice(0, 2);
  4986. controlPoint2 = param.slice(2, 4);
  4987. break;
  4988. case "A":
  4989. param = a2c.apply(null, currentPoint.concat(param));
  4990. j = 0;
  4991. while (j in param) {
  4992. controlPoint1 = param.slice(j, j + 2);
  4993. controlPoint2 = param.slice(j + 2, j + 4);
  4994. endPoint = param.slice(j + 4, j + 6);
  4995. // 写入当前一段曲线
  4996. res.push([ "C" ].concat(controlPoint1).concat(controlPoint2).concat(endPoint));
  4997. j += 6;
  4998. }
  4999. break;
  5000. }
  5001. if (command != "A") {
  5002. // 写入当前一段曲线
  5003. res.push([ "C" ].concat(controlPoint1).concat(controlPoint2).concat(endPoint));
  5004. }
  5005. // 为下次循环准备当前位置
  5006. currentPoint = endPoint;
  5007. // 二次贝塞尔曲线自己已经记录了上个控制点的位置,其它的记录控制点 2 的位置
  5008. if (command != "Q") {
  5009. lastControlPoint = controlPoint2;
  5010. }
  5011. if (shouldClose) {
  5012. res.push([ "Z" ]);
  5013. shouldClose = false;
  5014. }
  5015. }
  5016. res.isUniform = true;
  5017. res.isAbsolute = true;
  5018. res.isCurve = true;
  5019. res.toString = g.pathToString;
  5020. return res;
  5021. });
  5022. /**
  5023. * 将贝塞尔曲线切成两部分
  5024. *
  5025. * @see http://stackoverflow.com/questions/18655135/divide-bezier-curve-into-two-equal-halves
  5026. */
  5027. function cutBezier(bezierArray, t) {
  5028. function __(t) {
  5029. return function(p, q) {
  5030. return p + t * (q - p);
  5031. };
  5032. }
  5033. var _ = __(t || .5), ba = bezierArray, ax = ba[0], ay = ba[1], bx = ba[2], by = ba[3], cx = ba[4], cy = ba[5], dx = ba[6], dy = ba[7], ex = _(ax, bx), ey = _(ay, by), fx = _(bx, cx), fy = _(by, cy), gx = _(cx, dx), gy = _(cy, dy), hx = _(ex, fx), hy = _(ey, fy), jx = _(fx, gx), jy = _(fy, gy), kx = _(hx, jx), ky = _(hy, jy);
  5034. return [ [ ax, ay, ex, ey, hx, hy, kx, ky ], [ kx, ky, jx, jy, gx, gy, dx, dy ] ];
  5035. }
  5036. /**
  5037. * kity.g.cutBezier(bezierArray, t)
  5038. *
  5039. * 在指定位置把贝塞尔曲线切割为两部分
  5040. *
  5041. * @param {Array} bezierArray
  5042. * 表示贝塞尔曲线的一个数组 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  5043. * p1 和 p2 是贝塞尔曲线的起点和终点,c1 和 c2 是两个控制点
  5044. *
  5045. * @param {Number} t
  5046. * 切割的位置(0 到 1)
  5047. *
  5048. * @return {Array}
  5049. * 切割的两个贝塞尔曲线:[
  5050. * [p1x1, p1y1, c1x1, c1y1, c2x1, c2y1, p2x1, p2y1],
  5051. * [p1x2, p1y2, c1x2, c1y2, c2x2, c2y2, p2x2, p2y2]
  5052. * ]
  5053. *
  5054. */
  5055. g.cutBezier = cacher(cutBezier);
  5056. /**
  5057. * 求一段贝塞尔曲线的子段
  5058. *
  5059. * @param {Array} bezierArray
  5060. * 长度为 8 的数组,表示 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  5061. *
  5062. * @param {Number} t
  5063. * 子段的结束位置(0 到 1)
  5064. *
  5065. * @param {Number} t0
  5066. * 字段的开始位置(0 到 t),可不传,默认为 0
  5067. *
  5068. * @return {Array}
  5069. * 长度为 8 的数组,表示给定贝塞尔曲线的子段
  5070. */
  5071. g.subBezier = function(bezierArray, t, t0) {
  5072. var b2t = cutBezier(bezierArray, t)[0];
  5073. return t0 ? cutBezier(b2t, t0 / t)[1] : b2t;
  5074. };
  5075. /**
  5076. * 求贝塞尔曲线上的一个点
  5077. *
  5078. * @param {Array} bezierArray
  5079. * 长度为 8 的数组,表示 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  5080. *
  5081. * @param {Number} t
  5082. * 所求点的开始位置(0 到 1)
  5083. *
  5084. * @return {Point} p
  5085. * p.x: x 坐标
  5086. * p.y: y 坐标
  5087. * p.tan: 在 t 处的切线方向(类型为 kity.Vector,模为 1)
  5088. */
  5089. g.pointAtBezier = function(bezierArray, t) {
  5090. var b2t = cutBezier(bezierArray, t)[0];
  5091. var p = Point.parse(b2t.slice(6)), c = Point.parse(b2t.slice(4, 2)), v = Vector.fromPoints(c, p);
  5092. if (t === 0) {
  5093. p.tan = g.pointAtBezier(bezierArray, .01).tan;
  5094. } else {
  5095. p.tan = v.normalize();
  5096. }
  5097. return p;
  5098. };
  5099. /**
  5100. * 求贝塞尔曲线的长度
  5101. *
  5102. * @param {Array} bezierArray
  5103. * 长度为 8 的数组,表示 [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]
  5104. *
  5105. * @param {Number} tolerate
  5106. * 允许的误差,默认是 0.1
  5107. *
  5108. * @return {Number} 贝塞尔曲线的长度
  5109. */
  5110. g.bezierLength = cacher(function bezierLength(bezierArray) {
  5111. // 表示(c[0]*t^4 + c[1]*t^3 + c[2]*t^2 + c[3]*t^1 + c[4])^(1/2)的函数
  5112. function f(x) {
  5113. var m = c0 * Math.pow(x, 4) + c1 * Math.pow(x, 3) + c2 * Math.pow(x, 2) + c3 * x + c4;
  5114. if (m < 0) {
  5115. m = 0;
  5116. }
  5117. return Math.pow(m, .5);
  5118. }
  5119. // 用Newton-Cotes型求积公式
  5120. var arr = bezierArray;
  5121. // 三次贝塞尔曲线函数求导后,求出对应的方程系数,用cx[],cy[]表示x`(t)和y`(t)的系数
  5122. var cx0, cx1, cx2;
  5123. var cy0, cy1, cy2;
  5124. // 用c[]表示x`(t)^2 + y`(t)^2的结果的系数
  5125. var c0, c1, c2, c3, c4;
  5126. // 求x`(t) 和 y`(t)的系数
  5127. cx0 = -3 * arr[0] + 9 * arr[2] - 9 * arr[4] + 3 * arr[6];
  5128. cx1 = 6 * arr[0] - 12 * arr[2] + 6 * arr[4];
  5129. cx2 = -3 * arr[0] + 3 * arr[2];
  5130. cy0 = -3 * arr[1] + 9 * arr[3] - 9 * arr[5] + 3 * arr[7];
  5131. cy1 = 6 * arr[1] - 12 * arr[3] + 6 * arr[5];
  5132. cy2 = -3 * arr[1] + 3 * arr[3];
  5133. // 求x`(t)^2 + y`(t)^2的结果的系数 c[]
  5134. c0 = Math.pow(cx0, 2) + Math.pow(cy0, 2);
  5135. c1 = 2 * (cx0 * cx1 + cy0 * cy1);
  5136. c2 = 2 * (cx0 * cx2 + cy0 * cy2) + Math.pow(cx1, 2) + Math.pow(cy1, 2);
  5137. c3 = 2 * (cx1 * cx2 + cy1 * cy2);
  5138. c4 = Math.pow(cx2, 2) + Math.pow(cy2, 2);
  5139. // 用cotes积分公式求值
  5140. return (f(0) + f(1) + 4 * (f(.125) + f(.375) + f(.625) + f(.875)) + 2 * (f(.25) + f(.5) + f(.75))) / 24;
  5141. });
  5142. // 计算一个 pathSegment 中每一段的在整体中所占的长度范围,以及总长度
  5143. // 方法要求每一段都是贝塞尔曲线
  5144. var getBezierPathSegmentRanges = cacher(function(pathSegment) {
  5145. var i, ii, segment, position, bezierLength, segmentRanges, totalLength;
  5146. segmentRanges = [];
  5147. // 总长度
  5148. totalLength = 0;
  5149. for (i = 0, ii = pathSegment.length; i < ii; i++) {
  5150. segment = pathSegment[i];
  5151. if (segment[0] == "M") {
  5152. position = segment.slice(1);
  5153. segmentRanges.push(null);
  5154. continue;
  5155. }
  5156. if (segment[0] == "Z") {
  5157. segmentRanges.push(null);
  5158. continue;
  5159. }
  5160. bezierLength = g.bezierLength(position.concat(segment.slice(1)));
  5161. segmentRanges.push([ totalLength, totalLength + bezierLength ]);
  5162. totalLength += bezierLength;
  5163. // 迭代当前位置
  5164. position = segment.slice(4);
  5165. }
  5166. segmentRanges.totalLength = totalLength;
  5167. return segmentRanges;
  5168. });
  5169. /**
  5170. * 求一段路径的子路径
  5171. *
  5172. * @param {Array|String} path
  5173. * 原路径
  5174. *
  5175. * @param {Number} t1
  5176. * 要求的子路径的结束位置(0 到 1)
  5177. *
  5178. * @param {Number} t0
  5179. * 要求的子路径的开始位置(0 到 t1),可不传,默认为 0
  5180. *
  5181. * @return {Array}
  5182. * 子路径的 PathSegment
  5183. */
  5184. g.subPath = function(path, t1, t0) {
  5185. var dt;
  5186. t0 = t0 || 0;
  5187. dt = t1 - t0;
  5188. dt = dt - (dt | 0);
  5189. t0 = t0 - (t0 | 0);
  5190. t1 = t0 + dt;
  5191. if (t1 > 1) {
  5192. return g.subPath(path, 1, t0).concat(g.subPath(path, t1 - 1));
  5193. }
  5194. if (!path.isCurve) {
  5195. path = g.pathToCurve(path);
  5196. }
  5197. // path 每一段在整体中的长度区间
  5198. var segmentRanges = getBezierPathSegmentRanges(path);
  5199. // path 总长度
  5200. var totalLength = segmentRanges.totalLength;
  5201. // t1 和 t0 位置命中的长度位置
  5202. var t1Length = totalLength * t1, t0Length = totalLength * (t0 || 0);
  5203. // 产生的子路径
  5204. var subPath = [];
  5205. // 迭代变量,a 是一段的长度区间左值,b 是右值,d 是区间长度
  5206. var i, ii, a, b, d;
  5207. var position;
  5208. var bezier, subBezier, stared;
  5209. for (i = 0, ii = path.length; i < ii; i++) {
  5210. if (path[i][0] == "M") {
  5211. position = path[i].slice(1);
  5212. if (stared) {
  5213. subPath.push(path[i].slice());
  5214. }
  5215. continue;
  5216. }
  5217. if (path[i][0] == "Z") {
  5218. // subpath 路径不闭合
  5219. continue;
  5220. }
  5221. a = segmentRanges[i][0];
  5222. b = segmentRanges[i][1];
  5223. d = b - a;
  5224. bezier = position.concat(path[i].slice(1));
  5225. if (t0Length > b) {
  5226. // t0 和 t1 都右溢出
  5227. // -----------------------------------
  5228. // t0 t1
  5229. // |________|
  5230. //
  5231. // 需要跳过当前块
  5232. position = bezier.slice(bezier.length - 2);
  5233. continue;
  5234. } else if (t0Length >= a) {
  5235. // 命中 t0;t1 可能命中或右溢出
  5236. // -----------------------------------
  5237. // t0 t1
  5238. // |______|__|
  5239. //
  5240. // or: |_|____|__|
  5241. //
  5242. // 取当前块 t0 到 t1 的部分
  5243. subBezier = g.subBezier(bezier, Math.min((t1Length - a) / d, 1), (t0Length - a) / d);
  5244. stared = true;
  5245. position = subBezier.slice(0, 2);
  5246. subPath.push([ "M" ].concat(subBezier.slice(0, 2)));
  5247. subPath.push([ "C" ].concat(subBezier.slice(2)));
  5248. } else if (t1Length >= b) {
  5249. // t0 左溢出;t1 右溢出,整个块是需要的
  5250. // -----------------------------------
  5251. // t0 t1
  5252. // |_________|
  5253. //
  5254. // 此时取整个块
  5255. subPath.push(path[i].slice());
  5256. } else if (t1Length >= a) {
  5257. // t0 左溢出;t1 命中,取当前块 t1 之前的部分
  5258. // -----------------------------------
  5259. // t0 t1
  5260. // |__|______|
  5261. // 取当前块 t1 之前的部分
  5262. subBezier = g.subBezier(bezier, (t1Length - a) / d);
  5263. subPath.push([ "C" ].concat(subBezier.slice(2)));
  5264. stared = false;
  5265. } else {
  5266. // 没有可以再要的了
  5267. break;
  5268. }
  5269. position = bezier.slice(bezier.length - 2);
  5270. }
  5271. subPath.isAbsolute = true;
  5272. subPath.isCurve = true;
  5273. subPath.isUniform = true;
  5274. subPath.toString = g.pathToString;
  5275. return subPath;
  5276. };
  5277. /**
  5278. * 求路径上的一个点
  5279. *
  5280. * @param {Array|String} path
  5281. * 要求点的路径
  5282. *
  5283. * @param {Number} t
  5284. * 要求的点的位置(0 到 1)
  5285. *
  5286. * @return {Point} p
  5287. * p.x: x 坐标
  5288. * p.y: y 坐标
  5289. * p.tan: 在 t 处的切线方向(类型为 kity.Vector,模为 1)
  5290. */
  5291. g.pointAtPath = function(path, t) {
  5292. if (!path.isCurve) {
  5293. path = g.pathToCurve(path);
  5294. }
  5295. var subPath = g.subPath(path, t);
  5296. var lastCurve = subPath[subPath.length - 1][0] == "Z" ? subPath[subPath.length - 2] : subPath[subPath.length - 1];
  5297. // 跳过 'C' 命令,只留参数
  5298. lastCurve = lastCurve.slice(1);
  5299. var p = Point.parse(lastCurve.slice(4)), c = Point.parse(lastCurve.slice(2, 4));
  5300. p.tan = Vector.fromPoints(c, p).normalize();
  5301. return p;
  5302. };
  5303. /**
  5304. * 求一段路径的长度
  5305. *
  5306. * @param {string|Array} path
  5307. * 要求的路径
  5308. *
  5309. * @return {Number}
  5310. * 路径的长度
  5311. */
  5312. g.pathLength = cacher(function(path) {
  5313. if (!path.isCurve) {
  5314. path = g.pathToCurve(path);
  5315. }
  5316. // path 每一段在整体中的长度区间
  5317. var segmentRanges = getBezierPathSegmentRanges(path);
  5318. return segmentRanges.totalLength;
  5319. });
  5320. /**
  5321. * 求一段路径的关键点
  5322. *
  5323. * @param {string|Array} path
  5324. * 要求的路径
  5325. *
  5326. * @return {Array}
  5327. * 关键点的集合
  5328. */
  5329. g.pathKeyPoints = cacher(function(path) {
  5330. var i, ii, command, keyPoints;
  5331. if (!path.isCurve) {
  5332. path = g.pathToCurve(path);
  5333. }
  5334. keyPoints = [];
  5335. for (i = 0, ii = path.length; i < ii; i++) {
  5336. if (path[i][0] == "z") continue;
  5337. keyPoints.push(path[i].slice(path[i].length - 2));
  5338. }
  5339. return keyPoints;
  5340. });
  5341. // 对比两个路径的关键位置,在合适的位置切割合适的路径,使得两个路径的段数一致
  5342. // TODO: 使用插值算法,使对应点更合理
  5343. var alignCurve = cacher(function(path1, path2) {
  5344. if (!path1.isCurve) path1 = g.pathToCurve(path1);
  5345. if (!path2.isCurve) path2 = g.pathToCurve(path2);
  5346. var p1 = pathClone(path1);
  5347. var p2 = pathClone(path2);
  5348. p1.i = 0;
  5349. p2.i = 0;
  5350. p1.o = p2;
  5351. p2.o = p1;
  5352. function command(p, i) {
  5353. return p[i || p.i] && p[i || p.i][0];
  5354. }
  5355. function param(p, i) {
  5356. return p[i || p.i] && p[i || p.i].slice(1);
  5357. }
  5358. function point(p, i) {
  5359. var _param = param(p, i);
  5360. return _param && _param.slice(-2);
  5361. }
  5362. function fixZ(p) {
  5363. if (command(p) == "Z") {
  5364. p.splice(p.i, 1);
  5365. return true;
  5366. }
  5367. return false;
  5368. }
  5369. function fixM(p) {
  5370. if (command(p) == "M") {
  5371. p.o.splice(p.o.i, 0, [ "M" ].concat(point(p.o, p.o.i - 1)));
  5372. p.i++;
  5373. p.o.i++;
  5374. return true;
  5375. }
  5376. return false;
  5377. }
  5378. function fill(p) {
  5379. var lastPoint;
  5380. var i = 1;
  5381. while (!lastPoint) {
  5382. lastPoint = point(p, p.length - i++);
  5383. }
  5384. p.o.i = p.i;
  5385. while (p.length < p.o.length) {
  5386. if (fixZ(p.o)) continue;
  5387. if (fixM(p.o)) continue;
  5388. p.push([ "C" ].concat(lastPoint).concat(lastPoint).concat(lastPoint));
  5389. p.i++;
  5390. p.o.i++;
  5391. }
  5392. }
  5393. while (p1.i < p1.length && p2.i < p2.length) {
  5394. if (fixZ(p1) || fixZ(p2)) continue;
  5395. if (command(p1) == command(p2)) {
  5396. p1.i++;
  5397. p2.i++;
  5398. continue;
  5399. }
  5400. if (fixM(p1) || fixM(p2)) continue;
  5401. p1.i++;
  5402. p2.i++;
  5403. }
  5404. if (p1.i == p1.length) fill(p1);
  5405. if (p2.i == p2.length) fill(p2);
  5406. delete p1.i;
  5407. delete p1.o;
  5408. delete p2.i;
  5409. delete p2.o;
  5410. return [ p1, p2 ];
  5411. });
  5412. g.alignCurve = alignCurve;
  5413. /**
  5414. * 获得两个路径的补间结果
  5415. *
  5416. * @param {string|Array} path1
  5417. * 补间起始路径
  5418. *
  5419. * @param {string|Array} path2
  5420. * 补间结束路径
  5421. *
  5422. * @param {Number} t
  5423. * 补间比例,0 返回跟 path1 等效的结果;1 返回跟 path2 等效的结果
  5424. *
  5425. * @return {PathSegment}
  5426. * 补间的结果
  5427. */
  5428. g.pathTween = function(path1, path2, t) {
  5429. if (t === 0) return path1;
  5430. if (t === 1) return path2;
  5431. var aligned = alignCurve(path1, path2);
  5432. var result = [], seg, i, j;
  5433. path1 = aligned[0];
  5434. path2 = aligned[1];
  5435. for (i = 0; i < path1.length; i++) {
  5436. result.push(seg = []);
  5437. seg.push(path1[i][0]);
  5438. for (j = 1; j < path1[i].length; j++) {
  5439. seg.push(path1[i][j] + t * (path2[i][j] - path1[i][j]));
  5440. }
  5441. }
  5442. result.isUniform = result.isCurve = result.isAbsolute = true;
  5443. return result;
  5444. };
  5445. /**
  5446. * 变换指定的路径
  5447. *
  5448. * @param {String|Array} path
  5449. * 需要变换的路径
  5450. *
  5451. * @param {kity.Matrix} matrix
  5452. * 使用的变换矩阵
  5453. *
  5454. * @return {Array}
  5455. * 变换后的路径
  5456. */
  5457. g.transformPath = cacher(function(path, matrix) {
  5458. var i, ii, j, result, seg, pair;
  5459. if (!path.isCurve) {
  5460. path = g.pathToCurve(path);
  5461. }
  5462. result = [];
  5463. for (i = 0, ii = path.length; i < ii; i++) {
  5464. result.push(seg = [ path[i][0] ]);
  5465. for (j = 1; j < path[i].length; j += 2) {
  5466. pair = path[i].slice(j, j + 2);
  5467. pair = matrix.transformPoint(Point.parse(pair));
  5468. result.push(pair);
  5469. }
  5470. }
  5471. return result;
  5472. });
  5473. // entend
  5474. _p.r(11).extendClass(Matrix, {
  5475. transformPath: function(path) {
  5476. return g.transformPath(path, this);
  5477. }
  5478. });
  5479. return g;
  5480. }
  5481. };
  5482. //src/graphic/gradient.js
  5483. _p[35] = {
  5484. value: function(require, exports, module) {
  5485. var svg = _p.r(67);
  5486. var Resource = _p.r(58);
  5487. var Color = _p.r(28);
  5488. return _p.r(11).createClass("GradientBrush", {
  5489. base: Resource,
  5490. constructor: function(gradientNodeType, paper) {
  5491. this.callBase(gradientNodeType, paper);
  5492. this.stops = [];
  5493. },
  5494. addStop: function(offset, color, opacity) {
  5495. var gstop = svg.createNode("stop");
  5496. if (!(color instanceof Color)) {
  5497. color = Color.parse(color);
  5498. }
  5499. if (opacity === undefined) {
  5500. opacity = color.get("a");
  5501. }
  5502. gstop.setAttribute("offset", offset);
  5503. gstop.setAttribute("stop-color", color.toRGB());
  5504. if (opacity < 1) {
  5505. gstop.setAttribute("stop-opacity", opacity);
  5506. }
  5507. this.node.appendChild(gstop);
  5508. return this;
  5509. }
  5510. });
  5511. }
  5512. };
  5513. //src/graphic/group.js
  5514. _p[36] = {
  5515. value: function(require, exports, module) {
  5516. var ShapeContainer = _p.r(61);
  5517. return _p.r(11).createClass("Group", {
  5518. mixins: [ ShapeContainer ],
  5519. base: _p.r(60),
  5520. constructor: function Group() {
  5521. this.callBase("g");
  5522. }
  5523. });
  5524. }
  5525. };
  5526. //src/graphic/hyperlink.js
  5527. _p[37] = {
  5528. value: function(require, exports, module) {
  5529. var ShapeContainer = _p.r(61);
  5530. return _p.r(11).createClass("HyperLink", {
  5531. mixins: [ ShapeContainer ],
  5532. base: _p.r(60),
  5533. constructor: function(url) {
  5534. this.callBase("a");
  5535. this.setHref(url);
  5536. },
  5537. setHref: function(href) {
  5538. this.node.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", href);
  5539. return this;
  5540. },
  5541. getHref: function() {
  5542. return this.node.getAttributeNS("xlink:href");
  5543. },
  5544. setTarget: function(target) {
  5545. this.node.setAttribute("target", target);
  5546. return this;
  5547. },
  5548. getTarget: function() {
  5549. return this.node.getAttribute("target");
  5550. }
  5551. });
  5552. }
  5553. };
  5554. //src/graphic/image.js
  5555. _p[38] = {
  5556. value: function(require, exports, module) {
  5557. return _p.r(11).createClass("Image", {
  5558. base: _p.r(60),
  5559. constructor: function(url, width, height, x, y) {
  5560. this.callBase("image");
  5561. this.url = url;
  5562. this.width = width || 0;
  5563. this.height = height || 0;
  5564. this.x = x || 0;
  5565. this.y = y || 0;
  5566. this.update();
  5567. },
  5568. update: function() {
  5569. this.node.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", this.url);
  5570. this.node.setAttribute("x", this.x);
  5571. this.node.setAttribute("y", this.y);
  5572. this.node.setAttribute("width", this.width);
  5573. this.node.setAttribute("height", this.height);
  5574. return this;
  5575. },
  5576. setUrl: function(url) {
  5577. this.url = url === "" ? null : url;
  5578. return this.update();
  5579. },
  5580. getUrl: function() {
  5581. return this.url;
  5582. },
  5583. setWidth: function(width) {
  5584. this.width = width;
  5585. return this.update();
  5586. },
  5587. getWidth: function() {
  5588. return this.width;
  5589. },
  5590. setHeight: function(height) {
  5591. this.height = height;
  5592. return this.update();
  5593. },
  5594. getHeight: function() {
  5595. return this.height;
  5596. },
  5597. setX: function(x) {
  5598. this.x = x;
  5599. return this.update();
  5600. },
  5601. getX: function() {
  5602. return this.x;
  5603. },
  5604. setY: function(y) {
  5605. this.y = y;
  5606. return this.update();
  5607. },
  5608. getY: function() {
  5609. return this.y;
  5610. }
  5611. });
  5612. }
  5613. };
  5614. //src/graphic/line.js
  5615. _p[39] = {
  5616. value: function(require, exports, module) {
  5617. return _p.r(11).createClass("Line", {
  5618. base: _p.r(46),
  5619. constructor: function(x1, y1, x2, y2) {
  5620. this.callBase();
  5621. this.point1 = {
  5622. x: x1 || 0,
  5623. y: y1 || 0
  5624. };
  5625. this.point2 = {
  5626. x: x2 || 0,
  5627. y: y2 || 0
  5628. };
  5629. this.update();
  5630. },
  5631. setPoint1: function(x, y) {
  5632. this.point1.x = x;
  5633. this.point1.y = y;
  5634. return this.update();
  5635. },
  5636. setPoint2: function(x, y) {
  5637. this.point2.x = x;
  5638. this.point2.y = y;
  5639. return this.update();
  5640. },
  5641. getPoint1: function() {
  5642. return {
  5643. x: this.point1.x,
  5644. y: this.point1.y
  5645. };
  5646. },
  5647. getPoint2: function() {
  5648. return {
  5649. x: this.point2.x,
  5650. y: this.point2.y
  5651. };
  5652. },
  5653. update: function() {
  5654. var drawer = this.getDrawer();
  5655. drawer.clear();
  5656. drawer.moveTo(this.point1.x, this.point1.y);
  5657. drawer.lineTo(this.point2.x, this.point2.y);
  5658. return this;
  5659. }
  5660. });
  5661. }
  5662. };
  5663. //src/graphic/lineargradient.js
  5664. _p[40] = {
  5665. value: function(require, exports, module) {
  5666. var svg = _p.r(67);
  5667. var Gradient = _p.r(35);
  5668. return _p.r(11).createClass("LinearGradientBrush", {
  5669. base: Gradient,
  5670. constructor: function(paper) {
  5671. this.callBase("linearGradient", paper);
  5672. this.setStartPosition(0, 0);
  5673. this.setEndPosition(1, 0);
  5674. },
  5675. setStartPosition: function(px, py) {
  5676. this.node.setAttribute("x1", px);
  5677. this.node.setAttribute("y1", py);
  5678. return this;
  5679. },
  5680. setEndPosition: function(px, py) {
  5681. this.node.setAttribute("x2", px);
  5682. this.node.setAttribute("y2", py);
  5683. return this;
  5684. },
  5685. getStartPosition: function() {
  5686. return {
  5687. x: +this.node.getAttribute("x1"),
  5688. y: +this.node.getAttribute("y1")
  5689. };
  5690. },
  5691. getEndPosition: function() {
  5692. return {
  5693. x: +this.node.getAttribute("x2"),
  5694. y: +this.node.getAttribute("y2")
  5695. };
  5696. }
  5697. });
  5698. }
  5699. };
  5700. //src/graphic/marker.js
  5701. _p[41] = {
  5702. value: function(require, exports, module) {
  5703. var Point = _p.r(50);
  5704. var Marker = _p.r(11).createClass("Marker", {
  5705. base: _p.r(58),
  5706. mixins: [ _p.r(61), _p.r(75) ],
  5707. constructor: function() {
  5708. this.callBase("marker");
  5709. this.setOrient("auto");
  5710. },
  5711. setRef: function(x, y) {
  5712. if (arguments.length === 1) {
  5713. y = x.y;
  5714. x = x.x;
  5715. }
  5716. this.node.setAttribute("refX", x);
  5717. this.node.setAttribute("refY", y);
  5718. return this;
  5719. },
  5720. getRef: function() {
  5721. return new Point(+this.node.getAttribute("refX"), +this.node.getAttribute("refY"));
  5722. },
  5723. setWidth: function(width) {
  5724. this.node.setAttribute("markerWidth", this.width = width);
  5725. return this;
  5726. },
  5727. setOrient: function(orient) {
  5728. this.node.setAttribute("orient", this.orient = orient);
  5729. return this;
  5730. },
  5731. getOrient: function() {
  5732. return this.orient;
  5733. },
  5734. getWidth: function() {
  5735. return +this.width;
  5736. },
  5737. setHeight: function(height) {
  5738. this.node.setAttribute("markerHeight", this.height = height);
  5739. return this;
  5740. },
  5741. getHeight: function() {
  5742. return +this.height;
  5743. }
  5744. });
  5745. var Path = _p.r(46);
  5746. _p.r(11).extendClass(Path, {
  5747. setMarker: function(marker, pos) {
  5748. pos = pos || "end";
  5749. if (!marker) {
  5750. this.node.removeAttribute("marker-" + pos);
  5751. } else {
  5752. this.node.setAttribute("marker-" + pos, marker.toString());
  5753. }
  5754. return this;
  5755. }
  5756. });
  5757. return Marker;
  5758. }
  5759. };
  5760. //src/graphic/mask.js
  5761. /**
  5762. * 蒙板
  5763. */
  5764. _p[42] = {
  5765. value: function(require, exports, module) {
  5766. var Class = _p.r(11);
  5767. var Shape = _p.r(60);
  5768. var Mask = Class.createClass("Mask", {
  5769. base: Shape,
  5770. mixins: [ _p.r(61) ],
  5771. constructor: function() {
  5772. this.callBase("mask");
  5773. },
  5774. mask: function(shape) {
  5775. shape.getNode().setAttribute("mask", "url(#" + this.getId() + ")");
  5776. return this;
  5777. }
  5778. });
  5779. Class.extendClass(Shape, {
  5780. maskWith: function(mask) {
  5781. mask.mask(this);
  5782. return this;
  5783. }
  5784. });
  5785. return Mask;
  5786. }
  5787. };
  5788. //src/graphic/matrix.js
  5789. _p[43] = {
  5790. value: function(require, exports, module) {
  5791. var utils = _p.r(12);
  5792. var Box = _p.r(25);
  5793. var mPattern = /matrix\s*\((.+)\)/i;
  5794. var Point = _p.r(50);
  5795. // 注意,合并的结果是先执行m2,再执行m1的结果
  5796. function mergeMatrixData(m2, m1) {
  5797. return {
  5798. a: m1.a * m2.a + m1.c * m2.b,
  5799. b: m1.b * m2.a + m1.d * m2.b,
  5800. c: m1.a * m2.c + m1.c * m2.d,
  5801. d: m1.b * m2.c + m1.d * m2.d,
  5802. e: m1.a * m2.e + m1.c * m2.f + m1.e,
  5803. f: m1.b * m2.e + m1.d * m2.f + m1.f
  5804. };
  5805. }
  5806. function d2r(deg) {
  5807. return deg * Math.PI / 180;
  5808. }
  5809. var Matrix = _p.r(11).createClass("Matrix", {
  5810. constructor: function() {
  5811. if (arguments.length) {
  5812. this.setMatrix.apply(this, arguments);
  5813. } else {
  5814. this.setMatrix(1, 0, 0, 1, 0, 0);
  5815. }
  5816. },
  5817. translate: function(x, y) {
  5818. this.m = mergeMatrixData(this.m, {
  5819. a: 1,
  5820. c: 0,
  5821. e: x,
  5822. b: 0,
  5823. d: 1,
  5824. f: y
  5825. });
  5826. return this;
  5827. },
  5828. rotate: function(deg) {
  5829. var rad = d2r(deg);
  5830. var sin = Math.sin(rad), cos = Math.cos(rad);
  5831. this.m = mergeMatrixData(this.m, {
  5832. a: cos,
  5833. c: -sin,
  5834. e: 0,
  5835. b: sin,
  5836. d: cos,
  5837. f: 0
  5838. });
  5839. return this;
  5840. },
  5841. scale: function(sx, sy) {
  5842. if (sy === undefined) {
  5843. sy = sx;
  5844. }
  5845. this.m = mergeMatrixData(this.m, {
  5846. a: sx,
  5847. c: 0,
  5848. e: 0,
  5849. b: 0,
  5850. d: sy,
  5851. f: 0
  5852. });
  5853. return this;
  5854. },
  5855. skew: function(degX, degY) {
  5856. if (degY === undefined) {
  5857. degY = degX;
  5858. }
  5859. var tx = Math.tan(d2r(degX)), ty = Math.tan(d2r(degY));
  5860. this.m = mergeMatrixData(this.m, {
  5861. a: 1,
  5862. c: tx,
  5863. e: 0,
  5864. b: ty,
  5865. d: 1,
  5866. f: 0
  5867. });
  5868. return this;
  5869. },
  5870. /**
  5871. * 获得反转矩阵
  5872. *
  5873. * 这是我解方程算出来的
  5874. */
  5875. inverse: function() {
  5876. var m = this.m, a = m.a, b = m.b, c = m.c, d = m.d, e = m.e, f = m.f, k, aa, bb, cc, dd, ee, ff;
  5877. k = a * d - b * c;
  5878. aa = d / k;
  5879. bb = -b / k;
  5880. cc = -c / k;
  5881. dd = a / k;
  5882. ee = (c * f - e * d) / k;
  5883. ff = (b * e - a * f) / k;
  5884. return new Matrix(aa, bb, cc, dd, ee, ff);
  5885. },
  5886. setMatrix: function(a, b, c, d, e, f) {
  5887. if (arguments.length === 1) {
  5888. this.m = utils.clone(arguments[0]);
  5889. } else {
  5890. this.m = {
  5891. a: a,
  5892. b: b,
  5893. c: c,
  5894. d: d,
  5895. e: e,
  5896. f: f
  5897. };
  5898. }
  5899. return this;
  5900. },
  5901. getMatrix: function() {
  5902. return utils.clone(this.m);
  5903. },
  5904. getTranslate: function() {
  5905. var m = this.m;
  5906. return {
  5907. x: m.e / m.a,
  5908. y: m.f / m.d
  5909. };
  5910. },
  5911. mergeMatrix: function(matrix) {
  5912. return new Matrix(mergeMatrixData(this.m, matrix.m));
  5913. },
  5914. merge: function(matrix) {
  5915. return this.mergeMatrix(matrix);
  5916. },
  5917. toString: function() {
  5918. return this.valueOf().join(" ");
  5919. },
  5920. valueOf: function() {
  5921. var m = this.m;
  5922. return [ m.a, m.b, m.c, m.d, m.e, m.f ];
  5923. },
  5924. equals: function(matrix) {
  5925. var m1 = this.m, m2 = matrix.m;
  5926. return m1.a == m2.a && m1.b == m2.b && m1.c == m2.c && m1.d == m2.d && m1.e == m2.e && m1.f == m2.f;
  5927. },
  5928. transformPoint: function() {
  5929. return Matrix.transformPoint.apply(null, [].slice.call(arguments).concat([ this.m ]));
  5930. },
  5931. transformBox: function(box) {
  5932. return Matrix.transformBox(box, this.m);
  5933. },
  5934. clone: function() {
  5935. return new Matrix(this.m);
  5936. }
  5937. });
  5938. Matrix.parse = function(str) {
  5939. var match;
  5940. var f = parseFloat;
  5941. if (str instanceof Array) {
  5942. return new Matrix({
  5943. a: str[0],
  5944. b: str[1],
  5945. c: str[2],
  5946. d: str[3],
  5947. e: str[4],
  5948. f: str[5]
  5949. });
  5950. }
  5951. if (match = mPattern.exec(str)) {
  5952. var values = match[1].split(",");
  5953. if (values.length != 6) {
  5954. values = match[1].split(" ");
  5955. }
  5956. return new Matrix({
  5957. a: f(values[0]),
  5958. b: f(values[1]),
  5959. c: f(values[2]),
  5960. d: f(values[3]),
  5961. e: f(values[4]),
  5962. f: f(values[5])
  5963. });
  5964. }
  5965. return new Matrix();
  5966. };
  5967. Matrix.transformPoint = function(x, y, m) {
  5968. if (arguments.length === 2) {
  5969. m = y;
  5970. y = x.y;
  5971. x = x.x;
  5972. }
  5973. return new Point(m.a * x + m.c * y + m.e, m.b * x + m.d * y + m.f);
  5974. };
  5975. Matrix.transformBox = function(box, matrix) {
  5976. var xMin = Number.MAX_VALUE, xMax = -Number.MAX_VALUE, yMin = Number.MAX_VALUE, yMax = -Number.MAX_VALUE;
  5977. var bps = [ [ box.x, box.y ], [ box.x + box.width, box.y ], [ box.x, box.y + box.height ], [ box.x + box.width, box.y + box.height ] ];
  5978. var bp, rp, rps = [];
  5979. while (bp = bps.pop()) {
  5980. rp = Matrix.transformPoint(bp[0], bp[1], matrix);
  5981. rps.push(rp);
  5982. xMin = Math.min(xMin, rp.x);
  5983. xMax = Math.max(xMax, rp.x);
  5984. yMin = Math.min(yMin, rp.y);
  5985. yMax = Math.max(yMax, rp.y);
  5986. }
  5987. box = new Box({
  5988. x: xMin,
  5989. y: yMin,
  5990. width: xMax - xMin,
  5991. height: yMax - yMin
  5992. });
  5993. utils.extend(box, {
  5994. closurePoints: rps
  5995. });
  5996. return box;
  5997. };
  5998. // 获得从 node 到 refer 的变换矩阵
  5999. Matrix.getCTM = function(target, refer) {
  6000. var ctm = {
  6001. a: 1,
  6002. b: 0,
  6003. c: 0,
  6004. d: 1,
  6005. e: 0,
  6006. f: 0
  6007. };
  6008. var node = target.shapeNode || target.node;
  6009. refer = refer || "parent";
  6010. /**
  6011. * 由于新版chrome(dev 48.0)移除了getTransformToElement这个方法可能导致报错,这里做兼容处理
  6012. * @Date 2015-11-12
  6013. * @Editor Naixor
  6014. */
  6015. function getTransformToElement(target, source) {
  6016. var matrix;
  6017. try {
  6018. matrix = source.getScreenCTM().inverse();
  6019. } catch (e) {
  6020. throw new Error("Can not inverse source element' ctm.");
  6021. }
  6022. return matrix.multiply(target.getScreenCTM());
  6023. }
  6024. // 根据参照坐标系选区的不一样,返回不同的结果
  6025. switch (refer) {
  6026. case "screen":
  6027. // 以浏览器屏幕为参照坐标系
  6028. ctm = node.getScreenCTM();
  6029. break;
  6030. case "doc":
  6031. case "paper":
  6032. // 以文档(Paper)为参照坐标系
  6033. ctm = node.getCTM();
  6034. break;
  6035. case "view":
  6036. case "top":
  6037. // 以顶层绘图容器(视野)为参照坐标系
  6038. if (target.getPaper()) {
  6039. ctm = node.getTransformToElement !== undefined ? node.getTransformToElement(target.getPaper().shapeNode) : getTransformToElement(node, target.getPaper().shapeNode);
  6040. }
  6041. break;
  6042. case "parent":
  6043. // 以父容器为参照坐标系
  6044. if (target.node.parentNode) {
  6045. ctm = node.getTransformToElement !== undefined ? node.getTransformToElement(target.node.parentNode) : getTransformToElement(node, target.node.parentNode);
  6046. }
  6047. break;
  6048. default:
  6049. // 其他情况,指定参照物
  6050. if (refer.node) {
  6051. ctm = node.getTransformToElement !== undefined ? node.getTransformToElement(refer.shapeNode || refer.node) : getTransformToElement(node, refer.shapeNode || refer.node);
  6052. }
  6053. }
  6054. return ctm ? new Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f) : new Matrix();
  6055. };
  6056. return Matrix;
  6057. }
  6058. };
  6059. //src/graphic/palette.js
  6060. /**
  6061. * 调色板
  6062. */
  6063. _p[44] = {
  6064. value: function(require, exports, module) {
  6065. //标准color
  6066. var StandardColor = _p.r(64), Color = _p.r(28), Utils = _p.r(12);
  6067. var Palette = _p.r(11).createClass("Palette", {
  6068. constructor: function() {
  6069. this.color = {};
  6070. },
  6071. /*
  6072. * 获取颜色名称所对应的颜色值的Color对象
  6073. * @param name 需要获取的颜色名称
  6074. * @return 对应颜色名称的color对象, 如果未找到对应的名称, 则返回null
  6075. */
  6076. get: function(name) {
  6077. var colorValue = this.color[name] || StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name] || "";
  6078. if (colorValue) {
  6079. return new Color(colorValue);
  6080. }
  6081. return null;
  6082. },
  6083. /*
  6084. * 获取给定名称的颜色的hex值表示
  6085. * @param name 需要获取的颜色名称
  6086. * @return 如果找到对应的名称, 则返回该名称所对应的hex格式的值, 否则, 返回一个空字符串
  6087. */
  6088. getColorValue: function(name) {
  6089. return this.color[name] || StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name] || "";
  6090. },
  6091. /*
  6092. * 向调色板实例添加自己独有的颜色名称,对已存在的颜色名称, 将会覆盖掉
  6093. * @param name 新添加的颜色名称
  6094. * @param value 新添加的颜色名称所对应的值, 可以是一个合法的颜色字符串或者是一个color对象
  6095. * @return 新添加的颜色的值
  6096. */
  6097. add: function(name, value) {
  6098. if (typeof value === "string") {
  6099. this.color[name] = new Color(value).toRGBA();
  6100. } else {
  6101. this.color[name] = value.toRGBA();
  6102. }
  6103. return value;
  6104. },
  6105. /*
  6106. * 删除调色板实例上用户自己添加的颜色, 该方法不能删除内置的颜色
  6107. * @param name 需要删除的颜色名称
  6108. * @return 删除是否成功的bool值
  6109. */
  6110. remove: function(name) {
  6111. if (this.color.hasOwnProperty(name)) {
  6112. delete this.color[name];
  6113. return true;
  6114. }
  6115. return false;
  6116. }
  6117. });
  6118. Utils.extend(Palette, {
  6119. getColor: function(name) {
  6120. var colorValue = StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name];
  6121. if (colorValue) {
  6122. return new Color(colorValue);
  6123. }
  6124. return null;
  6125. },
  6126. /*
  6127. * 通过给定的名字获取标准的颜色值表示, 返回的值以hex的方式提供
  6128. * @param name 需要获取的标准颜色名称
  6129. * @return 名字所对应的颜色值的hex表示, 如果未找到对应名称的值, 则返回一个空字符串
  6130. */
  6131. getColorValue: function(name) {
  6132. return StandardColor.EXTEND_STANDARD[name] || StandardColor.COLOR_STANDARD[name] || "";
  6133. },
  6134. /*
  6135. * 向调色板添加颜色名称,新添加的颜色对所有的调色板对象都可见
  6136. * 对已存在的颜色名称, 将会覆盖掉
  6137. * @param name 新添加的颜色名称
  6138. * @param value 新添加的颜色名称所对于的值, 应该是一个hex格式的颜色字符串, 如: ”#ff0000“
  6139. * @return 新添加的颜色的值
  6140. */
  6141. addColor: function(name, value) {
  6142. if (typeof value === "string") {
  6143. StandardColor.EXTEND_STANDARD[name] = new Color(value).toRGBA();
  6144. } else {
  6145. StandardColor.EXTEND_STANDARD[name] = value.toRGBA();
  6146. }
  6147. return value;
  6148. },
  6149. /*
  6150. * 删除用户自己添加的颜色, 该方法不能删除内置的颜色, 该方法不会影响调色板实例自由的颜色
  6151. * @param name 需要删除的颜色名称
  6152. * @return 删除是否成功的bool值
  6153. */
  6154. removeColor: function(name) {
  6155. if (StandardColor.EXTEND_STANDARD.hasOwnProperty(name)) {
  6156. delete StandardColor.EXTEND_STANDARD[name];
  6157. return true;
  6158. }
  6159. return false;
  6160. }
  6161. });
  6162. return Palette;
  6163. }
  6164. };
  6165. //src/graphic/paper.js
  6166. _p[45] = {
  6167. value: function(require, exports, module) {
  6168. var Class = _p.r(11);
  6169. var utils = _p.r(12);
  6170. var svg = _p.r(67);
  6171. var Container = _p.r(29);
  6172. var ShapeContainer = _p.r(61);
  6173. var ViewBox = _p.r(75);
  6174. var EventHandler = _p.r(33);
  6175. var Styled = _p.r(66);
  6176. var Matrix = _p.r(43);
  6177. var Paper = Class.createClass("Paper", {
  6178. mixins: [ ShapeContainer, EventHandler, Styled, ViewBox ],
  6179. constructor: function(container) {
  6180. this.callBase();
  6181. this.node = this.createSVGNode();
  6182. this.node.paper = this;
  6183. this.node.appendChild(this.resourceNode = svg.createNode("defs"));
  6184. this.node.appendChild(this.shapeNode = svg.createNode("g"));
  6185. this.resources = new Container();
  6186. this.setWidth("100%").setHeight("100%");
  6187. if (container) {
  6188. this.renderTo(container);
  6189. }
  6190. this.callMixin();
  6191. },
  6192. renderTo: function(container) {
  6193. if (utils.isString(container)) {
  6194. container = document.getElementById(container);
  6195. }
  6196. this.container = container;
  6197. container.appendChild(this.node);
  6198. },
  6199. createSVGNode: function() {
  6200. var node = svg.createNode("svg");
  6201. node.setAttribute("xmlns", "http://www.w3.org/2000/svg");
  6202. node.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
  6203. node.setAttribute("version", "1.1");
  6204. return node;
  6205. },
  6206. getNode: function() {
  6207. return this.node;
  6208. },
  6209. getContainer: function() {
  6210. return this.container;
  6211. },
  6212. getWidth: function() {
  6213. return this.node.clientWidth;
  6214. },
  6215. setWidth: function(width) {
  6216. this.node.setAttribute("width", width);
  6217. return this;
  6218. },
  6219. getHeight: function() {
  6220. return this.node.clientHeight;
  6221. },
  6222. setHeight: function(height) {
  6223. this.node.setAttribute("height", height);
  6224. return this;
  6225. },
  6226. setViewPort: function(cx, cy, zoom) {
  6227. var viewport, box;
  6228. if (arguments.length == 1) {
  6229. viewport = arguments[0];
  6230. cx = viewport.center.x;
  6231. cy = viewport.center.y;
  6232. zoom = viewport.zoom;
  6233. }
  6234. zoom = zoom || 1;
  6235. box = this.getViewBox();
  6236. var matrix = new Matrix();
  6237. var dx = box.x + box.width / 2 - cx, dy = box.y + box.height / 2 - cy;
  6238. matrix.translate(-cx, -cy);
  6239. matrix.scale(zoom);
  6240. matrix.translate(cx, cy);
  6241. matrix.translate(dx, dy);
  6242. this.shapeNode.setAttribute("transform", "matrix(" + matrix + ")");
  6243. this.viewport = {
  6244. center: {
  6245. x: cx,
  6246. y: cy
  6247. },
  6248. offset: {
  6249. x: dx,
  6250. y: dy
  6251. },
  6252. zoom: zoom
  6253. };
  6254. return this;
  6255. },
  6256. getViewPort: function() {
  6257. if (!this.viewport) {
  6258. var box = this.getViewBox();
  6259. return {
  6260. zoom: 1,
  6261. center: {
  6262. x: box.x + box.width / 2,
  6263. y: box.y + box.height / 2
  6264. },
  6265. offset: {
  6266. x: 0,
  6267. y: 0
  6268. }
  6269. };
  6270. }
  6271. return this.viewport;
  6272. },
  6273. getViewPortMatrix: function() {
  6274. return Matrix.parse(this.shapeNode.getAttribute("transform"));
  6275. },
  6276. getViewPortTransform: function() {
  6277. var m = this.shapeNode.getCTM();
  6278. return new Matrix(m.a, m.b, m.c, m.d, m.e, m.f);
  6279. },
  6280. getTransform: function() {
  6281. return this.getViewPortTransform().reverse();
  6282. },
  6283. addResource: function(resource) {
  6284. this.resources.appendItem(resource);
  6285. if (resource.node) {
  6286. this.resourceNode.appendChild(resource.node);
  6287. }
  6288. return this;
  6289. },
  6290. removeResource: function(resource) {
  6291. if (resource.remove) {
  6292. resource.remove();
  6293. }
  6294. if (resource.node) {
  6295. this.resourceNode.removeChild(resource.node);
  6296. }
  6297. return this;
  6298. },
  6299. getPaper: function() {
  6300. return this;
  6301. }
  6302. });
  6303. var Shape = _p.r(60);
  6304. Class.extendClass(Shape, {
  6305. getPaper: function() {
  6306. var parent = this.container;
  6307. while (parent && parent instanceof Paper === false) {
  6308. parent = parent.container;
  6309. }
  6310. return parent;
  6311. },
  6312. isAttached: function() {
  6313. return !!this.getPaper();
  6314. },
  6315. whenPaperReady: function(fn) {
  6316. var me = this;
  6317. function check() {
  6318. var paper = me.getPaper();
  6319. if (paper && fn) {
  6320. fn.call(me, paper);
  6321. }
  6322. return paper;
  6323. }
  6324. if (!check()) {
  6325. this.on("add treeadd", function listen() {
  6326. if (check()) {
  6327. me.off("add", listen);
  6328. me.off("treeadd", listen);
  6329. }
  6330. });
  6331. }
  6332. return this;
  6333. }
  6334. });
  6335. return Paper;
  6336. }
  6337. };
  6338. //src/graphic/path.js
  6339. _p[46] = {
  6340. value: function(require, exports, module) {
  6341. var Utils = _p.r(12);
  6342. var createClass = _p.r(11).createClass;
  6343. var Shape = _p.r(60);
  6344. var svg = _p.r(67);
  6345. var g = _p.r(34);
  6346. var slice = Array.prototype.slice, flatten = Utils.flatten;
  6347. var PathDrawer = createClass("PathDrawer", {
  6348. constructor: function(path) {
  6349. this.segment = [];
  6350. this.path = path;
  6351. this.__clear = false;
  6352. },
  6353. getPath: function() {
  6354. return this.path;
  6355. },
  6356. redraw: function() {
  6357. this._transation = this._transation || [];
  6358. return this.clear();
  6359. },
  6360. done: function() {
  6361. var transation = this._transation;
  6362. this._transation = null;
  6363. this.push(transation);
  6364. return this;
  6365. },
  6366. clear: function() {
  6367. if (this._transation) {
  6368. this._transation = [];
  6369. } else {
  6370. this.path.setPathData("M 0 0");
  6371. }
  6372. this._clear = true;
  6373. return this;
  6374. },
  6375. push: function() {
  6376. var segment = slice.call(arguments);
  6377. var originData;
  6378. if (this._transation) {
  6379. this._transation.push(segment);
  6380. return this;
  6381. }
  6382. if (this._clear) {
  6383. originData = "";
  6384. this._clear = false;
  6385. } else {
  6386. originData = this.path.getPathData();
  6387. }
  6388. originData = originData || "";
  6389. this.path.setPathData(originData + g.pathToString(segment));
  6390. return this;
  6391. },
  6392. moveTo: function(x, y) {
  6393. return this.push("M", slice.call(arguments));
  6394. },
  6395. moveBy: function(dx, dy) {
  6396. return this.push("m", slice.call(arguments));
  6397. },
  6398. lineTo: function(x, y) {
  6399. return this.push("L", slice.call(arguments));
  6400. },
  6401. lineBy: function(dx, dy) {
  6402. return this.push("l", slice.call(arguments));
  6403. },
  6404. arcTo: function(rx, ry, xr, laf, sf, x, y) {
  6405. return this.push("A", slice.call(arguments));
  6406. },
  6407. arcBy: function(rx, ry, xr, laf, sf, dx, dy) {
  6408. return this.push("a", arguments);
  6409. },
  6410. carcTo: function(r, laf, sf, x, y) {
  6411. return this.push("A", [ r, r, 0 ].concat(slice.call(arguments, 1)));
  6412. },
  6413. carcBy: function(r, laf, sf, dx, dy) {
  6414. return this.push("a", [ r, r, 0 ].concat(slice.call(arguments, 1)));
  6415. },
  6416. bezierTo: function(x1, y1, x2, y2, x, y) {
  6417. return this.push("C", slice.call(arguments));
  6418. },
  6419. bezierBy: function(dx1, dy1, dx2, dy2, dx, dy) {
  6420. return this.push("c", slice.call(arguments));
  6421. },
  6422. close: function() {
  6423. return this.push("z");
  6424. }
  6425. });
  6426. return createClass("Path", {
  6427. base: Shape,
  6428. constructor: function(data) {
  6429. this.callBase("path");
  6430. if (data) {
  6431. this.setPathData(data);
  6432. }
  6433. this.node.setAttribute("fill", svg.defaults.fill);
  6434. this.node.setAttribute("stroke", svg.defaults.stroke);
  6435. },
  6436. setPathData: function(data) {
  6437. data = data || "M0,0";
  6438. this.pathdata = g.pathToString(data);
  6439. this.node.setAttribute("d", this.pathdata);
  6440. this.trigger("shapeupdate", {
  6441. type: "pathdata"
  6442. });
  6443. return this;
  6444. },
  6445. getPathData: function() {
  6446. return this.pathdata || "";
  6447. },
  6448. getDrawer: function() {
  6449. return new PathDrawer(this);
  6450. },
  6451. isClosed: function() {
  6452. var data = this.getPathData();
  6453. return !!~data.indexOf("z") || !!~data.indexOf("Z");
  6454. }
  6455. });
  6456. }
  6457. };
  6458. //src/graphic/pattern.js
  6459. _p[47] = {
  6460. value: function(require, exports, module) {
  6461. var Resource = _p.r(58);
  6462. var ShapeContainer = _p.r(61);
  6463. var svg = _p.r(67);
  6464. return _p.r(11).createClass("PatternBrush", {
  6465. base: Resource,
  6466. mixins: [ ShapeContainer ],
  6467. constructor: function(paper) {
  6468. this.callBase("pattern", paper);
  6469. this.node.setAttribute("patternUnits", "userSpaceOnUse");
  6470. },
  6471. setX: function(x) {
  6472. this.x = x;
  6473. this.node.setAttribute("x", x);
  6474. return this;
  6475. },
  6476. setY: function(y) {
  6477. this.y = y;
  6478. this.node.setAttribute("y", y);
  6479. return this;
  6480. },
  6481. setWidth: function(width) {
  6482. this.width = width;
  6483. this.node.setAttribute("width", width);
  6484. return this;
  6485. },
  6486. setHeight: function(height) {
  6487. this.height = height;
  6488. this.node.setAttribute("height", height);
  6489. return this;
  6490. },
  6491. getWidth: function() {
  6492. return this.width;
  6493. },
  6494. getHeight: function() {
  6495. return this.height;
  6496. }
  6497. });
  6498. }
  6499. };
  6500. //src/graphic/pen.js
  6501. _p[48] = {
  6502. value: function(require, exports, module) {
  6503. var Color = _p.r(28);
  6504. return _p.r(11).createClass("Pen", {
  6505. constructor: function(brush, width) {
  6506. this.brush = brush;
  6507. this.width = width || 1;
  6508. this.linecap = null;
  6509. this.linejoin = null;
  6510. this.dashArray = null;
  6511. this.opacity = 1;
  6512. },
  6513. getBrush: function() {
  6514. return this.brush;
  6515. },
  6516. setBrush: function(brush) {
  6517. this.brush = brush;
  6518. return this;
  6519. },
  6520. setColor: function(color) {
  6521. return this.setBrush(color);
  6522. },
  6523. getColor: function() {
  6524. return this.brush instanceof Color ? this.brush : null;
  6525. },
  6526. getWidth: function() {
  6527. return this.width;
  6528. },
  6529. setWidth: function(width) {
  6530. this.width = width;
  6531. return this;
  6532. },
  6533. getOpacity: function() {
  6534. return this.opacity;
  6535. },
  6536. setOpacity: function(opacity) {
  6537. this.opacity = opacity;
  6538. },
  6539. getLineCap: function() {
  6540. return this.linecap;
  6541. },
  6542. setLineCap: function(linecap) {
  6543. this.linecap = linecap;
  6544. return this;
  6545. },
  6546. getLineJoin: function() {
  6547. return this.linejoin;
  6548. },
  6549. setLineJoin: function(linejoin) {
  6550. this.linejoin = linejoin;
  6551. return this;
  6552. },
  6553. getDashArray: function() {
  6554. return this.dashArray;
  6555. },
  6556. setDashArray: function(dashArray) {
  6557. this.dashArray = dashArray;
  6558. return this;
  6559. },
  6560. stroke: function(shape) {
  6561. var node = shape.node;
  6562. node.setAttribute("stroke", this.brush.toString());
  6563. node.setAttribute("stroke-width", this.getWidth());
  6564. if (this.getOpacity() < 1) {
  6565. node.setAttribute("stroke-opacity", this.getOpacity());
  6566. }
  6567. if (this.getLineCap()) {
  6568. node.setAttribute("stroke-linecap", this.getLineCap());
  6569. }
  6570. if (this.getLineJoin()) {
  6571. node.setAttribute("stroke-linejoin", this.getLineJoin());
  6572. }
  6573. if (this.getDashArray()) {
  6574. node.setAttribute("stroke-dasharray", this.getDashArray());
  6575. }
  6576. }
  6577. });
  6578. }
  6579. };
  6580. //src/graphic/pie.js
  6581. _p[49] = {
  6582. value: function(require, exports, module) {
  6583. return _p.r(11).createClass({
  6584. base: _p.r(68),
  6585. constructor: function(radius, angle, angleOffset) {
  6586. this.callBase([ 0, radius ], angle, angleOffset);
  6587. },
  6588. getRadius: function() {
  6589. return this.getSectionArray()[1];
  6590. },
  6591. setRadius: function(radius) {
  6592. this.setSectionArray([ 0, radius ]);
  6593. }
  6594. });
  6595. }
  6596. };
  6597. //src/graphic/point.js
  6598. /*
  6599. * 点对象抽象
  6600. */
  6601. _p[50] = {
  6602. value: function(require, exports, module) {
  6603. /**
  6604. * @class kity.Point
  6605. * @description 表示一个点
  6606. */
  6607. var Point = _p.r(11).createClass("Point", {
  6608. /**
  6609. * @constructor
  6610. * @for kity.Point
  6611. * @description 指定默认的 x 和 y 创建一个点
  6612. *
  6613. * @param {Number} x 点的 x 坐标
  6614. * @param {Number} y 点的 y 坐标
  6615. */
  6616. constructor: function(x, y) {
  6617. /**
  6618. * @property
  6619. * @for kity.Point
  6620. * @description 表示点的 x 坐标
  6621. * @type {Number}
  6622. */
  6623. this.x = x || 0;
  6624. /**
  6625. * @property
  6626. * @for kity.Point
  6627. * @description 表示点的 y 坐标
  6628. * @type {Number}
  6629. */
  6630. this.y = y || 0;
  6631. },
  6632. offset: function(dx, dy) {
  6633. if (arguments.length == 1) {
  6634. dy = dx.y;
  6635. dx = dx.x;
  6636. }
  6637. return new Point(this.x + dx, this.y + dy);
  6638. },
  6639. valueOf: function() {
  6640. return [ this.x, this.y ];
  6641. },
  6642. toString: function() {
  6643. return this.valueOf().join(" ");
  6644. },
  6645. spof: function() {
  6646. return new Point((this.x | 0) + .5, (this.y | 0) + .5);
  6647. },
  6648. round: function() {
  6649. return new Point(this.x | 0, this.y | 0);
  6650. },
  6651. isOrigin: function() {
  6652. return this.x === 0 && this.y === 0;
  6653. }
  6654. });
  6655. /**
  6656. * @static
  6657. * @method fromPolar()
  6658. * @for kity.Point
  6659. * @grammar kity.Point.fromPolar(radius, angle, unit) => kity.Point
  6660. * @param {Number} radius 极坐标中的半径
  6661. * @param {Number} angle 极坐标中的角度
  6662. * @param {String} unit 角度使用的单位,默认为 'deg' (角度),可以取值为 'rad',表示传入的是弧度值
  6663. */
  6664. Point.fromPolar = function(radius, angle, unit) {
  6665. if (unit != "rad") {
  6666. // deg to rad
  6667. angle = angle / 180 * Math.PI;
  6668. }
  6669. return new Point(radius * Math.cos(angle), radius * Math.sin(angle));
  6670. };
  6671. Point.parse = function(unknown) {
  6672. if (!unknown) return new Point();
  6673. if (unknown instanceof Point) {
  6674. return unknown;
  6675. }
  6676. if (typeof unknown == "string") {
  6677. return Point.parse(unknown.split(/\s*[\s,]\s*/));
  6678. }
  6679. if ("0" in unknown && "1" in unknown) {
  6680. return new Point(unknown[0], unknown[1]);
  6681. }
  6682. };
  6683. return Point;
  6684. }
  6685. };
  6686. //src/graphic/pointcontainer.js
  6687. /**
  6688. * 点集合容器
  6689. */
  6690. _p[51] = {
  6691. value: function(require, exports, module) {
  6692. return _p.r(11).createClass("PointContainer", {
  6693. base: _p.r(29),
  6694. constructor: function() {
  6695. this.callBase();
  6696. },
  6697. addPoint: function(point, pos) {
  6698. return this.addItem.apply(this, arguments);
  6699. },
  6700. prependPoint: function() {
  6701. return this.prependItem.apply(this, arguments);
  6702. },
  6703. appendPoint: function() {
  6704. return this.appendItem.apply(this, arguments);
  6705. },
  6706. removePoint: function(pos) {
  6707. return this.removeItem.apply(this, arguments);
  6708. },
  6709. addPoints: function() {
  6710. return this.addItems.apply(this, arguments);
  6711. },
  6712. setPoints: function() {
  6713. return this.setItems.apply(this, arguments);
  6714. },
  6715. getPoint: function() {
  6716. return this.getItem.apply(this, arguments);
  6717. },
  6718. getPoints: function() {
  6719. return this.getItems.apply(this, arguments);
  6720. },
  6721. getFirstPoint: function() {
  6722. return this.getFirstItem.apply(this, arguments);
  6723. },
  6724. getLastPoint: function() {
  6725. return this.getLastItem.apply(this, arguments);
  6726. }
  6727. });
  6728. }
  6729. };
  6730. //src/graphic/poly.js
  6731. /*
  6732. * 通过点来决定图形的公共父类
  6733. */
  6734. _p[52] = {
  6735. value: function(require, exports, module) {
  6736. var Utils = _p.r(12);
  6737. return _p.r(11).createClass("Poly", {
  6738. base: _p.r(46),
  6739. mixins: [ _p.r(51) ],
  6740. constructor: function(points, closeable) {
  6741. this.callBase();
  6742. //是否可闭合
  6743. this.closeable = !!closeable;
  6744. this.setPoints(points || []);
  6745. this.changeable = true;
  6746. this.update();
  6747. },
  6748. //当点集合发生变化时采取的动作
  6749. onContainerChanged: function() {
  6750. if (this.changeable) {
  6751. this.update();
  6752. }
  6753. },
  6754. update: function() {
  6755. var drawer = this.getDrawer(), points = this.getPoints();
  6756. drawer.clear();
  6757. if (!points.length) {
  6758. return this;
  6759. }
  6760. drawer.moveTo(points[0]);
  6761. for (var i = 1, point, len = points.length; i < len; i++) {
  6762. point = points[i];
  6763. drawer.lineTo(point);
  6764. }
  6765. if (this.closeable && points.length > 2) {
  6766. drawer.close();
  6767. }
  6768. return this;
  6769. }
  6770. });
  6771. }
  6772. };
  6773. //src/graphic/polygon.js
  6774. _p[53] = {
  6775. value: function(require, exports, module) {
  6776. return _p.r(11).createClass("Polygon", {
  6777. base: _p.r(52),
  6778. constructor: function(points) {
  6779. this.callBase(points, true);
  6780. }
  6781. });
  6782. }
  6783. };
  6784. //src/graphic/polyline.js
  6785. _p[54] = {
  6786. value: function(require, exports, module) {
  6787. return _p.r(11).createClass("Polyline", {
  6788. base: _p.r(52),
  6789. constructor: function(points) {
  6790. this.callBase(points);
  6791. }
  6792. });
  6793. }
  6794. };
  6795. //src/graphic/radialgradient.js
  6796. _p[55] = {
  6797. value: function(require, exports, module) {
  6798. var Gradient = _p.r(35);
  6799. return _p.r(11).createClass("RadialGradientBrush", {
  6800. base: Gradient,
  6801. constructor: function(paper) {
  6802. this.callBase("radialGradient", paper);
  6803. this.setCenter(.5, .5);
  6804. this.setFocal(.5, .5);
  6805. this.setRadius(.5);
  6806. },
  6807. setCenter: function(cx, cy) {
  6808. this.node.setAttribute("cx", cx);
  6809. this.node.setAttribute("cy", cy);
  6810. return this;
  6811. },
  6812. getCenter: function() {
  6813. return {
  6814. x: +this.node.getAttribute("cx"),
  6815. y: +this.node.getAttribute("cy")
  6816. };
  6817. },
  6818. setFocal: function(fx, fy) {
  6819. this.node.setAttribute("fx", fx);
  6820. this.node.setAttribute("fy", fy);
  6821. return this;
  6822. },
  6823. getFocal: function() {
  6824. return {
  6825. x: +this.node.getAttribute("fx"),
  6826. y: +this.node.getAttribute("fy")
  6827. };
  6828. },
  6829. setRadius: function(r) {
  6830. this.node.setAttribute("r", r);
  6831. return this;
  6832. },
  6833. getRadius: function() {
  6834. return +this.node.getAttribute("r");
  6835. }
  6836. });
  6837. }
  6838. };
  6839. //src/graphic/rect.js
  6840. _p[56] = {
  6841. value: function(require, exports, module) {
  6842. var RectUtils = {}, Utils = _p.r(12), Point = _p.r(50), Box = _p.r(25);
  6843. Utils.extend(RectUtils, {
  6844. //根据传递进来的width、height和radius属性,
  6845. //获取最适合的radius值
  6846. formatRadius: function(width, height, radius) {
  6847. var minValue = Math.floor(Math.min(width / 2, height / 2));
  6848. return Math.min(minValue, radius);
  6849. }
  6850. });
  6851. /**
  6852. * @class kity.Rect
  6853. * @description 表示一个矩形
  6854. * @base kity.Path
  6855. */
  6856. var Rect = _p.r(11).createClass("Rect", {
  6857. base: _p.r(46),
  6858. /**
  6859. * @constructor
  6860. * @for kity.Rect
  6861. * @grammar new kity.Rect(width, height, x, y, radius)
  6862. * @param {Number} width 矩形的初始化宽度
  6863. * @param {Number} height 矩形的初始化高度
  6864. * @param {Number} x 矩形的初始化 x 坐标
  6865. * @param {Number} y 矩形的初始化 y 坐标
  6866. * @param {Number} radius 矩形的初始化圆角大小
  6867. */
  6868. constructor: function(width, height, x, y, radius) {
  6869. this.callBase();
  6870. this.x = x || 0;
  6871. this.y = y || 0;
  6872. this.width = width || 0;
  6873. this.height = height || 0;
  6874. this.radius = RectUtils.formatRadius(this.width, this.height, radius || 0);
  6875. this.update();
  6876. },
  6877. update: function() {
  6878. var x = this.x, y = this.y, w = this.width, h = this.height, r = this.radius;
  6879. var drawer = this.getDrawer().redraw();
  6880. if (!r) {
  6881. // 直角
  6882. drawer.push("M", x, y);
  6883. drawer.push("h", w);
  6884. drawer.push("v", h);
  6885. drawer.push("h", -w);
  6886. drawer.push("z");
  6887. } else {
  6888. //圆角
  6889. w -= 2 * r;
  6890. h -= 2 * r;
  6891. drawer.push("M", x + r, y);
  6892. drawer.push("h", w);
  6893. drawer.push("a", r, r, 0, 0, 1, r, r);
  6894. drawer.push("v", h);
  6895. drawer.push("a", r, r, 0, 0, 1, -r, r);
  6896. drawer.push("h", -w);
  6897. drawer.push("a", r, r, 0, 0, 1, -r, -r);
  6898. drawer.push("v", -h);
  6899. drawer.push("a", r, r, 0, 0, 1, r, -r);
  6900. drawer.push("z");
  6901. }
  6902. drawer.done();
  6903. return this;
  6904. },
  6905. /**
  6906. * @method setWidth
  6907. * @for kity.Rect
  6908. * @grammar setWidth(width) => kity.Rect
  6909. * @description 设置矩形的宽度,设置后返回矩形实例本身
  6910. * @param {Number} width 宽度值
  6911. *
  6912. * @example
  6913. * ```js
  6914. * rect.setWidth(300);
  6915. * ```
  6916. */
  6917. setWidth: function(width) {
  6918. this.width = width;
  6919. return this.update();
  6920. },
  6921. /**
  6922. * @method setHeight
  6923. * @for kity.Rect
  6924. * @grammar setHeight(height) => kity.Rect
  6925. * @description 设置矩形的高度,设置后返回矩形实例本身
  6926. * @param {Number} height 高度值
  6927. *
  6928. * @example
  6929. * ```js
  6930. * rect.setHeight(200);
  6931. * ```
  6932. */
  6933. setHeight: function(height) {
  6934. this.height = height;
  6935. return this.update();
  6936. },
  6937. /**
  6938. * @method setSize
  6939. * @for kity.Rect
  6940. * @grammar setSize(width, height) => kity.Rect
  6941. * @description 设置矩形的尺寸,设置后返回矩形本身
  6942. * @param {Number} width 矩形的宽度值
  6943. * @param {Number} height 矩形的高度值
  6944. *
  6945. * @example
  6946. * ```js
  6947. * rect.setSize(300, 200);
  6948. * ```
  6949. */
  6950. setSize: function(width, height) {
  6951. this.width = width;
  6952. this.height = height;
  6953. return this.update();
  6954. },
  6955. /**
  6956. * @method setBox
  6957. * @for kity.Rect
  6958. * @grammar setBox(box) => kity.Rect
  6959. * @description 使用一个 kity 的盒子数据,
  6960. * @param {kity.Box} box 盒子数据
  6961. */
  6962. setBox: function(box) {
  6963. this.x = box.x;
  6964. this.y = box.y;
  6965. this.width = box.width;
  6966. this.height = box.height;
  6967. return this.update();
  6968. },
  6969. getBox: function() {
  6970. return new Box(this.x, this.y, this.width, this.height);
  6971. },
  6972. getRadius: function() {
  6973. return this.radius;
  6974. },
  6975. setRadius: function(radius) {
  6976. this.radius = RectUtils.formatRadius(this.width, this.height, radius || 0);
  6977. return this.update();
  6978. },
  6979. getPosition: function() {
  6980. return new Point(this.x, this.y);
  6981. },
  6982. setPosition: function(x, y) {
  6983. if (arguments.length == 1) {
  6984. var p = Point.parse(arguments[0]);
  6985. y = p.y;
  6986. x = p.x;
  6987. }
  6988. this.x = x;
  6989. this.y = y;
  6990. return this.update();
  6991. },
  6992. getWidth: function() {
  6993. return this.width;
  6994. },
  6995. getHeight: function() {
  6996. return this.height;
  6997. },
  6998. getPositionX: function() {
  6999. return this.x;
  7000. },
  7001. getPositionY: function() {
  7002. return this.y;
  7003. },
  7004. setPositionX: function(x) {
  7005. this.x = x;
  7006. return this.update();
  7007. },
  7008. setPositionY: function(y) {
  7009. this.y = y;
  7010. return this.update();
  7011. }
  7012. });
  7013. return Rect;
  7014. }
  7015. };
  7016. //src/graphic/regularpolygon.js
  7017. _p[57] = {
  7018. value: function(require, exports, module) {
  7019. var Point = _p.r(50);
  7020. return _p.r(11).createClass("RegularPolygon", {
  7021. base: _p.r(46),
  7022. constructor: function(side, radius, x, y) {
  7023. this.callBase();
  7024. this.radius = radius || 0;
  7025. this.side = Math.max(side || 3, 3);
  7026. if (arguments.length > 2) {
  7027. if (arguments.length == 3) {
  7028. y = x.y;
  7029. x = x.x;
  7030. }
  7031. }
  7032. this.center = new Point(x, y);
  7033. this.draw();
  7034. },
  7035. getSide: function() {
  7036. return this.side;
  7037. },
  7038. setSide: function(side) {
  7039. this.side = side;
  7040. return this.draw();
  7041. },
  7042. getRadius: function() {
  7043. return this.radius;
  7044. },
  7045. setRadius: function(radius) {
  7046. this.radius = radius;
  7047. return this.draw();
  7048. },
  7049. draw: function() {
  7050. var radius = this.radius, side = this.side, step = Math.PI * 2 / side, drawer = this.getDrawer(), i;
  7051. drawer.clear();
  7052. drawer.moveTo(Point.fromPolar(radius, Math.PI / 2, "rad").offset(this.center));
  7053. for (i = 0; i <= side; i++) {
  7054. drawer.lineTo(Point.fromPolar(radius, step * i + Math.PI / 2, "rad").offset(this.center));
  7055. }
  7056. drawer.close();
  7057. return this;
  7058. }
  7059. });
  7060. }
  7061. };
  7062. //src/graphic/resource.js
  7063. /**
  7064. * @fileOverview
  7065. *
  7066. * 资源节点基类
  7067. *
  7068. * @author: techird
  7069. * @copyright: Baidu FEX, 2014
  7070. */
  7071. _p[58] = {
  7072. value: function(require, exports, module) {
  7073. var svg = _p.r(67);
  7074. return _p.r(11).createClass("Resource", {
  7075. constructor: function(nodeType, paper) {
  7076. this.callBase();
  7077. this.node = svg.createNode(nodeType);
  7078. if (paper) {
  7079. paper.addResource(this);
  7080. }
  7081. },
  7082. toString: function() {
  7083. return "url(#" + this.node.id + ")";
  7084. }
  7085. });
  7086. }
  7087. };
  7088. //src/graphic/ring.js
  7089. _p[59] = {
  7090. value: function(require, exports, module) {
  7091. return _p.r(11).createClass({
  7092. base: _p.r(68),
  7093. constructor: function(innerRadius, outerRadius) {
  7094. this.callBase([ innerRadius, outerRadius ], 360, 0);
  7095. },
  7096. getInnerRadius: function() {
  7097. return this.getSectionArray()[0];
  7098. },
  7099. getOuterRadius: function() {
  7100. return this.getSectionArray()[1];
  7101. },
  7102. setInnerRadius: function(value) {
  7103. this.setSectionArray([ value, this.getOuterRadius() ]);
  7104. },
  7105. setOuterRadius: function(value) {
  7106. this.setSectionArray([ this.getInnerRadius(), value ]);
  7107. }
  7108. });
  7109. }
  7110. };
  7111. //src/graphic/shape.js
  7112. _p[60] = {
  7113. value: function(require, exports, module) {
  7114. var svg = _p.r(67);
  7115. var utils = _p.r(12);
  7116. var EventHandler = _p.r(33);
  7117. var Styled = _p.r(66);
  7118. var Data = _p.r(31);
  7119. var Matrix = _p.r(43);
  7120. var Pen = _p.r(48);
  7121. var slice = Array.prototype.slice;
  7122. var Box = _p.r(25);
  7123. var Shape = _p.r(11).createClass("Shape", {
  7124. mixins: [ EventHandler, Styled, Data ],
  7125. constructor: function Shape(tagName) {
  7126. this.node = svg.createNode(tagName);
  7127. this.node.shape = this;
  7128. this.transform = {
  7129. translate: null,
  7130. rotate: null,
  7131. scale: null,
  7132. matrix: null
  7133. };
  7134. this.callMixin();
  7135. },
  7136. getId: function() {
  7137. return this.node.id;
  7138. },
  7139. setId: function(id) {
  7140. this.node.id = id;
  7141. return this;
  7142. },
  7143. getNode: function() {
  7144. return this.node;
  7145. },
  7146. getBoundaryBox: function() {
  7147. var box;
  7148. try {
  7149. box = this.node.getBBox();
  7150. } catch (e) {
  7151. box = {
  7152. x: this.node.clientLeft,
  7153. y: this.node.clientTop,
  7154. width: this.node.clientWidth,
  7155. height: this.node.clientHeight
  7156. };
  7157. }
  7158. return new Box(box);
  7159. },
  7160. getRenderBox: function(refer) {
  7161. var box = this.getBoundaryBox();
  7162. var matrix = this.getTransform(refer);
  7163. return matrix.transformBox(box);
  7164. },
  7165. getWidth: function() {
  7166. return this.getRenderBox().width;
  7167. },
  7168. getHeight: function() {
  7169. return this.getRenderBox().height;
  7170. },
  7171. getSize: function() {
  7172. var box = this.getRenderBox();
  7173. delete box.x;
  7174. delete box.y;
  7175. return box;
  7176. },
  7177. setOpacity: function(value) {
  7178. this.node.setAttribute("opacity", value);
  7179. return this;
  7180. },
  7181. getOpacity: function() {
  7182. var opacity = this.node.getAttribute("opacity");
  7183. return opacity ? +opacity : 1;
  7184. },
  7185. setVisible: function(value) {
  7186. if (value) {
  7187. this.node.removeAttribute("display");
  7188. } else {
  7189. this.node.setAttribute("display", "none");
  7190. }
  7191. return this;
  7192. },
  7193. getVisible: function() {
  7194. this.node.getAttribute("display");
  7195. },
  7196. hasAncestor: function(node) {
  7197. var parent = this.container;
  7198. while (parent) {
  7199. if (parent === node) {
  7200. return true;
  7201. }
  7202. parent = parent.container;
  7203. }
  7204. return false;
  7205. },
  7206. getTransform: function(refer) {
  7207. return Matrix.getCTM(this, refer);
  7208. },
  7209. clearTransform: function() {
  7210. this.node.removeAttribute("transform");
  7211. this.transform = {
  7212. translate: null,
  7213. rotate: null,
  7214. scale: null,
  7215. matrix: null
  7216. };
  7217. this.trigger("shapeupdate", {
  7218. type: "transform"
  7219. });
  7220. return this;
  7221. },
  7222. _applyTransform: function() {
  7223. var t = this.transform, result = [];
  7224. if (t.translate) {
  7225. result.push([ "translate(", t.translate, ")" ]);
  7226. }
  7227. if (t.rotate) {
  7228. result.push([ "rotate(", t.rotate, ")" ]);
  7229. }
  7230. if (t.scale) {
  7231. result.push([ "scale(", t.scale, ")" ]);
  7232. }
  7233. if (t.matrix) {
  7234. result.push([ "matrix(", t.matrix, ")" ]);
  7235. }
  7236. this.node.setAttribute("transform", utils.flatten(result).join(" "));
  7237. return this;
  7238. },
  7239. setMatrix: function(m) {
  7240. this.transform.matrix = m;
  7241. return this._applyTransform();
  7242. },
  7243. setTranslate: function(t) {
  7244. this.transform.translate = t !== null && slice.call(arguments) || null;
  7245. return this._applyTransform();
  7246. },
  7247. setRotate: function(r) {
  7248. this.transform.rotate = r !== null && slice.call(arguments) || null;
  7249. return this._applyTransform();
  7250. },
  7251. setScale: function(s) {
  7252. this.transform.scale = s !== null && slice.call(arguments) || null;
  7253. return this._applyTransform();
  7254. },
  7255. translate: function(dx, dy) {
  7256. var m = this.transform.matrix || new Matrix();
  7257. if (dy === undefined) {
  7258. dy = 0;
  7259. }
  7260. this.transform.matrix = m.translate(dx, dy);
  7261. return this._applyTransform();
  7262. },
  7263. rotate: function(deg) {
  7264. var m = this.transform.matrix || new Matrix();
  7265. this.transform.matrix = m.rotate(deg);
  7266. return this._applyTransform();
  7267. },
  7268. scale: function(sx, sy) {
  7269. var m = this.transform.matrix || new Matrix();
  7270. if (sy === undefined) {
  7271. sy = sx;
  7272. }
  7273. this.transform.matrix = m.scale(sx, sy);
  7274. return this._applyTransform();
  7275. },
  7276. skew: function(sx, sy) {
  7277. var m = this.transform.matrix || new Matrix();
  7278. if (sy === undefined) {
  7279. sy = sx;
  7280. }
  7281. this.transform.matrix = m.skew(sx, sy);
  7282. return this._applyTransform();
  7283. },
  7284. stroke: function(pen, width) {
  7285. if (pen && pen.stroke) {
  7286. pen.stroke(this);
  7287. } else if (pen) {
  7288. // 字符串或重写了 toString 的对象
  7289. this.node.setAttribute("stroke", pen.toString());
  7290. if (width) {
  7291. this.node.setAttribute("stroke-width", width);
  7292. }
  7293. } else if (pen === null) {
  7294. this.node.removeAttribute("stroe");
  7295. }
  7296. return this;
  7297. },
  7298. fill: function(brush) {
  7299. // 字符串或重写了 toString 的对象
  7300. if (brush) {
  7301. this.node.setAttribute("fill", brush.toString());
  7302. }
  7303. if (brush === null) {
  7304. this.node.removeAttribute("fill");
  7305. }
  7306. return this;
  7307. },
  7308. setAttr: function(a, v) {
  7309. var me = this;
  7310. if (utils.isObject(a)) {
  7311. utils.each(a, function(val, key) {
  7312. me.setAttr(key, val);
  7313. });
  7314. }
  7315. if (v === undefined || v === null || v === "") {
  7316. this.node.removeAttribute(a);
  7317. } else {
  7318. this.node.setAttribute(a, v);
  7319. }
  7320. return this;
  7321. },
  7322. getAttr: function(a) {
  7323. return this.node.getAttribute(a);
  7324. }
  7325. });
  7326. return Shape;
  7327. }
  7328. };
  7329. //src/graphic/shapecontainer.js
  7330. _p[61] = {
  7331. value: function(require, exports, module) {
  7332. var Container = _p.r(29);
  7333. var utils = _p.r(12);
  7334. var ShapeContainer = _p.r(11).createClass("ShapeContainer", {
  7335. base: Container,
  7336. isShapeContainer: true,
  7337. /* private */
  7338. handleAdd: function(shape, index) {
  7339. var parent = this.getShapeNode();
  7340. parent.insertBefore(shape.node, parent.childNodes[index] || null);
  7341. shape.trigger("add", {
  7342. container: this
  7343. });
  7344. if (shape.notifyTreeModification) {
  7345. shape.notifyTreeModification("treeadd", this);
  7346. }
  7347. },
  7348. /* private */
  7349. handleRemove: function(shape, index) {
  7350. var parent = this.getShapeNode();
  7351. parent.removeChild(shape.node);
  7352. shape.trigger("remove", {
  7353. container: this
  7354. });
  7355. if (shape.notifyTreeModification) {
  7356. shape.notifyTreeModification("treeremove", this);
  7357. }
  7358. },
  7359. /* private */
  7360. notifyTreeModification: function(type, container) {
  7361. this.eachItem(function(index, shape) {
  7362. if (shape.notifyTreeModification) {
  7363. shape.notifyTreeModification(type, container);
  7364. }
  7365. shape.trigger(type, {
  7366. container: container
  7367. });
  7368. });
  7369. },
  7370. /* public */
  7371. getShape: function(index) {
  7372. return this.getItem(index);
  7373. },
  7374. /* public */
  7375. addShape: function(shape, index) {
  7376. return this.addItem(shape, index);
  7377. },
  7378. put: function(shape) {
  7379. this.addShape(shape);
  7380. return shape;
  7381. },
  7382. appendShape: function(shape) {
  7383. return this.addShape(shape);
  7384. },
  7385. prependShape: function(shape) {
  7386. return this.addShape(shape, 0);
  7387. },
  7388. replaceShape: function(replacer, origin) {
  7389. var index = this.indexOf(origin);
  7390. if (index === -1) {
  7391. return;
  7392. }
  7393. this.removeShape(index);
  7394. this.addShape(replacer, index);
  7395. return this;
  7396. },
  7397. addShapeBefore: function(shape, refer) {
  7398. var index = this.indexOf(refer);
  7399. return this.addShape(shape, index);
  7400. },
  7401. addShapeAfter: function(shape, refer) {
  7402. var index = this.indexOf(refer);
  7403. return this.addShape(shape, index === -1 ? undefined : index + 1);
  7404. },
  7405. /* public */
  7406. addShapes: function(shapes) {
  7407. return this.addItems(shapes);
  7408. },
  7409. /* public */
  7410. removeShape: function(index) {
  7411. return this.removeItem(index);
  7412. },
  7413. getShapes: function() {
  7414. return this.getItems();
  7415. },
  7416. getShapesByType: function(name) {
  7417. var shapes = [];
  7418. function getShapes(shape) {
  7419. if (name.toLowerCase() == shape.getType().toLowerCase()) {
  7420. shapes.push(shape);
  7421. }
  7422. if (shape.isShapeContainer) {
  7423. utils.each(shape.getShapes(), function(n) {
  7424. getShapes(n);
  7425. });
  7426. }
  7427. }
  7428. getShapes(this);
  7429. return shapes;
  7430. },
  7431. /* public */
  7432. getShapeById: function(id) {
  7433. return this.getShapeNode().getElementById(id).shape;
  7434. },
  7435. arrangeShape: function(shape, index) {
  7436. return this.removeShape(shape).addShape(shape, index);
  7437. },
  7438. /* protected */
  7439. getShapeNode: function() {
  7440. return this.shapeNode || this.node;
  7441. }
  7442. });
  7443. var Shape = _p.r(60);
  7444. _p.r(11).extendClass(Shape, {
  7445. bringTo: function(index) {
  7446. this.container.arrangeShape(this, index);
  7447. return this;
  7448. },
  7449. bringFront: function() {
  7450. return this.bringTo(this.container.indexOf(this) + 1);
  7451. },
  7452. bringBack: function() {
  7453. return this.bringTo(this.container.indexOf(this) - 1);
  7454. },
  7455. bringTop: function() {
  7456. this.container.removeShape(this).addShape(this);
  7457. return this;
  7458. },
  7459. bringRear: function() {
  7460. return this.bringTo(0);
  7461. },
  7462. bringRefer: function(referShape, offset) {
  7463. if (referShape.container) {
  7464. if (this.remove) {
  7465. this.remove();
  7466. }
  7467. referShape.container.addShape(this, referShape.container.indexOf(referShape) + (offset || 0));
  7468. }
  7469. return this;
  7470. },
  7471. bringAbove: function(referShape) {
  7472. return this.bringRefer(referShape);
  7473. },
  7474. bringBelow: function(referShape) {
  7475. return this.bringRefer(referShape, 1);
  7476. },
  7477. replaceBy: function(newShape) {
  7478. if (this.container) {
  7479. newShape.bringAbove(this);
  7480. this.remove();
  7481. }
  7482. return this;
  7483. }
  7484. });
  7485. return ShapeContainer;
  7486. }
  7487. };
  7488. //src/graphic/shapeevent.js
  7489. /*
  7490. * 图形事件包装类
  7491. * */
  7492. _p[62] = {
  7493. value: function(require, exprots, module) {
  7494. var Matrix = _p.r(43), Utils = _p.r(12), Point = _p.r(50);
  7495. return _p.r(11).createClass("ShapeEvent", {
  7496. constructor: function(event) {
  7497. var target = null;
  7498. // dom 事件封装对象
  7499. if (!Utils.isObject(event.target)) {
  7500. this.type = event.type;
  7501. target = event.target;
  7502. // use标签有特殊属性, 需要区别对待
  7503. if (target.correspondingUseElement) {
  7504. target = target.correspondingUseElement;
  7505. }
  7506. this.originEvent = event;
  7507. this.targetShape = target.shape || target.paper || event.currentTarget && (event.currentTarget.shape || event.currentTarget.paper);
  7508. if (event._kityParam) {
  7509. Utils.extend(this, event._kityParam);
  7510. }
  7511. } else {
  7512. Utils.extend(this, event);
  7513. }
  7514. },
  7515. preventDefault: function() {
  7516. var evt = this.originEvent;
  7517. if (!evt) {
  7518. return true;
  7519. }
  7520. if (evt.preventDefault) {
  7521. evt.preventDefault();
  7522. return evt.cancelable;
  7523. } else {
  7524. evt.returnValue = false;
  7525. return true;
  7526. }
  7527. },
  7528. //当前鼠标事件在用户坐标系中点击的点的坐标位置
  7529. getPosition: function(refer, touchIndex) {
  7530. if (!this.originEvent) {
  7531. return null;
  7532. }
  7533. var eventClient = this.originEvent.touches ? this.originEvent.touches[touchIndex || 0] : this.originEvent;
  7534. var target = this.targetShape;
  7535. var targetNode = target.shapeNode || target.node;
  7536. var pScreen = new Point(eventClient && eventClient.clientX || 0, eventClient && eventClient.clientY || 0);
  7537. var pTarget = Matrix.transformPoint(pScreen, targetNode.getScreenCTM().inverse());
  7538. var pRefer = Matrix.getCTM(target, refer || "view").transformPoint(pTarget);
  7539. return pRefer;
  7540. },
  7541. stopPropagation: function() {
  7542. var evt = this.originEvent;
  7543. if (!evt) {
  7544. return true;
  7545. }
  7546. if (evt.stopPropagation) {
  7547. evt.stopPropagation();
  7548. } else {
  7549. evt.cancelBubble = false;
  7550. }
  7551. }
  7552. });
  7553. }
  7554. };
  7555. //src/graphic/shapepoint.js
  7556. /*
  7557. * 图形上的点抽象
  7558. */
  7559. _p[63] = {
  7560. value: function(require, exports, module) {
  7561. return _p.r(11).createClass("ShapePoint", {
  7562. base: _p.r(50),
  7563. constructor: function(px, py) {
  7564. this.callBase(px, py);
  7565. },
  7566. setX: function(x) {
  7567. return this.setPoint(x, this.y);
  7568. },
  7569. setY: function(y) {
  7570. return this.setPoint(this.x, y);
  7571. },
  7572. setPoint: function(x, y) {
  7573. this.x = x;
  7574. this.y = y;
  7575. this.update();
  7576. return this;
  7577. },
  7578. getPoint: function() {
  7579. return this;
  7580. },
  7581. update: function() {
  7582. if (this.container && this.container.update) {
  7583. this.container.update();
  7584. }
  7585. return this;
  7586. }
  7587. });
  7588. }
  7589. };
  7590. //src/graphic/standardcolor.js
  7591. /**
  7592. * 标准颜色映射
  7593. */
  7594. _p[64] = {
  7595. value: {
  7596. COLOR_STANDARD: {
  7597. aliceblue: "#f0f8ff",
  7598. antiquewhite: "#faebd7",
  7599. aqua: "#00ffff",
  7600. aquamarine: "#7fffd4",
  7601. azure: "#f0ffff",
  7602. beige: "#f5f5dc",
  7603. bisque: "#ffe4c4",
  7604. black: "#000000",
  7605. blanchedalmond: "#ffebcd",
  7606. blue: "#0000ff",
  7607. blueviolet: "#8a2be2",
  7608. brown: "#a52a2a",
  7609. burlywood: "#deb887",
  7610. cadetblue: "#5f9ea0",
  7611. chartreuse: "#7fff00",
  7612. chocolate: "#d2691e",
  7613. coral: "#ff7f50",
  7614. cornflowerblue: "#6495ed",
  7615. cornsilk: "#fff8dc",
  7616. crimson: "#dc143c",
  7617. cyan: "#00ffff",
  7618. darkblue: "#00008b",
  7619. darkcyan: "#008b8b",
  7620. darkgoldenrod: "#b8860b",
  7621. darkgray: "#a9a9a9",
  7622. darkgreen: "#006400",
  7623. darkgrey: "#a9a9a9",
  7624. darkkhaki: "#bdb76b",
  7625. darkmagenta: "#8b008b",
  7626. darkolivegreen: "#556b2f",
  7627. darkorange: "#ff8c00",
  7628. darkorchid: "#9932cc",
  7629. darkred: "#8b0000",
  7630. darksalmon: "#e9967a",
  7631. darkseagreen: "#8fbc8f",
  7632. darkslateblue: "#483d8b",
  7633. darkslategray: "#2f4f4f",
  7634. darkslategrey: "#2f4f4f",
  7635. darkturquoise: "#00ced1",
  7636. darkviolet: "#9400d3",
  7637. deeppink: "#ff1493",
  7638. deepskyblue: "#00bfff",
  7639. dimgray: "#696969",
  7640. dimgrey: "#696969",
  7641. dodgerblue: "#1e90ff",
  7642. firebrick: "#b22222",
  7643. floralwhite: "#fffaf0",
  7644. forestgreen: "#228b22",
  7645. fuchsia: "#ff00ff",
  7646. gainsboro: "#dcdcdc",
  7647. ghostwhite: "#f8f8ff",
  7648. gold: "#ffd700",
  7649. goldenrod: "#daa520",
  7650. gray: "#808080",
  7651. green: "#008000",
  7652. greenyellow: "#adff2f",
  7653. grey: "#808080",
  7654. honeydew: "#f0fff0",
  7655. hotpink: "#ff69b4",
  7656. indianred: "#cd5c5c",
  7657. indigo: "#4b0082",
  7658. ivory: "#fffff0",
  7659. khaki: "#f0e68c",
  7660. lavender: "#e6e6fa",
  7661. lavenderblush: "#fff0f5",
  7662. lawngreen: "#7cfc00",
  7663. lemonchiffon: "#fffacd",
  7664. lightblue: "#add8e6",
  7665. lightcoral: "#f08080",
  7666. lightcyan: "#e0ffff",
  7667. lightgoldenrodyellow: "#fafad2",
  7668. lightgray: "#d3d3d3",
  7669. lightgreen: "#90ee90",
  7670. lightgrey: "#d3d3d3",
  7671. lightpink: "#ffb6c1",
  7672. lightsalmon: "#ffa07a",
  7673. lightseagreen: "#20b2aa",
  7674. lightskyblue: "#87cefa",
  7675. lightslategray: "#778899",
  7676. lightslategrey: "#778899",
  7677. lightsteelblue: "#b0c4de",
  7678. lightyellow: "#ffffe0",
  7679. lime: "#00ff00",
  7680. limegreen: "#32cd32",
  7681. linen: "#faf0e6",
  7682. magenta: "#ff00ff",
  7683. maroon: "#800000",
  7684. mediumaquamarine: "#66cdaa",
  7685. mediumblue: "#0000cd",
  7686. mediumorchid: "#ba55d3",
  7687. mediumpurple: "#9370db",
  7688. mediumseagreen: "#3cb371",
  7689. mediumslateblue: "#7b68ee",
  7690. mediumspringgreen: "#00fa9a",
  7691. mediumturquoise: "#48d1cc",
  7692. mediumvioletred: "#c71585",
  7693. midnightblue: "#191970",
  7694. mintcream: "#f5fffa",
  7695. mistyrose: "#ffe4e1",
  7696. moccasin: "#ffe4b5",
  7697. navajowhite: "#ffdead",
  7698. navy: "#000080",
  7699. oldlace: "#fdf5e6",
  7700. olive: "#808000",
  7701. olivedrab: "#6b8e23",
  7702. orange: "#ffa500",
  7703. orangered: "#ff4500",
  7704. orchid: "#da70d6",
  7705. palegoldenrod: "#eee8aa",
  7706. palegreen: "#98fb98",
  7707. paleturquoise: "#afeeee",
  7708. palevioletred: "#db7093",
  7709. papayawhip: "#ffefd5",
  7710. peachpuff: "#ffdab9",
  7711. peru: "#cd853f",
  7712. pink: "#ffc0cb",
  7713. plum: "#dda0dd",
  7714. powderblue: "#b0e0e6",
  7715. purple: "#800080",
  7716. red: "#ff0000",
  7717. rosybrown: "#bc8f8f",
  7718. royalblue: "#4169e1",
  7719. saddlebrown: "#8b4513",
  7720. salmon: "#fa8072",
  7721. sandybrown: "#f4a460",
  7722. seagreen: "#2e8b57",
  7723. seashell: "#fff5ee",
  7724. sienna: "#a0522d",
  7725. silver: "#c0c0c0",
  7726. skyblue: "#87ceeb",
  7727. slateblue: "#6a5acd",
  7728. slategray: "#708090",
  7729. slategrey: "#708090",
  7730. snow: "#fffafa",
  7731. springgreen: "#00ff7f",
  7732. steelblue: "#4682b4",
  7733. tan: "#d2b48c",
  7734. teal: "#008080",
  7735. thistle: "#d8bfd8",
  7736. tomato: "#ff6347",
  7737. turquoise: "#40e0d0",
  7738. violet: "#ee82ee",
  7739. wheat: "#f5deb3",
  7740. white: "#ffffff",
  7741. whitesmoke: "#f5f5f5",
  7742. yellow: "#ffff00"
  7743. },
  7744. //标准扩展
  7745. EXTEND_STANDARD: {}
  7746. }
  7747. };
  7748. //src/graphic/star.js
  7749. _p[65] = {
  7750. value: function(require, exports, module) {
  7751. /**
  7752. * @see http://www.jdawiseman.com/papers/easymath/surds_star_inner_radius.html
  7753. */
  7754. var defaultRatioForStar = {
  7755. "3": .2,
  7756. // yy
  7757. "5": .38196601125,
  7758. "6": .57735026919,
  7759. "8": .541196100146,
  7760. "10": .726542528005,
  7761. "12": .707106781187
  7762. };
  7763. var Point = _p.r(50);
  7764. return _p.r(11).createClass("Star", {
  7765. base: _p.r(46),
  7766. constructor: function(vertex, radius, shrink, offset, angleOffset) {
  7767. this.callBase();
  7768. this.vertex = vertex || 3;
  7769. this.radius = radius || 0;
  7770. this.shrink = shrink;
  7771. this.offset = offset || new Point(0, 0);
  7772. this.angleOffset = angleOffset || 0;
  7773. this.draw();
  7774. },
  7775. getVertex: function() {
  7776. return this.vertex;
  7777. },
  7778. setVertex: function(value) {
  7779. this.vertex = value;
  7780. return this.draw();
  7781. },
  7782. getRadius: function() {
  7783. return this.radius;
  7784. },
  7785. setRadius: function(value) {
  7786. this.radius = value;
  7787. return this.draw();
  7788. },
  7789. getShrink: function() {
  7790. return this.shrink;
  7791. },
  7792. setShrink: function(value) {
  7793. this.shrink = value;
  7794. return this.draw();
  7795. },
  7796. getOffset: function() {
  7797. return this.offset;
  7798. },
  7799. setOffset: function(value) {
  7800. this.offset = value;
  7801. return this.draw();
  7802. },
  7803. getAngleOffset: function() {
  7804. return this.angleOffset;
  7805. },
  7806. setAngleOffset: function(value) {
  7807. this.angleOffset = value;
  7808. return this.draw();
  7809. },
  7810. draw: function() {
  7811. var innerRadius = this.radius, outerRadius = this.radius * (this.shrink || defaultRatioForStar[this.vertex] || .5), vertex = this.vertex, offset = this.offset, angleStart = 90, angleStep = 180 / vertex, angleOffset = this.angleOffset, drawer = this.getDrawer(), i, angle;
  7812. drawer.clear();
  7813. drawer.moveTo(Point.fromPolar(outerRadius, angleStart));
  7814. for (i = 1; i <= vertex * 2; i++) {
  7815. angle = angleStart + angleStep * i;
  7816. // 绘制内点
  7817. if (i % 2) {
  7818. drawer.lineTo(Point.fromPolar(innerRadius, angle + angleOffset).offset(offset));
  7819. } else {
  7820. drawer.lineTo(Point.fromPolar(outerRadius, angle));
  7821. }
  7822. }
  7823. drawer.close();
  7824. }
  7825. });
  7826. }
  7827. };
  7828. //src/graphic/styled.js
  7829. _p[66] = {
  7830. value: function(require, exports, module) {
  7831. // polyfill for ie
  7832. var ClassList = _p.r(11).createClass("ClassList", {
  7833. constructor: function(node) {
  7834. this._node = node;
  7835. this._list = node.className.toString().split(" ");
  7836. },
  7837. _update: function() {
  7838. this._node.className = this._list.join(" ");
  7839. },
  7840. add: function(name) {
  7841. this._list.push(name);
  7842. this._update();
  7843. },
  7844. remove: function(name) {
  7845. var index = this._list.indexOf(name);
  7846. if (~index) {
  7847. this._list.splice(index, 1);
  7848. }
  7849. this._update();
  7850. },
  7851. contains: function(name) {
  7852. return !!~this._list.indexOf(name);
  7853. }
  7854. });
  7855. function getClassList(node) {
  7856. if (!node.classList) {
  7857. node.classList = new ClassList(node);
  7858. }
  7859. return node.classList;
  7860. }
  7861. return _p.r(11).createClass("Styled", {
  7862. addClass: function(name) {
  7863. getClassList(this.node).add(name);
  7864. return this;
  7865. },
  7866. removeClass: function(name) {
  7867. getClassList(this.node).remove(name);
  7868. return this;
  7869. },
  7870. hasClass: function(name) {
  7871. return getClassList(this.node).contains(name);
  7872. },
  7873. setStyle: function(styles) {
  7874. if (arguments.length == 2) {
  7875. this.node.style[arguments[0]] = arguments[1];
  7876. return this;
  7877. }
  7878. for (var name in styles) {
  7879. if (styles.hasOwnProperty(name)) {
  7880. this.node.style[name] = styles[name];
  7881. }
  7882. }
  7883. return this;
  7884. }
  7885. });
  7886. }
  7887. };
  7888. //src/graphic/svg.js
  7889. _p[67] = {
  7890. value: function(require, exports, module) {
  7891. var doc = document;
  7892. var id = 0;
  7893. var svg = {
  7894. createNode: function(name) {
  7895. var node = doc.createElementNS(svg.ns, name);
  7896. node.id = "kity_" + name + "_" + id++;
  7897. return node;
  7898. },
  7899. defaults: {
  7900. stroke: "none",
  7901. fill: "none"
  7902. },
  7903. xlink: "http://www.w3.org/1999/xlink",
  7904. ns: "http://www.w3.org/2000/svg"
  7905. };
  7906. return svg;
  7907. }
  7908. };
  7909. //src/graphic/sweep.js
  7910. _p[68] = {
  7911. value: function(require, exports, module) {
  7912. var Point = _p.r(50);
  7913. return _p.r(11).createClass("Sweep", {
  7914. base: _p.r(46),
  7915. constructor: function(sectionArray, angle, angleOffset) {
  7916. this.callBase();
  7917. this.sectionArray = sectionArray || [];
  7918. this.angle = angle || 0;
  7919. this.angleOffset = angleOffset || 0;
  7920. this.draw();
  7921. },
  7922. getSectionArray: function() {
  7923. return this.sectionArray;
  7924. },
  7925. setSectionArray: function(value) {
  7926. this.sectionArray = value;
  7927. return this.draw();
  7928. },
  7929. getAngle: function() {
  7930. return this.angle;
  7931. },
  7932. setAngle: function(value) {
  7933. this.angle = value;
  7934. return this.draw();
  7935. },
  7936. getAngleOffset: function() {
  7937. return this.angleOffset;
  7938. },
  7939. setAngleOffset: function(value) {
  7940. this.angleOffset = value;
  7941. return this.draw();
  7942. },
  7943. draw: function() {
  7944. var sectionArray = this.sectionArray, i;
  7945. for (i = 0; i < sectionArray.length; i += 2) {
  7946. this.drawSection(sectionArray[i], sectionArray[i + 1]);
  7947. }
  7948. return this;
  7949. },
  7950. drawSection: function(from, to) {
  7951. var angleLength = this.angle && (this.angle % 360 ? this.angle % 360 : 360), angleStart = this.angleOffset, angleHalf = angleStart + angleLength / 2, angleEnd = angleStart + angleLength, sweepFlag = angleLength < 0 ? 0 : 1, drawer = this.getDrawer();
  7952. drawer.redraw();
  7953. if (angleLength === 0) {
  7954. drawer.done();
  7955. return;
  7956. }
  7957. drawer.moveTo(Point.fromPolar(from, angleStart));
  7958. drawer.lineTo(Point.fromPolar(to, angleStart));
  7959. if (to) {
  7960. drawer.carcTo(to, 0, sweepFlag, Point.fromPolar(to, angleHalf));
  7961. drawer.carcTo(to, 0, sweepFlag, Point.fromPolar(to, angleEnd));
  7962. }
  7963. drawer.lineTo(Point.fromPolar(from, angleEnd));
  7964. if (from) {
  7965. drawer.carcTo(from, 0, sweepFlag, Point.fromPolar(from, angleHalf));
  7966. drawer.carcTo(from, 0, sweepFlag, Point.fromPolar(from, angleStart));
  7967. }
  7968. drawer.close();
  7969. drawer.done();
  7970. }
  7971. });
  7972. }
  7973. };
  7974. //src/graphic/text.js
  7975. _p[69] = {
  7976. value: function(require, exports, module) {
  7977. var TextContent = _p.r(70);
  7978. var ShapeContainer = _p.r(61);
  7979. var svg = _p.r(67);
  7980. var utils = _p.r(12);
  7981. var offsetHash = {};
  7982. function getTextBoundOffset(text) {
  7983. var font = text._cachedFontHash;
  7984. if (offsetHash[font]) {
  7985. return offsetHash[font];
  7986. }
  7987. var textContent = text.getContent();
  7988. //text.setContent("百度Fex");
  7989. text.setContent("脑图");
  7990. var bbox = text.getBoundaryBox(), y = text.getY();
  7991. if (!bbox.height) return {
  7992. top: 0,
  7993. bottom: 0,
  7994. middle: 0
  7995. };
  7996. var topOffset = y - bbox.y + +text.node.getAttribute("dy"), bottomOffset = topOffset - bbox.height;
  7997. text.setContent(textContent);
  7998. return offsetHash[font] = {
  7999. top: topOffset,
  8000. bottom: bottomOffset,
  8001. middle: (topOffset + bottomOffset) / 2
  8002. };
  8003. }
  8004. return _p.r(11).createClass("Text", {
  8005. base: TextContent,
  8006. mixins: [ ShapeContainer ],
  8007. constructor: function(content) {
  8008. this.callBase("text");
  8009. if (content !== undefined) {
  8010. this.setContent(content);
  8011. }
  8012. this._buildFontHash();
  8013. },
  8014. fixPosition: function() {
  8015. if (!this.__fixedPosition) {
  8016. this.setVerticalAlign(this.getVerticalAlign());
  8017. }
  8018. },
  8019. _buildFontHash: function() {
  8020. var style = window.getComputedStyle(this.node);
  8021. this._cachedFontHash = [ style.fontFamily, style.fontSize, style.fontStretch, style.fontStyle, style.fontVariant, style.fontWeight ].join("-");
  8022. },
  8023. _fontChanged: function(font) {
  8024. var last = this._lastFont;
  8025. var current = utils.extend({}, last, font);
  8026. if (!last) {
  8027. this._lastFont = font;
  8028. return true;
  8029. }
  8030. var changed = last.family != current.family || last.size != current.size || last.style != current.style || last.weight != current.weight;
  8031. this._lastFont = current;
  8032. return changed;
  8033. },
  8034. setX: function(x) {
  8035. this.node.setAttribute("x", x);
  8036. return this;
  8037. },
  8038. setPosition: function(x, y) {
  8039. return this.setX(x).setY(y);
  8040. },
  8041. setY: function(y) {
  8042. this.node.setAttribute("y", y);
  8043. return this;
  8044. },
  8045. getX: function() {
  8046. return +this.node.getAttribute("x") || 0;
  8047. },
  8048. getY: function() {
  8049. return +this.node.getAttribute("y") || 0;
  8050. },
  8051. setFont: function(font) {
  8052. this.callBase(font);
  8053. if (this._fontChanged(font)) {
  8054. this._buildFontHash();
  8055. this.setVerticalAlign(this.getVerticalAlign());
  8056. }
  8057. return this;
  8058. },
  8059. setTextAnchor: function(anchor) {
  8060. this.node.setAttribute("text-anchor", anchor);
  8061. return this;
  8062. },
  8063. getTextAnchor: function() {
  8064. return this.node.getAttribute("text-anchor") || "start";
  8065. },
  8066. // top/bottom/middle/baseline
  8067. setVerticalAlign: function(align) {
  8068. this.whenPaperReady(function() {
  8069. var dy;
  8070. switch (align) {
  8071. case "top":
  8072. dy = getTextBoundOffset(this).top;
  8073. break;
  8074. case "bottom":
  8075. dy = getTextBoundOffset(this).bottom;
  8076. break;
  8077. case "middle":
  8078. dy = getTextBoundOffset(this).middle;
  8079. break;
  8080. default:
  8081. dy = 0;
  8082. }
  8083. if (dy) this.__fixedPosition = true;
  8084. this.node.setAttribute("dy", dy);
  8085. });
  8086. this.verticalAlign = align;
  8087. return this;
  8088. },
  8089. getVerticalAlign: function() {
  8090. return this.verticalAlign || "baseline";
  8091. },
  8092. setStartOffset: function(offset) {
  8093. // only for text path
  8094. if (this.shapeNode != this.node) {
  8095. this.shapeNode.setAttribute("startOffset", offset * 100 + "%");
  8096. }
  8097. },
  8098. addSpan: function(span) {
  8099. this.addShape(span);
  8100. return this;
  8101. },
  8102. setPath: function(path) {
  8103. var textpath = this.shapeNode;
  8104. if (this.shapeNode == this.node) {
  8105. // 当前还不是 textpath
  8106. textpath = this.shapeNode = svg.createNode("textPath");
  8107. while (this.node.firstChild) {
  8108. this.shapeNode.appendChild(this.node.firstChild);
  8109. }
  8110. this.node.appendChild(textpath);
  8111. }
  8112. textpath.setAttributeNS(svg.xlink, "xlink:href", "#" + path.node.id);
  8113. this.setTextAnchor(this.getTextAnchor());
  8114. return this;
  8115. }
  8116. });
  8117. }
  8118. };
  8119. //src/graphic/textcontent.js
  8120. _p[70] = {
  8121. value: function(require, exports, module) {
  8122. var Shape = _p.r(60);
  8123. return _p.r(11).createClass("TextContent", {
  8124. base: Shape,
  8125. constructor: function(nodeType) {
  8126. // call shape constructor
  8127. this.callBase(nodeType);
  8128. this.shapeNode = this.shapeNode || this.node;
  8129. this.shapeNode.setAttribute("text-rendering", "geometricPrecision");
  8130. },
  8131. clearContent: function() {
  8132. while (this.shapeNode.firstChild) {
  8133. this.shapeNode.removeChild(this.shapeNode.firstChild);
  8134. }
  8135. return this;
  8136. },
  8137. setContent: function(content) {
  8138. this.shapeNode.textContent = content;
  8139. return this;
  8140. },
  8141. getContent: function() {
  8142. return this.shapeNode.textContent;
  8143. },
  8144. appendContent: function(content) {
  8145. this.shapeNode.textContent += content;
  8146. return this;
  8147. },
  8148. setSize: function(value) {
  8149. return this.setFontSize(value);
  8150. },
  8151. setFontSize: function(value) {
  8152. return this.setFont({
  8153. size: value
  8154. });
  8155. },
  8156. setFontFamily: function(value) {
  8157. return this.setFont({
  8158. family: value
  8159. });
  8160. },
  8161. setFontBold: function(bold) {
  8162. return this.setFont({
  8163. weight: bold ? "bold" : "normal"
  8164. });
  8165. },
  8166. setFontItalic: function(italic) {
  8167. return this.setFont({
  8168. style: italic ? "italic" : "normal"
  8169. });
  8170. },
  8171. setFont: function(font) {
  8172. var node = this.node;
  8173. [ "family", "size", "weight", "style" ].forEach(function(section) {
  8174. if (font[section] === null) {
  8175. node.removeAttribute("font-" + section);
  8176. } else if (font[section]) {
  8177. node.setAttribute("font-" + section, font[section]);
  8178. }
  8179. });
  8180. return this;
  8181. },
  8182. getExtentOfChar: function(index) {
  8183. return this.node.getExtentOfChar(index);
  8184. },
  8185. getRotationOfChar: function(index) {
  8186. return this.node.getRotationOfChar(index);
  8187. },
  8188. getCharNumAtPosition: function(x, y) {
  8189. return this.node.getCharNumAtPosition(this.node.viewportElement.createSVGPoint(x, y));
  8190. }
  8191. });
  8192. }
  8193. };
  8194. //src/graphic/textspan.js
  8195. _p[71] = {
  8196. value: function(require, exports, module) {
  8197. var TextContent = _p.r(70);
  8198. var Styled = _p.r(66);
  8199. return _p.r(11).createClass("TextSpan", {
  8200. base: TextContent,
  8201. mixins: [ Styled ],
  8202. constructor: function(content) {
  8203. this.callBase("tspan");
  8204. this.setContent(content);
  8205. }
  8206. });
  8207. }
  8208. };
  8209. //src/graphic/use.js
  8210. /*
  8211. * USE 功能
  8212. */
  8213. _p[72] = {
  8214. value: function(require, exports, module) {
  8215. var Svg = _p.r(67);
  8216. var Class = _p.r(11);
  8217. var Use = Class.createClass("Use", {
  8218. base: _p.r(60),
  8219. constructor: function(shape) {
  8220. this.callBase("use");
  8221. this.ref(shape);
  8222. },
  8223. ref: function(shape) {
  8224. if (!shape) {
  8225. this.node.removeAttributeNS(Svg.xlink, "xlink:href");
  8226. return this;
  8227. }
  8228. var shapeId = shape.getId();
  8229. if (shapeId) {
  8230. this.node.setAttributeNS(Svg.xlink, "xlink:href", "#" + shapeId);
  8231. }
  8232. // by techird
  8233. // 作为 Use 的图形,如果没有 fill 和 stroke,移除默认的 'none' 值,用于 Use 覆盖
  8234. if (shape.node.getAttribute("fill") === "none") {
  8235. shape.node.removeAttribute("fill");
  8236. }
  8237. if (shape.node.getAttribute("stroke") === "none") {
  8238. shape.node.removeAttribute("stroke");
  8239. }
  8240. return this;
  8241. }
  8242. });
  8243. var Shape = _p.r(60);
  8244. Class.extendClass(Shape, {
  8245. // fast-use
  8246. use: function() {
  8247. return new Use(this);
  8248. }
  8249. });
  8250. return Use;
  8251. }
  8252. };
  8253. //src/graphic/vector.js
  8254. _p[73] = {
  8255. value: function(require, exports, module) {
  8256. var Point = _p.r(50);
  8257. var Matrix = _p.r(43);
  8258. var Vector = _p.r(11).createClass("Vector", {
  8259. base: Point,
  8260. constructor: function(x, y) {
  8261. this.callBase(x, y);
  8262. },
  8263. square: function() {
  8264. return this.x * this.x + this.y * this.y;
  8265. },
  8266. length: function() {
  8267. return Math.sqrt(this.square());
  8268. },
  8269. add: function(q) {
  8270. return new Vector(this.x + q.x, this.y + q.y);
  8271. },
  8272. minus: function(q) {
  8273. return new Vector(this.x - q.x, this.y - q.y);
  8274. },
  8275. dot: function(q) {
  8276. return this.x * q.x + this.y * q.y;
  8277. },
  8278. project: function(q) {
  8279. return q.multipy(this.dot(q) / q.square());
  8280. },
  8281. normalize: function(length) {
  8282. if (length === undefined) {
  8283. length = 1;
  8284. }
  8285. return this.multipy(length / this.length());
  8286. },
  8287. multipy: function(scale) {
  8288. return new Vector(this.x * scale, this.y * scale);
  8289. },
  8290. rotate: function(angle, unit) {
  8291. if (unit == "rad") {
  8292. angle = angle / Math.PI * 180;
  8293. }
  8294. var p = new Matrix().rotate(angle).transformPoint(this);
  8295. return new Vector(p.x, p.y);
  8296. },
  8297. vertical: function() {
  8298. return new Vector(this.y, -this.x);
  8299. },
  8300. reverse: function() {
  8301. return this.multipy(-1);
  8302. },
  8303. getAngle: function() {
  8304. var length = this.length();
  8305. if (length === 0) return 0;
  8306. var rad = Math.acos(this.x / length);
  8307. var sign = this.y > 0 ? 1 : -1;
  8308. return sign * 180 * rad / Math.PI;
  8309. }
  8310. });
  8311. Vector.fromPoints = function(p1, p2) {
  8312. return new Vector(p2.x - p1.x, p2.y - p1.y);
  8313. };
  8314. Vector.fromPolar = function() {
  8315. var p = Point.fromPolar.apply(Point, arguments);
  8316. return new Vector(p.x, p.y);
  8317. };
  8318. _p.r(11).extendClass(Point, {
  8319. asVector: function() {
  8320. return new Vector(this.x, this.y);
  8321. }
  8322. });
  8323. return Vector;
  8324. }
  8325. };
  8326. //src/graphic/view.js
  8327. _p[74] = {
  8328. value: function(require, exports, module) {
  8329. var ShapeContainer = _p.r(61);
  8330. var ViewBox = _p.r(75);
  8331. return _p.r(11).createClass("View", {
  8332. mixins: [ ShapeContainer, ViewBox ],
  8333. base: _p.r(74),
  8334. constructor: function() {
  8335. this.callBase("view");
  8336. }
  8337. });
  8338. }
  8339. };
  8340. //src/graphic/viewbox.js
  8341. _p[75] = {
  8342. value: function(require, exports, module) {
  8343. return _p.r(11).createClass("ViewBox", {
  8344. getViewBox: function() {
  8345. var attr = this.node.getAttribute("viewBox");
  8346. if (attr === null) {
  8347. // firefox:
  8348. // 1. viewBox 没有设置过的时候获得的是 null
  8349. // 2. svg 标签没有指定绝对大小的时候 clientWidth 和 clientHeigt 为 0,需要在父容器上查找
  8350. // TODO: 第 2 条取得的不准确(假如有 padding 之类的)
  8351. return {
  8352. x: 0,
  8353. y: 0,
  8354. width: this.node.clientWidth || this.node.parentNode.clientWidth,
  8355. height: this.node.clientHeight || this.node.parentNode.clientHeight
  8356. };
  8357. } else {
  8358. attr = attr.split(" ");
  8359. return {
  8360. x: +attr[0],
  8361. y: +attr[1],
  8362. width: +attr[2],
  8363. height: +attr[3]
  8364. };
  8365. }
  8366. },
  8367. setViewBox: function(x, y, width, height) {
  8368. this.node.setAttribute("viewBox", [ x, y, width, height ].join(" "));
  8369. return this;
  8370. }
  8371. });
  8372. }
  8373. };
  8374. //src/kity.js
  8375. /**
  8376. * @fileOverview kity 暴露的方法或对象
  8377. */
  8378. _p[76] = {
  8379. value: function(require, exports, module) {
  8380. var kity = {}, utils = _p.r(12);
  8381. kity.version = "2.0.0";
  8382. utils.extend(kity, {
  8383. // core
  8384. createClass: _p.r(11).createClass,
  8385. extendClass: _p.r(11).extendClass,
  8386. Utils: utils,
  8387. Browser: _p.r(10),
  8388. // shape
  8389. Box: _p.r(25),
  8390. Bezier: _p.r(23),
  8391. BezierPoint: _p.r(24),
  8392. Circle: _p.r(26),
  8393. Clip: _p.r(27),
  8394. Color: _p.r(28),
  8395. Container: _p.r(29),
  8396. Curve: _p.r(30),
  8397. Ellipse: _p.r(32),
  8398. Group: _p.r(36),
  8399. Gradient: _p.r(35),
  8400. HyperLink: _p.r(37),
  8401. Image: _p.r(38),
  8402. Line: _p.r(39),
  8403. LinearGradient: _p.r(40),
  8404. Mask: _p.r(42),
  8405. Matrix: _p.r(43),
  8406. Marker: _p.r(41),
  8407. Palette: _p.r(44),
  8408. Paper: _p.r(45),
  8409. Path: _p.r(46),
  8410. Pattern: _p.r(47),
  8411. Pen: _p.r(48),
  8412. Point: _p.r(50),
  8413. PointContainer: _p.r(51),
  8414. Polygon: _p.r(53),
  8415. Polyline: _p.r(54),
  8416. Pie: _p.r(49),
  8417. RadialGradient: _p.r(55),
  8418. Resource: _p.r(58),
  8419. Rect: _p.r(56),
  8420. RegularPolygon: _p.r(57),
  8421. Ring: _p.r(59),
  8422. Shape: _p.r(60),
  8423. ShapePoint: _p.r(63),
  8424. ShapeContainer: _p.r(61),
  8425. Sweep: _p.r(68),
  8426. Star: _p.r(65),
  8427. Text: _p.r(69),
  8428. TextSpan: _p.r(71),
  8429. Use: _p.r(72),
  8430. Vector: _p.r(73),
  8431. g: _p.r(34),
  8432. // animate
  8433. Animator: _p.r(0),
  8434. Easing: _p.r(1),
  8435. OpacityAnimator: _p.r(4),
  8436. RotateAnimator: _p.r(6),
  8437. ScaleAnimator: _p.r(7),
  8438. Timeline: _p.r(8),
  8439. TranslateAnimator: _p.r(9),
  8440. PathAnimator: _p.r(5),
  8441. MotionAnimator: _p.r(3),
  8442. requestFrame: _p.r(2).requestFrame,
  8443. releaseFrame: _p.r(2).releaseFrame,
  8444. // filter
  8445. Filter: _p.r(20),
  8446. GaussianblurFilter: _p.r(21),
  8447. ProjectionFilter: _p.r(22),
  8448. // effect
  8449. ColorMatrixEffect: _p.r(13),
  8450. CompositeEffect: _p.r(14),
  8451. ConvolveMatrixEffect: _p.r(15),
  8452. Effect: _p.r(16),
  8453. GaussianblurEffect: _p.r(17),
  8454. OffsetEffect: _p.r(18)
  8455. });
  8456. return window.kity = kity;
  8457. }
  8458. };
  8459. var moduleMapping = {
  8460. kity: 76
  8461. };
  8462. function use(name) {
  8463. _p.r([ moduleMapping[name] ]);
  8464. }
  8465. /* global use, inc: true */
  8466. /**
  8467. * 模块暴露
  8468. */
  8469. use('kity');
  8470. })();