|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561 |
- /*
- * KNWebGLObjects.js
- * Keynote HTML Player
- *
- * Created by Tungwei Cheng
- * Copyright (c) 2016-2019 Apple Inc. All rights reserved.
- */
-
- var kShaderUniformGravity = "Gravity";
- var kShaderUniformMaskTexture = "MaskTexture";
- var kShaderUniformNoiseAmount = "NoiseAmount";
- var kShaderUniformNoiseMax = "NoiseMax";
- var kShaderUniformNoiseSeed = "NoiseSeed";
- var kShaderUniformParticleBurstTiming = "ParticleBurstTiming";
- var kShaderUniformPreviousParticleBurstTiming = "PreviousParticleBurstTiming";
- var kShaderUniformPreviousPercent = "PreviousPercent";
- var kShaderUniformShouldSparkle = "ShouldSparkle";
- var kShaderUniformSparklePeriod = "SparklePeriod";
- var kShaderUniformSparkleStartTime = "SparkleStartTime";
- var kShaderUniformStartScale = "StartScale";
-
- var kShimmerUniformParticleScalePercent = "ParticleScalePercent";
- var kShimmerUniformRotationMatrix = "RotationMatrix";
-
- var KNSparkleMaxParticleLife = 0.667;
-
- var KNWebGLRenderer = Class.create({
- initialize: function(params) {
- var canvas = this.canvas = params.canvas;
- this.canvasId = params.canvasId;
- this.textureAssets = params.textureAssets;
- this.durationMax = params.overallEndTime * 1000;
- this.glPrograms = [];
-
- // to be used in request animation frame
- this.elapsed = 0;
-
- // attempt to create webgl context
- var gl = this.gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
-
- // if webgl is not supported then set noGL to true
- if (!gl) {
- this.noGL = true;
- return;
- }
-
- // indicate if the animation has started for this renderer
- this.animationStarted = false;
-
- gl.viewportWidth = canvas.width;
- gl.viewportHeight = canvas.height;
-
- // create default project matrix
- this.initMVPMatrix();
-
- // initialize core animation wrapper
- this.coreAnimationWrapper = new KNWebGLCoreAnimationWrapper(gl);
- },
-
- initMVPMatrix: function() {
- var gl = this.gl;
- var w = gl.viewportWidth;
- var h = gl.viewportHeight;
- var fovradians = 20 * (Math.PI / 180);
- var backupDistance = h / (2 * Math.tan(fovradians / 2));
- var frontclipping = backupDistance - (w * 1.5);
- var backclipping = backupDistance + (w * 15.0);
-
- // create default ortho and proj matrices
- this.slideProjectionMatrix = WebGraphics.makePerspectiveMatrix4(20, w / h, Math.max(1, frontclipping), backclipping);
-
- var translate = WebGraphics.translateMatrix4(WebGraphics.createMatrix4(), -w / 2, -h / 2, -backupDistance);
-
- this.slideProjectionMatrix = WebGraphics.multiplyMatrix4(this.slideProjectionMatrix, translate);
- this.slideOrthoMatrix = WebGraphics.makeOrthoMatrix4(0, w, 0, h, -1, 1);
- },
-
- setupTexture: function(effect) {
- var textures = [];
- this.textureInfoFromEffect(effect.kpfLayer, effect.name, {"pointX": 0, "pointY": 0}, effect.baseLayer.initialState.opacity, textures);
-
- for (var i = 0, length = textures.length; i < length; i++) {
- var textureId = textures[i].textureId;
- var image = this.textureAssets[textureId];
-
- textures[i].texture = KNWebGLUtil.createTexture(this.gl, image);
-
- var toTextureId = textures[i].toTextureId;
-
- if (toTextureId) {
- var toTextureImage = this.textureAssets[toTextureId];
-
- textures[i].toTexture = KNWebGLUtil.createTexture(this.gl, toTextureImage);
- }
- }
-
- return textures;
- },
-
- textureInfoFromEffect: function(kpfLayer, name, offset, parentOpacity, textures) {
- var textureInfo = {};
-
- textureInfo.offset = {
- "pointX": offset.pointX + kpfLayer.bounds.offset.pointX,
- "pointY": offset.pointY + kpfLayer.bounds.offset.pointY
- };
-
- textureInfo.parentOpacity = parentOpacity * kpfLayer.initialState.opacity;
-
- if (kpfLayer.textureId) {
- textureInfo.textureId = kpfLayer.textureId;
- textureInfo.width = kpfLayer.bounds.width;
- textureInfo.height = kpfLayer.bounds.height;
- textureInfo.initialState = kpfLayer.initialState;
- textureInfo.hasHighlightedBulletAnimation = kpfLayer.hasHighlightedBulletAnimation;
- textureInfo.texturedRectangle = kpfLayer.texturedRectangle;
-
- // search the animations within group for contents animation
- var groupAnimations = kpfLayer.animations;
-
- if (groupAnimations && groupAnimations.length > 0) {
- var groupAnimation = groupAnimations[0];
-
- if (groupAnimation.property === "contents") {
- textureInfo.toTextureId = groupAnimation.to.texture;
- } else if (!groupAnimation.property) {
- var animations = groupAnimation.animations;
-
- if (animations) {
- for (var i = 0, length = animations.length; i < length; i++) {
- var animation = animations[i];
-
- if (animation.property === "contents") {
- textureInfo.toTextureId = animation.to.texture;
- break;
- }
- }
- }
- }
- }
-
- textureInfo.animations = groupAnimations;
-
- textureInfo.textureRect = {
- origin: {
- x: textureInfo.offset.pointX,
- y: textureInfo.offset.pointY
- },
- size: {
- width: textureInfo.width,
- height: textureInfo.height
- }
- };
-
- textures.push(textureInfo);
- } else {
- for (var i = 0, length = kpfLayer.layers.length; i < length; i++) {
- this.textureInfoFromEffect(kpfLayer.layers[i], name, textureInfo.offset, textureInfo.parentOpacity, textures);
- }
- }
- },
-
- draw: function(effect) {
- var params = {
- effect: effect,
- textures: this.setupTexture(effect)
- };
-
- var effectType = effect.type;
- var program;
-
- if (effectType === "transition") {
- switch (effect.name) {
- case "apple:wipe-iris":
- program = new KNWebGLTransitionIris(this, params);
- break;
-
- case "com.apple.iWork.Keynote.BUKTwist":
- program = new KNWebGLTransitionTwist(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNColorPlanes":
- program = new KNWebGLTransitionColorPlanes(this, params);
- break;
-
- case "com.apple.iWork.Keynote.BUKFlop":
- program = new KNWebGLTransitionFlop(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNConfetti":
- program = new KNWebGLTransitionConfetti(this, params);
- break;
-
- case "apple:magic-move-implied-motion-path":
- program = new KNWebGLTransitionMagicMove(this, params);
- break;
-
- case "apple:ca-text-shimmer":
- program = new KNWebGLTransitionShimmer(this, params);
- break;
-
- case "apple:ca-text-sparkle":
- program = new KNWebGLTransitionSparkle(this, params);
- break;
-
- default:
- // fallback to dissolve
- program = new KNWebGLDissolve(this, params);
- break;
- }
- } else if (effectType === "buildIn" || effectType === "buildOut") {
- switch (effect.name) {
- case "apple:wipe-iris":
- program = new KNWebGLBuildIris(this, params);
- break;
-
- case "com.apple.iWork.Keynote.BUKAnvil":
- program = new KNWebGLBuildAnvil(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNFlame":
- program = new KNWebGLBuildFlame(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KNFireworks":
- program = new KNWebGLBuildFireworks(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNConfetti":
- program = new KNWebGLBuildConfetti(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNDiffuse":
- program = new KNWebGLBuildDiffuse(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNShimmer":
- program = new KNWebGLBuildShimmer(this, params);
- break;
-
- case "com.apple.iWork.Keynote.KLNSparkle":
- program = new KNWebGLBuildSparkle(this, params);
- break;
-
- default:
- // fallback to dissolve
- program = new KNWebGLDissolve(this, params);
- break;
- }
- } else if (effectType === "smartBuild") {
- switch (effect.name) {
- case "apple:gallery-dissolve":
- program = new KNWebGLContents(this, params);
- break;
-
- default:
- // fallback to dissolve
- program = new KNWebGLDissolve(this, params);
- break;
- }
- }
-
- // remove existing gl program for the same object when new program is rendered such as build in by highlighted paragraph
- this.removeProgram(effect.objectID);
-
- // push new gl program into the array
- this.glPrograms.push(program);
- },
-
- animate: function() {
- // compute time difference
- var time = new Date();
- var difference = 0;
- if (this.time) {
- var mseconds = time.getTime();
- difference = mseconds - this.time;
- this.time = mseconds;
- } else {
- difference = 0;
- this.time = time.getTime();
- }
- this.elapsed += difference;
-
- var glPrograms = this.glPrograms;
- var length = glPrograms.length;
-
- if (this.elapsed <= this.durationMax) {
- // set up the frame for the next drawing operation, only if there is time left in the animation
- this.animationRequest = window.requestAnimFrame(this.animate.bind(this));
- } else {
- // set gl program to isCompleted when there is no overall event time left
- for (var i = 0; i < length; i++) {
- var program = glPrograms[i];
- program.isCompleted = true;
- }
- }
-
- // clear the buffers before animation frame
- var gl = this.gl;
- gl.clearColor(0, 0, 0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-
- for (var i = 0; i < length; i++) {
- var program = glPrograms[i];
- program.drawFrame(difference, this.elapsed, program.duration);
- }
- },
-
- removeProgram: function(objectID) {
- var glPrograms = this.glPrograms;
- var glProgramLength = glPrograms.length;
-
- // remove gl program for the same objectID from the array
- while (glProgramLength--) {
- var glProgram = glPrograms[glProgramLength];
-
- if (glProgram.effect.objectID === objectID) {
- glPrograms.splice(glProgramLength, 1);
- }
- }
- },
-
- resize: function(viewport) {
- var gl = this.gl;
- var viewportWidth = viewport.width;
- var viewportHeight = viewport.height;
-
- if (gl.viewportWidth !== viewportWidth || gl.viewportHeight !== viewportHeight) {
- gl.viewport(0, 0, viewportWidth, viewportHeight);
- gl.viewportWidth = viewportWidth;
- gl.viewportHeight = viewportHeight;
- }
- }
- });
-
- var KNWebGLProgram = Class.create({
- initialize: function(renderer, programData) {
- // reference to the renderer
- this.renderer = renderer;
-
- // reference to gl context
- this.gl = renderer.gl;
-
- // specify textures
- this.textures = programData.textures;
-
- // reference to the effect object
- var effect = this.effect = programData.effect;
-
- // specify the effect type
- var type = this.type = effect.type;
-
- // specific the direction from the effect
- this.direction = effect.attributes ? effect.attributes.direction : null;
-
- // specify the duration from the effect
- this.duration = effect.duration * 1000;
-
- // boolean to indicate if the effect is a build out
- this.buildOut = type === "buildOut";
-
- // boolean to indicate if the effect is a build in
- this.buildIn = type === "buildIn";
-
- // create a shader program container object
- this.program = {};
-
- // indicate if the effect is completed
- this.isCompleted = false;
-
- // setup program data
- if (programData.programNames) {
- this.setupProgram(programData);
- }
- },
-
- setupProgram: function(programData) {
- var gl = this.gl;
-
- for (var i = 0, length = programData.programNames.length; i < length; i++) {
- var programName = programData.programNames[i];
-
- this.program[programName] = KNWebGLUtil.setupProgram(gl, programName);
- }
-
- // enable blend function
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
- }
- });
-
- var KNWebGLContents = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "contents",
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- // initialize percent finish based on effect type
- this.percentfinished = 0;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var textureRect = this.textures[0].textureRect;
- var vertexRect = CGRectMake(0, 0, textureRect.size.width, textureRect.size.height);
- var meshSize = CGSizeMake(2, 2);
-
- // init contents shader and data buffer
- var contentsShader = this.contentsShader = new TSDGLShader(gl);
- contentsShader.initWithContentsShader();
-
- // contents shader set methods
- contentsShader.setMat4WithTransform3D(renderer.slideProjectionMatrix, kTSDGLShaderUniformMVPMatrix);
-
- // outgoing Texture
- contentsShader.setGLint(0, kTSDGLShaderUniformTexture2);
-
- // incoming Texture
- contentsShader.setGLint(1, kTSDGLShaderUniformTexture);
-
- // init contents data buffer
- var contentsDataBuffer = this.contentsDataBuffer = new TSDGLDataBuffer(gl);
- contentsDataBuffer.initWithVertexRect(vertexRect, TSDRectUnit, meshSize, false, false);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var percentfinished = this.percentfinished;
-
- percentfinished += difference / duration;
-
- if (percentfinished >= 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- // draw contents using glsl mix
- this.p_drawContents(percentfinished);
- },
-
- p_drawContents: function(percent) {
- var gl = this.gl;
- var textures = this.textures;
- var incomingTexture = textures[0].texture;
- var outgoingTexture = textures[1].texture;
-
- // calculate the mix factor in ease in and ease out fashion
- var mixFactor = TSUSineMap(percent);
-
- if (percent >= 1) {
- mixFactor = 1.0;
- }
-
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, incomingTexture);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
-
- this.contentsShader.setGLFloat(mixFactor, "mixFactor");
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- this.contentsDataBuffer.drawWithShader(this.contentsShader, true);
- }
- });
-
- var KNWebGLDrawable = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "WebDrawable",
- programNames:["defaultTextureAndOpacity"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- this.Opacity = 1.0;
-
- // setup web drawable requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["defaultTextureAndOpacity"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textureInfo = this.textures[0];
-
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // create WebGLBuffer object for texture coordinates
- var textureCoordinateBuffer = this.textureCoordinateBuffer = gl.createBuffer();
- var textureCoordinates = this.textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordinateBuffer);
- // send vertex data to this bound buffer
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
-
- // create WebGLBuffer object for position coordinates
- var positionBuffer = this.positionBuffer = gl.createBuffer();
- var boxPosition = this.boxPosition = [
- 0.0, 0.0, 0.0,
- 0.0, textureInfo.height, 0.0,
- textureInfo.width, 0.0, 0.0,
- textureInfo.width, textureInfo.height, 0.0
- ];
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- // send vertex data to this bound buffer
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxPosition), gl.STATIC_DRAW);
-
- // move the MVPMatrix to appropriate offset
- this.MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, textureInfo.offset.pointX, gl.viewportHeight - textureInfo.offset.pointY - textureInfo.height, 0);
- },
-
- drawFrame: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["defaultTextureAndOpacity"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textures = this.textures;
- var texture = textures[0].texture;
-
- gl.useProgram(program.shaderProgram);
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordinateBuffer);
- // assigns the WebGLBuffer object currently bound to the gl.ARRAY_BUFFER target to a vertex attribute index
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
- // call enableVertexAttribArray, otherwise it won't draw
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
- // assigns the WebGLBuffer object currently bound to the gl.ARRAY_BUFFER target to a vertex attribute index
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
- // call enableVertexAttribArray, otherwise it won't draw
- gl.enableVertexAttribArray(attribs["Position"]);
-
- // set MVPMatrix
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, this.MVPMatrix);
-
- // set Opacity
- gl.uniform1f(uniforms["Opacity"], this.Opacity);
-
- // set sampler2D Texture in fragment shader to have the value 0, so it matches the texture unit gl.TEXTURE0
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
-
- // bind the texture to texture unit gl.TEXTURE0
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
- });
-
- var KNWebGLFramebufferDrawable = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var gl = renderer.gl;
- var frameRect = this.frameRect = params.frameRect;
- var texture = this.texture = this.createFramebufferTexture(gl, frameRect);
-
- this.buffer = this.createFramebuffer(gl, texture);
-
- var textureInfo = {
- width: frameRect.size.width,
- height: frameRect.size.height,
- offset: {pointX: 0, pointY: 0},
- texture: texture
- };
-
- this.programData = {
- name: "FramebufferDrawable",
- programNames:["defaultTexture"],
- effect: params.effect,
- textures: [textureInfo]
- };
-
- $super(renderer, this.programData);
-
- this.drawableFrame = params.drawableFrame;
-
- // setup web drawable requirements
- this.animationWillBeginWithContext();
- },
-
- createFramebufferTexture: function(gl, rect) {
- var texture = gl.createTexture();
-
- // bind texture
- gl.bindTexture(gl.TEXTURE_2D, texture);
-
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
-
- // setup texture parameters
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
-
- // specify the texture size for memory allocation
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, rect.size.width, rect.size.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-
- // unbind texture
- gl.bindTexture(gl.TEXTURE_2D, null);
-
- return texture;
- },
-
- createFramebuffer: function(gl, texture) {
- var buffer = gl.createFramebuffer();
-
- //bind framebuffer to texture
- gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
-
- return buffer;
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["defaultTexture"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textureInfo = this.textures[0];
-
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // create WebGLBuffer object for texture coordinates
- var textureCoordinateBuffer = this.textureCoordinateBuffer = gl.createBuffer();
- var textureCoordinates = this.textureCoordinates = [
- 0.0, 1.0,
- 0.0, 0.0,
- 1.0, 1.0,
- 1.0, 0.0,
- ];
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordinateBuffer);
- // send vertex data to this bound buffer
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
-
- // create WebGLBuffer object for position coordinates
- var positionBuffer = this.positionBuffer = gl.createBuffer();
- var boxPosition = this.boxPosition = [
- 0.0, 0.0, 0.0,
- 0.0, textureInfo.height, 0.0,
- textureInfo.width, 0.0, 0.0,
- textureInfo.width, textureInfo.height, 0.0
- ];
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- // send vertex data to this bound buffer
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxPosition), gl.STATIC_DRAW);
-
- // move the MVPMatrix to appropriate offset
- this.MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, textureInfo.offset.pointX, gl.viewportHeight - textureInfo.offset.pointY - textureInfo.height, 0);
- },
-
- drawFrame: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["defaultTexture"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textures = this.textures;
- var texture = textures[0].texture;
-
- gl.useProgram(program.shaderProgram);
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordinateBuffer);
- // assigns the WebGLBuffer object currently bound to the gl.ARRAY_BUFFER target to a vertex attribute index
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
- // call enableVertexAttribArray, otherwise it won't draw
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
- // assigns the WebGLBuffer object currently bound to the gl.ARRAY_BUFFER target to a vertex attribute index
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
- // call enableVertexAttribArray, otherwise it won't draw
- gl.enableVertexAttribArray(attribs["Position"]);
-
- // set MVPMatrix
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, this.MVPMatrix);
-
- // set sampler2D Texture in fragment shader to have the value 0, so it matches the texture unit gl.TEXTURE0
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
-
- // bind the texture to texture unit gl.TEXTURE0
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
- });
-
- var KNWebGLDissolve = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "dissolve",
- programNames:["defaultTextureAndOpacity"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- // initialize percent finish based on effect type
- this.percentfinished = 0;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["defaultTextureAndOpacity"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textureInfo = this.textures[0];
-
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // create WebGLBuffer object for texture coordinates
- var textureCoordinateBuffer = this.textureCoordinateBuffer = gl.createBuffer();
- var textureCoordinates = this.textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordinateBuffer);
- // send vertex data to this bound buffer
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
-
- // create WebGLBuffer object for position coordinates
- var positionBuffer = this.positionBuffer = gl.createBuffer();
- var boxPosition = this.boxPosition = [
- 0.0, 0.0, 0.0,
- 0.0, textureInfo.height, 0.0,
- textureInfo.width, 0.0, 0.0,
- textureInfo.width, textureInfo.height, 0.0
- ];
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- // send vertex data to this bound buffer
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxPosition), gl.STATIC_DRAW);
-
- this.MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, textureInfo.offset.pointX, gl.viewportHeight - (textureInfo.offset.pointY + textureInfo.height), 0);
-
- this.drawFrame(0, 0, 4);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var percentfinished = this.percentfinished;
-
- percentfinished += difference / duration;
- percentfinished > 1 ? percentfinished = 1 : 0;
-
- var percentAlpha = TSUSineMap(percentfinished);
- if (percentfinished === 1) {
- percentAlpha = 1.0;
- }
-
- if (this.buildOut) {
- percentAlpha = 1 - percentAlpha;
- }
-
- this.percentfinished = percentfinished;
- this.percentAlpha = percentAlpha;
- this.draw();
- },
-
- draw: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["defaultTextureAndOpacity"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textures = this.textures;
- var texture = textures[0].texture;
- var outgoingTexture;
-
- if (textures.length > 1) {
- outgoingTexture = textures[1].texture;
- }
-
- // use this program
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordinateBuffer);
- // send vertex data to this bound buffer
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
- // call enableVertexAttribArray, otherwise it won't draw
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- // bind WebGLBuffer object to gl.ARRAY_BUFFER target
- gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
- // send vertex data to this bound buffer
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
- // call enableVertexAttribArray, otherwise it won't draw
- gl.enableVertexAttribArray(attribs["Position"]);
-
- // set MVPMatrix
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, this.MVPMatrix);
-
- // set sampler2D Texture in fragment shader to have the value 0, so it matches the texture unit gl.TEXTURE0
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
-
- // bind the texture to texture unit gl.TEXTURE0
- if (outgoingTexture) {
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
- gl.uniform1f(uniforms["Opacity"], 1.0);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
-
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.uniform1f(uniforms["Opacity"], this.percentAlpha);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
- });
-
- var KNWebGLTransitionIris = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "apple:wipe-iris",
- programNames: ["iris"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- // determine the type and direction
- var direction = this.direction;
- var directionOut = direction === KNDirection.kKNDirectionOut;
- var buildOut = this.buildOut;
-
- if ((buildOut && directionOut) || (!buildOut && !directionOut)) {
- this.mix = 0.0;
- this.percentfinished = 1.0;
- } else {
- this.mix = 1.0;
- this.percentfinished = 0.0;
- }
-
- this.percentAlpha = 0.0;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["iris"];
- var attribs = program.attribs;
- var uniforms = program.uniforms;
- var textureInfo = this.textures[0];
-
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // initial scale uniform
- this.scale = textureInfo.width/textureInfo.height;
-
- // create buffers
- var textureCoordinatesBuffer = this.textureCoordinatesBuffer = gl.createBuffer();
- var textureCoordinates = this.textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordinatesBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
-
- var positionBuffer = this.positionBuffer = gl.createBuffer();
- var boxPosition = this.boxPosition = [
- 0.0, 0.0, 0.0,
- 0.0, textureInfo.height, 0.0,
- textureInfo.width, 0.0, 0.0,
- textureInfo.width, textureInfo.height, 0.0
- ];
-
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxPosition), gl.STATIC_DRAW);
-
- this.MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, textureInfo.offset.pointX, gl.viewportHeight - (textureInfo.offset.pointY + textureInfo.height), 0);
-
- this.drawFrame(0, 0, 4);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- // determine the type and direction
- var buildOut = this.buildOut;
- var directionOut = this.direction === KNDirection.kKNDirectionOut;
- var percentfinished = this.percentfinished;
-
- if ((buildOut && directionOut) || (!buildOut && !directionOut)) {
- percentfinished -= difference / duration;
- percentfinished < 0 ? percentfinished = 0 : 0;
- } else {
- percentfinished += difference / duration;
- percentfinished > 1 ? percentfinished = 1 : 0;
- }
-
- var percentAlpha = TSUSineMap(percentfinished);
- if (percentfinished === 1) {
- percentAlpha = 1.0;
- }
-
- if (buildOut) {
- percentAlpha = 1 - percentAlpha;
- }
-
- this.percentAlpha = percentAlpha;
- this.percentfinished = percentfinished;
- this.draw();
- },
-
- draw: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["iris"];
- var attribs = program.attribs;
- var uniforms = program.uniforms;
- var textures = this.textures;
- var texture = textures[0].texture;
- var textureInfo = textures[0];
-
- var outgoingTexture;
- var scale = this.scale;
-
- if (textures.length > 1) {
- outgoingTexture = textures[1].texture;
- }
-
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // setup attributes
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordinatesBuffer);
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["Position"]);
-
- // setup uniforms and textures
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, this.MVPMatrix);
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
-
- // set Opacity
- gl.uniform1f(uniforms["Opacity"], 1);
-
- // bg texture
- if (outgoingTexture) {
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
- gl.uniform1f(uniforms["PercentForAlpha"], 0.0);
- gl.uniform1f(uniforms["Scale"], scale);
- gl.uniform1f(uniforms["Mix"], 0.0);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0 , 4);
- }
-
- //fg texture
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.uniform1f(uniforms["PercentForAlpha"], this.percentAlpha);
- gl.uniform1f(uniforms["Scale"], scale);
- gl.uniform1f(uniforms["Mix"], this.mix);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0 , 4);
- }
- });
-
- var KNWebGLBuildIris = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var effect = params.effect;
-
- this.programData = {
- name: "apple:wipe-iris",
- programNames: ["iris"],
- effect: effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- // determine the type and direction
- var direction = this.direction;
- var directionOut = direction === KNDirection.kKNDirectionOut;
- var buildOut = this.buildOut;
-
- if ((buildOut && directionOut) || (!buildOut && !directionOut)) {
- this.mix = 0.0;
- this.percentfinished = 1.0;
- } else {
- this.mix = 1.0;
- this.percentfinished = 0.0;
- }
-
- this.percentAlpha = 0.0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
- this.drawableObjects.push(drawableObject);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["iris"];
- var attribs = program.attribs;
- var uniforms = program.uniforms;
-
- gl.useProgram(program.shaderProgram);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // setup attributes
- var textureCoordinatesBuffer = gl.createBuffer();
- var textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordinatesBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
-
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- this.irisSystems = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var width = textureInfo.width;
- var height = textureInfo.height;
-
- // initial scale uniform
- var scale = textureInfo.width/textureInfo.height;
-
- var positionBuffer = gl.createBuffer();
- var boxPosition = [
- 0.0, 0.0, 0.0,
- 0.0, textureInfo.height, 0.0,
- textureInfo.width, 0.0, 0.0,
- textureInfo.width, textureInfo.height, 0.0
- ];
-
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxPosition), gl.STATIC_DRAW);
-
- var MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, textureInfo.offset.pointX, gl.viewportHeight - (textureInfo.offset.pointY + textureInfo.height), 0);
-
- this.irisSystems[i] = {
- textureCoordinatesBuffer: textureCoordinatesBuffer,
- positionBuffer: positionBuffer,
- MVPMatrix: MVPMatrix,
- scale: scale
- };
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
-
- // determine the type and direction
- var buildOut = this.buildOut;
- var directionOut = this.direction === KNDirection.kKNDirectionOut;
-
- var percentfinished = this.percentfinished;
-
- if ((buildOut && directionOut) || (!buildOut && !directionOut)) {
- percentfinished -= difference / duration;
-
- if (percentfinished <= 0) {
- percentfinished = 0;
- this.isCompleted = true;
- }
- } else {
- percentfinished += difference / duration;
-
- if (percentfinished >= 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
- }
-
- var percentAlpha = TSUSineMap(percentfinished);
-
- if (percentfinished === 1) {
- percentAlpha = 1.0;
- }
-
- if (buildOut) {
- percentAlpha = 1 - percentAlpha;
- }
-
- this.percentAlpha = percentAlpha;
- this.percentfinished = percentfinished;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- if (buildOut) {
- opacity = opacityFrom + diff * (1 - this.percentfinished);
- } else {
- opacity = opacityFrom + diff * this.percentfinished;
- }
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- if (!buildOut) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- continue;
- }
-
- var program = this.program["iris"];
- var attribs = program.attribs;
- var uniforms = program.uniforms;
-
- var irisSystem = this.irisSystems[i];
- var scale = irisSystem.scale;
-
- gl.useProgram(program.shaderProgram);
-
- var textureCoordinatesBuffer = irisSystem.textureCoordinatesBuffer;
- gl.bindBuffer(gl.ARRAY_BUFFER, textureCoordinatesBuffer);
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- var positionBuffer = irisSystem.positionBuffer;
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["Position"]);
-
- var MVPMatrix = irisSystem.MVPMatrix;
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, MVPMatrix);
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
-
- // set Opacity
- gl.uniform1f(uniforms["Opacity"], this.parentOpacity * textureInfo.initialState.opacity);
-
- //fg texture
- gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
- gl.uniform1f(uniforms["PercentForAlpha"], this.percentAlpha);
- gl.uniform1f(uniforms["Scale"], scale);
- gl.uniform1f(uniforms["Mix"], this.mix);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0 , 4);
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- }
- });
-
- var KNWebGLTransitionTwist = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "com.apple.iWork.Keynote.BUKTwist",
- programNames:["twist"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var gl = this.gl;
- this.direction = this.effect.attributes.direction;
- this.percentfinished = 0.0;
-
- var mNumPoints = this.mNumPoints = 24;
- var dx = gl.viewportWidth / (mNumPoints - 1);
- var dy = gl.viewportHeight / (mNumPoints - 1);
- var fractionOfUnitLength = 1 / (mNumPoints - 1);
- var x, y;
- var TexCoords = this.TexCoords = [];
- var PositionCoords = this.PositionCoords = [];
- var NormalCoords = this.NormalCoords = [];
- for (y = 0; y < mNumPoints; y++) {
- for (x = 0; x < mNumPoints; x++) {
- var index = y * mNumPoints + x;
- PositionCoords[index * 3] = x * dx;
- PositionCoords[index * 3 + 1] = y * dy;
- PositionCoords[index * 3 + 2] = 0;
- TexCoords.push(x * fractionOfUnitLength);
- TexCoords.push(y * fractionOfUnitLength);
- NormalCoords.push(0);
- NormalCoords.push(0);
- NormalCoords.push(-1);
- }
- }
-
- var index = 0;
- var elementArray = this.elementArray = [];
- for (y = 0; y < mNumPoints - 1; y++) {
- for (x = 0; x < mNumPoints; x++) {
- elementArray[index++] = (y) * (mNumPoints) + x;
- elementArray[index++] = (y + 1) * (mNumPoints) + x;
- }
- }
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["twist"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
-
- gl.enable(gl.CULL_FACE);
-
- this.buffers = {};
- this.buffers["TexCoord"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["TexCoord"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.TexCoords), gl.STATIC_DRAW);
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- this.buffers["Position"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["Position"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.PositionCoords), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["Position"]);
-
- this.buffers["Normal"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["Normal"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.NormalCoords), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["Normal"], 3, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(attribs["Normal"]);
-
- this.MVPMatrix = renderer.slideProjectionMatrix;
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, this.MVPMatrix);
-
- this.AffineTransform = new Matrix3();
- this.AffineTransform.affineScale(1.0, -1.0);
- this.AffineTransform.affineTranslate(0.0, 1.0);
-
- this.AffineIdentity = new Matrix3();
-
- this.elementIndicesBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementIndicesBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.elementArray), gl.STATIC_DRAW);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
-
- this.drawFrame(0, 0, 4);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var gl = this.gl;
- var program = this.program["twist"];
- var attribs = program.attribs;
- var percentfinished = this.percentfinished;
-
- percentfinished += difference / duration;
- percentfinished > 1 ? percentfinished = 1 : 0;
- this.specularcolor = TSUSineMap(percentfinished * 2) * 0.5;
-
- var y, x;
- var height = gl.viewportHeight / 2.0;
- var mNumPoints = this.mNumPoints;
- var TexCoords = this.TexCoords;
- var PositionCoords = this.PositionCoords;
- var NormalCoords = this.NormalCoords;
-
- for (y = 0; y < mNumPoints; y++) {
- for (x = 0; x < mNumPoints; x++) {
- var index = y * mNumPoints + x;
- var start = {};
- start.x = TexCoords[index * 2];
- start.y = TexCoords[index * 2 + 1];
- var angle = -Math.PI * TwistFX(this.direction === KNDirection.kKNDirectionLeftToRight ? start.x : (1 - start.x), percentfinished);
- var result = {};
- result.y = (height - (height * (1 - start.y * 2) * Math.cos(angle)));
- result.z = (height * (1 - start.y * 2) * Math.sin(angle));
- PositionCoords[index * 3 + 1] = result.y;
- PositionCoords[index * 3 + 2] = result.z;
- }
- }
-
- for (y = 0; y < mNumPoints; y++) {
- for (x = 0; x < mNumPoints; x++) {
- var finalNormal = new vector3();
- var index = y * mNumPoints + x;
- for (var q = 0; q < 4; q++) {
- var q1x = 0, q1y = 0, q2x = 0, q2y = 0;
- switch (q) {
- case 0:
- q1x = 1;
- q2y = 1;
- break;
- case 1:
- q1y = 1;
- q2x = -1;
- break;
- case 2:
- q1x = -1;
- q2y = -1;
- break;
- case 3:
- q1y = -1;
- q2x = 1;
- default:
- break;
- }
- if ((x + q1x) < 0 || (x + q2x) < 0 || (y + q1y) < 0 || (y + q2y) < 0
- || x + q1x >= mNumPoints || x + q2x >= mNumPoints || y + q1y >= mNumPoints || y + q2y >= mNumPoints) {
- continue;
- }
- var thisV = new vector3([PositionCoords[index * 3], PositionCoords[index * 3 + 1], PositionCoords[index * 3 + 2] ]);
- var nextV = new vector3([PositionCoords[((y + q1y) * mNumPoints + (x + q1x)) * 3], PositionCoords[((y + q1y) * mNumPoints + (x + q1x)) * 3 + 1], PositionCoords[((y + q1y) * mNumPoints + (x + q1x)) * 3 + 2] ]);
- var prevV = new vector3([PositionCoords[(((y + q2y) * mNumPoints) + (x + q2x)) * 3], PositionCoords[(((y + q2y) * mNumPoints) + (x + q2x)) * 3 + 1], PositionCoords[(((y + q2y) * mNumPoints) + (x + q2x)) * 3 + 2] ]);
- nextV.subtract(thisV);
- prevV.subtract(thisV);
- nextV.cross(prevV); // cross gives you the normal
-
- finalNormal.add(nextV);
- }
- finalNormal.normalize();
- finalNormal.scale(-1.0);
- finalNormal = finalNormal.getArray();
- NormalCoords[index * 3] = finalNormal[0];
- NormalCoords[index * 3 + 1] = finalNormal[1];
- NormalCoords[index * 3 + 2] = finalNormal[2];
- }
- }
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["Position"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(PositionCoords), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers["Normal"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(NormalCoords), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["Normal"], 3, gl.FLOAT, false, 0, 0);
-
- this.percentfinished = percentfinished;
- this.draw();
- },
-
- draw: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["twist"];
- var uniforms = program.uniforms;
- var textures = this.textures;
- var texture = textures[0].texture;
- var outgoingTexture = textures[1].texture;
- var mNumPoints = this.mNumPoints;
- var specularcolor = this.specularcolor;
- var AffineTransform = this.AffineTransform.getColumnMajorFloat32Array();
- var AffineIdentity = this.AffineIdentity.getColumnMajorFloat32Array();
- var elementIndicesBuffer = this.elementIndicesBuffer;
-
- if (!specularcolor) {
- specularcolor = 0;
- }
- gl.uniform1f(uniforms["SpecularColor"], specularcolor);
- if (this.percentfinished < 0.5) {
- gl.cullFace(gl.BACK);
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementIndicesBuffer);
-
- gl.uniformMatrix3fv(uniforms["TextureMatrix"], false, AffineTransform);
- gl.uniform1f(uniforms["FlipNormals"], 1.0);
- // draw
- for (y = 0; y < mNumPoints - 1; y++) {
- gl.drawElements(gl.TRIANGLE_STRIP, mNumPoints * 2, gl.UNSIGNED_SHORT, y * mNumPoints * 2 * (2));
- }
- // ANIMATE OVERLAY
- gl.cullFace(gl.FRONT);
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
- gl.uniformMatrix3fv(uniforms["TextureMatrix"], false, AffineIdentity);
- gl.uniform1f(uniforms["FlipNormals"], -1.0);
- for (y = 0; y < mNumPoints - 1; y++) {
- gl.drawElements(gl.TRIANGLE_STRIP, mNumPoints * 2, gl.UNSIGNED_SHORT, y * mNumPoints * 2 * (2));
- }
- } else {
- gl.cullFace(gl.FRONT);
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
- gl.uniformMatrix3fv(uniforms["TextureMatrix"], false, AffineIdentity);
- gl.uniform1f(uniforms["FlipNormals"], -1.0);
- for (y = 0; y < mNumPoints - 1; y++) {
- gl.drawElements(gl.TRIANGLE_STRIP, mNumPoints * 2, gl.UNSIGNED_SHORT, y * mNumPoints * 2 * (2));
- }
-
- gl.cullFace(gl.BACK);
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementIndicesBuffer);
-
- gl.uniformMatrix3fv(uniforms["TextureMatrix"], false, AffineTransform);
- gl.uniform1f(uniforms["SpecularColor"], specularcolor);
- gl.uniform1f(uniforms["FlipNormals"], 1.0);
- // draw
- for (y = 0; y < mNumPoints - 1; y++) {
- gl.drawElements(gl.TRIANGLE_STRIP, mNumPoints * 2, gl.UNSIGNED_SHORT, y * mNumPoints * 2 * (2));
- }
- }
- }
- });
-
- var KNWebGLTransitionColorPlanes = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNColorPlanes",
- programNames:["colorPlanes"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var direction = this.effect.attributes.direction;
- if (direction !== KNDirection.kKNDirectionLeftToRight && direction !== KNDirection.kKNDirectionRightToLeft && direction !== KNDirection.kKNDirectionTopToBottom && direction !== KNDirection.kKNDirectionBottomToTop) {
- // default direction to left to right if not specified
- direction = KNDirection.kKNDirectionLeftToRight
- }
- this.direction = direction;
-
- this.mNumColors = 3;
- this.percentfinished = 0.0;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["colorPlanes"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textureInfo = this.textures[0];
-
- gl.disable(gl.CULL_FACE);
- gl.blendFunc(gl.ONE, gl.ONE);
-
- var buffers = this.buffers = {};
- buffers["TexCoord"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["TexCoord"]);
-
- var TexCoords = this.TexCoords = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(TexCoords), gl.STATIC_DRAW);
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0,0);
- gl.enableVertexAttribArray(attribs["TexCoord"]);
-
- buffers["Position"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["Position"]);
-
- var PositionCoords = this.PositionCoords = [
- 0.0, 0.0, 0.0,
- 0.0, textureInfo.height, 0.0,
- textureInfo.width, 0.0, 0.0,
- textureInfo.width, textureInfo.height, 0.0
- ];
-
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(PositionCoords), gl.STATIC_DRAW);
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0,0);
- gl.enableVertexAttribArray(attribs["Position"]);
-
- this.MVPMatrix = renderer.slideProjectionMatrix;
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, this.MVPMatrix);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(uniforms["Texture"], 0);
- this.drawFrame(0, 0, 4);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["colorPlanes"];
- var uniforms = program.uniforms;
- var attribs = program.attribs;
- var textures = this.textures;
- var textureInfo = textures[0];
- var outgoingTextureInfo = textures[1];
-
- this.percentfinished += difference / duration;
- this.percentfinished > 1 ? this.percentfinished = 1 : 0;
- var percent = this.percentfinished;
- var direction = this.direction;
-
- var planeSeparation = 0.25;
- var cameraPullBack = 1.0;
-
- var clockwise = (direction == KNDirection.kKNDirectionRightToLeft || direction == KNDirection.kKNDirectionBottomToTop);
- var yAxis = (direction == KNDirection.kKNDirectionLeftToRight || direction == KNDirection.kKNDirectionRightToLeft);
-
- var percentInvSq = 1-(1-percent)*(1-percent);
-
- var cameraAmount = yAxis ? textureInfo.width : textureInfo.height;
-
- var uCurve = TSUSineMap(percent * 2.0);
- var planeOffset = uCurve * cameraAmount * planeSeparation;
-
- var zOffset = Math.sin(-percentInvSq*2.*Math.PI);
- zOffset *= percentInvSq * cameraAmount * cameraPullBack;
-
- if (percent < 0.5) {
- gl.bindTexture(gl.TEXTURE_2D, outgoingTextureInfo.texture);
- gl.uniform2fv(uniforms["FlipTexCoords"], new Float32Array([0,0]));
- } else {
- gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
- if (direction == KNDirection.kKNDirectionTopToBottom || direction == KNDirection.kKNDirectionBottomToTop) {
- gl.uniform2fv(uniforms["FlipTexCoords"], new Float32Array([0,1]));
- } else {
- gl.uniform2fv(uniforms["FlipTexCoords"], new Float32Array([1,0]));
- }
- }
-
- for (var iHue = 0, mNumColors = this.mNumColors; iHue < mNumColors; iHue++) {
- var thisHue = iHue/mNumColors;
-
- // setup color mask
- var color = WebGraphics.colorWithHSBA(thisHue, 1, 1, 1/mNumColors);
- gl.uniform4fv(uniforms["ColorMask"], new Float32Array([color.red, color.green, color.blue, color.alpha]));
-
- var angle = (Math.PI/180.0) * (180.0 * (TSUSineMap(percent)));
- var mvpMatrix = WebGraphics.translateMatrix4(this.MVPMatrix, textureInfo.width/2, textureInfo.height/2, zOffset);
- mvpMatrix = WebGraphics.rotateMatrix4AboutXYZ(mvpMatrix, angle, (clockwise ? -1 : 1) * (yAxis ? 0 : 1), (clockwise ? -1 : 1) * (yAxis ? 1 : 0), 0);
- mvpMatrix = WebGraphics.translateMatrix4(mvpMatrix, -textureInfo.width/2, -textureInfo.height/2, planeOffset*(iHue-1));
-
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, mvpMatrix);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
- }
- });
-
- var KNWebGLTransitionFlop = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "com.apple.iWork.Keynote.BUKFlop",
- programNames:["flop", "defaultTexture"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var direction = this.effect.attributes.direction;
- if (direction !== KNDirection.kKNDirectionLeftToRight && direction !== KNDirection.kKNDirectionRightToLeft && direction !== KNDirection.kKNDirectionTopToBottom && direction !== KNDirection.kKNDirectionBottomToTop) {
- // default direction to left to right if not specified
- direction = KNDirection.kKNDirectionLeftToRight
- }
- this.direction = direction;
-
- this.percentfinished = 0.0;
- var elementArray = this.elementArray = [];
-
- var gl = this.gl;
- var texWidth = gl.viewportWidth;
- var texHeight = gl.viewportHeight;
- var width = texWidth
- var height = texHeight;
-
- if (direction === KNDirection.kKNDirectionTopToBottom || direction === KNDirection.kKNDirectionBottomToTop) {
- height *= 0.5;
- } else {
- width *= 0.5;
- }
-
- var mNumPoints = this.mNumPoints = 8;
- var index = 0;
-
- for (y = 0; y < mNumPoints - 1; y++) {
- for (x = 0; x < mNumPoints; x++) {
- elementArray[index++] = (y + 0) * (mNumPoints) + x;
- elementArray[index++] = (y + 1) * (mNumPoints) + x;
- }
- }
-
- var dx = width / (mNumPoints - 1);
- var dy = height / (mNumPoints - 1);
- var yOffset = (direction == KNDirection.kKNDirectionTopToBottom) ? height : yOffset = 0;
- var xOffset = (direction == KNDirection.kKNDirectionRightToLeft) ? width : xOffset = 0;
-
- var attributeBufferData = this.attributeBufferData = {
- Position: [],
- TexCoords: [],
- Normal: [],
- ShadowPosition: [],
- ShadowTexCoord: [],
- PreviousPosition: [],
- PreviousTexCoords: [],
- PreviousNormal: []
- };
-
- for (var y = 0; y < mNumPoints; y++) {
- for (var x = 0; x < mNumPoints; x++) {
- index = y * mNumPoints + x;
- KNWebGLUtil.setPoint3DAtIndexForAttribute(WebGraphics.makePoint3D(x * dx + xOffset, y * dy, 0), index, attributeBufferData["Position"]);
- KNWebGLUtil.setPoint2DAtIndexForAttribute(WebGraphics.makePoint((x * dx + xOffset) / texWidth, (y * dy + yOffset) / texHeight), index, attributeBufferData["TexCoords"]);
- KNWebGLUtil.setPoint3DAtIndexForAttribute(WebGraphics.makePoint3D(0, 0, 1), index, attributeBufferData["Normal"]);
- }
- }
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["flop"];
- var attribs = program.attribs;
- var uniforms = program.uniforms;
- var basicProgram = this.program["defaultTexture"];
- var MVPMatrix = this.MVPMatrix = renderer.slideProjectionMatrix;
- var width = gl.viewportWidth;
- var height = gl.viewportHeight;
- var direction = this.direction;
-
- if (direction === KNDirection.kKNDirectionTopToBottom || direction === KNDirection.kKNDirectionBottomToTop) {
- height *= 0.5;
- } else {
- width *= 0.5;
- }
-
- var textureCoordinates = [
- 0.0, 0.0,
- 0.0, 0.5,
- 1.0, 0.0,
- 1.0, 0.5,
- ];
-
- var boxPosition = [
- 0.0, 0.0, 0.0,
- 0.0, height, 0.0,
- width,0.0, 0.0,
- width, height, 0.0,
- ];
-
- var textureCoordinates2 = [
- 0.0, 0.5,
- 0.0, 1.0,
- 1.0, 0.5,
- 1.0, 1.0,
- ];
-
- var boxPosition2 = [
- 0.0, height, 0.0,
- 0.0, height*2, 0.0,
- width, height, 0.0,
- width, height*2, 0.0,
- ];
-
- // use this program and enable vertex attrib array
- KNWebGLUtil.enableAttribs(gl, program);
-
- var attributeBufferData = this.attributeBufferData;
- var buffers = this.buffers = {};
- var Coordinates = this.Coordinates = {};
-
- buffers["TexCoord"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["TexCoord"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributeBufferData["TexCoords"]), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0,0);
-
- buffers["Position"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["Position"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributeBufferData["Position"]), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["Position"], 3, gl.FLOAT, false, 0,0);
-
- buffers["Normal"] = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["Normal"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributeBufferData["Normal"]), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(attribs["Normal"], 3, gl.FLOAT, false, 0,0);
-
- gl.uniformMatrix4fv(uniforms["MVPMatrix"], false, MVPMatrix);
-
- var AffineTransform = this.AffineTransform = new Matrix3();
- if (direction === KNDirection.kKNDirectionTopToBottom) {
- AffineTransform.affineScale(1.0, -1.0);
- AffineTransform.affineTranslate(0.0,1.0);
- } else if (direction == KNDirection.kKNDirectionBottomToTop) {
- AffineTransform.affineScale(1.0, -1.0);
- AffineTransform.affineTranslate(0.0,1.0);
- textureCoordinates = [
- 0.0, 0.5,
- 0.0, 1.0,
- 1.0, 0.5,
- 1.0, 1.0,
- ];
-
- textureCoordinates2 = [
- 0.0, 0.0,
- 0.0, 0.5,
- 1.0, 0.0,
- 1.0, 0.5,
- ];
-
- boxPosition = [
- 0.0, height, 0.0,
- 0.0, height*2, 0.0,
- width,height, 0.0,
- width, height*2, 0.0,
- ];
-
- boxPosition2 = [
- 0, 0, 0.0,
- 0, height, 0.0,
- width, 0, 0.0,
- width, height, 0.0,
- ];
- } else if (direction == KNDirection.kKNDirectionRightToLeft) {
- AffineTransform.affineScale(-1.0, 1.0);
- AffineTransform.affineTranslate(1.0, 0.0);
- textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 0.5, 0.0,
- 0.5, 1.0,
- ];
- textureCoordinates2 = [
- 0.5, 0.0,
- 0.5, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
- boxPosition2 = [
- width, 0, 0.0,
- width, height, 0.0,
- width*2, 0, 0.0,
- width*2, height, 0.0,
- ];
- } else if (direction === KNDirection.kKNDirectionLeftToRight) {
- AffineTransform.affineScale(-1.0, 1.0);
- AffineTransform.affineTranslate(1.0, 0.0);
- boxPosition = [
- width, 0, 0.0,
- width, height, 0.0,
- width*2,0, 0.0,
- width*2, height, 0.0,
- ];
- textureCoordinates = [
- 0.5, 0.0,
- 0.5, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
- textureCoordinates2 = [
- 0.0, 0.0,
- 0.0, 1.0,
- 0.5, 0.0,
- 0.5, 1.0,
- ];
- boxPosition2 = [
- 0, 0, 0.0,
- 0, height, 0.0,
- width, 0, 0.0,
- width, height, 0.0,
- ];
- }
-
- this.AffineIdentity = new Matrix3();
- this.elementIndicesBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.elementIndicesBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.elementArray), gl.STATIC_DRAW);
-
- //setup second program
- Coordinates["DefaultTexture"] = textureCoordinates;
- Coordinates["DefaultTexture2"] = textureCoordinates2;
- Coordinates["DefaultPosition"] = boxPosition;
- Coordinates["DefaultPosition2"] = boxPosition2;
-
- // use this program and enable vertex attrib array
- KNWebGLUtil.enableAttribs(gl, basicProgram);
-
- //setup VBO and FTB
- buffers["TextureCoordinates"] = gl.createBuffer();
- buffers["PositionCoordinates"] = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["TextureCoordinates"]);
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["PositionCoordinates"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(basicProgram.attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
-
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(boxPosition), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(basicProgram.attribs["Position"], 3, gl.FLOAT, false, 0, 0);
-
- gl.uniform1i(basicProgram.uniforms["Texture"], 0);
- gl.uniformMatrix4fv(basicProgram.uniforms["MVPMatrix"], false, MVPMatrix);
-
- // switch back to main program with animation
- gl.useProgram(program.shaderProgram);
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(program.uniforms["Texture"], 0);
-
- this.drawFrame(0, 0, 4);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- this.percentfinished += difference / duration;
- this.percentfinished > 1 ? this.percentfinished = 1 : 0;
-
- this.updateFlopWithPercent();
- this.draw();
- },
-
- updateFlopWithPercent: function() {
- var gl = this.gl;
- var direction = this.direction;
- var texWidth = gl.viewportWidth;
- var texHeight = gl.viewportHeight;
-
- var thetaA = this.percentfinished * Math.PI;
- var thetaB = this.percentfinished * this.percentfinished * this.percentfinished * Math.PI;
-
- var height = texHeight / 2.0;
- var width = texWidth / 2.0;
- var location = 0.0;
- var mNumPoints = this.mNumPoints;
- var attributeBufferData = this.attributeBufferData;
-
- for (var y = 0; y < mNumPoints; y++) {
- for(var x = 0; x < mNumPoints; x++) {
- var index = y * mNumPoints + x;
- var start = KNWebGLUtil.getPoint2DForArrayAtIndex(attributeBufferData["TexCoords"], index);
-
- start.x *= texWidth;
- start.y *= texHeight;
-
- if (direction === KNDirection.kKNDirectionBottomToTop) {
- location = start.y / height;
- } else if (direction === KNDirection.kKNDirectionTopToBottom) {
- location = (height*2 - start.y) / height;
- } else if (direction === KNDirection.kKNDirectionLeftToRight) {
- location = start.x / width;
- } else {
- location = (width*2 - start.x) / width;
- }
-
- var angle = location*thetaA + (1-location) * thetaB;
- if (direction === KNDirection.kKNDirectionLeftToRight || direction === KNDirection.kKNDirectionTopToBottom) {
- angle *= -1;
- }
-
- var sinAngle = Math.sin(angle);
- var cosAngle = Math.cos(angle);
- var startPosition = KNWebGLUtil.getPoint3DForArrayAtIndex(attributeBufferData["Position"], index);
- var startNormal = KNWebGLUtil.getPoint3DForArrayAtIndex(attributeBufferData["Normal"], index);
-
- if (direction === KNDirection.kKNDirectionTopToBottom || direction === KNDirection.kKNDirectionBottomToTop) {
- var thisPosition = WebGraphics.makePoint3D(startPosition.x, height - (height - start.y) * cosAngle, (height - start.y) * sinAngle);
- KNWebGLUtil.setPoint3DAtIndexForAttribute(thisPosition, index, attributeBufferData["Position"]);
-
- var thisNormal = WebGraphics.makePoint3D(startNormal.x, -sinAngle, cosAngle);
- KNWebGLUtil.setPoint3DAtIndexForAttribute(thisNormal, index, attributeBufferData["Normal"]);
- } else {
- var thisPosition = WebGraphics.makePoint3D(width - (width - start.x) * cosAngle, startPosition.y, -(width - start.x) * sinAngle);
- KNWebGLUtil.setPoint3DAtIndexForAttribute(thisPosition, index, attributeBufferData["Position"]);
-
- var thisNormal = WebGraphics.makePoint3D(-sinAngle, startNormal.y, cosAngle);
- KNWebGLUtil.setPoint3DAtIndexForAttribute(thisNormal, index, attributeBufferData["Normal"]);
- }
- }
- }
- },
-
- draw: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["flop"];
- var basicProgram = this.program["defaultTexture"];
- var textures = this.textures;
- var outgoingTexture = textures[1].texture;
- var incomingTexture = textures[0].texture;
-
- gl.useProgram(basicProgram.shaderProgram);
- gl.disable(gl.CULL_FACE);
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
-
- var mNumPoints = this.mNumPoints;
- var buffers = this.buffers;
- var Coordinates = this.Coordinates;
- var attributeBufferData = this.attributeBufferData;
-
- KNWebGLUtil.bindDynamicBufferWithData(gl, basicProgram.attribs["Position"], buffers["PositionCoordinates"], Coordinates["DefaultPosition"], 3);
- KNWebGLUtil.bindDynamicBufferWithData(gl, basicProgram.attribs["TexCoord"], buffers["TextureCoordinates"], Coordinates["DefaultTexture"], 2);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- gl.useProgram(basicProgram.shaderProgram);
- gl.disable(gl.CULL_FACE);
- gl.bindTexture(gl.TEXTURE_2D, incomingTexture);
-
- KNWebGLUtil.bindDynamicBufferWithData(gl, basicProgram.attribs["Position"], buffers["PositionCoordinates"], Coordinates["DefaultPosition2"], 3);
- KNWebGLUtil.bindDynamicBufferWithData(gl, basicProgram.attribs["TexCoord"], buffers["TextureCoordinates"], Coordinates["DefaultTexture2"], 2);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- gl.enable(gl.CULL_FACE);
-
- //ANIMATE OVERLAY
- gl.useProgram(program.shaderProgram);
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["Position"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributeBufferData["Position"]), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(program.attribs["Position"], 3, gl.FLOAT, false, 0,0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["Normal"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributeBufferData["Normal"]), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(program.attribs["Normal"], 3, gl.FLOAT, false, 0,0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, buffers["TexCoord"]);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(attributeBufferData["TexCoords"]), gl.DYNAMIC_DRAW);
- gl.vertexAttribPointer(program.attribs["TexCoord"], 2, gl.FLOAT, false, 0,0);
-
- gl.cullFace(gl.BACK);
- gl.bindTexture(gl.TEXTURE_2D, incomingTexture);
-
- gl.uniformMatrix3fv(program.uniforms["TextureMatrix"], false, this.AffineTransform.getColumnMajorFloat32Array());
- gl.uniform1f(program.uniforms["FlipNormals"], -1.0);
-
- for (var y = 0; y< mNumPoints-1; y++) {
- gl.drawElements(gl.TRIANGLE_STRIP, mNumPoints*2, gl.UNSIGNED_SHORT, y*mNumPoints*2*(2));
- }
-
- gl.bindTexture(gl.TEXTURE_2D, outgoingTexture);
- gl.cullFace(gl.FRONT);
-
- gl.uniformMatrix3fv(program.uniforms["TextureMatrix"], false, this.AffineIdentity.getColumnMajorFloat32Array());
- gl.uniform1f(program.uniforms["FlipNormals"], 1.0);
- for (var y = 0; y < mNumPoints-1; y++) {
- gl.drawElements(gl.TRIANGLE_STRIP, mNumPoints*2, gl.UNSIGNED_SHORT, y*mNumPoints*2*(2));
- }
- }
-
- });
-
- var KNWebGLBuildAnvil = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var effect = params.effect;
-
- this.programData = {
- name: "com.apple.iWork.Keynote.BUKAnvil",
- programNames: ["anvilsmoke", "anvilspeck"],
- effect: effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var gl = this.gl;
-
- // bind required textures from base64 image source
- this.smokeTexture = KNWebGLUtil.bindTextureWithImage(gl, smokeImage);
- this.speckTexture = KNWebGLUtil.bindTextureWithImage(gl, speckImage);
-
- // initialize percent finish
- this.percentfinished = 0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
- this.drawableObjects.push(drawableObject);
- }
-
- this.objectY = 1;
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
-
- this.smokeSystems = [];
- this.speckSystems = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var width = textureInfo.width;
- var height = textureInfo.height;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- var numParticles = 300;
-
- var smokeSystem = new KNWebGLBuildAnvilSmokeSystem(
- renderer,
- this.program["anvilsmoke"],
- {"width": width, "height": height},
- {"width": viewportWidth, "height": viewportHeight},
- this.duration,
- {"width": numParticles, "height": 1},
- {"width": kParticleSize, "height": kParticleSize},
- this.smokeTexture);
-
- numParticles = 40;
- var speckSystem = new KNWebGLBuildAnvilSpeckSystem(
- renderer,
- this.program["anvilspeck"],
- {"width": width, "height": height},
- {"width": viewportWidth, "height": viewportHeight},
- this.duration,
- {"width": numParticles, "height": 1},
- {"width": kParticleSize, "height": kParticleSize},
- this.speckTexture);
-
- this.smokeSystems.push(smokeSystem);
- this.speckSystems.push(speckSystem);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
-
- this.percentfinished += difference / duration;
-
- if (this.percentfinished >= 1) {
- this.percentfinished = 1;
- this.isCompleted = true;
- }
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * this.percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- continue;
- }
-
- var width = textureInfo.width;
- var height = textureInfo.height;
- var offsetX = textureInfo.offset.pointX;
- var offsetY = textureInfo.offset.pointY;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- duration /= 1000;
-
- var kObjectSmashDuration = Math.min(0.20, duration * 0.4);
- var kCameraShakeDuration = Math.min(0.25, duration * 0.5);
-
- var cameraShakePoints = this.cameraShakePointsWithRandomGenerator();
- var cameraShakePercent = (this.percentfinished * duration - kObjectSmashDuration) / kCameraShakeDuration;
-
- var shakePoint = WebGraphics.makePoint(0, 0);
- if (0 < cameraShakePercent && cameraShakePercent < 1) {
- var minIndex = Math.floor(cameraShakePercent * kNumCameraShakePoints);
- var maxIndex = Math.ceil(WebGraphics.clamp(cameraShakePercent * kNumCameraShakePoints, 0, cameraShakePoints.length - 1));
- var minPoint = cameraShakePoints[minIndex];
- var maxPoint = cameraShakePoints[maxIndex];
- var cameraLerp = cameraShakePercent * kNumCameraShakePoints - minIndex;
- shakePoint = WebGraphics.makePoint(
- WebGraphics.mix(minPoint.x, maxPoint.x, cameraLerp),
- WebGraphics.mix(minPoint.y, maxPoint.y, cameraLerp));
- }
-
- var objectSmashPercent = WebGraphics.clamp((this.percentfinished * duration) / kObjectSmashDuration, 0, 1);
- var smokepercent = WebGraphics.clamp(((this.percentfinished * duration) - kObjectSmashDuration) / (duration - kObjectSmashDuration), 0, 1);
-
- var percent = this.percentfinished;
-
- // calculations for the camera shake
- this.objectY = offsetY + height;
- this.objectY *= (1.0 - objectSmashPercent * objectSmashPercent);
-
- // draw the texture
- this.drawableObjects[i].MVPMatrix = WebGraphics.translateMatrix4(
- renderer.slideOrthoMatrix,
- offsetX + (shakePoint.x * viewportWidth),
- viewportHeight - offsetY - height + this.objectY + (shakePoint.y * viewportHeight),
- 0);
-
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
-
- // draw smoke
- var MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, offsetX, viewportHeight - (offsetY + (height + 16)) * (1 - (smokepercent * smokepercent * 0.02)), 0);
- var smokeSystem = this.smokeSystems[i];
- smokeSystem.setMVPMatrix(MVPMatrix);
- smokeSystem.drawFrame(smokepercent, 1 - (smokepercent * smokepercent));
-
- // draw specks
- if (smokepercent < 0.50) {
- MVPMatrix = WebGraphics.translateMatrix4(renderer.slideOrthoMatrix, offsetX, viewportHeight - (offsetY + height + 16), 0);
- var speckSystem = this.speckSystems[i];
- speckSystem.setMVPMatrix(MVPMatrix);
- speckSystem.drawFrame(smokepercent, WebGraphics.clamp(1 - WebGraphics.sineMap(smokepercent) * 2, 0, 1));
- }
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- },
-
- cameraShakePointsWithRandomGenerator: function() {
- var cameraShakePoints = [];
- var globalScale = 0.025;
-
- for (var i = 0; i < kNumCameraShakePoints; i++) {
- var scale = 1 - (i / kNumCameraShakePoints);
- scale *= scale;
-
- var thisPoint = WebGraphics.makePoint(
- WebGraphics.randomBetween(-1, 1) * globalScale * scale * 0.4, Math.pow(-1, i) * globalScale * scale);
-
- cameraShakePoints[i] = thisPoint;
- }
- return cameraShakePoints;
- }
- });
-
- var KNWebGLBuildFlame = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNFlame",
- programNames: ["flame"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var gl = this.gl;
-
- // bind required textures from base64 image source
- this.flameTexture = KNWebGLUtil.bindTextureWithImage(gl, flameImage);
-
- // initialize percent finish
- this.percentfinished = 0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- // create framebuffer drawable object array for drawing flame
- this.framebufferDrawableObjects = [];
-
- this.slideSize = {"width": gl.viewportWidth, "height": gl.viewportHeight};
-
- var effect = this.effect;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
- this.drawableObjects.push(drawableObject);
-
- var drawableFrame = {
- "size": {
- "width": texture.width,
- "height": texture.height
- },
- "origin": {
- "x": texture.offset.pointX,
- "y": texture.offset.pointY
- }
- };
-
- var frameRect = this.frameOfEffectWithFrame(drawableFrame);
-
- var framebufferParams = {
- effect: effect,
- textures: [],
- drawableFrame: drawableFrame,
- frameRect: frameRect
- };
-
- var framebufferDrawable = new KNWebGLFramebufferDrawable(renderer, framebufferParams);
-
- // push the framebufferDrawable to the array
- this.framebufferDrawableObjects.push(framebufferDrawable);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- frameOfEffectWithFrame: function(drawableFrame) {
- var objSize = drawableFrame.size;
- var slideSize = this.slideSize;
-
- // the larger the object, the less we have to inflate its size
- var widthAdjust = (1.2 - Math.min(1.0, Math.sqrt(objSize.width / slideSize.width))) + 1.0;
- var heightAdjust = (1.25 - Math.min(1.0, Math.sqrt(objSize.height / slideSize.height))) + 1.0;
- var viewSize = {
- "width": Math.round(objSize.width * widthAdjust),
- "height": Math.round(objSize.height * heightAdjust)
- };
-
- if (objSize.width / objSize.height < 1.0) {
- // for really skinny objects, make sure GL View is more squarish
- viewSize.width = Math.max(viewSize.width, (objSize.width + objSize.height));
- }
-
- var rect = {
- "size": viewSize,
- "origin": {
- "x": drawableFrame.origin.x + (objSize.width - viewSize.width) / 2,
- "y": drawableFrame.origin.y + (objSize.height - viewSize.height) / 2
- }
- };
-
- // Now move the FBO up a bit so only 25% of extra space is on the bottom
- rect.origin.y -= (rect.size.height - drawableFrame.size.height) * 0.25;
-
- var gl = this.gl;
- var slideRect = {
- "origin": {
- "x": 0,
- "y": 0
- },
- "size": {
- "width": gl.viewportWidth,
- "height": gl.viewportHeight
- }
- };
-
- var mFrameRect = CGRectIntersection(rect, slideRect);
- mFrameRect = CGRectIntegral(mFrameRect);
-
- return mFrameRect;
- },
-
- p_orthoTransformWithScale: function(scale, offset, mFrameRect) {
- var size = {
- "width": mFrameRect.size.width * scale,
- "height": mFrameRect.size.height * scale
- };
-
- var ortho = WebGraphics.makeOrthoMatrix4(0, size.width, 0, size.height, -1, 1);
- var result = WebGraphics.translateMatrix4(ortho, offset.x, -offset.y, 0);
-
- return result;
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var duration = this.duration / 1000;
-
- this.flameSystems = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var width = textureInfo.width;
- var height = textureInfo.height;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
- var framebufferDrawable = this.framebufferDrawableObjects[i];
- var mFrameRect = framebufferDrawable.frameRect
- var mDrawableFrame = framebufferDrawable.drawableFrame;
-
- var orthoOffset = {
- "x": textureInfo.offset.pointX - mFrameRect.origin.x,
- "y": textureInfo.offset.pointY + height - (mFrameRect.origin.y + mFrameRect.size.height)
- };
-
- var bottomPadding = mDrawableFrame.origin.y - mFrameRect.origin.y;
- var topPadding = mFrameRect.origin.y + mFrameRect.size.height - (mDrawableFrame.origin.y + mDrawableFrame.size.height);
- orthoOffset.y += (topPadding - bottomPadding);
-
- framebufferDrawable.MVPMatrix = this.p_orthoTransformWithScale(1.0, orthoOffset, mFrameRect);
-
- var ratio = width / height;
- var numParticles = Math.round(ratio * 150);
- numParticles *= (duration + Math.max(0, 1.0 - duration / 2));
-
- // We updated actualSize, so need to update the max speed in the shader
- var flameSystem = new KNWebGLBuildFlameSystem(
- renderer,
- this.program["flame"],
- {"width": width, "height": height},
- {"width": viewportWidth, "height": viewportHeight},
- Math.max(2, this.duration),
- numParticles,
- this.flameTexture
- );
-
- flameSystem.p_setupParticleDataWithTexture(textureInfo);
-
- this.flameSystems.push(flameSystem);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["flame"];
- var uniforms = program.uniforms;
- var buildOut = this.buildOut;
- var percentfinished = this.percentfinished;
-
- percentfinished += difference / duration;
-
- if (percentfinished >= 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * this.percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- if (!buildOut) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- continue;
- }
-
- var width = textureInfo.width;
- var height = textureInfo.height;
- var offsetX = textureInfo.offset.pointX;
- var offsetY = textureInfo.offset.pointY;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- duration /= 1000;
-
- var percent = percentfinished;
-
- if (buildOut) {
- percent = 1.0 - percent;
- }
-
- var minCutoff = buildOut ? 0.25 : 0.5;
- var cutoff = Math.min(minCutoff, 1.0 / duration);
-
- if (percent > cutoff) {
- var newPercent = (percent - cutoff) / (1 - cutoff);
- var alpha = TSUSineMap(Math.min(1.0, 2 * newPercent));
- alpha *= this.parentOpacity * textureInfo.initialState.opacity;
-
- var drawable = this.drawableObjects[i];
- drawable.Opacity = alpha;
- drawable.drawFrame();
- }
-
- var framebufferDrawable = this.framebufferDrawableObjects[i];
- var mDrawableFrame = framebufferDrawable.drawableFrame;
- var mFrameRect = framebufferDrawable.frameRect;
-
- var orthoOffset = {
- "x": textureInfo.offset.pointX - mFrameRect.origin.x,
- "y": textureInfo.offset.pointY + height - (mFrameRect.origin.y + mFrameRect.size.height)
- };
-
- var bottomPadding = mDrawableFrame.origin.y - mFrameRect.origin.y;
- var topPadding = mFrameRect.origin.y + mFrameRect.size.height - (mDrawableFrame.origin.y + mDrawableFrame.size.height);
- orthoOffset.y += (topPadding - bottomPadding);
-
- // this is slightly different implementation because we do not scale up and down in web
- var MVPMatrix = this.p_orthoTransformWithScale(1, orthoOffset, mFrameRect);
-
- // change viewport to match the frame buffer size
- gl.viewport(0, 0, mFrameRect.size.width, mFrameRect.size.height);
-
- //bind framebuffer
- gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferDrawable.buffer);
-
- //now render the scene
- gl.clear(gl.COLOR_BUFFER_BIT);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-
- var flameOpacity = (percentfinished == 0.0 || percentfinished == 1.0 ? 0.0 : 1.0);
-
- // bind framebuffer texture
- gl.bindTexture(gl.TEXTURE_2D, framebufferDrawable.texture);
-
- var flameSystem = this.flameSystems[i];
- flameSystem.setMVPMatrix(MVPMatrix);
- gl.uniform1f(uniforms["SpeedMax"], flameSystem._speedMax);
- flameSystem.drawFrame(percentfinished, flameOpacity);
-
- // unbind the framebuffer
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-
- // unbind the texture
- gl.bindTexture(gl.TEXTURE_2D, null);
-
- // change viewport back to original size
- gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
-
- // send result to framebuffer
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- framebufferDrawable.MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, mFrameRect.origin.x, gl.viewportHeight - (mFrameRect.origin.y + mFrameRect.size.height), 0);
- framebufferDrawable.drawFrame();
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- }
- });
-
- var KNWebGLTransitionConfetti = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNConfetti",
- programNames: ["confetti", "defaultTexture"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- this.useGravity = this.direction === KNDirection.kKNDirectionGravity ? true : false;
- this.percentfinished = 0.0;
-
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function(){
- var renderer = this.renderer;
- var gl = this.gl;
- var textures = this.textures;
- var textureInfo = textures[0];
- var width = textureInfo.width;
- var height = textureInfo.height;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- var numParticles = 10000;
-
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
-
- // create a confetti system
- this.confettiSystem = new KNWebGLBuildConfettiSystem(
- renderer,
- this.program["confetti"],
- {"width": width, "height": height},
- {"width": viewportWidth, "height": viewportHeight},
- this.duration,
- numParticles,
- textures[1].texture);
-
- this.confettiSystem.setMVPMatrix(renderer.slideProjectionMatrix);
-
- // use default texture shader program for incoming slide
- var program = this.program["defaultTexture"];
-
- // enable attribs before binding and set the program to use.
- KNWebGLUtil.enableAttribs(gl, program);
-
- var textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- var boxPosition = [
- 0.0, 0.0, -1.0,
- 0.0, viewportHeight, -1.0,
- viewportWidth, 0.0, -1.0,
- viewportWidth, viewportHeight, -1.0,
- ];
-
- // setup VBO and FTB
- this.textureCoordinatesBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordinatesBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
- gl.vertexAttribPointer(program.attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
-
- this.positionBuffer = gl.createBuffer();
- KNWebGLUtil.bindDynamicBufferWithData(gl, program.attribs["Position"], this.positionBuffer, boxPosition, 3);
-
- gl.uniformMatrix4fv(program.uniforms["MVPMatrix"], false, renderer.slideOrthoMatrix);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(program.uniforms["Texture"], 0);
-
- this.drawFrame(0, 0, 4);
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- var percentfinished = this.percentfinished;
- percentfinished += difference / duration;
-
- if (percentfinished > 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- var percent = this.percentfinished = percentfinished;
- var revPercent = 1 - percent;
- var myPercent = 1 - revPercent*revPercent*revPercent;
- myPercent = myPercent*(1-percent*percent) + (1-revPercent*revPercent)*(percent*percent) + percent;
-
- myPercent *= 0.5;
- myPercent*= myPercent;
-
- var scale= 0.75 + (1 - Math.pow(revPercent,4)) * 0.25;
-
- var quadShaderMVPMatrix = WebGraphics.translateMatrix4(this.renderer.slideProjectionMatrix, viewportWidth / 2, viewportHeight / 2, 0);
- quadShaderMVPMatrix = WebGraphics.scaleMatrix4(quadShaderMVPMatrix, scale, scale, 1);
- quadShaderMVPMatrix = WebGraphics.translateMatrix4(quadShaderMVPMatrix, -viewportWidth / 2, -viewportHeight / 2, 0);
-
- // draw the incoming slide
- var program = this.program["defaultTexture"];
- gl.useProgram(program.shaderProgram);
- gl.uniformMatrix4fv(program.uniforms["MVPMatrix"], false, quadShaderMVPMatrix);
- this.draw();
-
- //draw the confetti system frame
- var finalPercent = 1 - percent;
- finalPercent = WebGraphics.clamp(finalPercent, 0, 1);
- myPercent = WebGraphics.clamp(myPercent, 0, 1);
-
- if (this.useGravity) {
- var ratio = 1;
- var MVPMatrix = this.renderer.slideProjectionMatrix;
-
- MVPMatrix = WebGraphics.translateMatrix4(MVPMatrix, 0, -viewportHeight * 2 * percent * percent * (1.0 - ratio * 0.5), 0);
- this.confettiSystem.setMVPMatrix(MVPMatrix);
- }
-
- this.confettiSystem.drawFrame(myPercent, finalPercent);
- },
-
- draw: function() {
- var gl = this.gl;
- var program = this.program["defaultTexture"];
- var attribs = program.attribs;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- gl.useProgram(program.shaderProgram);
-
- var textureCoordinates = [
- 0.0, 0.0,
- 0.0, 1.0,
- 1.0, 0.0,
- 1.0, 1.0,
- ];
-
- var boxPosition = [
- 0.0, 0.0, -1.0,
- 0.0, viewportHeight, -1.0,
- viewportWidth, 0.0, -1.0,
- viewportWidth, viewportHeight, -1.0,
- ];
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.textureCoordinatesBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates), gl.STATIC_DRAW);
- gl.vertexAttribPointer(attribs["TexCoord"], 2, gl.FLOAT, false, 0, 0);
-
- KNWebGLUtil.bindDynamicBufferWithData(gl, attribs["Position"], this.positionBuffer, boxPosition, 3);
-
- // bind incoming texture
- gl.bindTexture(gl.TEXTURE_2D, this.textures[0].texture);
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- }
- });
-
- var KNWebGLBuildConfetti = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var effect = params.effect;
-
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNConfetti",
- programNames: ["confetti"],
- effect: effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- this.useGravity = this.direction === KNDirection.kKNDirectionGravity ? true : false;
- this.percentfinished = 0.0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
- this.drawableObjects.push(drawableObject);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- this.confettiSystems = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var width = textureInfo.width;
- var height = textureInfo.height;
- var ratio = (height / viewportHeight * width / viewportWidth);
- ratio = Math.sqrt(Math.sqrt(ratio));
-
- var numParticles = Math.round(ratio * 10000);
-
- // create a confetti system
- var confettiSystem = new KNWebGLBuildConfettiSystem(
- renderer,
- this.program["confetti"],
- {"width": width, "height": height},
- {"width": viewportWidth, "height": viewportHeight},
- this.duration,
- numParticles,
- textureInfo.texture);
-
- // set ratio so we don't need to recalculate during draw frame
- confettiSystem.ratio = ratio;
-
- this.confettiSystems.push(confettiSystem);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- // determine the type and direction
- var buildIn = this.buildIn;
- var buildOut = this.buildOut;
-
- var percentfinished = this.percentfinished;
- percentfinished += difference / duration;
-
- if (percentfinished > 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- if (buildIn) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- continue;
- }
-
- var width = textureInfo.width;
- var height = textureInfo.height;
- var percent = buildIn ? 1 - percentfinished : percentfinished;
-
- var revPercent = 1 - percent;
- var myPercent = 1 - revPercent * revPercent * revPercent;
- myPercent = myPercent * (1 - percent * percent) + (1 - revPercent * revPercent) * (percent * percent) + percent;
- myPercent *= 0.5;
-
- if (buildIn) {
- myPercent *= myPercent;
- }
-
- //draw the confetti system frame
- var confettiSystem = this.confettiSystems[i];
- var MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, textureInfo.offset.pointX, viewportHeight - (textureInfo.offset.pointY + height), 0);
-
- var finalPercent = 1 - percent;
- finalPercent = WebGraphics.clamp(finalPercent, 0, 1);
- myPercent = WebGraphics.clamp(myPercent, 0, 1);
-
- if (this.useGravity) {
- var ratio = confettiSystem.ratio;
- MVPMatrix = WebGraphics.translateMatrix4(MVPMatrix, 0, -viewportHeight * 2 * percent * percent * (1.0 - ratio * 0.5), 0);
- }
-
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
-
- confettiSystem.setMVPMatrix(MVPMatrix);
- confettiSystem.drawFrame(myPercent, finalPercent);
- } else {
- if (!textureInfo.initialState.hidden) {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- }
- });
-
- var KNWebGLBuildDiffuse = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var effect = params.effect;
-
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNDiffuse",
- programNames: ["diffuse"],
- effect: effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- this.percentfinished = 0.0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
- this.drawableObjects.push(drawableObject);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- this.diffuseSystems = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var width = textureInfo.width;
- var height = textureInfo.height;
- var ratio = (height / viewportHeight * width / viewportWidth);
- ratio = Math.sqrt(Math.sqrt(ratio));
-
- var numParticles = Math.round(ratio * 4000);
-
- // create a confetti system
- var diffuseSystem = new KNWebGLBuildDiffuseSystem(
- renderer,
- this.program["diffuse"],
- {"width": width, "height": height},
- {"width": viewportWidth, "height": viewportHeight},
- this.duration,
- numParticles,
- textureInfo.texture,
- this.direction === KNDirection.kKNDirectionRightToLeft);
-
- this.diffuseSystems.push(diffuseSystem);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- var percentfinished = this.percentfinished;
- percentfinished += difference / duration;
-
- if (percentfinished > 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- var width = textureInfo.width;
- var height = textureInfo.height;
- var offsetX = textureInfo.offset.pointX;
- var offsetY = textureInfo.offset.pointY;
-
- //draw the diffuse system frame
- var diffuseSystem = this.diffuseSystems[i];
- var MVPMatrix = WebGraphics.translateMatrix4(renderer.slideProjectionMatrix, offsetX, viewportHeight - (offsetY + height), 0);
-
- diffuseSystem.setMVPMatrix(MVPMatrix);
- diffuseSystem.drawFrame(this.percentfinished, 1.0);
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- }
- });
-
- var KNWebGLBuildFireworks = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- this.programData = {
- name: "com.apple.iWork.Keynote.KNFireworks",
- programNames: ["fireworks"],
- effect: params.effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var gl = this.gl;
-
- // animation parameter group
- this.animParameterGroup = new KNAnimParameterGroup("Fireworks");
-
- // bind required textures from base64 image source
- this.fireworksTexture = KNWebGLUtil.bindTextureWithImage(gl, fireworksImage);
- this.fireworksCenterBurstTexture = KNWebGLUtil.bindTextureWithImage(gl, fireworksCenterBurstImage);
-
- // initialize percent finish
- this.percentfinished = 0;
- this.prevpercentfinished = 0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- // frame rect for all firework systems
- this.frameRect = this.frameOfEffectWithFrame();
-
- this.slideSize = {"width": gl.viewportWidth, "height": gl.viewportHeight};
-
- var effect = this.effect;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
-
- // push drawable object to drawableObjects array
- this.drawableObjects.push(drawableObject);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- frameOfEffectWithFrame: function() {
- var gl = this.gl;
- var slideRect = {
- "origin": {
- "x": 0,
- "y": 0
- },
- "size": {
- "width": gl.viewportWidth,
- "height": gl.viewportHeight
- }
- };
-
- return slideRect;
- },
-
- p_orthoTransformWithScale: function(scale, offset, mFrameRect) {
- var size = {
- "width": mFrameRect.size.width * scale,
- "height": mFrameRect.size.height * scale
- };
-
- var ortho = WebGraphics.makeOrthoMatrix4(0, size.width, 0, size.height, -1, 1);
- var result = WebGraphics.translateMatrix4(ortho, offset.x, -offset.y, 0);
-
- return result;
- },
-
- p_setupFBOWithSize: function(size) {
- this.framebuffer = new TSDGLFrameBuffer(this.gl, size, 2);
- },
-
- p_fireworksSystemsForTR: function(textureInfo) {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
- var duration = this.duration / 1000;
- var parameterGroup = this.animParameterGroup;
-
- var numFireworks = duration * parameterGroup.doubleForKey("FireworksCount");
- // At least 2 fireworks!
- numFireworks = Math.max(2, numFireworks);
-
- var systems = [];
-
- var startOnLeftIndex = 0;
- var startOnRightIndex = 1;
- var startImmediatelyIndex = parseInt(WebGraphics.randomBetween(0, numFireworks - 1));
-
- for (var i = 0; i < numFireworks; i++) {
- var numParticles = parameterGroup.doubleForKey("ParticleCount");
- var minSlideSide = Math.min(viewportWidth, viewportHeight);
- var fireworkSpan = minSlideSide * WebGraphics.doubleBetween(parameterGroup.doubleForKey("FireworkSizeMin"), parameterGroup.doubleForKey("FireworkSizeMax"));
-
- var particleSystem = new KNWebGLBuildFireworksSystem(
- renderer,
- this.program["fireworks"],
- {"width": textureInfo.width, "height": textureInfo.height},
- {"width": viewportWidth, "height": viewportHeight},
- this.duration,
- {"width": numParticles, "height": 1},
- {"width": 1, "height": 1},
- this.fireworksTexture
- );
-
- var randomSize = WebGraphics.makeSize(parameterGroup.doubleForKey("ParticleSizeMin"), parameterGroup.doubleForKey("ParticleSizeMax"));
- randomSize.width = randomSize.width * minSlideSide / 100;
- randomSize.height = randomSize.height * minSlideSide / 100;
-
- particleSystem.randomParticleSizeMinMax = randomSize;
- particleSystem.maxDistance = fireworkSpan;
- particleSystem.colorRandomness = parameterGroup.doubleForKey("ParticleColorRandomness");
- particleSystem.lifeSpanMinDuration = parameterGroup.doubleForKey("ParticleLifeSpanMinDuration");
- particleSystem.randomParticleSpeedMinMax = WebGraphics.makePoint(parameterGroup.doubleForKey("FireworkSpeedMin"), parameterGroup.doubleForKey("FireworkSpeedMax"));
-
- if (i % 2 === 0) {
- // 1/2 of particles start in left half
- particleSystem.fireworkStartingPositionX = WebGraphics.randomBetween(0, 0.5);
- } else if (i % 2 === 1) {
- // 1/2 of particles start in right half
- particleSystem.fireworkStartingPositionX = WebGraphics.randomBetween(0.5, 1);
- }
-
- if (i === startOnLeftIndex) {
- // Make sure at least one burst is all the way on the left side
- particleSystem.fireworkStartingPositionX = 0;
- }
-
- if (i === startOnRightIndex) {
- // Make sure at least one burst is all the way on the right side
- particleSystem.fireworkStartingPositionX = 1;
- }
-
- // Lifespan/duration of firework
- var randomDuration = WebGraphics.randomBetween(parameterGroup.doubleForKey("FireworkDurationMin"), parameterGroup.doubleForKey("FireworkDurationMax"));
-
- randomDuration /= duration;
-
- var startTime = WebGraphics.randomBetween(0, 1.0 - randomDuration);
-
- if (i === startImmediatelyIndex) {
- // Make sure ONE of the fireworks starts right away!
- startTime = 0;
- }
-
- startTime = Math.max(startTime, 0.001);
-
- particleSystem.lifeSpan = {
- "start": startTime,
- "duration": randomDuration
- };
-
- particleSystem.setupWithTexture(textureInfo);
-
- systems.push(particleSystem);
- }
-
- return systems;
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
- var gl = this.gl;
- var parameterGroup = this.animParameterGroup;
-
- var centerBurstVertexRect = CGRectMake(0, 0, 512, 512);
- var vertexRect = CGRectMake(0, 0, this.slideSize.width, this.slideSize.height);
- var textureRect = CGRectMake(0, 0, 1, 1);
- var meshSize = CGSizeMake(2, 2);
- var mFrameRect = this.frameRect;
-
- this.fireworksSystems = [];
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = this.textures[i];
-
- var orthoOffset = {
- "x": texture.offset.pointX - mFrameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (mFrameRect.origin.y + mFrameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, mFrameRect.size.width, 0, mFrameRect.size.height, -1, 1);
- var baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- // init object shader and data buffer
- var objectShader = new TSDGLShader(gl);
- objectShader.initWithDefaultTextureAndOpacityShader();
-
- // object shader set methods
- objectShader.setMat4WithTransform3D(baseTransform, kTSDGLShaderUniformMVPMatrix);
- objectShader.setGLint(0, kTSDGLShaderUniformTexture);
-
- // init object data buffer
- var objectTextureRect = texture.textureRect;
- var objectVertexRect = CGRectMake(0, 0, objectTextureRect.size.width, objectTextureRect.size.height);
- var objectDataBuffer = new TSDGLDataBuffer(gl);
-
- objectDataBuffer.initWithVertexRect(objectVertexRect, TSDRectUnit, meshSize, false, false);
-
- // Set up shaders for particle systems
- var fireworksMVP = renderer.slideProjectionMatrix;
- fireworksMVP = WebGraphics.translateMatrix4(fireworksMVP, orthoOffset.x, -orthoOffset.y, 0);
-
- var fireworksSystems = this.p_fireworksSystemsForTR(texture);
-
- // set up FBO
- this.p_setupFBOWithSize(mFrameRect.size);
-
- var fboShader = this.fboShader = new TSDGLShader(gl);
- fboShader.initWithShaderFileNames("fireworkstrails", "fireworkstrails");
-
- fboShader.setMat4WithTransform3D(baseOrthoTransform, kTSDGLShaderUniformMVPMatrix);
- fboShader.setGLint(0, kTSDGLShaderUniformTexture);
-
- var fboDataBuffer = this.fboDataBuffer = new TSDGLDataBuffer(gl);
- fboDataBuffer.initWithVertexRect(CGRectMake(0, 0, mFrameRect.size.width, mFrameRect.size.height), TSDRectUnit, meshSize, false, false);
-
- var centerBurstShader = this.centerBurstShader = new TSDGLShader(gl);
- centerBurstShader.initWithDefaultTextureAndOpacityShader();
-
- centerBurstShader.setGLFloat(1.0, kTSDGLShaderUniformOpacity);
-
- var centerBurstDataBuffer = this.centerBurstDataBuffer = new TSDGLDataBuffer(gl);
- centerBurstDataBuffer.initWithVertexRect(centerBurstVertexRect, TSDRectUnit, meshSize, false, false);
-
- var _bloomEffect = this._bloomEffect = new TSDGLBloomEffect(gl);
- _bloomEffect.initWithEffectSize(mFrameRect.size, parameterGroup.doubleForKey("BloomBlurScale"));
-
- var fireworksSystem = {
- "_baseOrthoTransform": baseOrthoTransform,
- "_baseTransform": baseTransform,
- "objectShader": objectShader,
- "objectDataBuffer": objectDataBuffer,
- "fireworksMVP": fireworksMVP,
- "systems": fireworksSystems
- };
-
- this.fireworksSystems.push(fireworksSystem);
-
- gl.clearColor(0.0, 0.0, 0.0, 0.0);
-
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- gl.disable(gl.DEPTH_TEST);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["fireworks"];
- var uniforms = program.uniforms;
- var buildOut = this.buildOut;
- var percentfinished = this.percentfinished;
- var parameterGroup = this.animParameterGroup;
- var noiseAmount = parameterGroup.doubleForKey("ParticleTrailsDitherAmount");
- var noiseMax = parameterGroup.doubleForKey("ParticleTrailsDitherMax");
- var bloomAmount = parameterGroup.doubleForKey("BloomPower");
-
- percentfinished += difference / duration;
-
- if (percentfinished >= 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * this.percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- if (!buildOut) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- continue;
- }
-
- var width = textureInfo.width;
- var height = textureInfo.height;
- var offsetX = textureInfo.offset.pointX;
- var offsetY = textureInfo.offset.pointY;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- duration /= 1000;
-
- var percent = percentfinished;
-
- var currentGLFramebuffer = TSDGLFrameBuffer.currentGLFramebuffer(gl);
-
- var fireworksSystem = this.fireworksSystems[i];
- var objectShader = fireworksSystem.objectShader;
- var objectDataBuffer = fireworksSystem.objectDataBuffer;
-
- // Draw the actual object
- this.p_drawObject(percent, textureInfo, objectShader, objectDataBuffer);
-
- // Draw particles into FBO to save trails
- var framebuffer = this.framebuffer;
- var fboShader = this.fboShader;
- var fboDataBuffer = this.fboDataBuffer;
-
- var previousFBOTexture = framebuffer.currentGLTexture();
- framebuffer.setCurrentTextureToNext();
- framebuffer.bindFramebuffer();
-
- // clear current framebuffer texture
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- // change viewport to match the frame buffer size
- gl.viewport(0, 0, framebuffer.size.width, framebuffer.size.height);
-
- // First, draw existing trails, but faded out a bit
- // bind previous framebuffer texture so we can take the content and draw into current one
- gl.bindTexture(gl.TEXTURE_2D, previousFBOTexture);
-
- var minDuration = parameterGroup.doubleForKey("FireworkDurationMin") / duration;
- minDuration = Math.min(minDuration / 2.0, 1.0);
-
- var trailsFadePercent = WebGraphics.clamp((percentfinished - minDuration) / (1.0 - minDuration), 0, 1);
- var trailsFadeOut = 1.0 - WebGraphics.mix(parameterGroup.doubleForKey("TrailsFadeOutMin"), parameterGroup.doubleForKey("TrailsFadeOutMax"), Math.pow(trailsFadePercent, 2));
-
- fboShader.setGLFloat(trailsFadeOut, kTSDGLShaderUniformOpacity);
- fboShader.setGLFloat(noiseAmount, kShaderUniformNoiseAmount);
- fboShader.setGLFloat(noiseMax, kShaderUniformNoiseMax);
-
- var noiseSeed = WebGraphics.makePoint(WebGraphics.randomBetween(0, 1), WebGraphics.randomBetween(0, 1));
- fboShader.setPoint2D(noiseSeed, kShaderUniformNoiseSeed);
-
- fboDataBuffer.drawWithShader(this.fboShader, true);
-
- // Draw center burst
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // need to use fireworks program before drawing particle system
- gl.useProgram(program.shaderProgram);
-
- var gravity = parameterGroup.doubleForKey("Gravity");
- gravity *= Math.min(viewportWidth, viewportHeight) * 0.001;
- gravity *= duration; // acceleration is per second!
- gl.uniform1f(uniforms["Gravity"], gravity);
-
- var minSlideSide = Math.min(viewportWidth, viewportHeight);
- var startScale = minSlideSide * parameterGroup.doubleForKey("ParticleSizeStart") / 100;
- gl.uniform1f(uniforms["StartScale"], startScale);
-
- gl.uniform1f(uniforms["SparklePeriod"], parameterGroup.doubleForKey("SparklePeriod"));
-
- // draw particle system with percent
- this.drawParticleSystemsWithPercent(percentfinished, false, 1.0, fireworksSystem);
-
- // change viewport back to original
- gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
-
- // done drawing particle into FBO so unbind the framebuffer
- framebuffer.unbindFramebufferAndBindGLFramebuffer(currentGLFramebuffer);
-
- // Draw particle trails
-
- var maxDuration = parameterGroup.doubleForKey("FireworkDurationMax");
- maxDuration = Math.min(maxDuration, 0.999);
- var particleOpacityPercent = WebGraphics.clamp((percentfinished - maxDuration) / (1.0 - maxDuration), 0, 1);
- var particleSystemOpacity = 1.0 - parameterGroup.doubleForAnimationCurve("ParticleTransparency", particleOpacityPercent);
-
- // apply bloom effect
- this._bloomEffect.bindFramebuffer();
-
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- // draw to bloom effect's _colorFramebuffer
- fboShader.setGLFloat(particleSystemOpacity, kTSDGLShaderUniformOpacity);
- fboShader.setGLFloat(0, kShaderUniformNoiseAmount);
-
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
-
- // bind to current framebuffer texture
- gl.bindTexture(gl.TEXTURE_2D, framebuffer.currentGLTexture());
-
- // draw trails FBO to bloom effect FBO
- fboDataBuffer.drawWithShader(fboShader, true);
-
- // draw new sparkles into bloom effect FBO
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // need to use the program before drawing fireworks particle system
- gl.useProgram(program.shaderProgram);
-
- this.drawParticleSystemsWithPercent(percentfinished, true, particleSystemOpacity, fireworksSystem);
-
- // unbind bloom effect framebuffer and bind to default drawing buffer
- this._bloomEffect.unbindFramebufferAndBindGLFramebuffer(currentGLFramebuffer);
-
- // additive blend mode
- gl.blendFunc(gl.ONE, gl.ONE);
-
- this._bloomEffect.drawBloomEffectWithMVPMatrix(fireworksSystem._baseOrthoTransform, bloomAmount, currentGLFramebuffer);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
-
- this.prevpercentfinished = this.percentfinished;
- },
-
- p_drawObject: function(percent, textureInfo, objectShader, objectDataBuffer) {
- var gl = this.gl;
- var parameterGroup = this.animParameterGroup;
-
- var beginTime = parameterGroup.doubleForKey("TextOpacityBeginTime");
- var endTime = parameterGroup.doubleForKey("TextOpacityEndTime");
-
- percent = WebGraphics.clamp((percent - beginTime) / (endTime - beginTime), 0, 1);
-
- var opacity = this.parentOpacity * textureInfo.initialState.opacity;
- opacity *= parameterGroup.doubleForAnimationCurve("TextOpacityTiming", percent);
-
- objectShader.setGLFloat(opacity, kTSDGLShaderUniformOpacity);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
-
- objectDataBuffer.drawWithShader(objectShader, true);
- },
-
- drawParticleSystemsWithPercent: function(percent, shouldDrawSparkles, particleSystemOpacity, fireworksSystem) {
- var renderer = this.renderer;
- var gl = this.gl;
- var program = this.program["fireworks"];
- var uniforms = program.uniforms;
- var parameterGroup = this.animParameterGroup;
- var systems = fireworksSystem.systems;
- var baseTransform = fireworksSystem._baseTransform;
- var MVPMatrix = fireworksSystem.fireworksMVP;
-
- // need to use fireworks program before drawing particle system
- gl.useProgram(program.shaderProgram);
-
- gl.uniform1f(uniforms["ShouldSparkle"], shouldDrawSparkles ? 1 : 0);
-
- for (var i = 0, length = systems.length; i < length; i++) {
- var particleSystem = systems[i];
- var lifeSpan = particleSystem.lifeSpan;
- var systemPercent = (percent - lifeSpan.start) / lifeSpan.duration;
-
- if (systemPercent <= 0 || systemPercent >= 1) {
- continue;
- }
-
- var systemPercent = WebGraphics.clamp(systemPercent, 0, 1);
- var prevSystemPercent = (this.prevpercentfinished - lifeSpan.start) / lifeSpan.duration;
- prevSystemPercent = WebGraphics.clamp(prevSystemPercent, systemPercent / 2, 1);
-
- var opacity = particleSystemOpacity;
- if (shouldDrawSparkles) {
- opacity = 1.0 - parameterGroup.doubleForAnimationCurve("ParticleTransparency", systemPercent);
- }
-
- // Also send in previous particle burst timing so we can blur in direction of burst velocity and avoid strobing
- var prevParticleBurstTiming = parameterGroup.doubleForAnimationCurve("ParticleBurstTiming", prevSystemPercent);
- var particleBurstTiming = parameterGroup.doubleForAnimationCurve("ParticleBurstTiming", systemPercent);
-
- gl.uniform1f(uniforms["ParticleBurstTiming"], particleBurstTiming);
-
- gl.uniform1f(uniforms["PreviousParticleBurstTiming"], prevParticleBurstTiming);
-
- gl.uniform1f(uniforms["PreviousPercent"], prevSystemPercent);
-
- if (!shouldDrawSparkles) {
- // Draw big center burst once at very first frame of Firework... the FBO fading will handle persisting it for a bit
-
- if (!particleSystem.didDrawCenterBurst) {
- gl.bindTexture(gl.TEXTURE_2D, this.fireworksCenterBurstTexture);
-
- // Scale is percent of slide size
- var scale = gl.viewportHeight / 512;
- scale *= WebGraphics.randomBetween(parameterGroup.doubleForKey("CenterBurstScaleMin"), parameterGroup.doubleForKey("CenterBurstScaleMax"));
-
- var center = particleSystem._startingPoint;
-
- var t = WebGraphics.translateMatrix4(baseTransform, center.x, center.y, 0);
- var centerAdjust = WebGraphics.makePoint(-(512 / 2.0 * scale), -(512 / 2.0 * scale));
-
- t = WebGraphics.translateMatrix4(t, centerAdjust.x, centerAdjust.y, 0);
- t = WebGraphics.scaleMatrix4(t, scale, scale, 1);
-
- this.centerBurstShader.setGLFloat(parameterGroup.doubleForKey("CenterBurstOpacity"), kTSDGLShaderUniformOpacity);
- this.centerBurstShader.setMat4WithTransform3D(t, kTSDGLShaderUniformMVPMatrix);
-
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
-
- this.centerBurstDataBuffer.drawWithShader(this.centerBurstShader, true);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- particleSystem.didDrawCenterBurst = true;
- }
- }
-
- // need to use fireworks program before drawing particle system
- gl.useProgram(program.shaderProgram);
-
- particleSystem.setMVPMatrix(MVPMatrix);
-
- particleSystem.drawFrame(systemPercent, opacity);
- }
- }
- });
-
- var KNWebGLBuildShimmer = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var effect = params.effect;
-
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNShimmer",
- programNames: ["shimmerObject", "shimmerParticle"],
- effect: effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var gl = this.gl;
-
- this.percentfinished = 0.0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- this.slideOrigin = {"x": 0, "y": 0};
- this.slideSize = {"width": gl.viewportWidth, "height": gl.viewportHeight};
- this.slideRect = {
- "origin": this.slideOrigin,
- "size": this.slideSize
- };
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableFrame = texture.textureRect;
-
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var frameRect = this.frameOfEffectWithFrame(drawableFrame);
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
-
- drawableObject.frameRect = frameRect;
-
- this.drawableObjects.push(drawableObject);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- frameOfEffectWithFrame: function(drawableFrame) {
- var gl = this.gl;
-
- var minPt = {
- "x": CGRectGetMinX(drawableFrame),
- "y": CGRectGetMinY(drawableFrame)
- };
-
- var maxPt = {
- "x": CGRectGetMaxX(drawableFrame),
- "y": CGRectGetMaxY(drawableFrame)
- };
-
- var extraPadding = Math.max(drawableFrame.size.width, drawableFrame.size.height);
- extraPadding = Math.max(extraPadding, this.slideSize.height / 3.0);
-
- minPt.y -= extraPadding;
- maxPt.y += extraPadding;
-
- minPt.x -= extraPadding;
- maxPt.x += extraPadding;
-
- var frameRect = TSDRectWithPoints(minPt, maxPt);
- frameRect = CGRectIntersection(frameRect, this.slideRect);
- frameRect = CGRectIntegral(frameRect);
-
- return frameRect;
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
-
- // initialize a shimmer effect object for each texture rectangle
- this.shimmerEffects = [];
-
- var program = this.program;
- var slideRect = this.slideRect;
- var duration = this.duration;
- var direction = this.direction;
- var type = this.type;
- var parentOpacity = this.parentOpacity;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = this.textures[i];
- var tr = this.textures[i].textureRect;
- var frameRect = this.drawableObjects[i].frameRect;
-
- var orthoOffset = {
- "x": texture.offset.pointX - frameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (frameRect.origin.y + frameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, frameRect.size.width, 0, frameRect.size.height, -1, 1);
- var baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- var shimmerEffect = new KNWebGLBuildShimmerEffect(
- renderer,
- program,
- slideRect,
- texture,
- frameRect,
- baseTransform,
- duration,
- direction,
- type,
- parentOpacity
- );
-
- this.shimmerEffects.push(shimmerEffect);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- var percentfinished = this.percentfinished;
- percentfinished += difference / duration;
-
- if (percentfinished > 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- if (this.buildIn) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
-
- continue;
- }
-
- var width = textureInfo.width;
- var height = textureInfo.height;
- var offsetX = textureInfo.offset.pointX;
- var offsetY = textureInfo.offset.pointY;
-
- //draw shimmer effect
- var shimmerEffect = this.shimmerEffects[i];
- shimmerEffect.renderEffectAtPercent(this.percentfinished);
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- }
- });
-
- var KNWebGLBuildShimmerEffect = Class.create({
- initialize: function(renderer, program, slideRect, texture, destinationRect, translate, duration, direction, buildType, parentOpacity) {
- this.renderer = renderer;
- this.gl = renderer.gl;
- this.program = program;
- this._slideRect = slideRect;
- this._texture = texture;
- this._destinationRect = destinationRect;
- this._translate = translate;
- this._duration = duration;
- this._direction = direction;
- this._buildType = buildType;
-
- this._baseTransform = new Float32Array(16);
-
- this._isSetup = false;
-
- this.parentOpacity = parentOpacity;
-
- // bind shimmer texture
- this.shimmerTexture = KNWebGLUtil.bindTextureWithImage(this.gl, shimmerImage);
-
- this.setupEffectIfNecessary();
- },
-
- setupEffectIfNecessary: function() {
- if (this._isSetup) {
- return;
- }
-
- var gl = this.gl;
-
- var texture = this._texture;
- var meshSize = CGSizeMake(2, 2);
- var mFrameRect = {
- "origin": {
- "x": 0,
- "y": 0
- },
- "size": {
- "width": gl.viewportWidth,
- "height": gl.viewportHeight
- }
- };
-
- var orthoOffset = {
- "x": texture.offset.pointX - mFrameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (mFrameRect.origin.y + mFrameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, mFrameRect.size.width, 0, mFrameRect.size.height, -1, 1);
- var baseTransform = this.baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- this._objectSystem = this.objectSystemForTR(this._texture, this._slideRect, this._duration);
- this._objectSystem.setMVPMatrix(this.baseTransform);
-
- // Set up particle particle system
- if (this._objectSystem.shouldDraw) {
- // Only set up the particles if we will actually draw this particle system!
- this._particleSystem = this.particleSystemForTR(this._texture, this._slideRect, this._duration);
- this._particleSystem.setMVPMatrix(this.baseTransform);
- }
-
- this._isSetup = true;
- },
-
- p_numberOfParticlesForTR: function(tr, slideRect, duration) {
- var destRect = this._destinationRect;
- var slideSize = slideRect.size;
- var slideRatio = (destRect.size.width / slideSize.width * destRect.size.height / slideSize.height);
- var texRatio = (tr.size.width / destRect.size.width * tr.size.height / destRect.size.height);
-
- // create as many particles as possible without hitting our vertex limit
- var numParticles = parseInt(Math.min((slideRatio * texRatio * 2000), 3276));
-
- return numParticles;
- },
-
- objectSystemForTR: function(texture, slideRect, duration) {
- var tr = texture.textureRect;
- var numParticles = this.p_numberOfParticlesForTR(tr, slideRect, duration);
-
- var particleSystem = new KNWebGLBuildShimmerObjectSystem(
- this.renderer,
- this.program["shimmerObject"],
- {"width": tr.size.width, "height": tr.size.height},
- {"width": slideRect.size.width, "height": slideRect.size.height},
- duration,
- numParticles,
- texture.texture,
- this._direction
- );
-
- return particleSystem;
- },
-
- particleSystemForTR: function(texture, slideRect, duration) {
- var tr = texture.textureRect;
- // Extra sparkles at end
- var extraParticles = this.p_numberOfParticlesForTR(tr, slideRect, duration);
-
- extraParticles = Math.max(2, extraParticles / 40);
-
- // Add in sparkles to match object's particles
- var objectSystemParticleCount = this._objectSystem.particleCount;
- var numParticles = objectSystemParticleCount;
-
- numParticles += extraParticles;
-
- numParticles = Math.min(numParticles, 3276);
-
- var particleSystem = new KNWebGLBuildShimmerParticleSystem(
- this.renderer,
- this.program["shimmerParticle"],
- {"width": tr.size.width, "height": tr.size.height},
- {"width": slideRect.size.width, "height": slideRect.size.height},
- duration,
- CGSizeMake(numParticles, 1),
- this._objectSystem.particleSize,
- this._objectSystem,
- this.shimmerTexture,
- this._direction
- );
-
- return particleSystem;
- },
-
- p_drawObject: function(percent, textureInfo, objectShader, objectDataBuffer) {
- var gl = this.gl;
- var opacity = this.parentOpacity * textureInfo.initialState.opacity;
-
- opacity = opacity * TSUSineMap(percent);
-
- objectShader.setGLFloat(opacity, kTSDGLShaderUniformOpacity);
-
- gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- objectDataBuffer.drawWithShader(objectShader, true);
- },
-
- renderEffectAtPercent: function(percent) {
- var gl = this.gl;
- var texture = this._texture;
-
- if (this._buildType === "buildOut") {
- percent = 1.0 - percent;
- }
-
- var accelPercent = (1 - percent) * (1 - percent);
- var isClockwise = this._buildType === "buildIn";
-
- var rotation = (TSUReverseSquare(percent) * this._duration/1000 + percent) * Math.PI/2;
-
- if (!isClockwise) {
- rotation *= -1.0;
- }
-
- // Draw main object as pieces
- var objectOpacitySpan = WebGraphics.makePoint(0.2, 0.4);
- var objectOpacity = (percent - objectOpacitySpan.x) / objectOpacitySpan.y;
-
- objectOpacity = WebGraphics.clamp(objectOpacity, 0.0, 1.0);
- objectOpacity = TSUSineMap(objectOpacity);
-
- var opacity = this.parentOpacity * texture.initialState.opacity;
- objectOpacity *= opacity;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // need to use the program before drawing the particle system
- gl.useProgram(this.program["shimmerObject"].shaderProgram);
-
- // set MVP Matrix for object system
- this._objectSystem.setMVPMatrix(this.baseTransform);
- this._objectSystem.drawGLSLWithPercent(accelPercent, objectOpacity, rotation, isClockwise, texture.texture);
-
- // Draw shimmers
-
- // need to use the program before drawing the particle system
- gl.useProgram(this.program["shimmerParticle"].shaderProgram);
-
- this._particleSystem.setMVPMatrix(this.baseTransform);
- this._particleSystem.drawGLSLWithPercent(accelPercent, opacity * 0.5, rotation, isClockwise, this.shimmerTexture);
- }
- });
-
- var KNWebGLBuildSparkle = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- var effect = params.effect;
-
- this.programData = {
- name: "com.apple.iWork.Keynote.KLNSparkle",
- programNames: ["sparkle"],
- effect: effect,
- textures: params.textures
- };
-
- $super(renderer, this.programData);
-
- var gl = this.gl;
-
- this.percentfinished = 0.0;
-
- // create drawable object for drawing static texture
- this.drawableObjects = [];
-
- this.slideOrigin = {"x": 0, "y": 0};
- this.slideSize = {"width": gl.viewportWidth, "height": gl.viewportHeight};
- this.slideRect = {
- "origin": this.slideOrigin,
- "size": this.slideSize
- };
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = params.textures[i];
- var drawableFrame = texture.textureRect;
-
- var drawableParams = {
- effect: effect,
- textures: [texture]
- };
-
- var frameRect = this.frameOfEffectWithFrame(drawableFrame);
- var drawableObject = new KNWebGLDrawable(renderer, drawableParams);
-
- drawableObject.frameRect = frameRect;
-
- this.drawableObjects.push(drawableObject);
- }
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup requirements
- this.animationWillBeginWithContext();
- },
-
- frameOfEffectWithFrame: function(drawableFrame) {
- var minPt = WebGraphics.makePoint(CGRectGetMinX(drawableFrame), CGRectGetMinY(drawableFrame));
- var maxPt = WebGraphics.makePoint(CGRectGetMaxX(drawableFrame), CGRectGetMaxY(drawableFrame));
-
- var extraPadding = Math.max(drawableFrame.size.width, drawableFrame.size.height);
- // Make sure the width is large enough to deal with floating point precision errors in proj matrix
- // (Otherwise very small text will look blurry)
- extraPadding = Math.max(extraPadding, 128);
-
- minPt.y = Math.max(CGRectGetMinY(this.slideRect), minPt.y - extraPadding);
- maxPt.y = Math.min(CGRectGetMaxY(this.slideRect), maxPt.y + extraPadding);
-
- minPt.x = Math.max(CGRectGetMinX(this.slideRect), minPt.x - extraPadding);
- maxPt.x = Math.min(CGRectGetMaxX(this.slideRect), maxPt.x + extraPadding);
-
- var frameRect = TSDRectWithPoints(minPt, maxPt);
- frameRect = CGRectIntegral(frameRect);
-
- return frameRect;
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
-
- // initialize a shimmer effect object for each texture rectangle
- this.sparkleEffects = [];
-
- var program = this.program;
- var slideRect = this.slideRect;
- var duration = this.duration;
- var direction = this.direction;
- var type = this.type;
- var parentOpacity = this.parentOpacity;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = this.textures[i];
- var direction = this.direction;
- var tr = this.textures[i].textureRect;
- var frameRect = this.drawableObjects[i].frameRect;
-
- var orthoOffset = {
- "x": texture.offset.pointX - frameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (frameRect.origin.y + frameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, frameRect.size.width, 0, frameRect.size.height, -1, 1);
- var baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- var sparkleEffect = new KNWebGLBuildSparkleEffect(
- renderer,
- program,
- slideRect,
- texture,
- frameRect,
- baseTransform,
- duration,
- direction,
- type,
- parentOpacity
- );
-
- this.sparkleEffects.push(sparkleEffect);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var renderer = this.renderer;
- var gl = this.gl;
- var viewportWidth = gl.viewportWidth;
- var viewportHeight = gl.viewportHeight;
-
- // determine the type and direction
- var buildIn = this.buildIn;
- var buildOut = this.buildOut;
-
- var percentfinished = this.percentfinished;
- percentfinished += difference / duration;
-
- if (percentfinished > 1) {
- percentfinished = 1;
- this.isCompleted = true;
- }
-
- this.percentfinished = percentfinished;
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var textureInfo = this.textures[i];
- var initialState = textureInfo.initialState;
- var animations = textureInfo.animations;
-
- if (textureInfo.hasHighlightedBulletAnimation) {
- if (!initialState.hidden) {
- var opacity;
- if (animations.length > 0 && animations[0].property === "opacity") {
- var opacityFrom = animations[0].from.scalar;
- var opacityTo = animations[0].to.scalar;
- var diff = opacityTo - opacityFrom;
- opacity = opacityFrom + diff * percentfinished;
- } else {
- opacity = textureInfo.initialState.opacity;
- }
-
- this.drawableObjects[i].Opacity = this.parentOpacity * opacity;
- this.drawableObjects[i].drawFrame();
- }
- } else if (textureInfo.animations.length > 0) {
- if (this.isCompleted) {
- if (buildIn) {
- // if completed, just draw its texture object for better performance
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- continue;
- }
-
- //draw shimmer effect
- var sparkleEffect = this.sparkleEffects[i];
- sparkleEffect.renderEffectAtPercent(this.percentfinished);
- } else {
- if (!textureInfo.initialState.hidden) {
- this.drawableObjects[i].Opacity = this.parentOpacity * textureInfo.initialState.opacity;
- this.drawableObjects[i].drawFrame();
- }
- }
- }
- }
- });
-
- var KNWebGLBuildSparkleEffect = Class.create({
- initialize: function(renderer, program, slideRect, texture, destinationRect, translate, duration, direction, buildType, parentOpacity) {
- this.renderer = renderer;
- this.gl = renderer.gl;
- this.program = program;
- this._slideRect = slideRect;
- this._texture = texture;
- this._destinationRect = destinationRect;
- this._translate = translate;
- this._duration = duration;
- this._direction = direction;
- this._buildType = buildType;
-
- this._baseTransform = new Float32Array(16);
-
- this._isSetup = false;
-
- this.parentOpacity = parentOpacity;
-
- // bind shimmer texture
- this.sparkleTexture = KNWebGLUtil.bindTextureWithImage(this.gl, sparkleImage);
-
- this.setupEffectIfNecessary();
- },
-
- setupEffectIfNecessary: function() {
- if (this._isSetup) {
- return;
- }
-
- var gl = this.gl;
-
- var texture = this._texture;
- var meshSize = CGSizeMake(2, 2);
- var mFrameRect = {
- "origin": {
- "x": 0,
- "y": 0
- },
- "size": {
- "width": gl.viewportWidth,
- "height": gl.viewportHeight
- }
- };
-
- var orthoOffset = {
- "x": texture.offset.pointX - mFrameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (mFrameRect.origin.y + mFrameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, mFrameRect.size.width, 0, mFrameRect.size.height, -1, 1);
- var baseTransform = this.baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- // init object shader and data buffer
- var objectShader = this._objectShader = new TSDGLShader(gl);
- objectShader.initWithDefaultTextureAndOpacityShader();
-
- // object shader set methods
- objectShader.setMat4WithTransform3D(baseTransform, kTSDGLShaderUniformMVPMatrix);
- objectShader.setGLint(0, kTSDGLShaderUniformTexture);
-
- // new data buffer attributes
- var objectPositionAttribute = new TSDGLDataBufferAttribute(kTSDGLShaderAttributePosition, GL_STREAM_DRAW, GL_FLOAT, false, 2);
- var objectTexCoordAttribute = new TSDGLDataBufferAttribute(kTSDGLShaderAttributeTexCoord, GL_STREAM_DRAW, GL_FLOAT, false, 2);
-
- // init object data buffer
- var objectDataBuffer = this._objectDataBuffer = new TSDGLDataBuffer(gl);
-
- objectDataBuffer.newDataBufferWithVertexAttributes([objectPositionAttribute, objectTexCoordAttribute] , meshSize, true);
-
- // Set up sparkle particle system
- this.sparkleSystem = this.sparkleSystemForTR(this._texture, this._slideRect, this._duration);
- this.sparkleSystem.setMVPMatrix(baseTransform);
- this.sparkleSystem.setColor(new Float32Array([1, 1, 1, 1]));
-
- this._isSetup = true;
- },
-
- p_numberOfParticlesForTR: function(tr, slideRect, duration) {
- var destRect = this._destinationRect;
- var slideSize = slideRect.size;
- var slideRatio = (destRect.size.width / slideSize.width * destRect.size.height / slideSize.height);
- var texRatio = (tr.size.width / destRect.size.width * tr.size.height / destRect.size.height);
-
- // create as many particles as possible without hitting our vertex limit
- var numParticles = parseInt(Math.min((slideRatio * texRatio * 2000), 3276));
-
- return numParticles;
- },
-
- sparkleSystemForTR: function(texture, slideRect, duration) {
- var tr = texture.textureRect;
- var slideSize = this._slideRect.size;
- var boundingRect = this._destinationRect;
-
- var slideRatio = Math.min(boundingRect.size.width, slideSize.width) / slideSize.width * Math.min(boundingRect.size.height, slideSize.height) / slideSize.height;
-
- var numParticles = parseInt(((2 - Math.sqrt(slideRatio)) / 2) * 1500 * this._duration / 1000);
-
- var sparkleSystem = new KNWebGLBuildSparkleSystem(
- this.renderer,
- this.program["sparkle"],
- {"width": tr.size.width, "height": tr.size.height},
- {"width": slideRect.size.width, "height": slideRect.size.height},
- duration,
- CGSizeMake(numParticles, 1),
- {"width": 128, "height": 128},
- this.sparkleTexture,
- this._direction
- );
-
- return sparkleSystem;
- },
-
- p_drawObject: function(percent, textureInfo, objectShader, objectDataBuffer) {
- var gl = this.gl;
- var opacity = this.parentOpacity * textureInfo.initialState.opacity;
-
- opacity = opacity * TSUSineMap(percent);
-
- objectShader.setGLFloat(opacity, kTSDGLShaderUniformOpacity);
-
- gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- objectDataBuffer.drawWithShader(objectShader, true);
- },
-
- renderEffectAtPercent: function(percent) {
- var gl = this.gl;
- var texture = this._texture;
- var direction = this._direction;
- var tr = texture.textureRect;
-
- var isReverse = (direction == KNDirection.kKNDirectionRightToLeft || direction == KNDirection.kKNDirectionTopToBottom);
- var isHorizontal = (direction == KNDirection.kKNDirectionRightToLeft || direction == KNDirection.kKNDirectionLeftToRight);
-
- var mvpMatrix = this._translate;
- var alpha = this.parentOpacity * texture.initialState.opacity;
-
- // CONSTANTS
- var duration = this._duration / 1000;
- var blurWidth = 0.2 / duration;
- var width = tr.size.width;
- var height = tr.size.height;
- // =========
-
- // FIRST, we draw the original image fading out
- var particleTiming = KNSparkleMaxParticleLife / Math.max(0.75, duration);
- var opaqueWidth = percent / (1. - particleTiming);
- var xStart = 0, yStart = 0, xEnd = 0, yEnd = 0, xTexStart = 0, yTexStart = 0, xTexEnd = 0, yTexEnd = 0;
-
- if (this._buildType == "buildOut") {
- opaqueWidth -= blurWidth;
- xStart = (isHorizontal) ? ((isReverse) ? 0 : width) : 0;
- yStart = (isHorizontal) ? 0 : ((isReverse) ? 0 : height);
- xEnd = (isHorizontal) ? ((isReverse) ? width - (width * WebGraphics.clamp(opaqueWidth, 0, 1)) : width * WebGraphics.clamp(opaqueWidth, 0, 1)) : width;
- yEnd = (isHorizontal) ? height : ((isReverse) ? height - (height * WebGraphics.clamp(opaqueWidth, 0, 1)) : (height * WebGraphics.clamp(opaqueWidth, 0, 1)));
- xTexStart = (isHorizontal) ? ((isReverse) ? 0 : 1) : 0;
- yTexStart = (isHorizontal) ? 0 : ((isReverse) ? 0 : 1);
- xTexEnd = (isHorizontal) ? ((isReverse) ? 1 - (1 * WebGraphics.clamp(opaqueWidth, 0, 1)) : (1 * WebGraphics.clamp(opaqueWidth, 0, 1))) : 1;
- yTexEnd = (isHorizontal) ? 1 : ((isReverse) ? 1 - (1 * WebGraphics.clamp(opaqueWidth, 0, 1)) : (1 * WebGraphics.clamp(opaqueWidth, 0, 1)));
- } else {
- opaqueWidth -= blurWidth;
- xStart = (isHorizontal) ? ((isReverse) ? width : 0) : 0;
- yStart = (isHorizontal) ? 0 : ((isReverse) ? height : 0);
- xEnd = (isHorizontal) ? ((isReverse) ? width - (width * WebGraphics.clamp(opaqueWidth, 0, 1)) : width * WebGraphics.clamp(opaqueWidth, 0, 1)) : width;
- yEnd = (isHorizontal) ? height : ((isReverse) ? height - (height * WebGraphics.clamp(opaqueWidth, 0, 1)) : height * WebGraphics.clamp(opaqueWidth, 0, 1));
- xTexStart = (isHorizontal) ? ((isReverse) ? 1 : 0) : 0;
- yTexStart = (isHorizontal) ? 0 : ((isReverse) ? 1 : 0);
- xTexEnd = (isHorizontal) ? ((isReverse) ? 1 - (1 * WebGraphics.clamp(opaqueWidth, 0, 1)) : 1 * WebGraphics.clamp(opaqueWidth, 0, 1)) : 1;
- yTexEnd = (isHorizontal) ? 1 : ((isReverse) ? 1 - (1 * WebGraphics.clamp(opaqueWidth, 0, 1)) : 1 * WebGraphics.clamp(opaqueWidth, 0, 1));
- }
-
- gl.bindTexture(gl.TEXTURE_2D, texture.texture);
-
- this._objectShader.setGLFloat(alpha, kTSDGLShaderUniformOpacity);
-
- // update data buffer position and text coord
- var objectDataBuffer = this._objectDataBuffer;
- var objectPositionAttribute = objectDataBuffer.vertexAttributeNamed(kTSDGLShaderAttributePosition);
- var objectTexCoordAttribute = objectDataBuffer.vertexAttributeNamed(kTSDGLShaderAttributeTexCoord);
-
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xStart, yStart), objectPositionAttribute, 0);
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xEnd, yStart), objectPositionAttribute, 1);
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xStart, yEnd), objectPositionAttribute, 2);
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xEnd, yEnd), objectPositionAttribute, 3);
-
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xTexStart, yTexStart), objectTexCoordAttribute, 0);
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xTexEnd, yTexStart), objectTexCoordAttribute, 1);
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xTexStart, yTexEnd), objectTexCoordAttribute, 2);
- objectDataBuffer.setGLPoint2D(WebGraphics.makePoint(xTexEnd, yTexEnd), objectTexCoordAttribute, 3);
-
- objectDataBuffer.drawWithShader(this._objectShader, true);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- // need to use the program before drawing the particle system
- gl.useProgram(this.program["sparkle"].shaderProgram);
-
- this.sparkleSystem.setMVPMatrix(this.baseTransform);
- this.sparkleSystem.drawFrame(percent, 1.0);
- }
- });
-
- var KNWebGLTransitionMagicMove = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- // initialize default program data for core animation wrapper program
- this.coreAnimationWrapperProgram = new KNWebGLCoreAnimationWrapperProgram(params);
-
- // create WebGL program using core animation wrapper program data
- $super(renderer, this.coreAnimationWrapperProgram.data);
-
- var gl = this.gl;
-
- this.percentfinished = 0.0;
-
- // create drawable object for drawing the texture
- this.drawableObjects = [];
-
- this.slideOrigin = {"x": 0, "y": 0};
- this.slideSize = {"width": gl.viewportWidth, "height": gl.viewportHeight};
- this.slideRect = {
- "origin": this.slideOrigin,
- "size": this.slideSize
- };
-
- this.frameRect = this.slideRect;
-
- var effect = params.effect;
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup web drawable requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
-
- // initialize a core animation wrapper based effect object for each texture rectangle
- this.coreAnimationWrapperBasedEffects = [];
-
- var program = this.program;
- var slideRect = this.slideRect;
- var duration = this.duration;
- var direction = this.direction;
- var buildType = this.type;
- var parentOpacity = this.parentOpacity;
- var parameterGroupName = this.parameterGroupName;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = this.textures[i];
- var direction = this.direction;
- var tr = this.textures[i].textureRect;
- var frameRect = this.frameRect;
-
- var orthoOffset = {
- "x": texture.offset.pointX - frameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (frameRect.origin.y + frameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, frameRect.size.width, 0, frameRect.size.height, -1, 1);
- var baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- var coreAnimationWrapperBasedEffect = new KNWebGLCoreAnimationWrapperBasedEffect(
- renderer,
- program,
- slideRect,
- texture,
- frameRect,
- baseTransform,
- duration,
- direction,
- buildType,
- parentOpacity
- );
-
- // push each effect into effect dictionary
- this.coreAnimationWrapperBasedEffects.push(coreAnimationWrapperBasedEffect);
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var coreAnimationWrapperBasedEffects = this.coreAnimationWrapperBasedEffects;
-
- for (var i = 0, length = coreAnimationWrapperBasedEffects.length; i < length; i++) {
- coreAnimationWrapperBasedEffects[i].drawFrame(difference, elapsed, duration);
- }
- }
- });
-
- var KNWebGLTransitionContentAware = Class.create(KNWebGLProgram, {
- initialize: function($super, renderer, params) {
- // initialize default program data for core animation wrapper program
- this.coreAnimationWrapperProgram = new KNWebGLCoreAnimationWrapperProgram(params);
-
- this.params = params;
-
- // create WebGL program using core animation wrapper program data
- $super(renderer, this.coreAnimationWrapperProgram.data);
-
- var gl = this.gl;
-
- this.percentfinished = 0.0;
-
- this.slideOrigin = {"x": 0, "y": 0};
- this.slideSize = {"width": gl.viewportWidth, "height": gl.viewportHeight};
- this.slideRect = {
- "origin": this.slideOrigin,
- "size": this.slideSize
- };
-
- // set frameRect to slideRect for content aware transition
- this.frameRect = this.slideRect;
-
- var effect = params.effect;
-
- // set parent opacity from CA baseLayer
- this.parentOpacity = effect.baseLayer.initialState.opacity;
-
- // setup web drawable requirements
- this.animationWillBeginWithContext();
- },
-
- animationWillBeginWithContext: function() {
- var renderer = this.renderer;
-
- // effect array object to include both text effects and CA wrapper based objects
- this.contentAwareEffects = [];
-
- var program = this.program;
- var slideRect = this.slideRect;
- var duration = this.duration;
- var direction = this.direction;
- var buildType = this.type;
- var parentOpacity = this.parentOpacity;
- var parameterGroupName = this.parameterGroupName;
-
- for (var i = 0, length = this.textures.length; i < length; i++) {
- var texture = this.textures[i];
- var direction = this.direction;
- var tr = this.textures[i].textureRect;
- var frameRect = this.frameRect;
-
- var orthoOffset = {
- "x": texture.offset.pointX - frameRect.origin.x,
- "y": texture.offset.pointY + texture.height - (frameRect.origin.y + frameRect.size.height)
- };
-
- var baseOrthoTransform = WebGraphics.makeOrthoMatrix4(0, frameRect.size.width, 0, frameRect.size.height, -1, 1);
- var baseTransform = WebGraphics.translateMatrix4(baseOrthoTransform, orthoOffset.x, -orthoOffset.y, 0);
-
- // make sure the effect only work on text type or shape object
- var texturedRectangle = texture.texturedRectangle;
- var textureType = texturedRectangle.textureType;
- var isShapeObject = (textureType === TSDTextureType.Object && texturedRectangle.shapePath) ? true : false;
-
- if (textureType === TSDTextureType.Text || isShapeObject) {
- var params = this.params;
- var effect = params.effect;
-
- // set this texture for text effect
- params.textures = [texture];
-
- // use hidden animations to find out the correct build type
- var groupAnimations = texture.animations;
- var program;
-
- if (groupAnimations && groupAnimations.length > 0) {
- var animations = groupAnimations[0].animations;
-
- for (var j = 0, animationLength = animations.length; j < animationLength; j++) {
- var animation = animations[j];
-
- if (animation.property === "hidden") {
- effect.type = animation.to.scalar ? "buildOut" : "buildIn";
- break;
- }
- }
- }
-
- switch (effect.name) {
- case "apple:ca-text-shimmer":
- program = new KNWebGLBuildShimmer(renderer, params);
- break;
-
- case "apple:ca-text-sparkle":
- program = new KNWebGLBuildSparkle(renderer, params);
- break;
-
- default:
- program = new KNWebGLDissolve(renderer, params);
- break;
- }
-
- // push each text effect into effect dictionary
- this.contentAwareEffects.push(program);
- } else {
- var coreAnimationWrapperBasedEffect = new KNWebGLCoreAnimationWrapperBasedEffect(
- renderer,
- program,
- slideRect,
- texture,
- frameRect,
- baseTransform,
- duration,
- direction,
- buildType,
- parentOpacity
- );
-
- // push each CA effect into effect dictionary
- this.contentAwareEffects.push(coreAnimationWrapperBasedEffect);
- }
- }
- },
-
- drawFrame: function(difference, elapsed, duration) {
- var contentAwareEffects = this.contentAwareEffects;
-
- for (var i = 0, length = contentAwareEffects.length; i < length; i++) {
- var contentAwareEffect = contentAwareEffects[i];
- contentAwareEffect.drawFrame(difference, elapsed, duration);
- }
- }
- });
-
- var KNWebGLTransitionShimmer = Class.create(KNWebGLTransitionContentAware, {
- initialize: function($super, renderer, params) {
- // Set up Shimmer as content aware transition
- $super(renderer, params);
- }
- });
-
- var KNWebGLTransitionSparkle = Class.create(KNWebGLTransitionContentAware, {
- initialize: function($super, renderer, params) {
- // Set up Sparkle as content aware transition
- $super(renderer, params);
- }
- });
|