|
- /*
- * 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);
- }
- });
|