Spaces:
Running
Running
one final try
Browse files- .gitattributes +0 -1
- assets/player/AnimationManager.js +1 -3
- assets/player/DebuggingSupport.js +276 -3
- assets/player/DisplayManager.js +1 -3
- assets/player/HelpPlacardController.js +194 -3
- assets/player/KPFObjects.js +1 -3
- assets/player/KeynoteDHTMLPlayer.js +1 -3
- assets/player/NarrationManager.js +179 -3
- assets/player/NavigatorController.js +325 -3
- assets/player/OrientationController.js +40 -3
- assets/player/ScriptManager.js +1 -3
- assets/player/ShowController.js +2105 -3
- assets/player/SlideManager.js +1 -3
- assets/player/SlideNumberController.js +1 -3
- assets/player/StageManager.js +1 -3
- assets/player/TSDAnimation.js +92 -3
- assets/player/TextureManager.js +1 -3
- assets/player/TouchController.js +276 -3
- assets/player/Utilities.js +286 -3
- assets/player/gl/KNWebGLObjects.js +0 -0
- assets/player/gl/KNWebGLParticleObjects.js +0 -0
- assets/player/gl/KNWebGLShader.js +1326 -3
- assets/player/gl/KNWebGLUtil.js +1145 -3
- assets/player/gl/ParameterGroup.js +153 -3
- assets/player/gl/TSDGLBloomEffect.js +170 -3
- assets/player/gl/TSDGLDataBuffer.js +823 -3
- assets/player/gl/TSDGLFrameBuffer.js +116 -3
- assets/player/gl/TSDGLShader.js +520 -3
- assets/player/pdfjs/bcmaps.js +0 -0
- assets/player/pdfjs/pdf.js +0 -0
- assets/player/pdfjs/pdf_worker.js +0 -0
- assets/player/pdfjs/web/compatibility.js +593 -3
- assets/player/prototype.js +0 -0
- assets/player/string.js +220 -3
.gitattributes
CHANGED
@@ -38,7 +38,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
38 |
*.pdfp filter=lfs diff=lfs merge=lfs -text
|
39 |
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
40 |
*.gif filter=lfs diff=lfs merge=lfs -text
|
41 |
-
*.js filter=lfs diff=lfs merge=lfs -text
|
42 |
*.png filter=lfs diff=lfs merge=lfs -text
|
43 |
*.bcmap filter=lfs diff=lfs merge=lfs -text
|
44 |
/assets/player/pdfjs/web/cmaps/LICENSE filter=lfs diff=lfs merge=lfs -text
|
|
|
38 |
*.pdfp filter=lfs diff=lfs merge=lfs -text
|
39 |
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
40 |
*.gif filter=lfs diff=lfs merge=lfs -text
|
|
|
41 |
*.png filter=lfs diff=lfs merge=lfs -text
|
42 |
*.bcmap filter=lfs diff=lfs merge=lfs -text
|
43 |
/assets/player/pdfjs/web/cmaps/LICENSE filter=lfs diff=lfs merge=lfs -text
|
assets/player/AnimationManager.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
|
2 |
-
oid sha256:caa5f82edd64ad130e8bd367c53083d36866b2db3edf177b7d28e071b93b4367
|
3 |
-
size 746
|
|
|
1 |
+
var kKeyframeRule=window.CSSRule.WEBKIT_KEYFRAMES_RULE;var AnimationManager=Class.create({initialize:function(){var a=document.createElement("style");a.type="text/css";a.media="screen";document.getElementsByTagName("head")[0].appendChild(a);this.styleSheet=document.styleSheets[document.styleSheets.length-1];this.createdAnimations=new Object()},createAnimation:function(a){this.styleSheet.insertRule(kKeyframesPropertyName+" "+a+" {}",0);return this.styleSheet.cssRules[0]},deleteAllAnimations:function(){while(this.styleSheet.cssRules.length>0){this.styleSheet.deleteRule(0)}this.createdAnimations=new Object()},markAnimationsCreated:function(a){this.createdAnimations[a]=true},animationsCreated:function(a){return this.createdAnimations[a]}});
|
|
|
|
assets/player/DebuggingSupport.js
CHANGED
@@ -1,3 +1,276 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* DebuggingSupport.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Responsibility: Tungwei Cheng
|
6 |
+
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Set this to "false" to disable ALL debugging logic
|
10 |
+
var gDebug = false;
|
11 |
+
|
12 |
+
// Set this to "false" to disable debug messages when running on the iPhone or iPad
|
13 |
+
var gDebugOnMobile = false;
|
14 |
+
|
15 |
+
// Globals:
|
16 |
+
// ===============================================================
|
17 |
+
|
18 |
+
var gNumDebugMessagesSent = 0;
|
19 |
+
var gNumDebugMessagesQueued = 0;
|
20 |
+
var gDebugMessageQueue = new Array();
|
21 |
+
var gDebugMessageRequest = null;
|
22 |
+
var gDebugLastClassName = "";
|
23 |
+
var gDebugLastMethodName = "";
|
24 |
+
|
25 |
+
// Enable these constants to simulate various conditions/errors:
|
26 |
+
|
27 |
+
var gDebugSimulateSlowTextureDownload = false;
|
28 |
+
var gDebugSimulateTextureLoadFailure = false;
|
29 |
+
var gDebugSimulateScriptDownloadFailure = false;
|
30 |
+
|
31 |
+
// Constants:
|
32 |
+
// ===============================================================
|
33 |
+
|
34 |
+
var kDebugFunction = "function";
|
35 |
+
var kDebugSurpressMessage = "!NoOp_!NoOp";
|
36 |
+
|
37 |
+
//----------------------------------------------------------------------
|
38 |
+
|
39 |
+
var kDebugSetupShowController = kDebugFunction + "_" + "setupShowController";
|
40 |
+
|
41 |
+
//----------------------------------------------------------------------
|
42 |
+
|
43 |
+
var kDebugShowController = "!ShowController";
|
44 |
+
|
45 |
+
var kDebugShowController_AdvanceToNextBuild = kDebugShowController + "_" + "!advanceToNextBuild";
|
46 |
+
var kDebugShowController_AdvanceToNextSlide = kDebugShowController + "_" + "!advanceToNextSlide";
|
47 |
+
var kDebugShowController_DoIdleProcessing = kDebugShowController + "_" + "!doIdleProcessing";
|
48 |
+
var kDebugShowController_GoBackToPreviousBuild = kDebugShowController + "_" + "!goBackToPreviousBuild";
|
49 |
+
var kDebugShowController_GoBackToPreviousSlide = kDebugShowController + "_" + "!goBackToPreviousSlide";
|
50 |
+
var kDebugShowController_HandleScriptDidDownloadEvent = kDebugShowController + "_" + "!handleScriptDidDownloadEvent";
|
51 |
+
var kDebugShowController_HandleScriptDidNotDownloadEvent = kDebugShowController + "_" + "!handleScriptDidNotDownloadEvent";
|
52 |
+
var kDebugShowController_JumpToScene = kDebugShowController + "_" + "!jumpToScene";
|
53 |
+
var kDebugShowController_OnKeyPress = kDebugShowController + "_" + "!onKeyPress";
|
54 |
+
|
55 |
+
//----------------------------------------------------------------------
|
56 |
+
|
57 |
+
var kDebugTouchController = "!TouchController";
|
58 |
+
|
59 |
+
var kDebugTouchController_HandleGestureEndEvent = kDebugTouchController + "_" + "!handleGestureEndEvent";
|
60 |
+
var kDebugTouchController_HandleGestureStartEvent = kDebugTouchController + "_" + "!handleGestureStartEvent";
|
61 |
+
var kDebugTouchController_HandleTouchCancelEvent = kDebugTouchController + "_" + "!handleTouchCancelEvent";
|
62 |
+
var kDebugTouchController_HandleTouchCancelEvent = kDebugTouchController + "_" + "!handleTouchMoveEvent";
|
63 |
+
var kDebugTouchController_HandleTouchEndEvent = kDebugTouchController + "_" + "!handleTouchEndEvent";
|
64 |
+
var kDebugTouchController_HandleTouchStartEvent = kDebugTouchController + "_" + "!handleTouchStartEvent";
|
65 |
+
var kDebugTouchController_Initialize = kDebugTouchController + "_" + "!initialize";
|
66 |
+
var kDebugTouchController_IsTouchWithinTrackArea = kDebugTouchController + "_" + "!isTouchWithinTrackArea";
|
67 |
+
var kDebugTouchController_SetTrackArea = kDebugTouchController + "_" + "!setTrackArea";
|
68 |
+
|
69 |
+
//----------------------------------------------------------------------
|
70 |
+
|
71 |
+
var kDebugScriptMangaer = "!ScriptManager";
|
72 |
+
|
73 |
+
var kDebugScriptMangaer_DownloadScript = kDebugScriptMangaer + "_" + "!downloadScript";
|
74 |
+
|
75 |
+
//----------------------------------------------------------------------
|
76 |
+
|
77 |
+
var kDebugTimer = "DebugTimer";
|
78 |
+
|
79 |
+
var kDebugTimer_AdvanceToNextBuild = kDebugTimer + "_" + "!advanceToNextBuild";
|
80 |
+
var kDebugTimer_CreateAnimationsForScene = kDebugTimer + "_" + "!createAnimationsForScene";
|
81 |
+
var kDebugTimer_ApplyAnimationsForScene = kDebugTimer + "_" + "!applyAnimationsForScene";
|
82 |
+
var kDebugTimer_PreProcessSceneAnimations = kDebugTimer + "_" + "!preProcessSceneAnimations";
|
83 |
+
var kDebugTimer_AdvanceToNextBuild_to_ApplyAnimations = kDebugTimer + "_" + "!preProcessSceneAnimations_to_ApplyAnimations";
|
84 |
+
var kDebugTimer_JumpToScene = kDebugTimer + "_" + "!jumpToScene";
|
85 |
+
var kDebugTimer_DisplayScene = kDebugTimer + "_" + "!displayScene";
|
86 |
+
|
87 |
+
// Functions:
|
88 |
+
// ===============================================================
|
89 |
+
|
90 |
+
function debugWarning(sender, messageText) {
|
91 |
+
if (gDebug === false) {
|
92 |
+
return;
|
93 |
+
}
|
94 |
+
debugSendMessage(sender, "WARNING: " + messageText, true);
|
95 |
+
}
|
96 |
+
|
97 |
+
function debugMessageAlways(sender, messageText) {
|
98 |
+
debugSendMessage(sender, messageText, true);
|
99 |
+
}
|
100 |
+
|
101 |
+
function debugMessage(sender, messageText) {
|
102 |
+
if (gDebug == false) {
|
103 |
+
return;
|
104 |
+
}
|
105 |
+
|
106 |
+
if ((gDevice == kDeviceMobile) && (gDebugOnMobile == false)) {
|
107 |
+
return;
|
108 |
+
}
|
109 |
+
|
110 |
+
debugSendMessage(sender, messageText, false);
|
111 |
+
}
|
112 |
+
|
113 |
+
function debugSendMessage(sender, messageText, always) {
|
114 |
+
var indexOfUnderscore = sender.indexOf("_");
|
115 |
+
var className = sender.substring(0, indexOfUnderscore);
|
116 |
+
var methodName = sender.substring(indexOfUnderscore + 1);
|
117 |
+
var suppress = false;
|
118 |
+
|
119 |
+
if (className[0] == "!") {
|
120 |
+
className = className.substring(1);
|
121 |
+
suppress = true;
|
122 |
+
}
|
123 |
+
|
124 |
+
if (methodName[0] == "!") {
|
125 |
+
methodName = methodName.substring(1);
|
126 |
+
suppress = true;
|
127 |
+
}
|
128 |
+
|
129 |
+
if (methodName[0] == "+") {
|
130 |
+
methodName = methodName.substring(1);
|
131 |
+
always = true;
|
132 |
+
}
|
133 |
+
|
134 |
+
if ((suppress == true) && (always == false)) {
|
135 |
+
return;
|
136 |
+
}
|
137 |
+
|
138 |
+
var prefix = "";
|
139 |
+
|
140 |
+
if (messageText == null) {
|
141 |
+
messageText = "";
|
142 |
+
}
|
143 |
+
|
144 |
+
if (messageText[0] != "-" || className != gDebugLastClassName || methodName != gDebugLastMethodName) {
|
145 |
+
if (className == kDebugTimer) {
|
146 |
+
prefix = sender + ": ";
|
147 |
+
}
|
148 |
+
else if (className == kDebugFunction) {
|
149 |
+
prefix = methodName + "() ";
|
150 |
+
}
|
151 |
+
else {
|
152 |
+
prefix = className + "." + methodName + "() ";
|
153 |
+
}
|
154 |
+
} else {
|
155 |
+
prefix = "";
|
156 |
+
}
|
157 |
+
|
158 |
+
gDebugLastClassName = className;
|
159 |
+
gDebugLastMethodName = methodName;
|
160 |
+
|
161 |
+
if (gDevice == kDeviceMobile) {
|
162 |
+
gNumDebugMessagesSent++;
|
163 |
+
|
164 |
+
var formattedMessageText = escape(gNumDebugMessagesSent + ": " + prefix + messageText);
|
165 |
+
|
166 |
+
gDebugMessageQueue[gNumDebugMessagesQueued] = formattedMessageText;
|
167 |
+
gNumDebugMessagesQueued++;
|
168 |
+
|
169 |
+
if (gNumDebugMessagesQueued == 1) {
|
170 |
+
debugCheckMessageQueue();
|
171 |
+
}
|
172 |
+
} else {
|
173 |
+
if (window.console) {
|
174 |
+
window.console.log( prefix + messageText );
|
175 |
+
}
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
function debugSendNextMessageInQueue() {
|
180 |
+
var formattedMessageText = gDebugMessageQueue[0];
|
181 |
+
|
182 |
+
gNumDebugMessagesQueued--;
|
183 |
+
gDebugMessageQueue.splice(0,1);
|
184 |
+
|
185 |
+
var messageUrl = '/debugMessage.rhtml?message="' + formattedMessageText + '"';
|
186 |
+
|
187 |
+
new Ajax.Request( messageUrl, {
|
188 |
+
method: "get",
|
189 |
+
onSuccess: function(transport) {debugMessageWasSent(transport);},
|
190 |
+
onFailure: function(transport) {debugMessageWasNotSent(transport);}
|
191 |
+
});
|
192 |
+
}
|
193 |
+
|
194 |
+
function debugMessageWasSent(transport) {
|
195 |
+
debugCheckMessageQueue();
|
196 |
+
}
|
197 |
+
|
198 |
+
function debugMessageWasNotSent(transport) {
|
199 |
+
debugCheckMessageQueue();
|
200 |
+
}
|
201 |
+
|
202 |
+
function debugCheckMessageQueue() {
|
203 |
+
if (gNumDebugMessagesQueued > 0) {
|
204 |
+
setTimeout(debugSendNextMessageInQueue, 10);
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
var DebugTimer = Class.create({
|
209 |
+
initialize: function(timerId) {
|
210 |
+
var indexOfUnderscore = timerId.indexOf("_");
|
211 |
+
var timerName = timerId.substring( indexOfUnderscore + 1 );
|
212 |
+
|
213 |
+
if (timerName[0] != "!") {
|
214 |
+
this.id = timerId;
|
215 |
+
this.startTime = new Date();
|
216 |
+
|
217 |
+
debugMessageAlways(timerId, "Start");
|
218 |
+
} else {
|
219 |
+
this.startTime = null;
|
220 |
+
}
|
221 |
+
},
|
222 |
+
|
223 |
+
stop: function() {
|
224 |
+
if (this.startTime != null) {
|
225 |
+
var endTime = new Date();
|
226 |
+
var elapsedTime = endTime - this.startTime;
|
227 |
+
|
228 |
+
debugMessageAlways(this.id , "Stop - Elapsed Time: " + elapsedTime);
|
229 |
+
}
|
230 |
+
}
|
231 |
+
});
|
232 |
+
|
233 |
+
function debugStopTimer(timer) {
|
234 |
+
if (timer) {
|
235 |
+
timer.stop();
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
var debugDomDumpLineNumber = 0;
|
240 |
+
|
241 |
+
function debugDumpDomFrom(rootObject, context) {
|
242 |
+
var kDebugDumpDomFrom = kDebugFunction + "_" + "debugDumpDomFrom";
|
243 |
+
|
244 |
+
debugDomDumpLineNumber = 0;
|
245 |
+
debugMessageAlways(kDebugDumpDomFrom, "------------------ S T A R T O F D O M D U M P --- Context: " + context);
|
246 |
+
debugRecursivelyDumpDomFrom(rootObject, "");
|
247 |
+
debugMessageAlways(kDebugDumpDomFrom, "------------------ E N D O F D O M D U M P");
|
248 |
+
}
|
249 |
+
|
250 |
+
function debugRecursivelyDumpDomFrom(object, indentPadding) {
|
251 |
+
var kDebugRecursivelyDumpDomFrom = kDebugFunction + "_" + "recursivelyDumpDomFrom";
|
252 |
+
var objectId = object.id;
|
253 |
+
var objectTag = object.nodeName.toLowerCase();
|
254 |
+
|
255 |
+
if (objectTag == "#text") {
|
256 |
+
return;
|
257 |
+
}
|
258 |
+
|
259 |
+
debugMessageAlways( kDebugRecursivelyDumpDomFrom, "-" + (debugDomDumpLineNumber++) + indentPadding + "<" + objectTag + " id='" + objectId + "'>");
|
260 |
+
|
261 |
+
var iChild;
|
262 |
+
|
263 |
+
for (iChild = 0; iChild < object.childNodes.length; iChild++) {
|
264 |
+
var child = object.childNodes[iChild];
|
265 |
+
recursivelyDumpDomFrom(child, indentPadding + " ");
|
266 |
+
}
|
267 |
+
|
268 |
+
if (objectTag == "img") {
|
269 |
+
return;
|
270 |
+
}
|
271 |
+
|
272 |
+
debugMessageAlways(kDebugRecursivelyDumpDomFrom, "-" + (debugDomDumpLineNumber++) + indentPadding + "</" + objectTag + ">");
|
273 |
+
}
|
274 |
+
|
275 |
+
|
276 |
+
|
assets/player/DisplayManager.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:fc42593d07bb05c4a045fc584bba10ded7b3092debfd256ecf1780f8929bd6fb
|
3 |
-
size 14869
|
|
|
1 |
+
var kStageSizeDidChangeEvent="DisplayManager:StageSizeDidChangeEvent";var kTimeoutValueForCursor=1000;var kMobilePortraitModeHorizontalMargin=8;var kMobilePortraitModeTopMargin=47;var kMobilePortraitModeVerticalCenterLine=161;var kMobilePortraitModeMaxStageHeight=228;var kMobilePortraitMaxStageHeight=0;var kMobilePortraitMaxStageWidth=0;var kMobileLandscapeModeVerticalMargin=7;var kMobileLandscapeModeHorizontallMargin=15;var kBottomButtonHeight=50;var kNavigationArrowSize=27;var kNavigationAreaHeight=kNavigationArrowSize;var kHelpAreaHeight=16;var kMobilePortraitModeVerticalCenterLineToNavigationAreaGap=148;var kStageToNavigationAreaGap=31;var kNavigationAreaToHelpAreaGap=52;var kHelpAreaToBottomGap=12;var kMobilePortraitModeNavigationAreaSideMargin=32;var kMobilePortraitModeHelpAreaSideMargin=16;var kMobileLandscapeModeMinSideSpacerWidth=kNavigationArrowSize+10;var kPadPortraitModeHorizontalMargin=8;var kPadPortraitModeMaxStageHeight=540;var kPadPortraitModeVerticalCenterLine=400;var kPadLandscapeModeHorizontallMargin=15;var kPadLandscapeModeVerticalMargin=7;var DisplayManager=Class.create({initialize:function(){document.observe(kShowSizeDidChangeEvent,this.handleShowSizeDidChangeEvent.bind(this));document.observe(kOrientationChangedEvent,this.handleOrientationDidChangeEvent.bind(this));this.body=document.getElementById("body");this.stageArea=document.getElementById("stageArea");this.stage=document.getElementById("stage");this.hyperlinkPlane=document.getElementById("hyperlinkPlane");this.waitingIndicator=document.getElementById("waitingIndicator");this.helpText=document.getElementById("helpText");this.previousButton=document.getElementById("previousButton");this.nextButton=document.getElementById("nextButton");this.slideCounter=document.getElementById("slideCounter");this.waitingIndicatorTimeout=null;this.orientation=kOrientationUnknown;this.showWidth=0;this.showHeight=0;this.stageAreaWidth=0;this.stageAreaHeight=0;this.stageAreaTop=0;this.stageAreaLeft=0;this.usableDisplayWidth=0;this.usableDisplayHeight=0;this.inLaunchMode=true;this.initialAddressBarScrollPerformed=false;this.updateUsableDisplayArea();this.positionWaitingIndicator();this.showWaitingIndicator();this.hyperlinksOnly=false;this.showStatisticsDisplay=gIpad&&getUrlParameter("statistics")==="1";this.hasCacheEverGoneOverPixelLimit=false;this.hhasStageEverGoneOverPixelLimit=false;this.cacheHighWaterMark=0;this.stageHighWaterMark=0;if(gMode===kModeMobile){this.stageArea.style.backgroundColor="black";this.helpText.innerHTML=kTapOrSwipeToAdvance}else{Event.observe(this.body,"mousemove",this.handleMouseMove.bind(this));this.lastMouseX=-1;this.lastMouseY=-1;this.cursorTimeout=null;this.setTimeoutForCursor()}},setHyperlinksOnlyMode:function(){this.hyperlinksOnly=true;this.setPreviousButtonEnabled(false);this.setNextButtonEnabled(false);this.helpText.style.display="none"},handleMouseMove:function(a){a=a||window.event;var b=Math.abs(this.lastMouseX-a.clientX)+Math.abs(this.lastMouseY-a.clientY);if(b>10){if(this.cursorIsShowing===false){this.showCursor()}else{if(!this.navigatorIsShowing){this.setTimeoutForCursor()}}}else{if(!this.navigatorIsShowing){this.setTimeoutForCursor()}}this.lastMouseX=a.clientX;this.lastMouseY=a.clientY},updateSlideNumber:function(b,a){var d="";var c=null;if(gMode!=kModeDesktop){d=kSlideLabel+" "+b+"/"+a;c=this.slideCounter}if(c!=null){c.innerHTML=d}},handleShowSizeDidChangeEvent:function(a){this.showWidth=a.memo.width;this.showHeight=a.memo.height;this.layoutDisplay()},handleOrientationDidChangeEvent:function(a){this.orientation=a.memo.orientation;clearTimeout(this.resizeTimer);this.resizeTimer=setTimeout(this.handleOrientationDidChangeEvent_partTwo.bind(this),300)},handleOrientationDidChangeEvent_partTwo:function(){this.layoutDisplay();if(this.inLaunchMode===false){this.showApplicableControls()}},showCursor:function(){if(this.inLaunchMode){return}this.body.style.cursor="default";this.cursorIsShowing=true;this.setTimeoutForCursor()},hideCursor:function(){this.body.style.cursor="none";this.cursorIsShowing=false},setTimeoutForCursor:function(){if(this.cursorTimeout){clearTimeout(this.cursorTimeout)}this.cursorTimeout=setTimeout(this.handleTimeoutForCursor.bind(this),kTimeoutValueForCursor)},clearTimeoutForCursor:function(){if(this.cursorTimeout){clearTimeout(this.cursorTimeout)}},handleTimeoutForCursor:function(){this.hideCursor()},updateUsableDisplayArea:function(){if(gMode===kModeMobile){var a=gIpad;if(this.orientation===kOrientationLandscape){this.usableDisplayWidth=(a?kiPadDeviceHeight:kiPhoneDeviceHeight);this.usableDisplayHeight=(a?kiPadDeviceWidth:kiPhoneDeviceWidth)-kiPhoneStatusBarHeight-kiPhoneLandscapeButtonBarHeight-(a?(kiPadAddressBarHeight+kiPadBookmarksBarHeight):0)}else{this.usableDisplayWidth=(a?kiPadDeviceWidth:kiPhoneDeviceWidth);this.usableDisplayHeight=(a?kiPadDeviceHeight:kiPhoneDeviceHeight)-kiPhoneStatusBarHeight-kiPhonePortraitButtonBarHeight-(a?kiPadBookmarksBarHeight+10:0)}}else{this.usableDisplayWidth=window.innerWidth;this.usableDisplayHeight=window.innerHeight}},clearLaunchMode:function(){this.inLaunchMode=false;var a=this;runInNextEventLoop(this.showAll.bind(this))},positionWaitingIndicator:function(){var c=110;var b=32;var a;var d;if(gMode===kModeMobile&&this.orientation===kOrientationUnknown){a=1000;d=1000}else{if(gMode===kModeMobile&&this.orientation===kOrientationPortrait){a=(this.usableDisplayWidth-c)/2;if(gIpad===false){d=kMobilePortraitModeVerticalCenterLine-(c/2)}else{d=kPadPortraitModeVerticalCenterLine-(c/2)}}else{a=(this.usableDisplayWidth-c)/2;d=(this.usableDisplayHeight-c)/2}}setElementPosition(this.waitingIndicator,d,a,c,c)},hideWaitingIndicator:function(){this.waitingIndicator.style.display="none"},showWaitingIndicator:function(){this.waitingIndicator.style.display="block"},convertDisplayCoOrdsToShowCoOrds:function(d){var b={};var c=this.stageAreaLeft+this.stageAreaWidth;var a=this.stageAreaTop+this.stageAreaHeight;if((d.pointX<this.stageAreaLeft)||(d.pointX>c)||(d.pointY<this.stageAreaTop)||(d.pointY>a)){b.pointX=-1;b.pointY=-1}else{b.pointX=((d.pointX-this.stageAreaLeft)/this.stageAreaWidth)*this.showWidth;b.pointY=((d.pointY-this.stageAreaTop)/this.stageAreaHeight)*this.showHeight}return b},layoutDisplay:function(){this.updateUsableDisplayArea();var q;var k;if(gMode===kModeDesktop){q=this.usableDisplayWidth;k=this.usableDisplayHeight;if(!gShowController.isFullscreen){if(q>this.showWidth||k>k){q=this.showWidth;k=k}}}else{if(gIpad===false){if(this.orientation===kOrientationPortrait){q=this.usableDisplayWidth-2*kMobilePortraitModeHorizontalMargin;k=kMobilePortraitModeMaxStageHeight}else{q=this.usableDisplayWidth-2*kMobileLandscapeModeHorizontallMargin;k=this.usableDisplayHeight-2*kMobileLandscapeModeVerticalMargin}}else{if(this.orientation===kOrientationPortrait){q=this.usableDisplayWidth-2*kPadPortraitModeHorizontalMargin;k=kPadPortraitModeMaxStageHeight}else{q=this.usableDisplayWidth-2*kPadLandscapeModeHorizontallMargin;k=this.usableDisplayHeight-2*kPadLandscapeModeVerticalMargin}}}var o=scaleSizeWithinSize(this.showWidth,this.showHeight,q,k);this.stageAreaWidth=o.width;this.stageAreaHeight=o.height;this.stageAreaLeft=(this.usableDisplayWidth-this.stageAreaWidth)/2;if(gMode===kModeDesktop){this.stageAreaTop=(k-this.stageAreaHeight)/2}else{if(this.orientation===kOrientationPortrait){if(gIpad===false){this.stageAreaTop=Math.max(10,kMobilePortraitModeVerticalCenterLine-(this.stageAreaHeight/2))}else{this.stageAreaTop=Math.max(10,kPadPortraitModeVerticalCenterLine-(this.stageAreaHeight/2))}}else{this.stageAreaTop=(this.usableDisplayHeight-this.stageAreaHeight)/2}}setElementPosition(this.stageArea,this.stageAreaTop,this.stageAreaLeft,this.stageAreaWidth,this.stageAreaHeight);var e=-1;var b=-1;var p=-1;var h=-1;var a=null;if(gMode===kModeDesktop){a=false;e=-1;b=-1;p=-1;h=-1}else{a=true;p=0;h=0;if(gIpad){b=kiPadDeviceHeight}else{b=kiPhoneDeviceHeight}e=b}if(p!=-1&&h!=-1&&e!=-1&&b!=-1){var s=document.getElementById("background");s.style.top=p;s.style.left=h;s.style.width=e;s.style.height=b;if(a===true){s.style.visibility="visible"}}var g={x:0,y:0,width:this.usableDisplayWidth,height:this.stageAreaTop};var d={x:0,y:this.stageAreaTop+this.stageAreaHeight,width:this.usableDisplayWidth,height:this.usableDisplayHeight-this.stageAreaTop-this.stageAreaHeight};var n={x:0,y:this.stageAreaTop,width:this.stageAreaLeft,height:this.stageAreaHeight};var i={x:this.stageAreaLeft+this.stageAreaWidth,y:this.stageAreaTop,width:this.usableDisplayWidth-this.stageAreaWidth-n.width,height:this.stageAreaHeight};var l=document.getElementById("statisticsDisplay");if(this.showStatisticsDisplay&&gIpad&&this.orientation===kOrientationPortrait){setElementPosition(l,d.y+70,0,this.usableDisplayWidth,d.height-105);l.style.visibility="visible"}if(gMode!=kModeDesktop){if(this.orientation===kOrientationPortrait){var m=kNavigationArrowSize+2*kMobilePortraitModeNavigationAreaSideMargin;var f=kNavigationArrowSize+2*kStageToNavigationAreaGap;var r=this.usableDisplayWidth-2*m;var c=d.y+7;setElementPosition(this.previousButton,c,0,m,f);setElementPosition(this.slideCounter,c+kStageToNavigationAreaGap,m,r,f);setElementPosition(this.nextButton,c,m+r-5,m,f);setElementPosition(this.helpText,d.y+d.height-kHelpAreaToBottomGap-kHelpAreaHeight,0,this.usableDisplayWidth,kHelpAreaHeight);setElementPosition(this.infoPanelIcon,this.usableDisplayHeight-kInfoPanelButtonHeight,this.usableDisplayWidth-kInfoPanelButtonWidth-5,kInfoPanelButtonWidth,kInfoPanelButtonHeight)}else{var j={x:0,y:0,width:0,height:0};if(n.width>kMobileLandscapeModeMinSideSpacerWidth){setElementRect(this.previousButton,n);setElementRect(this.nextButton,i)}else{setElementRect(this.previousButton,j);setElementRect(this.nextButton,j)}setElementRect(this.slideCounter,j);setElementRect(this.helpText,j);setElementRect(this.infoPanelIcon,j)}}this.positionWaitingIndicator();this.hideAddressBar();document.fire(kStageSizeDidChangeEvent,{left:this.stageAreaLeft,top:this.stageAreaTop,width:this.stageAreaWidth,height:this.stageAreaHeight})},showApplicableControls:function(){if(this.inLaunchMode===true){hideElement(this.previousButton);hideElement(this.nextButton);hideElement(this.slideCounter);hideElement(this.helpText);hideElement(this.infoPanelIcon)}else{if(gMode===kModeDesktop){hideElement(this.previousButton);hideElement(this.nextButton);hideElement(this.slideCounter);hideElement(this.helpText);hideElement(this.infoPanelIcon)}else{if(this.orientation===kOrientationPortrait){showElement(this.previousButton);showElement(this.nextButton);showElement(this.slideCounter);showElement(this.helpText);showElement(this.infoPanelIcon)}else{hideElement(this.slideCounter);hideElement(this.helpText);hideElement(this.infoPanelIcon);if(this.stageAreaLeft>kMobileLandscapeModeMinSideSpacerWidth){showElement(this.previousButton);showElement(this.nextButton)}else{hideElement(this.previousButton);hideElement(this.nextButton)}}}}this.hideAddressBar()},showAll:function(){this.hideWaitingIndicator();setTimeout(this.showAll_partTwo.bind(this))},showAll_partTwo:function(){if(gDevice===kDeviceMobile){window.scrollTo(0,1);setTimeout(this.showAll_partThree.bind(this))}else{this.showAll_partThree()}},showAll_partThree:function(){if(this.inLaunchMode===false){this.showApplicableControls()}showElement(this.stageArea);var a=navigator.userAgent.match(/Windows/);if(a){if(gShowController.delegate.triggerReflow){gShowController.delegate.triggerReflow()}}showElement(this.hyperlinkPlane);if(gMode===kModeMobile){showElement(this.infoPanelIcon)}},setPreviousButtonEnabled:function(a){if(this.hyperlinksOnly){return}if(gMode!=kModeDesktop){if(a){this.previousButton.setAttribute("class","previousButtonEnabled")}else{this.previousButton.setAttribute("class","previousButtonDisabled")}}},setNextButtonEnabled:function(a){if(this.hyperlinksOnly){return}if(gMode!=kModeDesktop){if(a){this.nextButton.setAttribute("class","nextButtonEnabled")}else{this.nextButton.setAttribute("class","nextButtonDisabled")}}},hideAddressBar:function(){if(this.inLaunchMode){return}if(gDevice===kDeviceMobile){var a=this.initialAddressBarScrollPerformed?0:kHideAddressBarDelay;setTimeout("window.scrollTo(0, 1);",a);this.initialAddressBarScrollPerformed=true}},updateStatisticsDisplay:function(){if(this.showStatisticsDisplay===false){return}var k=document.getElementById("statisticsDisplay");var j=gShowController.textureManager.getCacheStatistics();var a=gShowController.scriptManager.degradeStatistics;var h=gShowController.stageManager.debugGetStageStatistics();var d=gShowController.textureManager.numLoadFailures;var c=gShowController.textureManager.numOutstandingLoadRequests;var i=1024*1024;var b=gSafeMaxPixelCount/i;b=Math.floor(b*100)/100;j.numPixels/=i;h.numPixels/=i;j.numPixels=Math.floor(j.numPixels*100)/100;h.numPixels=Math.floor(h.numPixels*100)/100;var e=false;var g=false;if(j.numPixels>b){e=true;this.hasCacheEverGoneOverPixelLimit=true}if(h.numPixels>b){g=true;this.hasStageEverGoneOverPixelLimit=true}if(j.numPixels>this.cacheHighWaterMark){this.cacheHighWaterMark=j.numPixels}if(h.numPixels>this.stageHighWaterMark){this.stageHighWaterMark=h.numPixels}var f="<div style='position: absolute; left: 0px;'><b>Cache Statistics:</b><br>- Scenes: <b>"+j.numScenes+"</b><br>- Textures: <b>"+j.numTextures+"</b><br>- Pixels: <b>"+j.numPixels+" MP</b><br>- Peak Pixels: <b>"+this.cacheHighWaterMark+" MP</b><br>%nbsp<br><b>Limits:</b><br>- Max Pixels: <b>"+b+" MP</b><br></div><div style='position: absolute; left: 175px;'><b>Scene Statistics:</b><br>- Scene Index: <b>"+gShowController.currentSceneIndex+"</b><br>- Textures: <b>"+h.numTextures+"</b><br>- Total Pixels: <b>"+h.numPixels+" MP</b><br>- Peak Pixels: <b>"+this.stageHighWaterMark+" MP</b><br><b>Texture Loader:</b><br>- Num Load Requests: <b>"+(c>0?("<span style='color:yellow;'>"+c+"</span>"):"0")+"</b><br>- Num Load Failures: <b>"+(d>0?("<span style='color:red;'>"+d+"</span>"):"0")+"</b><br></div><div style='position: absolute; left: 350px;'><b>Degrade Statistics:</b><br>- Scenes w/Degrades: <b>"+a.numDegradedSlides+"</b><br>- Total Textures Degraded: <b>"+a.numDegradedTextures+"</b><br>- Max Textures/Scene: <b>"+a.maxNumDegradedTexturesPerSlide+"</b><br>- Textures in Current: <b>"+(h.numDegraded>0?("<span style='color:yellow;'>"+h.numDegraded+"</span>"):"0")+"</b><br></div><div style='position: absolute; left: 550px;'><b>Summary:</b><br>- Cache: <br>- Over Pixel Limit Now: <b>"+(e?"<span style='color:red;'>YES</span>":"NO")+"</b><br>- Ever Over Pixel Limit: <b>"+(this.hasCacheEverGoneOverPixelLimit?"<span style='color:red;'>YES</span>":"NO")+"</b><br>- Stage: <br>- Over Pixel Limit Now: <b>"+(g?"<span style='color:red;'>YES</span>":"NO")+"</b><br>- Ever Over Pixel Limit: <b>"+(this.hasStageEverGoneOverPixelLimit?"<span style='color:red;'>YES</span>":"NO")+"</b><br></div>";k.innerHTML=f}});
|
|
|
|
assets/player/HelpPlacardController.js
CHANGED
@@ -1,3 +1,194 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* HelpPlacardController.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var HelpPlacardController = Class.create({
|
10 |
+
initialize: function(domNode) {
|
11 |
+
//root node for the slide number control
|
12 |
+
this.domNode = domNode;
|
13 |
+
this.width = 822;
|
14 |
+
this.height = 603;
|
15 |
+
|
16 |
+
var itemList = [
|
17 |
+
{key: " ", text: kHelpPlacardNavigationTitle, header:true},
|
18 |
+
{key: "return/enter space → ↓ page down", text: kHelpPlacardAdvanceToNextBuild},
|
19 |
+
{key: "[ shift - page up shift - ←", text: kHelpPlacardGoBackToPreviousBuild},
|
20 |
+
{key: "] shift - →", text: kHelpPlacardAdvanceAndSkipBuild},
|
21 |
+
{key: "shift - page down shift - ↓ + =", text: kHelpPlacardAdvanceToNextSlide},
|
22 |
+
{key: "← ↑ - shift - ↑", text: kHelpPlacardGoBackToPreviousSlide},
|
23 |
+
{key: "home", text: kHelpPlacardGoToFirstSlide},
|
24 |
+
{key: "end", text: kHelpPlacardGoToLastSlide},
|
25 |
+
{key: "slide number + return/enter", text: kHelpPlacardGoToSpecificSlide},
|
26 |
+
{key: " ", text: kHelpPlacardOtherTitle, header: true},
|
27 |
+
{key: "? /", text: kHelpPlacardShowOrHideKeyboardShortcuts},
|
28 |
+
{key: "s", text: kHelpPlacardShowOrHideTheCurrentSlideNumber},
|
29 |
+
{key: "esc q", text: kHelpPlacardQuitPresentationMode}
|
30 |
+
];
|
31 |
+
|
32 |
+
this.helpPlacardTitleBar = new HelpPlacardTitleBar();
|
33 |
+
this.helpPlacardContentPanel = new HelpPlacardContentPanel(itemList);
|
34 |
+
this.helpPlacardFooter = new HelpPlacardFooter();
|
35 |
+
|
36 |
+
this.domNode.appendChild(this.helpPlacardTitleBar.domNode);
|
37 |
+
this.domNode.appendChild(this.helpPlacardContentPanel.domNode);
|
38 |
+
this.domNode.appendChild(this.helpPlacardFooter.domNode);
|
39 |
+
|
40 |
+
this.isShowing = false;
|
41 |
+
},
|
42 |
+
|
43 |
+
handleClickEvent: function(event) {
|
44 |
+
event = event || window.event;
|
45 |
+
var target = event.target || event.srcElement;
|
46 |
+
|
47 |
+
// stop event from propagating up
|
48 |
+
if (this.isShowing) {
|
49 |
+
if (browserPrefix === "ms") {
|
50 |
+
event.cancelBubble = true;
|
51 |
+
} else {
|
52 |
+
event.stopPropagation();
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
this.hide();
|
57 |
+
},
|
58 |
+
|
59 |
+
setPosition: function(left, top) {
|
60 |
+
this.domNode.style.left = left + "px";
|
61 |
+
this.domNode.style.top = top + "px"
|
62 |
+
},
|
63 |
+
|
64 |
+
show: function() {
|
65 |
+
this.isShowing = true;
|
66 |
+
this.domNode.style.display = "block";
|
67 |
+
this.domNode.style.opacity = 1;
|
68 |
+
},
|
69 |
+
|
70 |
+
hide: function() {
|
71 |
+
this.isShowing = false;
|
72 |
+
this.domNode.style.display = "none";
|
73 |
+
this.domNode.style.opacity = 0;
|
74 |
+
},
|
75 |
+
|
76 |
+
registerDragEvents: function() {
|
77 |
+
this.drag = this.dragging.bindAsEventListener(this);
|
78 |
+
this.dragStop = this.stopDragging.bindAsEventListener(this);
|
79 |
+
|
80 |
+
Event.observe(this.domNode, "mousedown", this.startDragging.bindAsEventListener(this));
|
81 |
+
},
|
82 |
+
|
83 |
+
startDragging: function(event) {
|
84 |
+
this.startX = Event.pointerX(event);
|
85 |
+
this.startY = Event.pointerY(event);
|
86 |
+
|
87 |
+
this.left = parseInt(this.domNode.style.left);
|
88 |
+
this.top = parseInt(this.domNode.style.top);
|
89 |
+
|
90 |
+
Event.observe(document, "mousemove", this.drag);
|
91 |
+
Event.observe(this.domNode, "mouseup", this.dragStop);
|
92 |
+
},
|
93 |
+
|
94 |
+
dragging: function(event) {
|
95 |
+
var x = Event.pointerX(event);
|
96 |
+
var y = Event.pointerY(event);
|
97 |
+
|
98 |
+
this.domNode.style.left = (x - this.startX + this.left) + "px";
|
99 |
+
this.domNode.style.top = (y - this.startY + this.top) + "px";
|
100 |
+
|
101 |
+
Event.stop(event);
|
102 |
+
},
|
103 |
+
|
104 |
+
stopDragging: function(event) {
|
105 |
+
Event.stopObserving(document, "mousemove", this.drag);
|
106 |
+
Event.stopObserving(this.domNode, "mouseup", this.dragStop);
|
107 |
+
|
108 |
+
Event.stop(event);
|
109 |
+
}
|
110 |
+
});
|
111 |
+
|
112 |
+
var HelpPlacardTitleBar = Class.create({
|
113 |
+
initialize: function() {
|
114 |
+
this.domNode = document.createElement("div");
|
115 |
+
this.domNode.setAttribute("class", "helpPlacardTitleBar");
|
116 |
+
|
117 |
+
this.closeButton = document.createElement("div");
|
118 |
+
this.closeButton.setAttribute("class", "helpPlacardCloseButton");
|
119 |
+
|
120 |
+
this.title = document.createElement("div");
|
121 |
+
this.title.setAttribute("class", "helpPlacardTitle");
|
122 |
+
this.title.innerHTML = kHelpPlacardMainTitle;
|
123 |
+
|
124 |
+
this.domNode.appendChild(this.closeButton);
|
125 |
+
this.domNode.appendChild(this.title);
|
126 |
+
}
|
127 |
+
});
|
128 |
+
|
129 |
+
var HelpPlacardContentPanel = Class.create({
|
130 |
+
initialize: function(itemList) {
|
131 |
+
this.domNode = document.createElement("div");
|
132 |
+
this.domNode.setAttribute("class", "helpPlacardContentPanel");
|
133 |
+
|
134 |
+
for (var i = 0, length = itemList.length; i < length; i++) {
|
135 |
+
var item = itemList[i];
|
136 |
+
var div = document.createElement("div");
|
137 |
+
var leftDiv, rightDiv;
|
138 |
+
|
139 |
+
if (item.header) {
|
140 |
+
div.setAttribute("class", "helpPlacardHeader");
|
141 |
+
|
142 |
+
leftDiv = document.createElement("div");
|
143 |
+
leftDiv.setAttribute("class", "helpPlacardLeftHeaderItem");
|
144 |
+
leftDiv.innerHTML = item.text;
|
145 |
+
|
146 |
+
div.appendChild(leftDiv);
|
147 |
+
}
|
148 |
+
else {
|
149 |
+
div.setAttribute("class", "helpPlacardItem");
|
150 |
+
|
151 |
+
leftDiv = document.createElement("div");
|
152 |
+
leftDiv.setAttribute("class", "helpPlacardRightItem");
|
153 |
+
leftDiv.innerHTML = item.key;
|
154 |
+
|
155 |
+
rightDiv = document.createElement("div");
|
156 |
+
rightDiv.setAttribute("class", "helpPlacardLeftItem");
|
157 |
+
rightDiv.innerHTML = item.text;
|
158 |
+
|
159 |
+
div.appendChild(leftDiv);
|
160 |
+
div.appendChild(rightDiv);
|
161 |
+
}
|
162 |
+
|
163 |
+
this.domNode.appendChild(div);
|
164 |
+
}
|
165 |
+
}
|
166 |
+
});
|
167 |
+
|
168 |
+
var HelpPlacardFooter = Class.create({
|
169 |
+
initialize: function() {
|
170 |
+
this.domNode = document.createElement("div");
|
171 |
+
this.domNode.setAttribute("class", "helpPlacardFooter");
|
172 |
+
|
173 |
+
var div = document.createElement("div");
|
174 |
+
div.innerHTML = "Acknowledgements";
|
175 |
+
div.setAttribute("class", "helpPlacardAcknowledgementsButton");
|
176 |
+
|
177 |
+
Event.observe(div, "click", this.handleClickEvent.bind(this));
|
178 |
+
|
179 |
+
this.domNode.appendChild(div);
|
180 |
+
},
|
181 |
+
|
182 |
+
handleClickEvent: function(event) {
|
183 |
+
event = event || window.event;
|
184 |
+
|
185 |
+
// stop event from propagating up
|
186 |
+
if (browserPrefix === "ms") {
|
187 |
+
event.cancelBubble = true;
|
188 |
+
} else {
|
189 |
+
event.stopPropagation();
|
190 |
+
}
|
191 |
+
|
192 |
+
window.open("Acknowledgements.pdf", "_Acknowledgements");
|
193 |
+
}
|
194 |
+
});
|
assets/player/KPFObjects.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:6c33531bbaa192876ad04fc2c35cbccd9bdff583af65debf7d4c39af79dba2ff
|
3 |
-
size 58322
|
|
|
1 |
+
var kpfLayerCounter=0;var eventOverallDuration=0;var KPFPlaybackController=Class.create({initialize:function(b,a){this.domNode=a;this.kpfEvent=null},destroy:function(){this.removeEvent();this.domNode=null},removeEvent:function(){if(this.kpfEvent){this.kpfEvent.destroy();delete this.kpfEvent;this.kpfEvent=null;while(this.domNode.childNodes.length>0){this.domNode.removeChild(this.domNode.childNodes[0])}}},renderEvent:function(a){this.removeEvent();this.kpfEvent=a;this.kpfEvent.renderEvent(this.domNode)},renderEffects:function(){var a=this.kpfEvent.renderEffects(this.kpfEvent.event.effects);return a},animateEffects:function(a){this.kpfEvent.animateEffects(a)},eventOverallEndTime:function(){return this.kpfEvent.eventOverallEndTime}});var KPFEvent=Class.create({initialize:function(a){this.slideId=a.slideId;this.slideIndex=a.slideIndex;this.sceneIndex=a.sceneIndex;this.animationSupported=a.animationSupported;this.event=a.event;this.baseLayer={};this.effects=[];this.cssRenderer={};this.glRenderer={};this.canvasIdFromObjectIdLookup={};this.eventOverallEndTime=0;this.overallEndTimeInternal()},destroy:function(){this.baseLayer.destroy();this.cssRenderer.destroy();for(var a=0,b=this.effects.length;a<b;a++){this.effects[a].destroy()}delete this.baseLayer;delete this.cssRenderer;delete this.effects;delete this.event;this.slideId=null;this.slideIndex=null;this.sceneIndex=null;this.animationSupported=null;this.eventOverallEndTime=null},addAnimationsToIdenticalLayer:function(c,f){if(c.animations&&c.animations.length>0){for(var b=0,e=c.animations.length;b<e;b++){f.animations.push(c.animations[b])}}if(c.layers&&c.layers.length>0){for(var a=0,d=c.layers.length;a<d;a++){this.addAnimationsToIdenticalLayer(c.layers[a],f.layers[a])}}},processEffects:function(a){var d=[];for(var h=0;h<a.length;h++){var m=a[h];if(m.type==="actionBuild"){var f=false;var l;for(var g=0,b=d.length;g<b;g++){if(d[g].type==="actionBuild"&&d[g].objectID===m.objectID){l=g;f=true;break}}if(f){this.addAnimationsToIdenticalLayer(m.baseLayer,d[l].baseLayer);if(m.beginTime<d[l].beginTime){d[l].beginTime=m.beginTime}if(m.beginTime+m.duration>d[l].beginTime+d[l].duration){d[l].duration=m.beginTime+m.duration}for(var e=0,c=m.effects.length;e<c;e++){d[l].effects.push(m.effects[e])}if(d[l].names==null){d[l].names=[]}d[l].names.push(m.name)}else{d.push(m)}}else{d.push(m)}}for(var h=0,b=d.length;h<b;h++){d[h].effects=this.processEffects(d[h].effects)}return d},renderEffects:function(c){var o=[];for(var h=0,f=c.length;h<f;h++){var m=new KPFEffect(c[h],this.animationSupported);var k=false;var b=m.objectID;this.cssRenderer.initRendererFlags(m);if(m.baseLayer==null){this.renderAudioOnlyEffect(m)}else{if(m.name==="renderMovie"){this.renderMovie(this.baseLayer,m)}else{if(m.type==="actionBuild"&&!m.isEmphasisBuild){for(var g=0,q=this.effects.length;g<q;g++){if(this.effects[g].objectID===b){if(this.effects[g].type==="actionBuild"||this.effects[g].name==="renderMovie"){k=true}else{k=false}}}}if(this.baseLayer.objectID===b){var l=new KPFLayer(m.baseLayer,{animationSupported:this.animationSupported,name:m.name,type:m.type,objectID:b});var n="layer"+this.baseLayer.layerId;var p=document.getElementById(n);var a=p.parentNode;var r=document.createElement("div");r.setAttribute("id","layer"+l.layerId);this.baseLayer=l;m.kpfLayer=l;if(useWebGL&&kSupportedWebGLEffects.indexOf(m.name)!==-1){var e=this.canvasId;var d;if(e){d=document.getElementById(e)}else{e=this.canvasId=b+"-canvas";d=this.createCanvasElement(e);a.appendChild(d)}m.nodeToSwapId=n;m.canvasId=e}else{this.cssRenderer.layer=l;this.cssRenderer.domNode=r;this.cssRenderer.draw(a);a.removeChild(p)}}else{this.renderEffect(this.baseLayer,m,k)}}}this.effects.push(m);o.push(m)}return o},renderMovie:function(c,m){var h;for(var j=0,f=c.layers.length;j<f;j++){var d=m.objectID;var b=m.name;var p=m.type;var g=m.movie;if(c.layers[j].objectID===d){var l=new KPFLayer(m.baseLayer,{animationSupported:this.animationSupported,name:b,type:p,objectID:d,movie:g},c.bounds.offset);var o="layer"+c.layers[j].layerId;var n="layer"+c.layers[j].layerId;var q=document.getElementById(n);if(!q){continue}var a=q.parentNode;m.kpfLayer=l;var e=this.canvasIdFromObjectIdLookup[d];if(e){var k=this.glRenderer[e];if(k){k.removeProgram(d)}}c.layers[j]=l;var r=this.cssRenderer.createNodes(a,c,l);a.replaceChild(r,q);h=true}else{h=this.renderMovie(c.layers[j],m)}if(h){break}}return h},renderEffect:function(E,C,k){var D;for(var z=0,j=E.layers.length;z<j;z++){var x=C.objectID;var G=C.name;var h=C.type;var v=C.movie;if(E.layers[z].objectID===x){var F=new KPFLayer(C.baseLayer,{animationSupported:this.animationSupported,name:G,type:h,objectID:x,movie:v},E.bounds.offset);var u="layer"+E.layers[z].layerId;var a="layer"+E.layers[z].layerId;var l=document.getElementById(a);if(!l){continue}var q=l.parentNode;C.kpfLayer=F;if(useWebGL&&kSupportedWebGLEffects.indexOf(G)!==-1){var B=this.canvasId;var f;if(B){f=document.getElementById(B);f.style.opacity=1}else{B=this.canvasId=x+"-canvas";f=this.createCanvasElement(B);q.appendChild(f)}this.canvasIdFromObjectIdLookup[x]=B;C.nodeToSwapId=a;C.canvasId=B}else{var B=this.canvasIdFromObjectIdLookup[x];if(B){var y=this.glRenderer[B];if(y){y.removeProgram(x)}}if(!k){E.layers[z]=F;var b=this.cssRenderer.createNodes(q,E,F);q.replaceChild(b,l)}else{var c=C.objectID+"-video";var A=gShowController.movieCache&&gShowController.movieCache[c];if(C.name==="apple:action-scale"&&!A){var g=document.getElementById(l.childNodes[0].id+"-contents");var w=this.cssRenderer.createNodes(q,E,F);var p=w.childNodes[0].id;var o=document.getElementById(p+"-contents-from");var t=document.getElementById(p+"-contents-to");if(o&&t){var r=E.bounds;var e=r.width;var m=r.height;var s=l.childNodes[0].id;var d=document.createElement("div");d.id=s+"-contents-to";this.setStyle(d,"0px","0px",e+"px",m+"px",kPositionAbsolutePropertyValue,null,null);d.appendChild(t.childNodes[0]);g.appendChild(d);setElementProperty(d,"opacity",0);var n=document.createElement("div");n.id=s+"-contents-from";this.setStyle(n,"0px","0px",e+"px",m+"px",kPositionAbsolutePropertyValue,null,null);n.appendChild(o.childNodes[0]);g.appendChild(n)}else{w.parentNode.removeChild(w)}}C.currentKPFLayer=E.layers[z]}}D=true}else{D=this.renderEffect(E.layers[z],C,k)}if(D){break}}return D},renderEvent:function(a){var b={animationSupported:this.animationSupported};if(this.event.effects&&this.event.effects.length===1){b.name=this.event.effects[0].name;b.type=this.event.effects[0].type;b.objectID=this.event.effects[0].objectID}this.baseLayer=new KPFLayer(this.event.baseLayer,b);this.cssRenderer=new KPFCssRenderer(this.baseLayer,this.sceneIndex,this.animationSupported,this.effects);this.cssRenderer.draw(a)},renderAudioOnlyEffect:function(e){if(e.name!="renderMovie"){return}var b=e.movie;if(!b.isAudioOnly){return}if(gShowController.audioCache==null){gShowController.audioCache={}}var a=b.asset+"-audio";var d=gShowController.audioCache[a];if(d==null){var c=gShowController.textureManager.urlForAsset(b.asset,this.slideId);d=new Audio(c);if(b){if(b.loopMode&&b.loopMode==="looping"){d.loop=true}if(b.volume){d.volume=b.volume}}gShowController.audioCache[a]=d}d.play()},animateEffects:function(e){for(var b=0,c=e.length;b<c;b++){var a=e[b];this.animateEffect(a)}for(var f in this.glRenderer){var d=this.glRenderer[f];d.animate();d.animationStarted=true}},animateEffect:function(c){var f=c.canvasId;var g=c.nodeToSwapId;if(f){var b=document.getElementById(f);var e={canvasId:f,canvas:b,nodeToSwapId:g,textureAssets:gShowController.textureManager.slideCache[this.slideIndex].textureAssets,effect:c,overallEndTime:this.eventOverallEndTime};var d=this.glRenderer[f];if(!d){d=new KNWebGLRenderer(e);this.glRenderer[f]=d}var a=c.beginTime*1000;if(c.type==="transition"){a=0}setTimeout(this.animateEffectWillBegin.bind(this,e),a)}else{this.cssRenderer.animate(c)}if(c.effects.length>0){setTimeout(this.handleEffectDidComplete.bind(this,c),(c.beginTime+c.duration)*1000)}},animateEffectWillBegin:function(e){var d=e.canvasId;var b=e.effect;var c=this.glRenderer[d];c.draw(b);if(!c.animationStarted){c.animate();c.animationStarted=true}var a=document.getElementById(e.nodeToSwapId);if(!a){return}if(b.type==="transition"){a.parentNode.removeChild(a)}else{a.style.opacity=0}},handleEffectDidComplete:function(c){var e=this.renderEffects(c.effects);for(var b=0,d=e.length;b<d;b++){var a=e[b];this.animateEffect(a)}},overallEndTime:function(){return this.eventOverallEndTime},overallEndTimeInternal:function(){for(var a=0,d=this.event.effects.length;a<d;a++){var c=0;var b=this.event.effects[a];this.calculateOverallEndTime(c,b)}},calculateOverallEndTime:function(e,c){var b=e+c.beginTime+c.duration;if(b>this.eventOverallEndTime){this.eventOverallEndTime=b}for(var a=0,d=c.effects.length;a<d;a++){this.calculateOverallEndTime(b,c.effects[a])}},createCanvasElement:function(b){var a=document.createElement("canvas");a.width=gShowController.script.slideWidth;a.height=gShowController.script.slideHeight;a.setAttribute("id",b);return a},setStyle:function(f,h,g,e,b,a,d,c){f.style.top=h;f.style.left=g;f.style.width=e;f.style.height=b;f.style.position=a;if(d!=null&&d!=undefined){f.style.opacity=d}if(c!=null&&c!=undefined){f.style.visibility=c}}});var KPFEffect=Class.create({initialize:function(b,a){this.attributes=b.attributes;this.type=b.type;this.name=b.name;this.beginTime=b.beginTime;this.duration=b.duration;this.objectID=b.objectID;this.baseLayer=b.baseLayer;if(kEmphasisEffects.indexOf(this.name)>-1){this.isEmphasisBuild=true}if(b.movie){this.movie=b.movie}this.effects=[];this.addSubEffect(b.effects,a)},destroy:function(){for(var a=0,b=this.effects.length;a<b;a++){this.destroyEffect(this.effects[a])}this.type=null;this.name=null;this.beginTime=null;this.duration=null;this.objectID=null;delete this.kpfLayer;delete this.effects;delete this.baseLayer;if(this.movie){delete this.movie}if(this.currentKPFLayer){delete this.currentKPFLayer}},destroyEffect:function(b){for(var a=0,c=b.effects.length;a<c;a++){this.destroyEffect(b.effects[a])}b.type=null;b.name=null;b.beginTime=null;b.duration=null;b.objectID=null;delete b.kpfLayer;delete b.effects;delete b.baseLayer;if(b.movie){delete b.movie}if(b.currentKPFLayer){delete b.currentKPFLayer}},addSubEffect:function(c,a){for(var b=0,e=c.length;b<e;b++){var d=new KPFEffect(c[b],a);this.effects.push(d)}}});var KPFMovie=Class.create({initialize:function(b){this.objectID=b.objectID;this.movieId=b.movieId;this.width=b.width;this.height=b.height;this.sceneIndex=b.sceneIndex;this.textureId=b.textureId;this.src=b.src;this.showControls=b.showControls;this.movieDiv=b.movieDiv;this.parentLayer=b.parentLayer;var a=this.videoElement=document.createElement("video");this.setDefaultStyle();this.setInsertBeforeOrAfterTextureId();setElementProperty(a,"pointer-events","all");a.setAttribute("id",this.movieId);a.setAttribute("src",this.src);if(this.showControls){Event.observe(a,"mouseover",this.handleMouseOver.bind());Event.observe(a,"mouseleave",this.handleMouseLeave.bind())}this.isFirstRendered=true;this.isEnded=false;this.isPlaying=false},destroy:function(){var a=this.videoElement;if(a){a.pause();a.src=""}},handleMouseOver:function(){this.setAttribute("controls","controls")},handleMouseLeave:function(){this.removeAttribute("controls")},setDefaultStyle:function(){var a=this.videoElement.style;a.top="0px";a.left="0px";a.width=this.width+"px";a.height=this.height+"px";a.position=kPositionAbsolutePropertyValue;a.visibility="hidden"},setInsertBeforeOrAfterTextureId:function(){var d=this.parentLayer.layers;for(var b=0,c=d.length;b<c;b++){var a=d[b];if(a.isVideoLayer){if(b+1<c){this.insertBeforeTextureId=d[b+1].textureId}if(b-1>=0){this.insertAfterTextureId=d[b-1].textureId}}}},observeEvents:function(a){var b=this.videoElement;Event.stopObserving(b,"canplay");Event.stopObserving(b,"ended");Event.observe(b,"canplay",this.handleMovieDidStart.bind(this,a));Event.observe(b,"ended",this.handleMovieDidEnd.bind(this,a))},setLoop:function(a){this.videoElement.loop=a},setVolume:function(a){this.videoElement.volume=a},removeControls:function(){if(this.videoElement.hasAttribute("controls")){this.videoElement.removeAttribute("controls")}},handleMovieDidStart:function(a){this.videoElement.style.visibility="visible";if(a){setTimeout(this.hideMoviePoster.bind(this,a),120)}},handleMovieDidEnd:function(a){if(!this.videoElement.loop){this.isEnded=true}},startMovie:function(){if(this.videoElement){this.videoElement.play();this.isPlaying=true}},stopMovie:function(){if(this.videoElement){this.videoElement.pause()}},hideMoviePoster:function(a){var b=a.style;b.visibility="hidden";b.display="none";if(a.parentNode){a.parentNode.removeChild(a)}}});var KPFCssRenderer=Class.create({initialize:function(b,d,a,c){this.textureId=b.textureId;this.nativeWidth=b.bounds.width;this.nativeHeight=b.bounds.height;this.opacity=b.opacity;this.visibility=b.hidden===true?"hidden":"visible";this.textureTransform=b.textureTransform;this.affineTransform=b.affineTransform;this.anchorPoint=b.anchorPoint;this.contentsRect=b.contentsRect;this.layer=b;this.sceneIndex=d;this.animationSupported=a;this.enableCompositingUsingBackface=false;this.enablePreserve3DFromParent=false;if(c.length>0){this.initRendererFlags(c[0])}this.glContentsRenderer={};this.domNode=document.createElement("div");this.domNode.setAttribute("id","layer"+b.layerId)},initRendererFlags:function(a){if(a.type==="transition"&&a.name!="apple:ca-swing"&&a.name!="com.apple.iWork.Keynote.BLTSwoosh"){this.enableCompositingUsingBackface=true;this.enablePreserve3DFromParent=true;if(isChrome&&(a.name==="apple:ca-push"||a.name==="com.apple.iWork.Keynote.BLTFadeThruColor")){this.enableCompositingUsingBackface=false;this.enablePreserve3DFromParent=false}}else{this.enableCompositingUsingBackface=false;this.enablePreserve3DFromParent=false}if(a.name==="apple:apple-grid"){this.isGridTransition=true}else{if(a.name==="com.apple.iWork.Keynote.BLTMosaicFlip"){this.isMosaicTransition=true}else{if(a.name==="com.apple.iWork.Keynote.BLTSwoosh"&&a.type==="transition"){this.isSwooshTransition=true}}}},destroy:function(){this.textureId=null;this.nativeWidth=null;this.nativeHeight=null;this.opacity=null;this.visibility=null;this.textureTransform=null;this.affineTransform=null;this.anchorPoint=null;this.textureAnimation=null;this.contentsRect=null;this.requiresPerspectiveTransform=null;this.sceneIndex=null;var d=this.domNode.getElementsByTagName("canvas");for(var c=d.length;c--;){var a=d[c];if(a){var b=a.getContext("2d");if(b){b.clearRect(0,0,a.width,a.height);d[c].remove()}}}if(this.domNode.hasChildNodes()){while(this.domNode.childNodes.length>0){this.domNode.removeChild(this.domNode.firstChild)}}this.domNode=null},addAnimationNode:function(e,d,a,c){if(d==null){return e}var f=d.shift();if(f==null){return e}var h=document.createElement("div");var g=a+"-"+escapeTextureId(f);h.setAttribute("id",g);if(c.initialState.masksToBounds){setElementProperty(h,"overflow","hidden")}if(this.enableCompositingUsingBackface){setElementProperty(h,kBackfaceVisibilityPropertyName,"hidden")}else{if(this.isSwooshTransition){setElementProperty(h,kTransformPropertyName,"translateZ(0px)")}}this.setStyle(h,"0px","0px",e.style.width,e.style.height,kPositionAbsolutePropertyValue,null,null);setElementProperty(h,kTransformStylePropertyName,kTransformStylePreserve3DPropertyValue);if(c.anchorPoint.pointX!=0.5||c.anchorPoint.pointY!=0.5){setElementProperty(h,kTransformOriginPropertyName,(c.anchorPoint.pointX*100)+"% "+(c.anchorPoint.pointY*100)+"%")}var b=["opacity","doubleSided","anchorPointZ"];if(c.transformOriginValue&&c.transformOriginZValue){if(c.animationInfo.name==="apple:ca-revolve"){b.push("anchorPoint","position","zPosition")}else{if(c.animationInfo.name==="apple:3D-cube"){b.push("anchorPoint","position","zPosition","transform.rotation.x","transform.rotation.y")}}}if(c.transformOriginZValue&&b.indexOf(f)===-1){if(Prototype.Browser.Gecko){setElementProperty(h,kTransformOriginPropertyName,(c.anchorPoint.pointX*100)+"% "+(c.anchorPoint.pointY*100)+"% "+c.transformOriginZValue+"px")}else{setElementProperty(h,kTransformOriginZPropertyName,c.transformOriginZValue+"px");if(navigator.userAgent.lastIndexOf("Chrome/")<=0){setElementProperty(h,kTransformPropertyName,"translateZ("+c.transformOriginZValue+"px)")}}}e.appendChild(h);return this.addAnimationNode(h,d,a,c)},createNodes:function(a,d,c){var b=gShowController.movieCache;if(b&&c.animationInfo.name!=="renderMovie"){this.setVideoLayer(c,b)}var e=this.addNode(a,d,c);return e},setVideoLayer:function(l,p){var a=l.objectID;var o=a+"-video";kpfMovie=p[o];if(!kpfMovie){for(var h=0,b=l.layers.length;h<b;h++){this.setVideoLayer(l.layers[h],p)}}else{if(l.layers.length===1){if(l.layers[0].textureId){l.layers[0].isVideoLayer=true;l.layers[0].movieObjectID=a}else{if(l.layers[0].layers[0].textureId){l.layers[0].layers[0].isVideoLayer=true;l.layers[0].layers[0].movieObjectID=a}}}else{var m=false;var d;for(var h=0,b=l.layers.length;h<b;h++){var k;if(l.layers[h].textureId){k=l.layers[h]}else{k=l.layers[h].layers[0]}var g=k.textureId;if(g===kpfMovie.insertAfterTextureId){d=k}var n=false;for(var f=0,c=kpfMovie.parentLayer.layers.length;f<c;f++){var e=kpfMovie.parentLayer.layers[f].textureId;if(e===g){n=true;break}}if(!n){m=true;k.isVideoLayer=true;k.movieObjectID=a}}if(!m&&d){d.isVideoLayer=true;d.movieObjectID=a}}}},addNode:function(r,E,f){if(f.canvasId){return}var G="layer"+f.layerId;var ae=document.createElement("div");ae.setAttribute("id",G);setElementProperty(ae,"pointer-events","none");var Q=f.contentsRect.x;var O=f.contentsRect.y;var R=f.contentsRect.width;var ad=f.contentsRect.height;var ao=f.affineTransform[0];var am=f.affineTransform[1];var al=f.affineTransform[2];var ak=f.affineTransform[3];var ai=f.affineTransform[4];var af=f.affineTransform[5];var v=f.animationInfo;var S=false;if(ao===-1&&v.name==="com.apple.iWork.Keynote.KLNComet"){ao=1;S=true}var C="matrix("+ao+","+am+","+al+","+ak+","+(ai+f.bounds.offset.pointX)+","+(af+f.bounds.offset.pointY)+")";var o=f.bounds;var s=o.width;var U=o.height;this.setStyle(ae,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,f.opacity,f.visibility);setElementProperty(ae,kTransformPropertyName,C);if(f.anchorPoint.pointX!=0.5||f.anchorPoint.pointY!=0.5){setElementProperty(ae,kTransformOriginPropertyName,(f.anchorPoint.pointX*100)+"% "+(f.anchorPoint.pointY*100)+"%")}if(f.initialState.masksToBounds){setElementProperty(ae,"overflow","hidden")}r.appendChild(ae);var H;if(this.animationSupported){H=this.addAnimationNode(ae,f.divNames,G,f)}else{H=ae}if(f.isTransition&&this.enablePreserve3DFromParent){if(E.sublayerTransform[11]!=0){setElementProperty(ae,kTransformStylePropertyName,kTransformStylePreserve3DPropertyValue)}if(f.sublayerTransform[11]!=0){setElementProperty(ae,kPerspectivePropertyName,gShowController.stageManager.perspective+"px");setElementProperty(ae,kTransformStylePropertyName,kTransformStylePreserve3DPropertyValue)}}else{if(E.sublayerTransform[11]!=0){setElementProperty(r,kPerspectivePropertyName,gShowController.stageManager.perspective+"px");setElementProperty(ae,kTransformStylePropertyName,kTransformStylePreserve3DPropertyValue)}else{setElementProperty(ae,kTransformStylePropertyName,kTransformStyleFlatPropertyValue)}}if(isChrome){if(this.enableCompositingUsingBackface){setElementProperty(ae,kBackfaceVisibilityPropertyName,"hidden")}else{if(this.isSwooshTransition){setElementProperty(ae,kTransformPropertyName,"translateZ(0px)")}}}var M=f.textureId;if(M){var z=gShowController.textureManager;var F=z.getTextureObject(this.sceneIndex,M);if(!F){return ae}var p=document.createElement("canvas");var ap=p.getContext("2d");var a=F.width;var d=F.height;if(Q===0&&O===0&&R===1&&ad===1){p.width=a;p.height=d;if(a>0&&d>0){ap.drawImage(F,0,0)}this.setStyle(p,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,null,null)}else{var n=O*d;var X=(Q+R)*a;var c=(O+ad)*d;var k=Q*a;var u=p.width=X-k;var j=p.height=c-n;ap.drawImage(F,k*pdfScaleFactor,n*pdfScaleFactor,u*pdfScaleFactor,j*pdfScaleFactor,0,0,u,j);this.setStyle(p,"0px","0px",u+"px",j+"px",kPositionAbsolutePropertyValue,null,null)}var L=p;L.setAttribute("id",M);if(browserPrefix==="webkit"&&f.isTransition==null){if(S){setElementProperty(L,kTransformPropertyName,"rotateY(180deg) translateZ(0px)")}else{setElementProperty(L,kTransformPropertyName,"translateZ(0px)")}}if(f.isTransition){if(isChrome){if(this.enableCompositingUsingBackface){if(!this.isGridTransition&&!this.isMosaicTransition){setElementProperty(L,kBackfaceVisibilityPropertyName,"hidden")}}else{if(this.isSwooshTransition){setElementProperty(L,kTransformPropertyName,"translateZ(0px)")}}}else{if(this.enableCompositingUsingBackface){setElementProperty(L,kBackfaceVisibilityPropertyName,"hidden")}else{setElementProperty(L,kTransformPropertyName,"translateZ(0px)")}}}var K=v.objectID;var g=v&&v.type==="buildOut";var W;var t;if(f.isVideoLayer){if(v.name==="renderMovie"){var Y=z.getMovieUrl(this.sceneIndex,v.movie.asset);var P=/(?:\.([^.]+))?$/;var ah=P.exec(Y)[1];if(ah==="gif"){t=new Image();this.setStyle(t,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,null,null);Event.observe(t,"load",this.hideElement.bind(this,L));t.src=Y}else{if(gShowController.movieCache==null){gShowController.movieCache={}}var V=K+"-video";f.hasMovie=true;f.movieId=V;W=gShowController.movieCache[V];if(W==null){var ag={objectID:K,movieId:V,width:s,height:U,sceneIndex:this.sceneIndex,textureId:M,src:Y,showControls:gShowController.isRecording===false?true:false,movieDiv:ae,parentLayer:E};W=new KPFMovie(ag);gShowController.movieCache[V]=W;W.observeEvents(L)}}}else{var Z=gShowController.movieCache;if(Z){var V=f.movieObjectID+"-video";W=Z[V]}}}if(f.hasContentsAnimation){var an=f.cssAnimation.animations;var T;var e;for(var m=0,ab=an.length;m<ab;m++){if(an[m].property==="contents"){T=an[m].to.texture;e=an[m].from.texture;break}}var b=z.getTextureObject(this.sceneIndex,T);var N=document.createElement("canvas");var aq=N.getContext("2d");var a=N.width=b.width;var d=N.height=b.height;var J=a/s;var I=d/U;aq.drawImage(b,0,0);N.setAttribute("id",T);if(J>1&&I>1&&J!==0&&I!==0){this.setStyle(N,"0px","0px",a+"px",d+"px",kPositionAbsolutePropertyValue,null,null);setElementProperty(N,kTransformOriginPropertyName,"0% 0%");setElementProperty(N,kTransformPropertyName,"scale("+1/J+","+1/I+")")}else{this.setStyle(N,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,null,null)}var B=document.createElement("div");B.id=G+"-contents-to";this.setStyle(B,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,null,null);B.appendChild(N);H.appendChild(B);setElementProperty(B,"opacity",0);var D=z.getTextureObject(this.sceneIndex,e);var q=document.createElement("canvas");var aj=q.getContext("2d");q.width=D.width;q.height=D.height;aj.drawImage(D,0,0);q.setAttribute("id",e);this.setStyle(q,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,null,null);var l=document.createElement("div");l.id=G+"-contents-from";this.setStyle(l,"0px","0px",s+"px",U+"px",kPositionAbsolutePropertyValue,null,null);l.appendChild(q);H.appendChild(l)}else{H.appendChild(L);if(t){H.appendChild(t)}}if(W){if(W.isFirstRendered){H.insertBefore(W.videoElement,L);W.isFirstRendered=false}else{if(f.animationInfo&&f.animationInfo.name!=="renderMovie"){if(W.objectID===K&&g){W.stopMovie();W.removeControls();W.isBuiltOut=true}else{if(!W.isBuiltOut){H.parentNode.appendChild(W.movieDiv)}}}}}}else{if(f.initialState.backgroundColor){var aa=f.initialState.backgroundColor;setElementProperty(H,"background-color","rgba("+parseInt(aa[0]*255)+","+parseInt(aa[1]*255)+","+parseInt(aa[2]*255)+","+aa[3]+")")}}for(var ac=0,A=f.layers.length;ac<A;ac++){this.addNode(H,f,f.layers[ac])}return ae},hideElement:function(a){a.style.visibility="hidden"},serializeSvg:function(e){var f=e.getElementsByTagName("image");for(var d=0,b=f.length;d<b;d++){var a=f[d];var g=document.createElement("a");g.href=a.getAttributeNS("http://www.w3.org/1999/xlink","href");var j=window.location.protocol+"//"+g.host+g.pathname;a.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",j)}var h=new XMLSerializer;var c=h.serializeToString(e);return c},draw:function(a){this.setStyle(this.domNode,"0px","0px",this.nativeWidth+"px",this.nativeHeight+"px",kPositionAbsolutePropertyValue,this.opacity,this.visibility);if(browserPrefix==="webkit"){if(this.enableCompositingUsingBackface&&isChrome){setElementProperty(this.domNode,kBackfaceVisibilityPropertyName,"hidden")}else{setElementProperty(this.domNode,kTransformPropertyName,"translateZ(0px)")}}if(this.layer.sublayerTransform[11]!=0){setElementProperty(this.domNode,kPerspectivePropertyName,gShowController.stageManager.perspective+"px");setElementProperty(this.domNode,kTransformStylePropertyName,kTransformStylePreserve3DPropertyValue)}else{setElementProperty(this.domNode,kTransformStylePropertyName,kTransformStyleFlatPropertyValue)}for(var b=0,c=this.layer.layers.length;b<c;b++){this.createNodes(this.domNode,this.layer,this.layer.layers[b])}a.appendChild(this.domNode)},setStyle:function(f,h,g,e,b,a,d,c){f.style.top=h;f.style.left=g;f.style.width=e;f.style.height=b;f.style.position=a;if(d!=null&&d!=undefined){f.style.opacity=d}if(c!=null&&c!=undefined){f.style.visibility=c}},overallEndTime:function(a){var b={};b.duration=0;this.overallEndTimeForLayer(this.layer,b);return b.duration},overallEndTimeForLayer:function(b,c){if(b.cssAnimation){if(b.cssAnimation.overallEndTime>c.duration){c.duration=b.cssAnimation.overallEndTime}}for(var a=0,d=b.layers.length;a<d;a++){this.overallEndTimeForLayer(b.layers[a],c)}},animate:function(a){if(this.animationSupported){if(a.kpfLayer){if(a.movie){this.animateEffect(a,a.kpfLayer,a.currentKPFLayer?a.currentKPFLayer:null,a.movie)}else{this.animateEffect(a,a.kpfLayer,a.currentKPFLayer?a.currentKPFLayer:null)}}}},animateEffect:function(q,b,k,e){var m=q.objectID+"-video";if(b.cssAnimationRules.length>0){var g=k?"layer"+k.layerId:"layer"+b.layerId;var d=document.getElementById(g);if(d){this.applyCssAnimation(d,b,k,q)}else{if(q.currentKPFLayer){g="layer"+q.currentKPFLayer.layerId;if(q.currentKPFLayer.layers[0]){g="layer"+q.currentKPFLayer.layers[0].layerId}d=document.getElementById(g);if(d){this.applyCssAnimation(d,b,q.currentKPFLayer,q)}}}}else{if(b.isRenderMovie&&b.animationInfo.name==="renderMovie"){var j=gShowController.movieCache;if(j){var p=j[m];if(p){if(e.loopMode&&e.loopMode==="looping"){p.setLoop(true)}if(e.volume){p.setVolume(e.volume)}p.startMovie()}}}if(k){var a=document.getElementById("layer"+k.layerId);var l=window.getComputedStyle(a,null);var n=l.getPropertyValue(kTransformPropertyName);var f=parseTransformMatrix(n);var o="matrix("+f[0]+","+f[1]+","+f[2]+","+f[3]+","+b.bounds.offset.pointX+","+b.bounds.offset.pointY+")";if(q.name==="apple:action-motion-path"){setElementProperty(a,kTransformPropertyName,o)}}}for(var h=0,c=b.layers.length;h<c;h++){if(gShowController.movieCache&&gShowController.movieCache[m]){this.animateEffect(q,b.layers[h],k,e)}else{this.animateEffect(q,b.layers[h],k?k.layers[h]:null,e)}}},applyCssAnimation:function(y,h,K,Z){var U=h.cssAnimation;var B=h.cssAnimationRules;var T=h.cssAnimation.overallEndTime;if(h.hasMovie){if(h.animationInfo.type==="buildOut"){this.stopMovie(document.getElementById(h.movieId))}}if(isChrome&&h.animationInfo.name==="apple:doorway"){if(h.layers.length===0&&h.contentsRect.x===0&&h.contentsRect.y===0&&h.contentsRect.width===1&&h.contentsRect.height===1){y.style.visibility="hidden"}}var g=U.keyAnimations.bounds;if(g){var z=document.styleSheets[1].cssRules;var ag=z.length;var D=y.id+"-bounds";if(K){D="layer"+h.layerId+"-bounds"}for(var ac=0;ac<ag;ac++){var v=z[ac];if(v.name===D){while(v.cssRules.length>0){if(isIE){for(var ab=0,E=v.cssRules.length;ab<E;ab++){v.deleteRule(ab)}}else{v.deleteRule(v.cssRules[0].keyText)}}for(var ab=0,A=g.keyframes.length;ab<A;ab++){var k=g.keyframes[ab];var V,ad,a,e;if(k.keyframe==0){V=k.value.width;ad=k.value.height;v.appendRule("0% {"+kTransformPropertyName+": scaleX(1) scaleY(1); "+kAnimationTimingFunctionPropertyName+": "+k.timingFunction+";}")}else{a=k.value.width;e=k.value.height;v.appendRule(k.keyframe+"% {"+kTransformPropertyName+": scaleX("+a/V+") scaleY("+e/ad+"); "+kAnimationTimingFunctionPropertyName+": "+k.timingFunction+";}")}}}}}if(h.animationInfo.name!=="apple:ca-swing"&&(h.initialState.rotation!==0||h.initialState.scale!==1)){var l=document.getElementById(y.id);var H=window.getComputedStyle(l,null);var M=H.getPropertyValue(kTransformPropertyName);var N=parseTransformMatrix(M);var o="matrix(1,0,0,1,"+N[4]+","+N[5]+")";setElementProperty(l,kTransformPropertyName,o);var x=document.getElementById(y.id+"-"+escapeTextureId("transform.rotation.z"));if(x){setElementProperty(x,kTransformPropertyName,"rotateZ("+h.initialState.rotation+"rad)")}var F=document.getElementById(y.id+"-"+escapeTextureId("transform.scale.x"));if(F){setElementProperty(F,kTransformPropertyName,"scaleX("+h.initialState.scale+")")}var p=document.getElementById(y.id+"-"+escapeTextureId("transform.scale.y"));if(p){setElementProperty(p,kTransformPropertyName,"scaleY("+h.initialState.scale+")")}}for(var G in U.keyAnimations){var u=U.keyAnimations[G];var C=u.keyActions;var J=C[C.length-1];var I=u.keyframes[u.keyframes.length-1];var ai=this.cssPropertyNameForAction(G);var aa=this.cssPropertyValueForActionValue(G,I.value);var d=u.repeatCount;var n=T+"s";var D="";var R="";if(G==="isPlaying"){continue}if(K&&h.animationInfo.type==="actionBuild"&&kActionBuildKeyAnimations[h.animationInfo.name].indexOf(G)===-1){continue}if(G==="doubleSided"){var m=document.getElementById(y.id+"-"+escapeTextureId(G));if(m){setElementProperty(m,ai,aa)}continue}if(h.animationInfo.name==="apple:ca-swing"&&(G==="anchorPoint"||G==="transform.translation")){continue}if((h.animationInfo.name==="apple:ca-revolve"||h.animationInfo.name==="apple:3D-cube")&&h.transformOriginValue&&h.transformOriginZValue&&(G==="anchorPointZ"||G==="zPosition")){continue}switch(G){case"opacity":D=y.id+"-opacity";R=D;if(K){if(document.getElementById(D)==null){D=y.id}R="layer"+h.layerId+"-opacity"}else{setElementProperty(y,"opacity",1)}break;case"hidden":ai="opacity";if(aa==="hidden"){aa=0}else{y.style.visibility="visible";aa=1}D=y.id;R=D+"-hidden";if(K){R="layer"+h.layerId+"-hidden"}break;case"bounds":D=y.id+"-bounds";R=D;if(K){R="layer"+h.layerId+"-bounds"}var V,ad,w,L;var q=u.keyframes[0];var W=u.keyframes[u.keyframes.length-1];aa="scaleX("+W.value.width/q.value.width+") scaleY("+W.value.height/q.value.height+")";break;default:D=y.id+"-"+escapeTextureId(G);R=D;if(K){R="layer"+h.layerId+"-"+escapeTextureId(G)}break}if(G==="contents"){if(Z.type==="smartBuild"){var f=y.id+"-contents-canvas";var r=document.createElement("canvas");r.width=h.initialState.width;r.height=h.initialState.height;r.setAttribute("id",f);var Y=gShowController.scriptManager.slideIndexFromSceneIndex(this.sceneIndex);var b={canvasId:f,canvas:r,textureAssets:gShowController.textureManager.slideCache[Y].textureAssets,effect:Z,overallEndTime:T,element:y};var O=this.glContentsRenderer[f];if(!O){O=new KNWebGLRenderer(b);this.glContentsRenderer[f]=O}var ah=document.getElementById(y.id);ah.appendChild(r);var Q=Z.beginTime*1000;setTimeout(this.animateContentsWillBegin.bind(this,b),Q)}else{var X=y.id+"-contents-from";var ae=y.id+"-contents-to";var P=X;var t=ae;if(K){P="layer"+h.layerId+"-contents-from";t="layer"+h.layerId+"-contents-to"}var s=document.getElementById(X);var af=document.getElementById(ae);setElementProperty(s,"opacity",0);setElementProperty(s,kAnimationNamePropertyName,P);setElementProperty(s,kAnimationDurationPropertyName,n);setElementProperty(af,"opacity",1);setElementProperty(af,kAnimationNamePropertyName,t);setElementProperty(af,kAnimationDurationPropertyName,n)}continue}var c=document.getElementById(D);if(c){if(G==="anchorPoint"){var S={x:I.value.pointX,y:I.value.pointY};if(h.magicMoveOffsetValue){S.x=h.magicMoveOffsetValue.pointX;S.y=h.magicMoveOffsetValue.pointY}ai=kTransformPropertyName;aa="translateX("+S.x+"px) translateY("+S.y+"px)"}else{if(G==="anchorPointZ"){if(Prototype.Browser.Gecko||navigator.userAgent.lastIndexOf("Chrome/")>0){ai=kTransformPropertyName;aa="translateZ("+-h.transformOriginZValue+"px)"}else{ai=kTransformPropertyName;aa="translateZ("+h.transformOriginZValue+"px)"}}}if(G!=="hidden"){setElementProperty(c,ai,aa)}setElementProperty(c,kAnimationFillModePropertyName,J.fillMode==="removed"?"none":J.fillMode);setElementProperty(c,kAnimationNamePropertyName,R);setElementProperty(c,kAnimationDurationPropertyName,n);if(d>1&&(h.animationInfo.name==="apple:action-blink"||h.animationInfo.name==="apple:action-pulse")){setElementProperty(c,kAnimationIterationCountPropertyName,d)}}}},animateContentsWillBegin:function(d){var c=d.canvasId;var i=d.effect;var e=d.element;var g=this.glContentsRenderer[c];g.draw(i);if(!g.animationStarted){g.animate();g.animationStarted=true}var b=e.id+"-contents-from";var a=e.id+"-contents-to";var h=document.getElementById(b);var f=document.getElementById(a);setElementProperty(h,"opacity",0);setElementProperty(f,"opacity",0)},cssPropertyValueForActionValue:function(a,b){switch(a){case"hidden":if(b.scalar===true){return"hidden"}else{return"visible"}case"anchorPoint":return b.pointX+"% "+b.pointY+"%";case"anchorPointZ":return b.scalar;case"position":return"translate("+b.pointX+"px,"+b.pointY+"px)";case"zPosition":return"translateZ("+b.scalar+"px)";case"translationEmphasis":return"translateX("+b.translationEmphasis[0]+"px) translateY("+b.translationEmphasis[1]+"px) translateZ("+b.translationEmphasis[2]+")";case"rotationEmphasis":return"rotateZ("+b.rotationEmphasis[6]+"rad)";case"scaleEmphasis":return"scale3d("+ensureScaleFactorNotZero(b.scaleEmphasis[3])+","+ensureScaleFactorNotZero(b.scaleEmphasis[4])+","+ensureScaleFactorNotZero(b.scaleEmphasis[5])+")";case"transform.scale":case"transform.scale.xy":return"scale("+ensureScaleFactorNotZero(b.scalar)+")";case"transform.scale.x":return"scaleX("+ensureScaleFactorNotZero(b.scalar)+")";case"transform.scale.y":return"scaleY("+ensureScaleFactorNotZero(b.scalar)+")";case"transform.rotation.x":return"rotateX("+b.scalar+"rad)";case"transform.rotation.y":return"rotateY("+b.scalar+"rad)";case"transform.rotation.z":case"transform.rotation":return"rotateZ("+b.scalar+"rad)";case"transform.translation":return"translateX("+b.pointX+"px) translateY("+b.pointY+"px)";case"transform.translation.x":return"translateX("+b.scalar+"px)";case"transform.translation.y":return"translateY("+b.scalar+"px)";case"transform.translation.z":return"translateZ("+b.scalar+"px)";case"isPlaying":case"opacity":case"opacityMultiplier":return b.scalar+"";case"transform":return"matrix3d("+b.transform+")";case"doubleSided":if(b.scalar===false){return"hidden"}else{return"visible"}default:return"some value"}},cssPropertyNameForAction:function(a){switch(a){case"hidden":return kVisibilityPropertyName;case"anchorPoint":return kTransformOriginPropertyName;case"anchorPointZ":return kTransformOriginZPropertyName;case"opacityMultiplier":return kOpacityPropertyName;case"translationEmphasis":case"rotationEmphasis":case"scaleEmphasis":case"position":case"zPosition":case"transform":case"transform.scale":case"transform.scale.xy":case"transform.scale.x":case"transform.scale.y":case"transform.rotation.x":case"transform.rotation.y":case"transform.rotation.z":case"transform.rotation":case"transform.translation":case"transform.translation.x":case"transform.translation.y":case"transform.translation.z":case"bounds":return kTransformPropertyName;case"doubleSided":return kBackfaceVisibilityPropertyName;case"contents":return kBackgroundImagePropertyName;default:return a}},hideMoviePoster:function(a){a.style.visibility="hidden"},handleMovieDidStart:function(a,b){b.style.visibility="visible";setTimeout(this.hideMoviePoster.bind(this,a),120)},handleMovieDidEnd:function(a,b){if(!b.loop){b.isEnded=true}},startMovie:function(a){if(a){a.play();a.isPlaying=true}},stopMovie:function(a){if(a){a.pause()}}});var KPFLayer=Class.create({initialize:function(c,d,b){this.animationInfo=d;this.layerId=kpfLayerCounter;kpfLayerCounter=kpfLayerCounter+1;this.objectID=c.objectID!=null?c.objectID:null;this.textureId=c.texture?c.texture:null;this.animations=c.animations;this.initialState=c.initialState;this.isVideoLayer=c.isVideoLayer;this.hasHighlightedBulletAnimation=c.hasHighlightedBulletAnimation;this.cssAnimationRules=[];this.layers=[];this.affineTransform=this.initialState.affineTransform;this.position=this.initialState.position;this.textureTransform="";if(this.initialState.transform!=null&&this.initialState.transform!=undefined){this.textureTransform="matrix3D("+this.initialState.transform+")"}else{this.textureTransform="matrix("+this.affineTransform+")"}this.anchorPoint=this.initialState.anchorPoint;if(b==null){b={pointX:0,pointY:0}}var a=this.position.pointX-this.initialState.width/2-(this.anchorPoint.pointX-0.5)*this.initialState.width;var e=this.position.pointY-this.initialState.height/2-(this.anchorPoint.pointY-0.5)*this.initialState.height;a=Math.round(a*1000000)/1000000;e=Math.round(e*1000000)/1000000;this.bounds={width:this.initialState.width,height:this.initialState.height,origin:{pointX:this.affineTransform[4],pointY:this.affineTransform[5]},offset:{pointX:a,pointY:e},canvasOffset:{pointX:a+b.pointX,pointY:e+b.pointY}};this.sublayerTransform=this.initialState.sublayerTransform;this.contentsRect=this.initialState.contentsRect;this.hidden=this.initialState.hidden;this.opacity=this.initialState.opacity;this.visibility=this.hidden===true?"hidden":"visible";this.addSublayer(c.layers,d,this.bounds.offset);if(d.animationSupported){this.initLayerAnimations()}},destroy:function(){this.initialState=null;this.cssAnimationRules=null;this.affineTransform=null;this.textureTransform=null;this.anchorPoint=null;this.anchorPointZ=null;this.bounds=null;this.contentsRect=null;this.hidden=null;this.opacity=null},addSublayer:function(f,e,d){for(var a=0,b=f.length;a<b;a++){var c=new KPFLayer(f[a],e,d);this.layers.push(c)}},initLayerAnimations:function(){var l=false;var h=false;var b=false;var s=false;var g=false;var f=false;var d=false;var a=false;var p=false;var o=false;var m=false;var u=false;var x=false;var w=false;var c=false;var y=false;var r=false;var t=[];var e=false;var n=this.animationInfo;var k=n.type;var A=n.name;var q=["isPlaying","opacityMultiplier","hidden"];if(k==="actionBuild"){this.isActionBuild=true}else{if(k==="buildIn"){this.isBuildIn=true}else{if(k==="buildOut"){this.isBuildOut=true}else{if(k==="transition"){this.isTransition=true}}}}if(A==="apple:magic-move-implied-motion-path"){this.isMagicMove=true}else{if(A==="apple:ca-isometric"){e=true}else{if(A==="renderMovie"){this.isRenderMovie=true}else{if(kEmphasisEffects.indexOf(A)>-1){this.isEmphasisBuild=true}}}}if(this.animations.length>0){this.cssAnimation=new KPFCssAnimation(this.animations,this)}this.divNames=[];if(this.objectID&&this.isRenderMovie){this.divNames=["opacity","position","transform.rotation.z","transform.scale.x","transform.scale.y","bounds","contents"]}else{if(this.cssAnimation){for(var z in this.cssAnimation.keyAnimations){if(q.indexOf(z)>0){continue}if(z=="opacity"){h=true}else{if(z==="anchorPoint"){b=true}else{if(z==="anchorPointZ"){s=true}else{if(!e&&z==="transform.translation.x"){g=true}else{if(!e&&z==="transform.translation.y"){f=true}else{if(!e&&z==="transform.translation.z"){d=true}else{if(!e&&z==="transform.translation"){a=true}else{if(!e&&z==="transform.rotation.x"){p=true}else{if(!e&&z==="transform.rotation.y"){o=true}else{if(!e&&z==="transform.rotation.z"){m=true}else{if(!e&&z==="transform.rotation"){u=true}else{if(z==="transform.scale.x"){x=true}else{if(z==="transform.scale.y"){w=true}else{if(z==="transform.scale.xy"){c=true}else{if(z==="transform.scale"){y=true}else{if(z==="transform"){r=true}else{if(z==="doubleSided"){l=true}else{if(z==="contents"){this.hasContentsAnimation=true}else{if(z==="bounds"){this.hasBoundsAnimation=true}else{if(z==="position"){this.hasPosition=true}else{t.push(z)}}}}}}}}}}}}}}}}}}}}}if(h&&this.isActionBuild&&!this.isEmphasisBuild){this.divNames.push("opacity");for(var v=0,j=this.layers.length;v<j;v++){if(this.layers[v].animations.length===0){this.layers[v].divNames=["opacity","position","transform.rotation.z","transform.scale.x","transform.scale.y","bounds","contents"]}}}else{if((h||this.isActionBuild)&&this.divNames.indexOf("opacity")===-1){this.divNames.push("opacity")}if(r){this.divNames.push("transform")}if(this.hasPosition||this.isActionBuild){this.divNames.push("position")}if(b){this.divNames.push("anchorPoint")}if(s){this.divNames.push("anchorPointZ")}for(var v=0,j=t.length;v<j;v++){this.divNames.push(t[v])}if(g){this.divNames.push("transform.translation.x")}if(f){this.divNames.push("transform.translation.y")}if(a){this.divNames.push("transform.translation")}if(d){this.divNames.push("transform.translation.z")}if(p){this.divNames.push("transform.rotation.x")}if(o){this.divNames.push("transform.rotation.y")}if(m){this.divNames.push("transform.rotation.z")}if((this.initialState.rotation!==0||this.isActionBuild)&&this.divNames.indexOf("transform.rotation.z")===-1){this.divNames.push("transform.rotation.z")}if(u){this.divNames.push("transform.rotation")}if(x){this.divNames.push("transform.scale.x")}if(w){this.divNames.push("transform.scale.y")}if(this.initialState.scale!==1||this.isActionBuild){if(this.divNames.indexOf("transform.scale.x")===-1){this.divNames.push("transform.scale.x")}if(this.divNames.indexOf("transform.scale.y")===-1){this.divNames.push("transform.scale.y")}}if(c){this.divNames.push("transform.scale.xy")}if(y){this.divNames.push("transform.scale")}if(this.textureId&&(this.hasBoundsAnimation||this.isActionBuild)){this.divNames.push("bounds")}if(this.textureId&&(this.hasContentsAnimation||this.isActionBuild)){this.divNames.push("contents")}if(l){this.divNames.push("doubleSided")}}}}}});var KPFCssAnimation=Class.create({initialize:function(o,I){this.kDelta=0.0001;this.kRoundingFactor=10000;this.animations=[];this.keyAnimations={};for(var C=0,g=o.length;C<g;C++){var F=o[C];var v=F.beginTime;var b=F.duration;var d=F.timingFunction?F.timingFunction:"linear";var H;var G;var l;var f;var y;var w=v+b;this.overallEndTime=0;if(w>this.overallEndTime){this.overallEndTime=w}if(d=="custom"){H=F.timingControlPoint1x;G=F.timingControlPoint1y;l=F.timingControlPoint2x;f=F.timingControlPoint2y}if(F.animations!=null&&F.animations.length>0){var q=F.animations;var p=v;if(q[0].property==null){p=q[0].beginTime;q=q[0].animations}for(var z=0,e=q.length;z<e;z++){var a=q[z];var n=a.property;var B=this.keyAnimations[n];if(B==null){B={groupBeginTime:p,earliestBeginTime:p+a.beginTime,latestEndTime:-1,repeatCount:a.repeatCount,keyActions:[]};this.keyAnimations[n]=B}if(p+a.beginTime+a.duration>B.latestEndTime){B.latestEndTime=p+a.beginTime+a.duration}if(a.path){var E=F.path.length;for(var x=0;C<E-1;x++){var r=F.path[x];var c=F.path[x+1];var A=r.points[0];var h=c.points[0];var u={pointX:A[0],pointY:A[1]};var D={pointX:h[0],pointY:h[1]};switch(r.type){case"MoveToPoint":case"AddLine":case"AddCurve":case"AddQuadCurve":y={property:"position",from:u,to:D,fillMode:"forwards",beginTime:p+a.beginTime+(x/(E-1))*a.duration,duration:1/(E-1)*a.duration,timingFunction:"linear",groupTimingFunction:d,groupBeginTime:v,groupDuration:b,groupTimingControlPoint1x:H,groupTimingControlPoint1y:G,groupTimingControlPoint2x:l,groupTimingControlPoint2y:f};break}this.addAction(y,a)}}else{if(a.keyTimes){var t=a.keyTimes.length;for(var x=0;x<t-1;x++){var s=a.keyTimes[x];var m=a.keyTimes[x+1];y={property:a.property,from:a.values[x],to:a.values[x+1],fillMode:a.fillMode,beginTime:p+a.beginTime+(s/1*a.duration),duration:(m-s)*a.duration,timingFunction:a.timingFunctions?a.timingFunctions[x]:"linear",groupTimingFunction:d,groupBeginTime:v,groupDuration:b,groupTimingControlPoint1x:H,groupTimingControlPoint1y:G,groupTimingControlPoint2x:l,groupTimingControlPoint2y:f};this.addAction(y,a)}}else{y={property:a.property,from:a.from,to:a.to,fillMode:a.fillMode,beginTime:p+a.beginTime,duration:a.duration,timingFunction:a.timingFunction?a.timingFunction:"linear",groupTimingFunction:d,groupBeginTime:v,groupDuration:b,groupTimingControlPoint1x:H,groupTimingControlPoint1y:G,groupTimingControlPoint2x:l,groupTimingControlPoint2y:f};this.addAction(y,a)}}}}else{var n=F.property;var B=this.keyAnimations[n];if(B==null){B={groupBeginTime:0,earliestBeginTime:F.beginTime,latestEndTime:-1,repeatCount:F.repeatCount,keyActions:[]};this.keyAnimations[n]=B}if(F.beginTime+F.duration>B.latestEndTime){B.latestEndTime=F.beginTime+F.duration}if(F.path){var E=F.path.length;for(var x=0;x<E-1;x++){var r=F.path[x];var c=F.path[x+1];var A=r.points[0];var h=c.points[0];var u={pointX:A[0],pointY:A[1]};var D={pointX:h[0],pointY:h[1]};switch(r.type){case"MoveToPoint":case"AddLine":case"AddCurve":case"AddQuadCurve":y={property:"position",from:u,to:D,fillMode:"forwards",beginTime:v+x/(E-1)*b,duration:1/(E-1)*b,timingFunction:"linear"};break}this.addAction(y,F)}}else{if(F.keyTimes){var t=F.keyTimes.length;for(var x=0;x<t-1;x++){var s=F.keyTimes[x];var m=F.keyTimes[x+1];y={property:F.property,from:F.values[x],to:F.values[x+1],fillMode:F.fillMode,beginTime:v+s*b,duration:(m-s)*b,timingFunction:F.timingFunctions?F.timingFunctions[x]:"linear"};this.addAction(y,F)}}else{y={property:F.property,from:F.from,to:F.to,fillMode:F.fillMode,beginTime:v,duration:b,timingFunction:d?d:"linear"};this.addAction(y,F)}}}}this.createKeyActions();this.createAnimationRules(I);this.createAnimationRuleForKeyframes(I)},addAction:function(b,a){if(a.timingFunction==="custom"){b.timingControlPoint1x=a.timingControlPoint1x;b.timingControlPoint1y=a.timingControlPoint1y;b.timingControlPoint2x=a.timingControlPoint2x;b.timingControlPoint2y=a.timingControlPoint2y}else{if(b.timingFunction.timingFunction!=null){if(b.timingFunction.timingFunction==="custom"){b.timingControlPoint1x=b.timingFunction.timingControlPoint1x;b.timingControlPoint1y=b.timingFunction.timingControlPoint1y;b.timingControlPoint2x=b.timingFunction.timingControlPoint2x;b.timingControlPoint2y=b.timingFunction.timingControlPoint2y}b.timingFunction=b.timingFunction.timingFunction}}this.animations.push(b)},createKeyActions:function(){for(var e=0,a=this.animations.length;e<a;e++){var c=this.animations[e];var d=c.beginTime;var b=c.duration;var g=d+b;var n=c.property;var h=this.keyAnimations[n];var m=h.keyActions;var k=h.latestEndTime-h.earliestBeginTime;var l=0;var j=100;if(k>0){l=100*d/this.overallEndTime;j=100*g/this.overallEndTime}if(j>99.9999){j=100}var f={startKeyframe:l,endKeyframe:j,from:c.from,to:c.to,timingFunction:c.timingFunction};if(c.fillMode){f.fillMode=c.fillMode}if(c.timingFunction=="custom"){f.timingControlPoint1x=c.timingControlPoint1x;f.timingControlPoint1y=c.timingControlPoint1y;f.timingControlPoint2x=c.timingControlPoint2x;f.timingControlPoint2y=c.timingControlPoint2y}m.push(f);m.sort(this.sortAction)}},sortAction:function(b,a){return b.startKeyframe-a.startKeyframe},roundNum:function(a){return Math.round(a*this.kRoundingFactor)/this.kRoundingFactor},createAnimationRules:function(w){var f=this.kDelta;for(var h in this.keyAnimations){if(h=="playing"){continue}var q=this.keyAnimations[h];var g=q.keyActions;var j=false;q.keyframes=[];var o=g[0];var s=this.roundNum(o.startKeyframe);var m=this.roundNum(100*q.groupBeginTime/this.overallEndTime);if(h=="anchorPoint"){var c={};c.x=o.to.pointX;c.y=o.to.pointY;var n={pointX:-(o.from.pointX-w.anchorPoint.pointX)*w.bounds.width,pointY:-(o.from.pointY-w.anchorPoint.pointY)*w.bounds.height};if(w.isMagicMove){var u=this.anchorPointOffset(w,{x:o.from.pointX,y:o.from.pointY});var k={pointX:u.x,pointY:u.y};var d=this.anchorPointOffset(w,{x:o.to.pointX,y:o.to.pointY});var v={pointX:d.x,pointY:d.y};if(k.pointX!==v.pointX||k.pointY!=v.pointY){n={pointX:v.pointX-k.pointX,pointY:v.pointY-k.pointY};w.magicMoveOffsetValue=n}}if(s!=0){var t={pointX:0,pointY:0};if(m>0){this.insertInitialKeyframes(q,m-f,"position",t)}if(s-m>f){if(o.fillMode==="both"||o.fillMode==="backwards"){t=n}q.keyframes.push({keyframe:m,keyName:"position",value:t,timingFunction:"linear"});q.keyframes.push({keyframe:s-f,keyName:"position",value:t,timingFunction:"linear"})}}q.keyframes.push({keyframe:s,keyName:"position",value:n,timingFunction:"linear"});q.keyframes.push({keyframe:100,keyName:"position",value:n,timingFunction:"linear"});w.transformOriginValue=(c.x*100)+"% "+(c.y*100)+"%";continue}if(h=="anchorPointZ"){j=true;if(s!=0){var t=this.createInitialKeyframeValue(w,h,o.from,true);q.keyframes.push({keyframe:0,keyName:"zPosition",value:t,timingFunction:"linear"});q.keyframes.push({keyframe:s-f,keyName:"zPosition",value:t,timingFunction:"linear"})}q.keyframes.push({keyframe:s,keyName:"zPosition",value:o.from,timingFunction:"linear"});q.keyframes.push({keyframe:100,keyName:"zPosition",value:o.to,timingFunction:"linear"});w.transformOriginZValue=o.to.scalar;continue}if(o==null){continue}var l=0;var r=null;var e=null;if(s!=0){if(h==="hidden"){e={scalar:w.hidden};this.insertInitialKeyframes(q,s-f,h,e)}else{if(h==="opacity"){if(o.fillMode==="both"||o.fillMode==="backwards"){e=o.from}else{e={scalar:w.opacity}}this.insertInitialKeyframes(q,s-f,h,e)}else{if(h==="position"){if(w.isBuildIn||w.isBuildOut){if(m>0&&o.fillMode!=="both"&&o.fillMode!=="backwards"){e={pointX:0,pointY:0}}else{e={pointX:this.roundNum(o.from.pointX-w.initialState.position.pointX),pointY:this.roundNum(o.from.pointY-w.initialState.position.pointY)}}}else{e={pointX:0,pointY:0}}this.insertInitialKeyframes(q,s-f,h,e)}else{e=this.createInitialKeyframeValue(w,h,o.from,j);if(m>0){this.insertInitialKeyframes(q,m-f,h,e)}if(s-m>f){if(o.fillMode==="both"||o.fillMode==="backwards"){e=o.from}if(h==="transform.translation"){e.pointX=this.roundNum(e.pointX);e.pointY=this.roundNum(e.pointY)}q.keyframes.push({keyframe:m,keyName:h,value:e,timingFunction:"linear"});q.keyframes.push({keyframe:s-f,keyName:h,value:e,timingFunction:"linear"})}}}}l=o.startKeyframe;r=e}for(var p=0,b=g.length;p<b;p++){o=g[p];if(h=="position"){e=w.initialState.position;o.from={pointX:this.roundNum(o.from.pointX-e.pointX),pointY:this.roundNum(o.from.pointY-e.pointY)};o.to={pointX:this.roundNum(o.to.pointX-e.pointX),pointY:this.roundNum(o.to.pointY-e.pointY)}}if(Math.abs(o.startKeyframe-l)>f){q.keyframes.push({keyframe:this.roundNum(o.startKeyframe)-f,keyName:h,value:r,timingFunction:"linear"})}if(h==="transform.translation"){o.from.pointX=this.roundNum(o.from.pointX);o.from.pointY=this.roundNum(o.from.pointY);o.to.pointX=this.roundNum(o.to.pointX);o.to.pointY=this.roundNum(o.to.pointY)}var a=this.createTimingFunctionForAction(o);q.keyframes.push({keyframe:this.roundNum(o.startKeyframe),keyName:h,value:o.from,timingFunction:a});q.keyframes.push({keyframe:this.roundNum(o.endKeyframe)-(o.endKeyframe==100?0:f),keyName:h,value:o.to,timingFunction:a});r=o.to;l=o.endKeyframe}if(l!=100&&h!="hidden"){q.keyframes.push({keyframe:this.roundNum(l),keyName:h,value:r,timingFunction:"linear"});q.keyframes.push({keyframe:100,keyName:h,value:r,timingFunction:"linear"})}}},insertInitialKeyframes:function(b,c,d,a){b.keyframes.push({keyframe:0,keyName:d,value:a,timingFunction:"linear"});b.keyframes.push({keyframe:c,keyName:d,value:a,timingFunction:"linear"})},anchorPointOffset:function(c,e){var a={};var b={};var f={};var d=c.bounds;a.x=d.width/2;a.y=d.height/2;b.x=e.x*d.width;b.y=e.y*d.height;f.x=(a.x-b.x);f.y=(a.y-b.y);return f},createInitialKeyframeValue:function(a,c,e,b){var d={};switch(c){case"anchorPoint":d.pointX=(a.anchorPoint.pointX-0.5)*a.bounds.width;d.pointY=(a.anchorPoint.pointY-0.5)*a.bounds.height;break;case"anchorPointZ":if(Prototype.Browser.Gecko||Prototype.Browser.IE||isChrome||isIE||isEdge){d.scalar=0}else{d.scalar=e.scalar+e.scalar}break;case"opacity":case"opacityMultiplier":d.scalar=a.opacity;break;case"hidden":d.scalar=a.hidden;break;case"position":d.pointX=a.affineTransform[4];d.pointY=a.affineTransform[5];break;case"zPosition":d.scalar=0;break;case"transform.scale":case"transform.scale.xy":case"transform.scale.x":case"transform.scale.y":d.scalar=a.initialState.scale;break;case"transform.rotation.z":d.scalar=a.initialState.rotation;case"transform":d.transform=e.transform;break;case"bounds":d.pointX=0;d.pointY=0;d.width=a.initialState.width;d.height=a.initialState.height;break;default:d.scalar=0;d.pointX=0;d.pointY=0;break}return d},createTimingFunctionForAction:function(c){var b="";var a=c.timingFunction;var d=c;if(typeof a==="object"){a=a.timingFunction;d=c.timingFunction}switch(a.toLowerCase()){case"easein":b="ease-in";break;case"easeout":b="ease-out";break;case"easeinout":case"easeineaseout":b="ease-in-out";break;case"custom":b="cubic-bezier("+d.timingControlPoint1x+","+d.timingControlPoint1y+","+d.timingControlPoint2x+","+d.timingControlPoint2y+")";break;case"linear":b="linear";break;default:b="linear";break}return b},createAnimationRuleForKeyframes:function(d){for(var n in this.keyAnimations){var f=this.keyAnimations[n];var e="layer"+d.layerId+"-"+escapeTextureId(n);var b;var h="";var o;if(n==="contents"){var m=this.roundNum(f.keyActions[0].startKeyframe);b=gShowController.animationManager.createAnimation(e+"-from");var l="0% {opacity: 1; "+kAnimationTimingFunctionPropertyName+": linear;}";var k="49.999% {opacity: 1; "+kAnimationTimingFunctionPropertyName+": linear;}";var j="50% {opacity: 0; "+kAnimationTimingFunctionPropertyName+": linear;}";var g="100% {opacity: 0; "+kAnimationTimingFunctionPropertyName+": linear;}";if(m!==0){k=((100-m)/2+m-this.kDelta)-this.kDelta+"% {opacity: 1; "+kAnimationTimingFunctionPropertyName+": linear;}";j=((100-m)/2+m)+"% {opacity: 0; "+kAnimationTimingFunctionPropertyName+": linear;}"}b.appendRule(l);b.appendRule(k);b.appendRule(j);b.appendRule(g);b=gShowController.animationManager.createAnimation(e+"-to");l="0% {opacity: 0; "+kAnimationTimingFunctionPropertyName+": linear;}";k="49.999% {opacity: 0; "+kAnimationTimingFunctionPropertyName+": linear;}";j="50% {opacity: 1; "+kAnimationTimingFunctionPropertyName+": linear;}";g="100% {opacity: 1; "+kAnimationTimingFunctionPropertyName+": linear;}";if(m!==0){k=((100-m)/2+m-this.kDelta)-this.kDelta+"% {opacity: 0; "+kAnimationTimingFunctionPropertyName+": linear;}";j=((100-m)/2+m)+"% {opacity: 1; "+kAnimationTimingFunctionPropertyName+": linear;}"}b.appendRule(l);b.appendRule(k);b.appendRule(j);b.appendRule(g);d.cssAnimationRules.push(e);continue}if(!isIE){b=gShowController.animationManager.createAnimation(e);for(var c=0,a=f.keyframes.length;c<a;c++){o=f.keyframes[c];h=this.createAnimationRuleForKeyframe(n,o,d)+" ";b.appendRule(h)}d.cssAnimationRules.push(e)}else{if(browserVersion>=10){for(var c=0,a=f.keyframes.length;c<a;c++){o=f.keyframes[c];h+=this.createAnimationRuleForKeyframe(n,o,d)+" "}gShowController.animationManager.styleSheet.insertRule(kKeyframesPropertyName+" "+e+" {"+h+"}",0);d.cssAnimationRules.push(e)}}}},createAnimationRuleForKeyframe:function(l,m,g){var j=m.keyframe;var f=m.keyName;var k=m.value;var n=m.timingFunction;var d;var c=g.transformOriginValue;var e=g.transformOriginZValue;var h="";if(c){h=kTransformOriginPropertyName+": "+c+";"}if(g.animationInfo.name==="apple:ca-swing"&&f==="hidden"){h=""}if(f==="hidden"){var a={scalar:-1};if(k.scalar==false){a.scalar=1}else{a.scalar=0}f="opacity";d=this.cssPropertyValueForActionValue(l,f,a)}else{d=this.cssPropertyValueForActionValue(l,f,k)}var b;b=this.cssPropertyNameForAction(f)+": "+d+"; "+(j<100?kAnimationTimingFunctionPropertyName+": "+n+";":"");var i=j+"% {"+h+b+"}";return i},cssPropertyValueForActionValue:function(b,a,c){switch(a){case"hidden":if(c.scalar==true){return"hidden"}else{return"visible"}case"anchorPoint":return c.pointX+"% "+c.pointY+"%";case"anchorPointZ":return c.scalar;case"position":return"translate("+c.pointX+"px,"+c.pointY+"px)";case"zPosition":if(b=="anchorPointZ"&&(Prototype.Browser.Gecko||navigator.userAgent.lastIndexOf("Chrome/")>0)){return"translateZ("+-c.scalar+"px)"}else{return"translateZ("+c.scalar+"px)"}case"translationEmphasis":return"translateX("+c.translationEmphasis[0]+"px) translateY("+c.translationEmphasis[1]+"px) translateZ("+c.translationEmphasis[2]+")";case"rotationEmphasis":return"rotateZ("+c.rotationEmphasis[6]+"rad)";case"scaleEmphasis":return"scale3d("+ensureScaleFactorNotZero(c.scaleEmphasis[3])+","+ensureScaleFactorNotZero(c.scaleEmphasis[4])+","+ensureScaleFactorNotZero(c.scaleEmphasis[5])+")";case"transform.scale":case"transform.scale.xy":return"scale("+ensureScaleFactorNotZero(c.scalar)+")";case"transform.scale.x":return"scaleX("+ensureScaleFactorNotZero(c.scalar)+")";case"transform.scale.y":return"scaleY("+ensureScaleFactorNotZero(c.scalar)+")";case"transform.rotation.x":return"rotateX("+c.scalar+"rad)";case"transform.rotation.y":return"rotateY("+c.scalar+"rad)";case"transform.rotation.z":case"transform.rotation":return"rotateZ("+c.scalar+"rad)";case"transform.translation":return"translateX("+c.pointX+"px) translateY("+c.pointY+"px)";case"transform.translation.x":return"translateX("+c.scalar+"px)";case"transform.translation.y":return"translateY("+c.scalar+"px)";case"transform.translation.z":return"translateZ("+c.scalar+"px)";case"isPlaying":case"opacity":case"opacityMultiplier":return c.scalar+"";case"transform":return"matrix3d("+c.transform+")";case"doubleSided":if(c.scalar==false){return"hidden"}else{return"visible"}case"contents":return c.texture;default:return"some value"}},cssPropertyNameForAction:function(a){switch(a){case"hidden":return kVisibilityPropertyName;case"anchorPoint":return kTransformOriginPropertyName;case"anchorPointZ":return kTransformOriginZPropertyName;case"opacityMultiplier":return kOpacityPropertyName;case"translationEmphasis":case"rotationEmphasis":case"scaleEmphasis":case"position":case"zPosition":case"transform":case"transform.scale":case"transform.scale.xy":case"transform.scale.x":case"transform.scale.y":case"transform.rotation.x":case"transform.rotation.y":case"transform.rotation.z":case"transform.rotation":case"transform.translation":case"transform.translation.x":case"transform.translation.y":case"transform.translation.z":case"bounds":return kTransformPropertyName;case"doubleSided":return kBackfaceVisibilityPropertyName;case"contents":return kBackgroundImagePropertyName;default:return a}}});
|
|
|
|
assets/player/KeynoteDHTMLPlayer.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:627d0e596d63740c4601cacda44fe91f76e37e9a3baf58ce2b752059b873c5a9
|
3 |
-
size 11670
|
|
|
1 |
+
var kDeviceUnknown="deviceUnknown";var kDeviceDesktop="deviceDesktop";var kDeviceMobile="deviceMobile";var kModeUnknown="modeUnknown";var kModeDesktop="modeDesktop";var kModeMobile="modeMobile";var kBrowserUnknown="browserUnknown";var kBrowserDesktopSafari="browserDesktopSafari";var kBrowserMobileSafari="browserMobileSafari";var kOrientationUnknown="orientationUnknown";var kOrientationLandscape="orientationLandscape";var kOrientationPortrait="orientationPortrait";var kShowModeNormal=0;var kShowModeAutoplay=1;var kShowModeHyperlinksOnly=2;var kSoundTrackModePlayOnce=0;var kSoundTrackModeLooping=1;var kSoundTrackModeOff=2;var kOpacityPropertyName="opacity";var kVisibilityPropertyName="visibility";var kZIndexPropertyName="z-index";var kDisplayPropertyName="display";var kDisplayBlockPropertyValue="block";var kDisplayNonePropertyValue="none";var kTransformOriginTopLeftPropertyValue="top left";var kTransformOriginCenterPropertyValue="center";var kTransformStylePreserve3DPropertyValue="preserve-3d";var kTransformStyleFlatPropertyValue="flat";var kPositionAbsolutePropertyValue="absolute";var kPositionRelativePropertyValue="relative";var kBackfaceVisibilityHiddenPropertyValue="hidden";var kiPhoneDeviceWidth=320;var kiPhoneDeviceHeight=480;var kiPhoneLandscapeButtonBarHeight=32;var kiPhonePortraitButtonBarHeight=44;var kiPhoneUrlBarHeight=60;var kiPhoneStatusBarHeight=20;var kiPadDeviceWidth=768;var kiPadDeviceHeight=1024;var kiPadLandscapeButtonBarHeight=32;var kiPadPortraitButtonBarHeight=44;var kiPadUrlBarHeight=0;var kiPadStatusBarHeight=0;var kiPadAddressBarHeight=30;var kiPadBookmarksBarHeight=30;var kiPadMaxMoviesPerScene=20;var kMaxSceneDownloadWaitTime=60000;var kMaxScriptDownloadWaitTime=60000;var kWaitingIndicatorFadeOutDuration=2000;var kHideAddressBarDelay=3000;var kSceneLoadPollInterval=100;var kSceneLoadDisplaySpinnerTime=3000;var kSceneLoadDisplaySpinnerPollCount=kSceneLoadDisplaySpinnerTime/kSceneLoadPollInterval;var kSceneLoadGiveUpTime=60000;var kSceneLoadGiveUpPollCount=kSceneLoadGiveUpTime/kSceneLoadPollInterval;var kPropertyName_currentSlide="currentSlide";var kKeyCode_Plus=107;var kKeyCode_Minus=109;var kKeyCode_Dot=110;var kKeyCode_F11=122;var kKeyCode_F12=123;var kKeyCode_Hyphen=189;var kKeyCode_Equal=187;var kKeyCode_Period=190;var kKeyCode_Slash=191;var kKeyCode_Space=32;var kKeyCode_Escape=27;var kKeyCode_LeftArrow=37;var kKeyCode_UpArrow=38;var kKeyCode_RightArrow=39;var kKeyCode_DownArrow=40;var kKeyCode_OpenBracket=219;var kKeyCode_CloseBracket=221;var kKeyCode_Home=36;var kKeyCode_End=35;var kKeyCode_PageUp=33;var kKeyCode_PageDown=34;var kKeyCode_Return=13;var kKeyCode_N=78;var kKeyCode_P=80;var kKeyCode_Q=81;var kKeyCode_S=83;var kKeyCode_Delete=8;var kKeyCode_0=48;var kKeyCode_9=57;var kKeyCode_Numeric_0=96;var kKeyCode_Numeric_9=105;var kKeyModifier_Shift=1000;var kKeyModifier_Ctrl=2000;var kKeyModifier_Alt=3000;var kKeyModifier_Meta=4000;var kHelpPlacardMainTitle=CoreDocs.loc("Keyboard Shortcuts","Keyboard Shortcuts");var kHelpPlacardNavigationTitle=CoreDocs.loc("Navigation","Navigation");var kHelpPlacardOtherTitle=CoreDocs.loc("Other","Other");var kHelpPlacardAdvanceToNextBuild=CoreDocs.loc("Advance to next build","Advance to next build");var kHelpPlacardGoBackToPreviousBuild=CoreDocs.loc("Go back to previous build","Go back to previous build");var kHelpPlacardAdvanceAndSkipBuild=CoreDocs.loc("Advance and skip build","Advance and skip build");var kHelpPlacardAdvanceToNextSlide=CoreDocs.loc("Advance to next slide","Advance to next slide");var kHelpPlacardGoBackToPreviousSlide=CoreDocs.loc("Go back to previous slide","Go back to previous slide");var kHelpPlacardGoToFirstSlide=CoreDocs.loc("Go to first slide","Go to first slide");var kHelpPlacardGoToLastSlide=CoreDocs.loc("Go to last slide","Go to last slide");var kHelpPlacardQuitPresentationMode=CoreDocs.loc("Quit presentation mode","Quit presentation mode");var kHelpPlacardGoToSpecificSlide=CoreDocs.loc("Go to specific slide","Go to specific slide");var kHelpPlacardShowOrHideKeyboardShortcuts=CoreDocs.loc("Show or hide Keyboard Shortcuts","Show or hide Keyboard Shortcuts");var kHelpPlacardShowOrHideTheCurrentSlideNumber=CoreDocs.loc("Show or hide the current slide number","Show or hide the current slide number");var kUnableToReachiWorkTryAgain=CoreDocs.loc("Slide couldn't be displayed.\nDo you want to try again?","alert text to display when we timeout trying to download resources from iWork.com");var kSlideLabel=CoreDocs.loc("Slide","Prefix label for 'Slide I/N' display");var kTapOrSwipeToAdvance=CoreDocs.loc("Tap or Swipe to advance","Help string for bottom of portrait mode on mobile device");var kOSUnknown="unknown";var kOSWindows="Windows";var kOSMacOSX="Mac OS X";var kOSiOS="iOS";var gTheoreticalMaxPixelCount=1024*1024*3;var gSafeMaxPixelCount=gTheoreticalMaxPixelCount*0.9;var gShowController=null;var gDevice=kDeviceUnknown;var gBrowser=kBrowserUnknown;var gMode=kModeUnknown;var gIpad=false;var gOS=kOSUnknown;var browserPrefix,browserVersion;var userAgentString=window.navigator.userAgent;var isMacOS=window.navigator.platform.indexOf("Mac")!==-1;var isChrome=false;var isEdge=false;var isIE=false;if(userAgentString.lastIndexOf("Edge/")>0){isEdge=true;browserPrefix="webkit";browserVersion=12}else{if(userAgentString.lastIndexOf("Trident/")>0){isIE=true;browserPrefix="ms";var revisionStringIE=userAgentString.substring(userAgentString.lastIndexOf("rv"),userAgentString.lastIndexOf(")"));var revisionIE=[];if(revisionStringIE.lastIndexOf(":")>0){revisionIE=revisionStringIE.split(":");browserVersion=parseFloat(revisionIE[1])}else{if(revisionStringIE.lastIndexOf(" ")>0){revisionIE=revisionStringIE.split(" ");browserVersion=parseFloat(revisionIE[1])}else{browserVersion=11}}}else{if(Prototype.Browser.WebKit){browserPrefix="webkit";if(userAgentString.lastIndexOf("Chrome/")>0){isChrome=true}}else{if(Prototype.Browser.Gecko){browserPrefix="moz"}else{if(Prototype.Browser.IE){isIE=true;browserPrefix="ms";browserVersion=parseFloat(navigator.appVersion.split("MSIE")[1])}}}}}var kKeyframesPropertyName="@-"+browserPrefix+"-keyframes";var kAnimationNamePropertyName="-"+browserPrefix+"-animation-name";var kAnimationDurationPropertyName="-"+browserPrefix+"-animation-duration";var kAnimationDelayPropertyName="-"+browserPrefix+"-animation-delay";var kAnimationFillModePropertyName="-"+browserPrefix+"-animation-fill-mode";var kAnimationTimingFunctionPropertyName="-"+browserPrefix+"-animation-timing-function";var kAnimationIterationCountPropertyName="-"+browserPrefix+"-animation-iteration-count";var kTransformPropertyName="-"+browserPrefix+"-transform";var kTransformOriginPropertyName="-"+browserPrefix+"-transform-origin";var kTransformOriginZPropertyName="-"+browserPrefix+"-transform-origin-z";var kTransitionPropertyName="-"+browserPrefix+"-transition-property";var kTransitionDurationName="-"+browserPrefix+"-transition-duration";var kTransformStylePropertyName="-"+browserPrefix+"-transform-style";var kTransitionPropertyName="-"+browserPrefix+"-transition";var kTransitionEndEventName=browserPrefix+"TransitionEnd";var kAnimationEndEventName=browserPrefix+"AnimationEnd";var kPerspectivePropertyName="-"+browserPrefix+"-perspective";var kPerspectiveOriginPropertyName="-"+browserPrefix+"-perspective-origin";var kBackfaceVisibilityPropertyName="-"+browserPrefix+"-backface-visibility";var kBoxShadowPropertyName="-"+browserPrefix+"-box-shadow";var kBorderPropertyName="border";var kBackgroundImagePropertyName="background-image";var kEmphasisEffects=["apple:action-pop","apple:action-pulse","apple:action-blink","apple:action-flip","apple:action-bounce","apple:action-jiggle"];var kActionBuildKeyAnimations={"apple:action-opacity":["opacity"],"apple:action-motion-path":["position"],"apple:action-rotation":["transform.rotation.z"],"apple:action-scale":["transform.scale.x","transform.scale.y","anchorPoint","contents","bounds"],"apple:action-blink":["opacity"],"apple:action-bounce":["anchorPoint","transform.scale.y","transform.translation.y","transform.scale.x"],"apple:action-flip":["transform.rotation.y","transform.scale.xy"],"apple:action-jiggle":["transform.rotation.z"],"apple:action-pop":["transform.scale.xy"],"apple:action-pulse":["transform.scale.xy"]};var kSupportedWebGLEffects=["apple:wipe-iris","com.apple.iWork.Keynote.BUKAnvil","com.apple.iWork.Keynote.BUKTwist","com.apple.iWork.Keynote.BUKFlop","com.apple.iWork.Keynote.KLNColorPlanes","com.apple.iWork.Keynote.KLNFlame","com.apple.iWork.Keynote.KLNConfetti","com.apple.iWork.Keynote.KLNDiffuse","com.apple.iWork.Keynote.KNFireworks","com.apple.iWork.Keynote.KLNShimmer","com.apple.iWork.Keynote.KLNSparkle"];var useWebGL=true;var usePDF=true;var pdfScaleFactor=1;var kFullscreenChangeEventName=browserPrefix+"fullscreenchange";window.addEventListener("load",setupShowController,false);function static_url(a){return a}function setupShowController(){var a=isMobileSafari();if(a){gBrowser=kBrowserMobileSafari;gDevice=kDeviceMobile;gMode=kModeMobile;gIpad=isiPad()}else{gBrowser=kBrowserDesktopSafari;gDevice=kDeviceDesktop;gMode=kModeDesktop}debugMessage(kDebugSetupShowController,"================================================================================");debugMessage(kDebugSetupShowController,"=== S T A R T O F S E S S I O N ===");debugMessage(kDebugSetupShowController,"================================================================================");debugMessage(kDebugSetupShowController,"userAgent: "+navigator.userAgent);debugMessage(kDebugSetupShowController,"url: "+window.location.href);if(navigator.userAgent.match(/Windows/)){gOS=kOSWindows}var b=getUrlParameter("pixelLimit");if(b!=""){gSafeMaxPixelCount=1024*1024*parseInt(b)}if(navigator.userAgent.indexOf("deviceDesktop")!=-1){debugMessage(kDebugSetupShowController,"Device was '"+gDevice+"', overriding device to be 'deviceDesktop'");gDevice=kDeviceDesktop}if(navigator.userAgent.indexOf("deviceMobile")!=-1){debugMessage(kDebugSetupShowController,"Device was '"+gDevice+"', overriding device to be 'deviceMobile'");gDevice=kDeviceMobile}if(navigator.userAgent.indexOf("modeDesktop")!=-1){debugMessage(kDebugSetupShowController,"Mode was '"+gMode+"', overriding device to be 'modeDesktop'");gMode=kModeDesktop}if(navigator.userAgent.indexOf("modeMobile")!=-1){debugMessage(kDebugSetupShowController,"Mode was '"+gMode+"', overriding device to be 'modeMobile'");gMode=kModeMobile}debugMessage(kDebugSetupShowController," gDevice: "+gDevice);debugMessage(kDebugSetupShowController," gBrowser: "+gBrowser);debugMessage(kDebugSetupShowController," gMode: "+gMode);debugMessage(kDebugSetupShowController," gOS: "+gOS);gShowController=new ShowController();gShowController.displayManager.showWaitingIndicator();gShowController.delegate.setPlaybackReadyHandler(function(){if(usePDF){if(window.location.protocol==="file:"){PDFJS.disableWorker=true}PDFJS.workerSrc="./pdfjs/pdf_worker.js";PDFJS.cMapUrl="./pdfjs/web/cmaps/";PDFJS.cMapPacked=true;var c=document.createElement("canvas");var d=c.getContext("webgl")||c.getContext("experimental-webgl");if(!d){useWebGL=false}}gShowController.startShow()})}function extractDelegateFromUrlParameter(){var d=getUrlParameter("delegate");var a;if((d=="")||(d==null)||(typeof(d)=="undefined")){a=new NullDelegate()}else{var c=d.indexOf(".");a=window;while(c!=-1){var b=d.substring(0,c);a=a[b];d=d.substring(c+1);c=d.indexOf(".")}a=a[d]}return a}var NullDelegate=Class.create({initialize:function(){},showDidLoad:function(){},showExited:function(){history.go(-1)},propertyChanged:function(b,a){},setPlaybackReadyHandler:function(a){a()}});
|
|
|
|
assets/player/NarrationManager.js
CHANGED
@@ -1,3 +1,179 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* NarrationManager.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var NarrationManager = Class.create({
|
10 |
+
initialize: function(recording) {
|
11 |
+
// recording movies in an array
|
12 |
+
this.movieSegments = recording.movieSegments;
|
13 |
+
|
14 |
+
// total time of this recording
|
15 |
+
this.duration = recording.duration;
|
16 |
+
|
17 |
+
// navigation, movie and pause in eventTracks array
|
18 |
+
this.eventTracks = recording.eventTracks;
|
19 |
+
|
20 |
+
// current navigation event index
|
21 |
+
this.currentNavigationEventIndex = 0;
|
22 |
+
|
23 |
+
// last scene index
|
24 |
+
this.lastSceneIndex = 0;
|
25 |
+
|
26 |
+
for (var i = 0, length = this.eventTracks.length; i < length; i++) {
|
27 |
+
var eventTrack = this.eventTracks[i];
|
28 |
+
|
29 |
+
if (eventTrack.type === "navigation") {
|
30 |
+
this.navigationEvents = eventTrack.events;
|
31 |
+
} else if (eventTrack.type === "movie") {
|
32 |
+
this.movieEvents = eventTrack.events;
|
33 |
+
} else if (eventTrack.type === "pause") {
|
34 |
+
this.pauseEvents = eventTrack.events;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
},
|
39 |
+
|
40 |
+
start: function() {
|
41 |
+
// set up media resources
|
42 |
+
var audio = new Audio();
|
43 |
+
audio.src = "../" + this.movieSegments[0].url;
|
44 |
+
|
45 |
+
// observe play event
|
46 |
+
Event.observe(audio, "playing", this.handleAudioDidStart.bind(this));
|
47 |
+
Event.observe(audio, "ended", this.handleAudioDidEnd.bind(this, 0));
|
48 |
+
|
49 |
+
audio.play();
|
50 |
+
},
|
51 |
+
|
52 |
+
handleAudioDidStart: function() {
|
53 |
+
// audio has started, now navigate to the first navigation event
|
54 |
+
setTimeout(this.navigate(this.navigationEvents[0], true), 100);
|
55 |
+
},
|
56 |
+
|
57 |
+
handleAudioDidEnd: function(audioIndex) {
|
58 |
+
var nextAudioIndex = audioIndex + 1;
|
59 |
+
|
60 |
+
if (this.movieSegments[nextAudioIndex]) {
|
61 |
+
var audio = new Audio();
|
62 |
+
audio.src = "../" + this.movieSegments[nextAudioIndex].url;
|
63 |
+
audio.play();
|
64 |
+
|
65 |
+
Event.stopObserving(audio, "ended");
|
66 |
+
Event.observe(audio, "ended", this.handleAudioDidEnd.bind(this, nextAudioIndex));
|
67 |
+
}
|
68 |
+
},
|
69 |
+
|
70 |
+
navigate: function(event, startup) {
|
71 |
+
var sceneIndex = this.sceneIndexFromNavigationEvent(event);
|
72 |
+
|
73 |
+
if (event.animationPhase === "start") {
|
74 |
+
// if event's slideIndex has been changed from lastScene's slide
|
75 |
+
// check to see if this is our next scene to play
|
76 |
+
var isNextScene = false;
|
77 |
+
|
78 |
+
if (gShowController.script.loopSlideshow) {
|
79 |
+
if (this.lastSceneIndex === gShowController.script.numScenes - 1) {
|
80 |
+
if (sceneIndex === 0) {
|
81 |
+
isNextScene = true;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
} else {
|
85 |
+
if (this.lastSceneIndex + 1 === sceneIndex) {
|
86 |
+
isNextScene = true;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
if (isNextScene) {
|
91 |
+
if (gShowController.state === kShowControllerState_IdleAtInitialState) {
|
92 |
+
gShowController.playCurrentScene();
|
93 |
+
} else if (gShowController.state === kShowControllerState_IdleAtFinalState) {
|
94 |
+
gShowController.jumpToScene(this.lastSceneIndex, true);
|
95 |
+
}
|
96 |
+
} else {
|
97 |
+
// this is the slide we are jumping to
|
98 |
+
var slideIndexToJump = gShowController.scriptManager.slideIndexFromSceneIndex(sceneIndex);
|
99 |
+
var sceneIndexOfHyperlink = this.lastSceneIndex;
|
100 |
+
|
101 |
+
// get hyperlink from slide, find the first occurrence of slideId in hyperlinks
|
102 |
+
var hyperlinks = gShowController.script.events[sceneIndexOfHyperlink].hyperlinks;
|
103 |
+
var hyperlink;
|
104 |
+
var hyperlinkEvent;
|
105 |
+
|
106 |
+
for (var i = 0, length = hyperlinks.length; i < length; i++) {
|
107 |
+
hyperlink = hyperlinks[i];
|
108 |
+
hyperlinkEvent = hyperlink.events[event.slide];
|
109 |
+
|
110 |
+
if (hyperlinkEvent) {
|
111 |
+
break;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
if (hyperlink) {
|
116 |
+
// call jumpToHyperlinkSlide to play hyperlink transition
|
117 |
+
gShowController.jumpToHyperlinkSlide(slideIndexToJump, hyperlink);
|
118 |
+
} else {
|
119 |
+
// if no hyperlink event is found for any reason, we still want to jump
|
120 |
+
gShowController.jumpToScene(sceneIndex, false);
|
121 |
+
}
|
122 |
+
}
|
123 |
+
} else if (event.animationPhase === "none" && startup == null) {
|
124 |
+
gShowController.jumpToScene(sceneIndex, false);
|
125 |
+
}
|
126 |
+
|
127 |
+
// if there is any more event then set it to run next
|
128 |
+
var nextEvent = this.navigationEvents[this.currentNavigationEventIndex + 1];
|
129 |
+
|
130 |
+
if (nextEvent == null) {
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
|
134 |
+
// set timeout to navigate to next event
|
135 |
+
var duration = nextEvent.startTime - event.startTime;
|
136 |
+
setTimeout(this.navigate.bind(this, nextEvent), duration * 1000);
|
137 |
+
|
138 |
+
this.lastSceneIndex = sceneIndex;
|
139 |
+
this.currentNavigationEventIndex = this.currentNavigationEventIndex + 1;
|
140 |
+
},
|
141 |
+
|
142 |
+
handleCurrentSceneDidComplete: function(sceneIndexToJump) {
|
143 |
+
// scene did complete, jump to next scene so we have more time to set it up
|
144 |
+
gShowController.jumpToScene(sceneIndexToJump, false);
|
145 |
+
},
|
146 |
+
|
147 |
+
sceneIndexFromNavigationEvent: function(event) {
|
148 |
+
// return sceneIndex from navigation event
|
149 |
+
var slideId = event.slide;
|
150 |
+
var slideList = gShowController.script.slideList;
|
151 |
+
var newSlideIndex = -1;
|
152 |
+
|
153 |
+
for (var i = 0, length = slideList.length; i < length; i++) {
|
154 |
+
if (slideList[i] === slideId) {
|
155 |
+
newSlideIndex = i;
|
156 |
+
break;
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
var sceneIndex = gShowController.scriptManager.sceneIndexFromSlideIndex(newSlideIndex);
|
161 |
+
var newSceneIndex = event.eventIndex + sceneIndex;
|
162 |
+
|
163 |
+
return newSceneIndex;
|
164 |
+
},
|
165 |
+
|
166 |
+
slideIndexFromSlideId: function(slideId) {
|
167 |
+
var slideList = gShowController.slideList;
|
168 |
+
var slideIndex = -1;
|
169 |
+
|
170 |
+
for (var i = 0, length = slideList.length; i < length; i++) {
|
171 |
+
if (slideList[i] === slideId) {
|
172 |
+
slideIndex = i;
|
173 |
+
break;
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
return slideIndex;
|
178 |
+
}
|
179 |
+
});
|
assets/player/NavigatorController.js
CHANGED
@@ -1,3 +1,325 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* NavigatorController.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var NavigatorController = Class.create({
|
10 |
+
initialize: function(domNode) {
|
11 |
+
// root node for the navigator control
|
12 |
+
this.domNode = domNode;
|
13 |
+
|
14 |
+
// initialize an instance of NavigatorThumbnailSidebar object
|
15 |
+
this.thumbnailSidebar = new NavigatorThumbnailSidebar();
|
16 |
+
|
17 |
+
// initialize an instance of NavigatorThumbnailScroller object
|
18 |
+
this.thumbnailScroller = new NavigatorThumbnailScroller();
|
19 |
+
|
20 |
+
// initialize an instance of NavigatorThumbnailSelection object
|
21 |
+
this.thumbnailSelection = new NavigatorThumbnailSelection();
|
22 |
+
|
23 |
+
// initialize an instance of NavigatorThumbnailContainer object
|
24 |
+
this.thumbnailContainer = new NavigatorThumbnailContainer();
|
25 |
+
|
26 |
+
this.thumbnailSidebar.domNode.appendChild(this.thumbnailScroller.domNode);
|
27 |
+
this.thumbnailScroller.domNode.appendChild(this.thumbnailSelection.domNode);
|
28 |
+
this.thumbnailScroller.domNode.appendChild(this.thumbnailContainer.domNode);
|
29 |
+
this.domNode.appendChild(this.thumbnailSidebar.domNode);
|
30 |
+
|
31 |
+
// create left sidebar to react to events
|
32 |
+
this.leftSidebar = new NavigatorLeftSidebar();
|
33 |
+
this.domNode.appendChild(this.leftSidebar.domNode);
|
34 |
+
|
35 |
+
// mouse events
|
36 |
+
Event.observe(this.domNode, "click", this.handleClickEvent.bind(this));
|
37 |
+
Event.observe(this.leftSidebar.domNode, "mouseover", this.handleMouseOverEvent.bind(this));
|
38 |
+
Event.observe(this.domNode, "mouseleave", this.handleMouseOutEvent.bind(this));
|
39 |
+
|
40 |
+
// events
|
41 |
+
document.observe(kSlideIndexDidChangeEvent, this.handleSlideIndexDidChangeEvent.bind(this));
|
42 |
+
document.observe(kScriptDidDownloadEvent, this.handleScriptDidDownloadEvent.bind(this));
|
43 |
+
|
44 |
+
this.slideThumbnail = null;
|
45 |
+
},
|
46 |
+
|
47 |
+
initScrollbar: function(){
|
48 |
+
if (this.thumbnailScroller.domNode.scrollHeight > this.thumbnailScroller.domNode.offsetHeight) {
|
49 |
+
this.thumbnailScroller.domNode.style.width = "126px";
|
50 |
+
} else {
|
51 |
+
this.thumbnailScroller.domNode.style.width = "129px";
|
52 |
+
}
|
53 |
+
|
54 |
+
// adjust navigator width for IE
|
55 |
+
// see <rdar://problem/12511461> IE9/10: Navigator scroll bar touching slide thumbnails while in show mode
|
56 |
+
if (browserPrefix === "ms") {
|
57 |
+
this.domNode.style.width = "148px";
|
58 |
+
this.thumbnailSidebar.domNode.style.left = "-148px";
|
59 |
+
this.thumbnailSidebar.domNode.style.width = "137px";
|
60 |
+
this.thumbnailScroller.domNode.style.width = "137px";
|
61 |
+
}
|
62 |
+
},
|
63 |
+
|
64 |
+
handleClickEvent: function(event) {
|
65 |
+
if (gShowController.isRecording) {
|
66 |
+
return;
|
67 |
+
}
|
68 |
+
|
69 |
+
event = event || window.event;
|
70 |
+
var target = event.target || event.srcElement;
|
71 |
+
var slideNumber;
|
72 |
+
|
73 |
+
// stop event from propagating up
|
74 |
+
if (browserPrefix === "ms") {
|
75 |
+
event.cancelBubble = true;
|
76 |
+
} else {
|
77 |
+
event.stopPropagation();
|
78 |
+
}
|
79 |
+
|
80 |
+
while ((target.slideNumber == null) && target.nodeName.toLowerCase() != 'body') {
|
81 |
+
target = target.parentNode;
|
82 |
+
}
|
83 |
+
|
84 |
+
if (target.slideNumber) {
|
85 |
+
this.selectedSlideIndex = target.slideNumber;
|
86 |
+
this.select(this.selectedSlideIndex);
|
87 |
+
}
|
88 |
+
},
|
89 |
+
|
90 |
+
select: function(slideIndex) {
|
91 |
+
gShowController.jumpToSlide(slideIndex);
|
92 |
+
},
|
93 |
+
|
94 |
+
handleMouseOverEvent: function(event) {
|
95 |
+
event = event || window.event;
|
96 |
+
|
97 |
+
// do not show navigator when the show is starting
|
98 |
+
var x = 0;
|
99 |
+
var y = 0;
|
100 |
+
if (event.pageX || event.pageY) {
|
101 |
+
x = event.pageX;
|
102 |
+
y = event.pageY;
|
103 |
+
} else if (event.clientX || event.clientY) {
|
104 |
+
x = event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft;
|
105 |
+
y = event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop;
|
106 |
+
}
|
107 |
+
|
108 |
+
if (x === 0 && y === 0) {
|
109 |
+
return;
|
110 |
+
}
|
111 |
+
|
112 |
+
// calculate thumbnailScroller scrollTop position
|
113 |
+
var position = this.selectedSlideIndex * 76;
|
114 |
+
var scrollTop = this.thumbnailScroller.domNode.scrollTop;
|
115 |
+
var height = this.thumbnailScroller.domNode.clientHeight;
|
116 |
+
|
117 |
+
if (scrollTop > position) {
|
118 |
+
this.thumbnailScroller.domNode.scrollTop = position;
|
119 |
+
} else if (scrollTop + height < position + 76) {
|
120 |
+
var minimumScrollingAmount = position - scrollTop - height + 76;
|
121 |
+
this.thumbnailScroller.domNode.scrollTop = this.thumbnailScroller.domNode.scrollTop + minimumScrollingAmount;
|
122 |
+
}
|
123 |
+
|
124 |
+
clearTimeout(this.navigatorTimeout);
|
125 |
+
this.navigatorTimeout = setTimeout(this.thumbnailSidebar.show.bind(this.thumbnailSidebar, this.leftSidebar), 400);
|
126 |
+
},
|
127 |
+
|
128 |
+
handleMouseOutEvent: function(event) {
|
129 |
+
clearTimeout(this.navigatorTimeout);
|
130 |
+
|
131 |
+
this.navigatorTimeout = setTimeout(this.thumbnailSidebar.hide.bind(this.thumbnailSidebar, this.leftSidebar), 400);
|
132 |
+
},
|
133 |
+
|
134 |
+
handleSlideIndexDidChangeEvent: function(event) {
|
135 |
+
this.selectedSlideIndex = event.memo.slideIndex;
|
136 |
+
|
137 |
+
this.thumbnailSelection.select(this.selectedSlideIndex);
|
138 |
+
},
|
139 |
+
|
140 |
+
handleScriptDidDownloadEvent: function(event) {
|
141 |
+
var script = event.memo.script;
|
142 |
+
|
143 |
+
for (var i = 0, length = script.slideList.length; i < length; i++) {
|
144 |
+
var slideId = script.slideList[i];
|
145 |
+
|
146 |
+
// initialize thumbnail item
|
147 |
+
var thumbnailItem = new NavigatorThumbnailItem();
|
148 |
+
thumbnailItem.domNode.slideNumber = i + 1;
|
149 |
+
thumbnailItem.numberNode.innerHTML = i + 1;
|
150 |
+
setElementProperty(thumbnailItem.domNode, "top", i * 76 + "px");
|
151 |
+
this.thumbnailContainer.addItem(thumbnailItem);
|
152 |
+
|
153 |
+
// do not request thumbnails when delegate will be providing
|
154 |
+
if (gShowController.delegate.getKPFJsonStringForShow == null) {
|
155 |
+
// create slide img object
|
156 |
+
var src = "../" + slideId + "/thumbnail.jpeg";
|
157 |
+
var img = document.createElement("img");
|
158 |
+
Event.observe(img, "load", this.updateThumbnail.bind(this, i, img));
|
159 |
+
img.src = src;
|
160 |
+
} else {
|
161 |
+
gShowController.delegate.loadTextureBySlideIndex(
|
162 |
+
i,
|
163 |
+
{
|
164 |
+
"type": "slideThumbnail",
|
165 |
+
"state":"outgoing"
|
166 |
+
},
|
167 |
+
(function (slideIndex, domNode){
|
168 |
+
this.updateThumbnail(slideIndex, domNode);
|
169 |
+
}).bind(this, i));
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
this.initScrollbar();
|
174 |
+
},
|
175 |
+
|
176 |
+
updateThumbnail: function(slideIndex, domNode){
|
177 |
+
var canvasContainer = this.thumbnailContainer.thumbnailItems[slideIndex].canvasContainer;
|
178 |
+
|
179 |
+
if (this.slideThumbnail == null) {
|
180 |
+
var originalSlideWidth = gShowController.script.originalSlideWidth;
|
181 |
+
var originalSlideHeight = gShowController.script.originalSlideHeight;
|
182 |
+
var aspectRatio = originalSlideWidth / originalSlideHeight;
|
183 |
+
var width, height;
|
184 |
+
|
185 |
+
if (aspectRatio >= 4/3) {
|
186 |
+
width = 88;
|
187 |
+
height = Math.ceil(88 * (1/aspectRatio));
|
188 |
+
} else {
|
189 |
+
width = Math.ceil(66 * aspectRatio);
|
190 |
+
height = 66;
|
191 |
+
}
|
192 |
+
|
193 |
+
this.slideThumbnail = {
|
194 |
+
width: width,
|
195 |
+
height: height,
|
196 |
+
top: Math.ceil((66 - height)/2),
|
197 |
+
left: Math.ceil((88 - width)/2),
|
198 |
+
scaleX: width / originalSlideWidth,
|
199 |
+
scaleY: height / originalSlideHeight
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
if (domNode.nodeName.toLowerCase() === "svg") {
|
204 |
+
domNode.firstElementChild.setAttribute("transform", "matrix(" + this.slideThumbnail.scaleX + ",0,0," + this.slideThumbnail.scaleY + ",0,0)");
|
205 |
+
}
|
206 |
+
|
207 |
+
domNode.setAttribute("style", kTransitionPropertyName + ":opacity; " + kTransitionDurationName + ":500; width:" + this.slideThumbnail.width + "px; height:" + this.slideThumbnail.height + "px; left:" + this.slideThumbnail.left + "px; top:" + this.slideThumbnail.top + "px; opacity: 0; position: absolute;");
|
208 |
+
|
209 |
+
// prevent the thumbnail from being dragged
|
210 |
+
domNode.setAttribute("draggable", false);
|
211 |
+
|
212 |
+
if (browserPrefix === "moz") {
|
213 |
+
Event.observe(domNode, "dragstart", function(e){e.preventDefault();});
|
214 |
+
}
|
215 |
+
|
216 |
+
canvasContainer.appendChild(domNode);
|
217 |
+
domNode.style.opacity = 1;
|
218 |
+
}
|
219 |
+
});
|
220 |
+
|
221 |
+
var NavigatorLeftSidebar = Class.create({
|
222 |
+
initialize: function() {
|
223 |
+
this.domNode = document.createElement("div");
|
224 |
+
this.domNode.setAttribute("class", "navigatorLeftSidebar");
|
225 |
+
}
|
226 |
+
});
|
227 |
+
|
228 |
+
var NavigatorThumbnailSidebar = Class.create({
|
229 |
+
initialize: function() {
|
230 |
+
// root node for the sidebar
|
231 |
+
this.domNode = document.createElement("div");
|
232 |
+
this.domNode.setAttribute("class", "navigatorThumbnailSidebar");
|
233 |
+
},
|
234 |
+
|
235 |
+
show: function(leftSidebar) {
|
236 |
+
leftSidebar.domNode.style.visibility = "hidden";
|
237 |
+
this.domNode.style.left = "0px";
|
238 |
+
gShowController.displayManager.navigatorIsShowing = true;
|
239 |
+
gShowController.displayManager.clearTimeoutForCursor();
|
240 |
+
},
|
241 |
+
|
242 |
+
hide: function(leftSidebar) {
|
243 |
+
leftSidebar.domNode.style.visibility = "visible";
|
244 |
+
this.domNode.style.left = "-140px";
|
245 |
+
gShowController.displayManager.navigatorIsShowing = false;
|
246 |
+
gShowController.displayManager.setTimeoutForCursor();
|
247 |
+
}
|
248 |
+
|
249 |
+
});
|
250 |
+
|
251 |
+
var NavigatorThumbnailScroller = Class.create({
|
252 |
+
initialize: function() {
|
253 |
+
// root node for the scroller
|
254 |
+
this.domNode = document.createElement("div");
|
255 |
+
this.domNode.setAttribute("class", "navigatorThumbnailScroller");
|
256 |
+
}
|
257 |
+
});
|
258 |
+
|
259 |
+
var NavigatorThumbnailSelection = Class.create({
|
260 |
+
initialize: function(params) {
|
261 |
+
this.domNode = document.createElement("div");
|
262 |
+
this.domNode.setAttribute("class", "navigatorThumbnailSelection");
|
263 |
+
},
|
264 |
+
|
265 |
+
select: function(slideIndex) {
|
266 |
+
this.domNode.style.top = 76 * slideIndex + "px";
|
267 |
+
this.domNode.style.display = "block";
|
268 |
+
}
|
269 |
+
|
270 |
+
});
|
271 |
+
|
272 |
+
var NavigatorThumbnailContainer = Class.create({
|
273 |
+
initialize: function() {
|
274 |
+
// thumbnail container domNode
|
275 |
+
this.domNode = document.createElement("div");
|
276 |
+
this.domNode.setAttribute("class", "navigatorThumbnailContainer");
|
277 |
+
|
278 |
+
// item container
|
279 |
+
this.thumbnailItems = [];
|
280 |
+
},
|
281 |
+
|
282 |
+
addItem: function(thumbnailItem) {
|
283 |
+
this.thumbnailItems.push(thumbnailItem);
|
284 |
+
this.domNode.appendChild(thumbnailItem.domNode);
|
285 |
+
}
|
286 |
+
|
287 |
+
});
|
288 |
+
|
289 |
+
var NavigatorThumbnailItem = Class.create({
|
290 |
+
initialize: function() {
|
291 |
+
// thumbnail item root
|
292 |
+
this.domNode = document.createElement("div");
|
293 |
+
this.domNode.setAttribute("class", "navigatorThumbnailItem");
|
294 |
+
|
295 |
+
// thumbnail content node
|
296 |
+
this.thumbnailContentNode = document.createElement("div");
|
297 |
+
this.thumbnailContentNode.setAttribute("style", "position: absolute; height: 76px; width: 119px;");
|
298 |
+
|
299 |
+
// number node
|
300 |
+
this.numberNode = document.createElement("div");
|
301 |
+
this.numberNode.setAttribute("style", "position: absolute; bottom: 1px; width: 20px; height: 20px; text-align: right; font-weight: bold; color: white;");
|
302 |
+
|
303 |
+
// image node
|
304 |
+
this.imageNode = document.createElement("div");
|
305 |
+
this.imageNode.setAttribute("style", "position: absolute; left: 24px; width: 95px; height: 76px;");
|
306 |
+
|
307 |
+
// thumb node
|
308 |
+
this.thumb = document.createElement("div");
|
309 |
+
this.thumb.setAttribute("style", "position: absolute; top: 4px; width: 90px; height: 68px;");
|
310 |
+
|
311 |
+
// create canvas container object
|
312 |
+
this.canvasContainer = document.createElement("div");
|
313 |
+
this.canvasContainer.setAttribute("class", "navigatorThumbnailItemCanvasContainer");
|
314 |
+
|
315 |
+
// add thumbnail image
|
316 |
+
this.thumb.appendChild(this.canvasContainer);
|
317 |
+
this.imageNode.appendChild(this.thumb);
|
318 |
+
|
319 |
+
this.thumbnailContentNode.appendChild(this.numberNode);
|
320 |
+
this.thumbnailContentNode.appendChild(this.imageNode);
|
321 |
+
|
322 |
+
this.domNode.appendChild(this.thumbnailContentNode);
|
323 |
+
}
|
324 |
+
|
325 |
+
});
|
assets/player/OrientationController.js
CHANGED
@@ -1,3 +1,40 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* OrientationController.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Responsibility: Tungwei Cheng
|
6 |
+
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var kOrientationChangedEvent = "OrientationController:OrientationChangedEvent";
|
10 |
+
|
11 |
+
var OrientationController = Class.create({
|
12 |
+
initialize: function() {
|
13 |
+
if (gDevice == kDeviceMobile) {
|
14 |
+
Event.observe(window, "orientationchange", this.handleDeviceOrientationChangeEvent.bind(this));
|
15 |
+
this.handleDeviceOrientationChangeEvent();
|
16 |
+
}
|
17 |
+
|
18 |
+
this.orientation = kOrientationUnknown;
|
19 |
+
},
|
20 |
+
|
21 |
+
handleDeviceOrientationChangeEvent: function(event) {
|
22 |
+
var orientationInDegrees = window.orientation;
|
23 |
+
var newOrientation = kOrientationUnknown;
|
24 |
+
|
25 |
+
if ((orientationInDegrees === 0) || (orientationInDegrees === 180)) {
|
26 |
+
newOrientation = kOrientationPortrait;
|
27 |
+
} else {
|
28 |
+
newOrientation = kOrientationLandscape;
|
29 |
+
}
|
30 |
+
this.changeOrientation(newOrientation);
|
31 |
+
},
|
32 |
+
|
33 |
+
changeOrientation: function(newOrientation) {
|
34 |
+
this.orientation = newOrientation;
|
35 |
+
|
36 |
+
document.fire(kOrientationChangedEvent, {
|
37 |
+
orientation: this.orientation
|
38 |
+
});
|
39 |
+
}
|
40 |
+
});
|
assets/player/ScriptManager.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:1a581c64572e658d757efaed895f2d374231bb1d29efb30b1c193de87332fb6d
|
3 |
-
size 24503
|
|
|
1 |
+
var kShowSizeDidChangeEvent="ScriptManager:ShowSizeDidChangeEvent";var kScriptDidDownloadEvent="ScriptManager:ScriptDidDownloadEvent";var kScriptDidNotDownloadEvent="ScriptManager:ScriptDidNotDownloadEvent";var kSlideDidDownloadEvent="SlideManager:SlideDidDownloadEvent";var kSlideDidNotDownloadEvent="SlideManager:SlideDidNotDownloadEvent";var ScriptManager=Class.create({initialize:function(a){this.script=null;this.showUrl=a;this.slideManager=null;document.observe(kSlideDidDownloadEvent,this.handleSlideDidDownloadEvent.bind(this));document.observe(kSlideDidNotDownloadEvent,this.handleSlideDidDownloadEvent.bind(this))},handleSlideDidDownloadEvent:function(c){var k=true;for(var l in this.slideManager.slides){if(this.slideManager.slides.hasOwnProperty(l)){if(!this.slideManager.slides[l].downloaded){k=false;break}}}if(k){this.script.events=[];this.script.originalEvents=[];this.script.slideIndexFromSceneIndexLookup={};this.script.sceneIndexFromSlideIndexLookup={};this.script.slides={};this.script.originalSlides={};var m,g,h,f,j=0,b=0,a=0;for(var l in this.slideManager.slides){if(this.slideManager.slides.hasOwnProperty(l)){h=this.slideManager.slides[l].script;f=this.slideManager.slides[l].originalScript;m=h.events;g=f.events;this.script.slides[l]=h;this.script.originalSlides[l]=f;this.script.sceneIndexFromSlideIndexLookup[j]=b;for(var e=0,d=m.length;e<d;e++){this.script.events.push(m[e]);this.script.originalEvents.push(g[e]);this.script.slideIndexFromSceneIndexLookup[a]=j;a+=1}j+=1;b=a}}this.script.numScenes=this.script.events.length;this.script.lastSceneIndex=this.script.numScenes-1;this.script.lastSlideIndex=this.script.slideList.length-1;this.script.originalSlideWidth=this.script.slideWidth;this.script.originalSlideHeight=this.script.slideHeight;if(isIE||isEdge){this.adjustScriptForIE()}else{this.adjustScript()}if(this.delegate.setViewScale){this.applyScaleFactor();this.delegate.setViewScale(this.scaleFactor)}document.fire(kScriptDidDownloadEvent,{script:this.script,delegate:this.delegate});document.fire(kShowSizeDidChangeEvent,{width:this.script.slideWidth,height:this.script.slideHeight})}},adjustScript:function(){for(var c=0,f=this.script.events.length;c<f;c++){var d=this.script.events[c];var e=this.script.originalEvents[c];for(var h=0,o=d.effects.length;h<o;h++){var s=d.effects[h];var m=e.effects[h];this.adjustEffects(s,m);this.adjustEmphasisBuilds(s,m);if(isChrome){this.adjustEffectsForChrome(s,m)}if(browserPrefix==="moz"){this.adjustEffectsForFirefox(s,m)}}for(var h=0,b=d.hyperlinks.length;h<b;h++){var q=d.hyperlinks[h];var n=e.hyperlinks[h];for(var r in q.events){var k=q.events[r];var l=n.events[r];for(var g=0,o=k.effects.length;g<o;g++){var p=k.effects[g];var a=l.effects[g];this.adjustEffects(p,a);this.adjustEmphasisBuilds(p,a);if(isChrome){this.adjustEffectsForChrome(s,m)}if(browserPrefix==="moz"){this.adjustEffectsForFirefox(s,m)}}}}}},adjustEffects:function(d,a){switch(d.name){case"com.apple.iWork.Keynote.BLTBlinds":if(d.type==="transition"){var c=a.baseLayer.layers[0];var f=d.baseLayer.layers[0];f.layers.splice(0,2);c.layers.splice(0,2)}break;case"apple:apple-grid":var c=a.baseLayer.layers[0];var f=d.baseLayer.layers[0];f.layers.splice(0,2);c.layers.splice(0,2);break;case"com.apple.iWork.Keynote.BLTSwoosh":var c=a.baseLayer.layers[0];var f=d.baseLayer.layers[0];if(d.type==="transition"){f.layers[1].layers[0].layers.splice(0,1);c.layers[1].layers[0].layers.splice(0,1);var b=c.layers[1];c.layers[1]=c.layers[2];c.layers[2]=b;var e=f.layers[1];f.layers[1]=f.layers[2];f.layers[2]=e}break;default:break}},adjustEmphasisBuilds:function(q,o){switch(q.name){case"apple:action-jiggle":var m=o.baseLayer.layers[0];var n=q.baseLayer.layers[0];if(!m.animations[0]){m=o.baseLayer.layers[0].layers[0];n=q.baseLayer.layers[0].layers[0]}var b=m.animations[0];var f=n.animations[0];var a=f.animations.length;for(var h=0;h<a;h++){var l=Math.ceil(f.duration/f.animations[h].duration);for(var g=0;g<l-1;g++){var p=JSON.parse(JSON.stringify(b.animations[h]));var e=JSON.parse(JSON.stringify(f.animations[h]));p.beginTime=b.animations[h].duration*(g+1);e.beginTime=f.animations[h].duration*(g+1);m.animations[0].animations.push(p);n.animations[0].animations.push(e);if(g===l-2){p.duration=f.duration-p.beginTime;e.duration=f.duration-e.beginTime;if(f.animations[h].property==="transform.rotation.z"){p.to.scalar=0;e.to.scalar=0}else{if(f.animations[h].property==="position"){p.to.pointX=(p.from.pointX+p.to.pointX)/2;e.to.pointX=(e.from.pointX+e.to.pointX)/2}}}}}break;default:break}for(var d=0,c=q.effects.length;d<c;d++){this.adjustEmphasisBuilds(q.effects[d],o.effects[d])}},adjustEffectsForChrome:function(m,o){switch(m.name){case"apple:fall":var k=o.baseLayer.layers[0];var g=m.baseLayer.layers[0];var l=k.layers[1].animations[0].beginTime;var i=k.layers[1].animations[0].duration;if(!k.layers[1].animations[0].animations){break}var d={animations:[],beginTime:l,duration:i-0.01,fillMode:"forwards",from:{scalar:1},property:"transform.translation.z",timingFunction:"linear",to:{scalar:1}};var n={animations:[],beginTime:i-0.01,duration:0.01,fillMode:"forwards",from:{scalar:-1},property:"transform.translation.z",timingFunction:"linear",to:{scalar:-1}};k.layers[1].animations[0].animations.push(d);g.layers[1].animations[0].animations.push(d);k.layers[1].animations[0].animations.push(n);g.layers[1].animations[0].animations.push(n);break;case"apple:scale":var k=o.baseLayer.layers[0];var g=m.baseLayer.layers[0];if(k.layers[0].animations.length>0){var t=k.layers[0];k.layers[0]=k.layers[1];k.layers[1]=t;k.layers[1].initialState.hidden=true;var p=g.layers[0];g.layers[0]=g.layers[1];g.layers[1]=p;g.layers[1].initialState.hidden=true;var l=k.layers[1].animations[0].beginTime;var i=k.layers[1].animations[0].duration;var q=k.layers[1].animations[0].animations[0].beginTime;var a=k.layers[1].animations[0].animations[0].duration;var c;if(l==q){for(var r=0,h=k.layers[1].animations[0].animations.length;r<h;r++){if(k.layers[1].animations[0].animations[r].property==="transform.translation.z"){k.layers[1].animations[0].animations.splice(r,1);g.layers[1].animations[0].animations.splice(r,1)}}c={animations:[],beginTime:l,duration:i,fillMode:"forwards",from:{scalar:false},property:"hidden",timingFunction:"linear",to:{scalar:false}};k.layers[1].animations[0].animations.push(c);g.layers[1].animations[0].animations.push(c)}else{for(var r=0,h=k.layers[1].animations[0].animations[0].animations.length;r<h;r++){if(k.layers[1].animations[0].animations[0].animations[r].property==="transform.translation.z"){k.layers[1].animations[0].animations[0].animations.splice(r,1);g.layers[1].animations[0].animations[0].animations.splice(r,1)}}c={animations:[],beginTime:k.layers[1].animations[0].animations[0].animations[0].beginTime+0.03,duration:k.layers[1].animations[0].animations[0].animations[0].duration,fillMode:"forwards",from:{scalar:false},property:"hidden",timingFunction:"linear",to:{scalar:false}};k.layers[1].animations[0].animations[0].animations.push(c);g.layers[1].animations[0].animations[0].animations.push(c)}}break;case"com.apple.iWork.Keynote.KLNSwap":var k=o.baseLayer.layers[0];var g=m.baseLayer.layers[0];var a,f,s,b,e;if(k.layers[1].animations[0].animations.length>1){for(var r=0,h=k.layers[1].animations[0].animations.length;r<h;r++){b=k.layers[1].animations[0].animations[r];e=g.layers[1].animations[0].animations[r];if(b.property==="opacity"){break}}a=k.layers[1].animations[0].duration}else{for(var r=0,h=k.layers[1].animations[0].animations[0].animations.length;r<h;r++){b=k.layers[1].animations[0].animations[0].animations[r];e=g.layers[1].animations[0].animations[0].animations[r];if(b.property==="opacity"){break}}a=k.layers[1].animations[0].animations[0].duration}f=a*0.4;s=a*0.4;b.to.scalar=0;b.beginTime=f;b.duration=s;e.to.scalar=0;e.beginTime=f;e.duration=s;break;default:break}},adjustEffectsForFirefox:function(r,m){switch(r.name){case"apple:scale":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];if(q.layers[0].animations.length>0){var l=q.layers[0];q.layers[0]=q.layers[1];q.layers[1]=l;q.layers[1].initialState.hidden=true;var f=k.layers[0];k.layers[0]=k.layers[1];k.layers[1]=f;k.layers[1].initialState.hidden=true;var a=q.layers[1].animations[0].beginTime;var c=q.layers[1].animations[0].duration;var h=q.layers[1].animations[0].animations[0].beginTime;var e=q.layers[1].animations[0].animations[0].duration;var i;if(a==h){for(var g=0,o=q.layers[1].animations[0].animations.length;g<o;g++){if(q.layers[1].animations[0].animations[g].property==="transform.translation.z"){q.layers[1].animations[0].animations.splice(g,1);k.layers[1].animations[0].animations.splice(g,1)}}i={animations:[],beginTime:a,duration:c,fillMode:"forwards",from:{scalar:false},property:"hidden",timingFunction:"linear",to:{scalar:false}};q.layers[1].animations[0].animations.push(i);k.layers[1].animations[0].animations.push(i)}else{for(var g=0,o=q.layers[1].animations[0].animations[0].animations.length;g<o;g++){if(q.layers[1].animations[0].animations[0].animations[g].property==="transform.translation.z"){q.layers[1].animations[0].animations[0].animations.splice(g,1);k.layers[1].animations[0].animations[0].animations.splice(g,1)}}i={animations:[],beginTime:q.layers[1].animations[0].animations[0].animations[0].beginTime+0.03,duration:q.layers[1].animations[0].animations[0].animations[0].duration,fillMode:"forwards",from:{scalar:false},property:"hidden",timingFunction:"linear",to:{scalar:false}};q.layers[1].animations[0].animations[0].animations.push(i);k.layers[1].animations[0].animations[0].animations.push(i)}}break;case"com.apple.iWork.Keynote.KLNSwap":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];var e,d,n,b,p;if(q.layers[1].animations[0].animations.length>1){for(var g=0,o=q.layers[1].animations[0].animations.length;g<o;g++){b=q.layers[1].animations[0].animations[g];p=k.layers[1].animations[0].animations[g];if(b.property==="opacity"){break}}e=q.layers[1].animations[0].duration}else{for(var g=0,o=q.layers[1].animations[0].animations[0].animations.length;g<o;g++){b=q.layers[1].animations[0].animations[0].animations[g];p=k.layers[1].animations[0].animations[0].animations[g];if(b.property==="opacity"){break}}e=q.layers[1].animations[0].animations[0].duration}d=e*0.4;n=e*0.4;b.to.scalar=0;b.beginTime=d;b.duration=n;p.to.scalar=0;p.beginTime=d;p.duration=n;break;default:break}},adjustScriptForIE:function(){for(var c=0,f=this.script.events.length;c<f;c++){var d=this.script.events[c];var e=this.script.originalEvents[c];for(var h=0,o=d.effects.length;h<o;h++){var s=d.effects[h];var m=e.effects[h];this.adjustEffectsForIE(s,m);this.adjustEmphasisBuilds(s,m)}for(var h=0,b=d.hyperlinks.length;h<b;h++){var q=d.hyperlinks[h];var n=e.hyperlinks[h];for(var r in q.events){var k=q.events[r];var l=n.events[r];for(var g=0,o=k.effects.length;g<o;g++){var p=k.effects[g];var a=l.effects[g];this.adjustEffectsForIE(p,a);this.adjustEmphasisBuilds(p,a)}}}}},adjustEffectsForIE:function(r,m){switch(r.name){case"apple:bounce":case"apple:slide":case"apple:pivot":case"apple:scale":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];if(q.layers[0].animations.length>0){var l=q.layers[0];q.layers[0]=q.layers[1];q.layers[1]=l;q.layers[1].initialState.hidden=true;var f=k.layers[0];k.layers[0]=k.layers[1];k.layers[1]=f;k.layers[1].initialState.hidden=true;var a=q.layers[1].animations[0].beginTime;var c=q.layers[1].animations[0].duration;var h=q.layers[1].animations[0].animations[0].beginTime;var e=q.layers[1].animations[0].animations[0].duration;var i;if(a==h){for(var g=0,o=q.layers[1].animations[0].animations.length;g<o;g++){if(q.layers[1].animations[0].animations[g].property==="transform.translation.z"){q.layers[1].animations[0].animations.splice(g,1);k.layers[1].animations[0].animations.splice(g,1)}}i={animations:[],beginTime:a,duration:c,fillMode:"forwards",from:{scalar:false},property:"hidden",timingFunction:"linear",to:{scalar:false}};q.layers[1].animations[0].animations.push(i);k.layers[1].animations[0].animations.push(i)}else{for(var g=0,o=q.layers[1].animations[0].animations[0].animations.length;g<o;g++){if(q.layers[1].animations[0].animations[0].animations[g].property==="transform.translation.z"){q.layers[1].animations[0].animations[0].animations.splice(g,1);k.layers[1].animations[0].animations[0].animations.splice(g,1)}}i={animations:[],beginTime:q.layers[1].animations[0].animations[0].animations[0].beginTime+0.03,duration:q.layers[1].animations[0].animations[0].animations[0].duration,fillMode:"forwards",from:{scalar:false},property:"hidden",timingFunction:"linear",to:{scalar:false}};q.layers[1].animations[0].animations[0].animations.push(i);k.layers[1].animations[0].animations[0].animations.push(i)}}break;case"apple:doorway":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];var a=q.layers[0].animations[0].beginTime;var c=q.layers[0].animations[0].duration;var h=q.layers[0].animations[0].animations[0].beginTime;var e=q.layers[0].animations[0].animations[0].duration;q.layers[0].layers=[];q.layers[0].animations=[];k.layers[0].layers=[];k.layers[0].animations=[];if(a==h){q.layers[1].animations[0].animations[0].beginTime=h;q.layers[1].animations[0].animations[0].duration=e;k.layers[1].animations[0].animations[0].beginTime=h;k.layers[1].animations[0].animations[0].duration=e}else{q.layers[1].animations[0].animations[0].animations[0].duration=e;k.layers[1].animations[0].animations[0].animations[0].duration=e}q.layers.splice(2,1);k.layers.splice(2,1);break;case"com.apple.iWork.Keynote.BLTBlinds":case"apple:3D-cube":case"com.apple.iWork.Keynote.BLTReflection":case"apple:revolve":case"com.apple.iWork.Keynote.BLTRevolvingDoor":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];var p;p={animations:[],beginTime:0,duration:m.duration,fillMode:"both",from:{scalar:1},property:"opacity",timingFunction:"easeInEaseOut",to:{scalar:0}};q.layers[0].layers=[];q.layers[0].animations=[];q.layers[1].layers=[];q.layers[1].animations=[];q.layers[1].animations.push(p);k.layers[0].layers=[];k.layers[0].animations=[];k.layers[1].layers=[];k.layers[1].animations=[];k.layers[1].animations.push(p);if(r.name==="com.apple.iWork.Keynote.BLTBlinds"){q.layers[0].initialState.hidden=false;q.layers[1].initialState.hidden=false;k.layers[0].initialState.hidden=false;k.layers[1].initialState.hidden=false;q.layers.splice(2,q.layers.length-2);k.layers.splice(2,k.layers.length-2)}break;case"com.apple.iWork.Keynote.KLNSwap":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];var e,d,n,b,p;if(q.layers[1].animations[0].animations.length>1){for(var g=0,o=q.layers[1].animations[0].animations.length;g<o;g++){b=q.layers[1].animations[0].animations[g];p=k.layers[1].animations[0].animations[g];if(b.property==="opacity"){break}}e=q.layers[1].animations[0].duration}else{for(var g=0,o=q.layers[1].animations[0].animations[0].animations.length;g<o;g++){b=q.layers[1].animations[0].animations[0].animations[g];p=k.layers[1].animations[0].animations[0].animations[g];if(b.property==="opacity"){break}}e=q.layers[1].animations[0].animations[0].duration}d=e*0.4;n=e*0.4;b.to.scalar=0;b.beginTime=d;b.duration=n;p.to.scalar=0;p.beginTime=d;p.duration=n;break;case"apple:FlipThrough":var q=m.baseLayer.layers[0];var k=r.baseLayer.layers[0];if(q.layers[0].animations.length>0){var l=JSON.parse(JSON.stringify(q.layers[1]));q.layers.splice(0,0,l);var f=JSON.parse(JSON.stringify(k.layers[1]));k.layers.splice(0,0,f);var a=q.layers[1].animations[0].beginTime;var c=q.layers[1].animations[0].duration;var h=q.layers[1].animations[0].animations[0].beginTime;var e=q.layers[1].animations[0].animations[0].duration;var i;if(a==h){for(var g=0,o=q.layers[1].animations[0].animations.length;g<o;g++){if(q.layers[1].animations[0].animations[g].property==="transform.translation.z"){q.layers[1].animations[0].animations.splice(g,1);k.layers[1].animations[0].animations.splice(g,1)}}i={animations:[],beginTime:a+c/2,duration:c/2,fillMode:"forwards",from:{scalar:true},property:"hidden",timingFunction:"linear",to:{scalar:true}};q.layers[2].animations[0].animations.push(i);k.layers[2].animations[0].animations.push(i)}else{for(var g=0,o=q.layers[1].animations[0].animations[0].animations.length;g<o;g++){if(q.layers[1].animations[0].animations[0].animations[g].property==="transform.translation.z"){q.layers[1].animations[0].animations[0].animations.splice(g,1);k.layers[1].animations[0].animations[0].animations.splice(g,1)}}i={animations:[],beginTime:q.layers[2].animations[0].animations[0].animations[0].beginTime+q.layers[2].animations[0].animations[0].animations[0].duration/2,duration:q.layers[2].animations[0].animations[0].animations[0].duration/2,fillMode:"forwards",from:{scalar:true},property:"hidden",timingFunction:"linear",to:{scalar:true}};q.layers[2].animations[0].animations[0].animations.push(i);k.layers[2].animations[0].animations[0].animations.push(i)}}break;default:break}},handleSlideDidNotDownloadEvent:function(a){this.scriptDidNotDownload.bind(this)},reapplyScaleFactor:function(){if(this.delegate.setViewScale){this.applyScaleFactor();this.delegate.setViewScale(this.scaleFactor)}},applyScaleFactorForAnimation:function(c,b,g){var h=c.property;if(c.path){for(var e=0,k=c.path.length;e<k;e++){var j=c.path[e].points;var d=b.path[e].points;j[0][0]=d[0][0]*g;j[0][1]=d[0][1]*g}}switch(h){case"anchorPointZ":case"zPosition":case"transform.translation.x":case"transform.translation.y":if(c.from){c.from.scalar=b.from.scalar*g}if(c.to){c.to.scalar=b.to.scalar*g}if(c.values){for(var e=0,f=c.values.length;e<f;e++){c.values[e].scalar=b.values[e].scalar*g}}break;case"transform.translation.z":if(c.from&&c.from.scalar!=1&&c.from.scalar!=0.01){c.from.scalar=b.from.scalar*g}if(c.to&&c.to.scalar!=1&&c.to.scalar!=0.01){c.to.scalar=b.to.scalar*g}if(c.values){for(var e=0,f=c.values.length;e<f;e++){c.values[e].scalar=b.values[e].scalar*g}}break;case"position":case"transform.translation":if(c.from){c.from.pointX=b.from.pointX*g;c.from.pointY=b.from.pointY*g}if(c.to){c.to.pointX=b.to.pointX*g;c.to.pointY=b.to.pointY*g}if(c.values){for(var e=0,f=c.values.length;e<f;e++){c.values[e].pointX=b.values[e].pointX*g;c.values[e].pointY=b.values[e].pointY*g}}break;case"transform":if(c.from){c.from.transform[12]=b.from.transform[12]*g;c.from.transform[13]=b.from.transform[13]*g;c.from.transform[14]=b.from.transform[14]*g}if(c.to){c.to.transform[12]=b.to.transform[12]*g;c.to.transform[13]=b.to.transform[13]*g;c.to.transform[14]=b.to.transform[14]*g}if(c.values){for(var e=0,f=c.values.length;e<f;e++){c.values[e].transform[12]=b.values[e].transform[12]*g;c.values[e].transform[13]=b.values[e].transform[13]*g;c.values[e].transform[14]=b.values[e].transform[14]*g}}break;case"bounds":if(c.from){c.from.width=b.from.width*g;c.from.height=b.from.height*g}if(c.to){c.to.width=b.to.width*g;c.to.height=b.to.height*g}break;case"transform.scale.xy":case"transform.scale.x":case"transform.scale.y":break}if(c.animations){for(var e=0,a=c.animations.length;e<a;e++){this.applyScaleFactorForAnimation(c.animations[e],b.animations[e],g)}}},applyScaleFactorForLayer:function(g,f,l,k,j,h){var b=g.initialState;var d=f.initialState;var c=d.contentsRect;b.affineTransform[4]=d.affineTransform[4]*l;b.affineTransform[5]=d.affineTransform[5]*l;b.width=d.width*l;b.height=d.height*l;b.position.pointX=d.position.pointX*l;b.position.pointY=d.position.pointY*l;switch(k){case"com.apple.iWork.Keynote.BLTBlinds":case"com.apple.iWork.Keynote.BLTMosaicFlip":this.adjustForCropAnimation(b,c,h.particleCount.x,h.particleCount.y);break;default:break}if(g.animations){for(var e=0,a=g.animations.length;e<a;e++){this.applyScaleFactorForAnimation(g.animations[e],f.animations[e],l)}}for(var e=0,a=g.layers.length;e<a;e++){this.applyScaleFactorForLayer(g.layers[e],f.layers[e],l,k,j,h)}},applyScaleFactorForBaseLayer:function(b,c,f){var a=b.initialState;var g=c.initialState;a.affineTransform[4]=g.affineTransform[4]*f;a.affineTransform[5]=g.affineTransform[5]*f;a.width=g.width*f;a.height=g.height*f;a.position.pointX=g.position.pointX*f;a.position.pointY=g.position.pointY*f;for(var d=0,e=b.layers.length;d<e;d++){this.applyScaleFactorForBaseLayer(b.layers[d],c.layers[d],f)}},applyScaleFactor:function(){var y=this.script.originalSlideWidth;var F=this.script.originalSlideHeight;var s=window.innerWidth;var B=window.innerHeight;var L=scaleSizeWithinSize(y,F,s,B);var f=L.width;var o=L.height;var k=o/F;this.scaleFactor=k;this.script.slideWidth=this.script.originalSlideWidth*k;this.script.slideHeight=this.script.originalSlideHeight*k;for(var Q=0,q=this.script.events.length;Q<q;Q++){var T=this.script.events[Q];var u=this.script.originalEvents[Q];var K=this.script.slideIndexFromSceneIndexLookup[Q];var I=this.script.slideList[K];this.applyScaleFactorForBaseLayer(T.baseLayer,u.baseLayer,k);for(var O=0,c=T.effects.length;O<c;O++){var M=T.effects[O];var n=u.effects[O];var C={};if(M.name==="com.apple.iWork.Keynote.BLTMosaicFlip"||M.name==="com.apple.iWork.Keynote.BLTBlinds"){var G=0,g=0;for(var b=0,J=M.baseLayer.layers[0].layers.length;b<J;b++){var d=n.baseLayer.layers[0].layers[b];var e=d.initialState.contentsRect;var l=Math.round(e.x/e.width);var z=Math.round(e.y/e.height);if(l>G){G=l}if(z>g){g=z}}C.particleCount={x:G+1,y:g+1}}this.applyScaleFactorForLayer(M.baseLayer,n.baseLayer,k,M.name,I,C)}for(var O=0,t=T.hyperlinks.length;O<t;O++){var h=T.hyperlinks[O];var w=u.hyperlinks[O];var A=h.targetRectangle;var D=w.targetRectangle;A.y=D.y*k;A.x=D.x*k;A.width=D.width*k;A.height=D.height*k;for(var H in h.events){var m=h.events[H];var x=w.events[H];for(var N=0,c=m.effects.length;N<c;N++){var R=m.effects[N];var S=x.effects[N];var C={};if(R.name==="com.apple.iWork.Keynote.BLTMosaicFlip"||R.name==="com.apple.iWork.Keynote.BLTBlinds"){var G=0,g=0;for(var b=0,J=R.baseLayer.layers[0].layers.length;b<J;b++){var d=R.baseLayer.layers[0].layers[b];var e=d.initialState.contentsRect;var l=Math.round(e.x/e.width);var z=Math.round(e.y/e.height);if(l>G){G=l}if(z>g){g=z}}C.particleCount={x:G+1,y:g+1}}this.applyScaleFactorForLayer(R.baseLayer,S.baseLayer,k,R.name,I,C)}}}}for(var p in this.script.slides){if(this.script.slides.hasOwnProperty(p)){var a=this.script.slides[p];var v=this.script.originalSlides[p];for(var E in a.assets){if(a.assets.hasOwnProperty(E)){var r=a.assets[E];var P=v.assets[E];r.width=P.width*k;r.height=P.height*k}}}}},adjustForCropAnimation:function(a,b,i,h){var d=this.script.slideWidth;var f=this.script.slideHeight;var j=Math.floor(d/i);var g=Math.floor(f/h);var e=Math.round(b.x/b.width);var c=Math.round(b.y/b.height);if(b.width!=1||b.height!=1){if(e!=i-1){a.width=j}else{a.width=d-j*(i-1)}if(c!=h-1){a.height=g}else{a.height=f-g*(h-1)}a.position.pointX=j*e+a.width/2;a.position.pointY=g*c+a.height/2;a.contentsRect.x=j*e/d;a.contentsRect.y=g*c/f;a.contentsRect.width=a.width/d;a.contentsRect.height=a.height/f}},downloadScript:function(b){this.delegate=b;if(this.delegate.getKPFJsonStringForShow){this.script=JSON.parse(this.delegate.getKPFJsonStringForShow());if(this.script==null){debugMessageAlways(kDebugScriptMangaer_DownloadScript,"An error occured on the server. KPF header json is null.");return}this.slideManager=new SlideManager({header:this.script});this.slideManager.getSlides(this.script.slideList,this.delegate);return}this.downloadTimeout=setTimeout(this.scriptDidNotDownload.bind(this),kMaxScriptDownloadWaitTime);this.downloadAlreadyFailed=false;var c=this.showUrl+"header.json";if(window.location.protocol==="file:"){c=c+"p";window.local_header=(function(d){this.scriptDidDownload(d,true)}).bind(this);var a=document.createElement("script");a.setAttribute("src",c);document.head.appendChild(a)}else{new Ajax.Request(c,{method:"get",onSuccess:this.scriptDidDownload.bind(this),onFailure:this.scriptDidNotDownload.bind(this)})}},scriptDidDownload:function(b,a){clearTimeout(this.downloadTimeout);if(a){this.script=b}else{this.script=JSON.parse(b.responseText)}this.slideManager=new SlideManager({header:this.script});this.slideManager.downloadSlides(this.script.slideList)},scriptDidNotDownload:function(a){this.downloadAlreadyFailed=true;if(a){clearTimeout(this.downloadTimeout)}document.fire(kScriptDidNotDownloadEvent,{})},sceneIndexFromSlideIndex:function(a){if((this.script==null)||(a<0)||(a>=this.script.slideList.length)){return -1}return this.script.sceneIndexFromSlideIndexLookup[a]},slideIndexFromSceneIndex:function(a){if((this.script==null)||(a<0)||(a>=this.script.events.length)){return -1}return this.script.slideIndexFromSceneIndexLookup[a]}});
|
|
|
|
assets/player/ShowController.js
CHANGED
@@ -1,3 +1,2105 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* ShowController.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Responsibility: Tungwei Cheng
|
6 |
+
* Copyright (c) 2009-2016 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var kShowControllerState_Stopped = "Stopped";
|
10 |
+
var kShowControllerState_Starting = "Starting";
|
11 |
+
var kShowControllerState_DownloadingScript = "DownloadingScipt";
|
12 |
+
var kShowControllerState_SettingUpScene = "SettingUpScene";
|
13 |
+
var kShowControllerState_IdleAtFinalState = "IdleAtFinalState";
|
14 |
+
var kShowControllerState_IdleAtInitialState = "IdleAtInitialState";
|
15 |
+
var kShowControllerState_WaitingToJump = "WaitingToJump";
|
16 |
+
var kShowControllerState_ReadyToJump = "ReadyToJump";
|
17 |
+
var kShowControllerState_WaitingToDisplay = "WaitingToDisplay";
|
18 |
+
var kShowControllerState_ReadyToDisplay = "ReadyToDisplay";
|
19 |
+
var kShowControllerState_WaitingToPlay = "WaitingToPlay";
|
20 |
+
var kShowControllerState_ReadyToPlay = "ReadyToPlay";
|
21 |
+
var kShowControllerState_Playing = "Playing";
|
22 |
+
|
23 |
+
// Events:
|
24 |
+
// -------
|
25 |
+
var kKeyDownEvent = "keydown";
|
26 |
+
var kSlideIndexDidChangeEvent = "ShowController:SlideIndexDidChangeEvent";
|
27 |
+
|
28 |
+
var ShowController = Class.create({
|
29 |
+
initialize: function() {
|
30 |
+
// extract delegate from url or create a default delegate
|
31 |
+
this.delegate = extractDelegateFromUrlParameter();
|
32 |
+
this.delegate.showDidLoad();
|
33 |
+
|
34 |
+
this.showUrl = "../";
|
35 |
+
|
36 |
+
// These must be created before the OrientationController as they
|
37 |
+
// subscribe to its event
|
38 |
+
this.displayManager = new DisplayManager();
|
39 |
+
this.scriptManager = new ScriptManager(this.showUrl);
|
40 |
+
this.textureManager = new TextureManager(this.showUrl);
|
41 |
+
this.stageManager = new StageManager(this.textureManager, this.scriptManager);
|
42 |
+
this.touchController = new TouchController();
|
43 |
+
this.animationManager = new AnimationManager();
|
44 |
+
this.orientationController = new OrientationController();
|
45 |
+
|
46 |
+
this.activeHyperlinks = new Array();
|
47 |
+
this.movieHyperlinks = new Array();
|
48 |
+
|
49 |
+
// initialize default values
|
50 |
+
this.script = null;
|
51 |
+
this.currentSceneIndex = -1;
|
52 |
+
this.nextSceneIndex = -1;
|
53 |
+
this.currentSlideIndex = -1;
|
54 |
+
this.previousSlideIndex = -1;
|
55 |
+
this.currentSoundTrackIndex = 0;
|
56 |
+
this.transformOriginValue = "";
|
57 |
+
this.accumulatingDigits = false;
|
58 |
+
this.digitAccumulator = 0;
|
59 |
+
this.firstSlide = true;
|
60 |
+
this.lastSlideViewedIndex = -1;
|
61 |
+
|
62 |
+
this.accountID = "";
|
63 |
+
this.guid = "";
|
64 |
+
this.locale = "EN";
|
65 |
+
this.isNavigationBarVisible = false;
|
66 |
+
this.isFullscreen = false;
|
67 |
+
this.volume = 3.0;
|
68 |
+
this.muted = false;
|
69 |
+
|
70 |
+
this.soundTrackPlayer = null;
|
71 |
+
this.sceneIndexOfPrebuiltAnimations = -1;
|
72 |
+
|
73 |
+
// store queued user action
|
74 |
+
this.queuedUserAction = null;
|
75 |
+
|
76 |
+
// events
|
77 |
+
document.observe(kScriptDidDownloadEvent, this.handleScriptDidDownloadEvent.bind(this));
|
78 |
+
document.observe(kScriptDidNotDownloadEvent, this.handleScriptDidNotDownloadEvent.bind(this));
|
79 |
+
document.observe(kStageIsReadyEvent, this.handleStageIsReadyEvent.bind(this));
|
80 |
+
document.observe(kStageSizeDidChangeEvent, this.handleStageSizeDidChangeEvent.bind(this));
|
81 |
+
|
82 |
+
// swipe and keydown events
|
83 |
+
document.observe(kKeyDownEvent, this.handleKeyDownEvent.bind(this));
|
84 |
+
document.observe(kSwipeEvent, this.handleSwipeEvent.bind(this));
|
85 |
+
|
86 |
+
// mouse event
|
87 |
+
Event.observe(this.displayManager.body, "click", this.handleClickEvent.bind(this));
|
88 |
+
|
89 |
+
// fullscreen change event
|
90 |
+
document.observe(kFullscreenChangeEventName, this.handleFullscreenChangeEvent.bind(this));
|
91 |
+
|
92 |
+
// windows resize event
|
93 |
+
Event.observe(window, "resize", this.handleWindowResizeEvent.bind(this));
|
94 |
+
|
95 |
+
// Can't use event observer for tap events
|
96 |
+
// - this would cause the handler to be on a seperate event loop
|
97 |
+
// invocation
|
98 |
+
// - this would prevent us from doing this like opening new tabs (popup
|
99 |
+
// blocker logic kicks in)
|
100 |
+
this.touchController.registerTapEventCallback(this.handleTapEvent.bind(this));
|
101 |
+
|
102 |
+
// Initialize state to Stopped
|
103 |
+
this.changeState(kShowControllerState_Stopped);
|
104 |
+
|
105 |
+
// movie cache to be used across different event timeline within one slide
|
106 |
+
this.movieCache = null;
|
107 |
+
|
108 |
+
// audio cache
|
109 |
+
this.audioCache = null;
|
110 |
+
|
111 |
+
// KPF playback controller
|
112 |
+
this.playbackController = new KPFPlaybackController({}, this.stageManager.stage);
|
113 |
+
|
114 |
+
// Navigator
|
115 |
+
this.navigatorController = new NavigatorController(document.getElementById("slideshowNavigator"));
|
116 |
+
|
117 |
+
// Slide number feedback
|
118 |
+
this.slideNumberController = new SlideNumberController(document.getElementById("slideNumberControl"));
|
119 |
+
|
120 |
+
// Slide number display
|
121 |
+
this.slideNumberDisplay = new SlideNumberDisplay(document.getElementById("slideNumberDisplay"));
|
122 |
+
|
123 |
+
// Help Placard
|
124 |
+
this.helpPlacard = new HelpPlacardController(document.getElementById("helpPlacard"));
|
125 |
+
|
126 |
+
// indicate if the show has recording
|
127 |
+
this.isRecording = false;
|
128 |
+
|
129 |
+
// a boolean to indicate if the recording is started
|
130 |
+
this.isRecordingStarted = false;
|
131 |
+
|
132 |
+
// IE9 does not support CSS animations
|
133 |
+
if (isIE && browserVersion < 10) {
|
134 |
+
this.animationSupported = false;
|
135 |
+
}
|
136 |
+
else {
|
137 |
+
this.animationSupported = true;
|
138 |
+
}
|
139 |
+
|
140 |
+
// disable mouse right click context menu
|
141 |
+
document.observe("contextmenu", this.handleContextMenuEvent.bind(this));
|
142 |
+
|
143 |
+
Event.observe(this.displayManager.previousButton, "click", this.goBackToPreviousSlide.bind(this, "tapPreviousButton"));
|
144 |
+
Event.observe(this.displayManager.nextButton, "click", this.advanceToNextBuild.bind(this, "tapNextButton"));
|
145 |
+
},
|
146 |
+
|
147 |
+
startShow: function() {
|
148 |
+
this.changeState(kShowControllerState_DownloadingScript);
|
149 |
+
this.scriptManager.downloadScript(this.delegate);
|
150 |
+
},
|
151 |
+
|
152 |
+
exitShow: function(endNow) {
|
153 |
+
clearTimeout(this.exitTimeout);
|
154 |
+
|
155 |
+
if (endNow) {
|
156 |
+
this.delegate.showExited();
|
157 |
+
} else {
|
158 |
+
this.exitTimeout = setTimeout((function(){
|
159 |
+
this.delegate.showExited();
|
160 |
+
}).bind(this), 750);
|
161 |
+
}
|
162 |
+
},
|
163 |
+
|
164 |
+
promptUserToTryAgain: function(message) {
|
165 |
+
var tryAgain = false;
|
166 |
+
|
167 |
+
tryAgain = confirm(message);
|
168 |
+
return tryAgain;
|
169 |
+
},
|
170 |
+
|
171 |
+
handleScriptDidDownloadEvent: function(event) {
|
172 |
+
switch (this.state) {
|
173 |
+
case kShowControllerState_DownloadingScript:
|
174 |
+
var script = this.script = event.memo.script;
|
175 |
+
var showMode = script.showMode;
|
176 |
+
|
177 |
+
if (showMode == kShowModeHyperlinksOnly) {
|
178 |
+
this.displayManager.setHyperlinksOnlyMode();
|
179 |
+
}
|
180 |
+
|
181 |
+
this.changeState(kShowControllerState_Starting);
|
182 |
+
|
183 |
+
// checking to see if a restarting scene index was specified in url...
|
184 |
+
var sceneIndex;
|
185 |
+
var restartingSceneIndex = parseInt(getUrlParameter("restartingSceneIndex"));
|
186 |
+
|
187 |
+
// also look for a fragment identifier which can also indicate scene index
|
188 |
+
var currentUrl = document.URL.split("?");
|
189 |
+
var fragments = currentUrl[0].split("#");
|
190 |
+
if (fragments[1]) {
|
191 |
+
restartingSceneIndex = parseInt(fragments[1]);
|
192 |
+
}
|
193 |
+
|
194 |
+
if (restartingSceneIndex) {
|
195 |
+
// found a restarting scene index, using that...restartingSceneIndex
|
196 |
+
sceneIndex = restartingSceneIndex;
|
197 |
+
} else {
|
198 |
+
// checking to see if a starting slide number was specified in url...
|
199 |
+
var startingSlide = getUrlParameter("currentSlide");
|
200 |
+
var startingSlideNumber;
|
201 |
+
|
202 |
+
if (startingSlide) {
|
203 |
+
startingSlideNumber = parseInt(startingSlide);
|
204 |
+
} else {
|
205 |
+
// nope, not there, use 1...
|
206 |
+
startingSlideNumber = 1;
|
207 |
+
}
|
208 |
+
sceneIndex = this.scriptManager.sceneIndexFromSlideIndex(startingSlideNumber - 1);
|
209 |
+
}
|
210 |
+
|
211 |
+
// if this show has recording, then we start the show in recording mode
|
212 |
+
if (script.recording) {
|
213 |
+
if (script.recording.eventTracks[0].type === "navigation") {
|
214 |
+
this.narrationManager = new NarrationManager(script.recording);
|
215 |
+
sceneIndex = this.narrationManager.sceneIndexFromNavigationEvent(this.narrationManager.navigationEvents[0]);
|
216 |
+
this.isRecording = true;
|
217 |
+
this.jumpToScene(sceneIndex, false);
|
218 |
+
|
219 |
+
break;
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
+
if (sceneIndex > script.lastSceneIndex) {
|
224 |
+
break;
|
225 |
+
}
|
226 |
+
|
227 |
+
if (showMode === kShowModeAutoplay) {
|
228 |
+
this.jumpToScene(sceneIndex, true);
|
229 |
+
} else {
|
230 |
+
var event = script.events[sceneIndex];
|
231 |
+
var automaticPlay = event.automaticPlay == 1 || event.automaticPlay == true;
|
232 |
+
this.jumpToScene(sceneIndex, automaticPlay);
|
233 |
+
}
|
234 |
+
break;
|
235 |
+
|
236 |
+
default:
|
237 |
+
debugMessage(kDebugShowController_HandleScriptDidDownloadEvent,
|
238 |
+
"- hmmm we seem to have arrived here from an unpredicted state");
|
239 |
+
break;
|
240 |
+
}
|
241 |
+
},
|
242 |
+
|
243 |
+
handleScriptDidNotDownloadEvent: function(event) {
|
244 |
+
debugMessage(kDebugShowController_HandleScriptDidNotDownloadEvent);
|
245 |
+
|
246 |
+
var tryAgain = this.promptUserToTryAgain(kUnableToReachiWorkTryAgain);
|
247 |
+
|
248 |
+
if (tryAgain) {
|
249 |
+
this.scriptManager.downloadScript();
|
250 |
+
} else {
|
251 |
+
this.displayManager.clearLaunchMode();
|
252 |
+
this.displayManager.hideWaitingIndicator();
|
253 |
+
}
|
254 |
+
},
|
255 |
+
|
256 |
+
handleStageIsReadyEvent: function(event) {
|
257 |
+
if (this.isFullscreen) {
|
258 |
+
setTimeout((function() {
|
259 |
+
this.displayManager.stageArea.style.opacity = 1;
|
260 |
+
}).bind(this), 50)
|
261 |
+
} else {
|
262 |
+
setTimeout((function() {
|
263 |
+
this.displayManager.stageArea.style.opacity = 1;
|
264 |
+
}).bind(this), 500)
|
265 |
+
}
|
266 |
+
|
267 |
+
this.positionSlideNumberControl();
|
268 |
+
this.positionSlideNumberDisplay();
|
269 |
+
this.positionHelpPlacard();
|
270 |
+
},
|
271 |
+
|
272 |
+
positionSlideNumberControl: function() {
|
273 |
+
var left = (this.displayManager.usableDisplayWidth - this.slideNumberController.width) / 2;
|
274 |
+
var top = this.displayManager.stageAreaTop + this.displayManager.stageAreaHeight - (this.slideNumberController.height + 16);
|
275 |
+
|
276 |
+
this.slideNumberController.setPosition(left, top);
|
277 |
+
},
|
278 |
+
|
279 |
+
positionSlideNumberDisplay: function() {
|
280 |
+
var left = (this.displayManager.usableDisplayWidth - this.slideNumberDisplay.width) / 2;
|
281 |
+
var top = this.displayManager.stageAreaTop + this.displayManager.stageAreaHeight - (this.slideNumberDisplay.height + 16);
|
282 |
+
|
283 |
+
this.slideNumberDisplay.setPosition(left, top);
|
284 |
+
},
|
285 |
+
|
286 |
+
positionHelpPlacard: function() {
|
287 |
+
var left = (this.displayManager.usableDisplayWidth - this.helpPlacard.width) / 2;
|
288 |
+
var top = (this.displayManager.usableDisplayHeight - this.helpPlacard.height) / 2;
|
289 |
+
|
290 |
+
this.helpPlacard.setPosition(left, top);
|
291 |
+
},
|
292 |
+
|
293 |
+
handleFullscreenChangeEvent: function() {
|
294 |
+
if (document.webkitIsFullScreen || document.mozFullScreen) {
|
295 |
+
this.isFullscreen = true;
|
296 |
+
} else {
|
297 |
+
this.isFullscreen = false;
|
298 |
+
}
|
299 |
+
|
300 |
+
setTimeout((function() {
|
301 |
+
this.displayManager.layoutDisplay();
|
302 |
+
}).bind(this), 0);
|
303 |
+
},
|
304 |
+
|
305 |
+
handleWindowResizeEvent: function() {
|
306 |
+
clearTimeout(this.resizeTimer);
|
307 |
+
this.resizeTimer = setTimeout(this.changeWindowSize.bind(this), 1000);
|
308 |
+
},
|
309 |
+
|
310 |
+
changeWindowSize: function() {
|
311 |
+
if (this.delegate.setViewScale) {
|
312 |
+
this.scriptManager.reapplyScaleFactor();
|
313 |
+
|
314 |
+
this.textureManager.slideCache = null;
|
315 |
+
this.textureManager.slideCache = {};
|
316 |
+
|
317 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
318 |
+
|
319 |
+
if (this.state === kShowControllerState_IdleAtFinalState) {
|
320 |
+
if (this.currentSceneIndex < this.script.numScenes - 1) {
|
321 |
+
sceneIndexToUse = this.currentSceneIndex + 1;
|
322 |
+
} else {
|
323 |
+
if (this.script.loopSlideshow) {
|
324 |
+
sceneIndexToUse = 0;
|
325 |
+
}
|
326 |
+
}
|
327 |
+
}
|
328 |
+
|
329 |
+
this.jumpToScene(sceneIndexToUse, false);
|
330 |
+
}
|
331 |
+
|
332 |
+
document.fire(kShowSizeDidChangeEvent, {
|
333 |
+
width: this.script.slideWidth,
|
334 |
+
height: this.script.slideHeight
|
335 |
+
});
|
336 |
+
},
|
337 |
+
|
338 |
+
handleStageSizeDidChangeEvent: function(event) {
|
339 |
+
// update TouchController with new track area
|
340 |
+
this.touchController.setTrackArea(event.memo.left, event.memo.top, event.memo.width, event.memo.height);
|
341 |
+
},
|
342 |
+
|
343 |
+
handleKeyDownEvent: function(event) {
|
344 |
+
var key = event.charCode || event.keyCode;
|
345 |
+
|
346 |
+
// allow F11 and F12 to work on IE
|
347 |
+
if (key === kKeyCode_F11 || key === kKeyCode_F12) {
|
348 |
+
return;
|
349 |
+
}
|
350 |
+
|
351 |
+
var modifiers = {
|
352 |
+
altKey: !!event.altKey,
|
353 |
+
ctrlKey: !!event.ctrlKey,
|
354 |
+
shiftKey: !!event.shiftKey,
|
355 |
+
metaKey: !!event.metaKey
|
356 |
+
};
|
357 |
+
|
358 |
+
if (modifiers.metaKey) {
|
359 |
+
if (key === kKeyCode_Period || key === kKeyCode_Dot) {
|
360 |
+
// cmd - . to exit show
|
361 |
+
this.exitShow(true);
|
362 |
+
} else if (key != kKeyCode_Return) {
|
363 |
+
// allow browsers to handle cmd-key
|
364 |
+
return;
|
365 |
+
}
|
366 |
+
} else if (modifiers.ctrlKey) {
|
367 |
+
// allow browsers to handle ctrl-key
|
368 |
+
return;
|
369 |
+
}
|
370 |
+
|
371 |
+
event.stop();
|
372 |
+
this.onKeyPress(key, modifiers);
|
373 |
+
},
|
374 |
+
|
375 |
+
handleContextMenuEvent: function(event) {
|
376 |
+
event.stop();
|
377 |
+
},
|
378 |
+
|
379 |
+
handleClickEvent: function(event) {
|
380 |
+
if (this.isRecording) {
|
381 |
+
return;
|
382 |
+
}
|
383 |
+
|
384 |
+
var x, y;
|
385 |
+
|
386 |
+
if (event.pageX || event.pageY) {
|
387 |
+
x = event.pageX;
|
388 |
+
y = event.pageY;
|
389 |
+
} else {
|
390 |
+
x = event.clientX;
|
391 |
+
y = event.clientY;
|
392 |
+
}
|
393 |
+
|
394 |
+
var displayCoOrds = {
|
395 |
+
pointX: x,
|
396 |
+
pointY: y
|
397 |
+
};
|
398 |
+
|
399 |
+
// for IE make sure windows has focus
|
400 |
+
if (isIE) {
|
401 |
+
window.focus();
|
402 |
+
}
|
403 |
+
|
404 |
+
// For video element, let the event to propagate
|
405 |
+
if (event.target.nodeName.toLowerCase() === "video") {
|
406 |
+
return;
|
407 |
+
}
|
408 |
+
|
409 |
+
this.processClickOrTapAtDisplayCoOrds(displayCoOrds);
|
410 |
+
},
|
411 |
+
|
412 |
+
handleTapEvent: function(event) {
|
413 |
+
var displayCoOrds = {
|
414 |
+
pointX: event.memo.pointX,
|
415 |
+
pointY: event.memo.pointY
|
416 |
+
};
|
417 |
+
|
418 |
+
this.processClickOrTapAtDisplayCoOrds(displayCoOrds);
|
419 |
+
},
|
420 |
+
|
421 |
+
processClickOrTapAtDisplayCoOrds: function(displayCoOrds) {
|
422 |
+
var isHyperlink = false;
|
423 |
+
var hyperlink;
|
424 |
+
|
425 |
+
if (this.slideNumberController.isShowing) {
|
426 |
+
if (this.slideNumberTimeout) {
|
427 |
+
clearTimeout(this.slideNumberTimeout);
|
428 |
+
}
|
429 |
+
this.slideNumberTimeout = setTimeout(this.hideAndResetSlideNumberController.bind(this), 0);
|
430 |
+
return;
|
431 |
+
}
|
432 |
+
|
433 |
+
if (this.helpPlacard.isShowing) {
|
434 |
+
this.helpPlacard.hide();
|
435 |
+
return;
|
436 |
+
}
|
437 |
+
|
438 |
+
var showCoOrds = this.displayManager.convertDisplayCoOrdsToShowCoOrds(displayCoOrds);
|
439 |
+
|
440 |
+
if (showCoOrds.pointX != -1) {
|
441 |
+
hyperlink = this.findHyperlinkAtCoOrds(showCoOrds);
|
442 |
+
}
|
443 |
+
|
444 |
+
if (hyperlink) {
|
445 |
+
this.processHyperlink(hyperlink);
|
446 |
+
} else {
|
447 |
+
this.advanceToNextBuild("processClickOrTapAtDisplayCoOrds");
|
448 |
+
}
|
449 |
+
},
|
450 |
+
|
451 |
+
handleSwipeEvent: function(event) {
|
452 |
+
if (event.memo.direction === "left") {
|
453 |
+
switch (event.memo.fingers) {
|
454 |
+
case 1:
|
455 |
+
this.advanceToNextBuild("handleSwipeEvent");
|
456 |
+
break;
|
457 |
+
case 2:
|
458 |
+
this.advanceToNextSlide("handleSwipeEvent");
|
459 |
+
break;
|
460 |
+
default:
|
461 |
+
break;
|
462 |
+
}
|
463 |
+
} else if (event.memo.direction === "right") {
|
464 |
+
switch (event.memo.fingers) {
|
465 |
+
case 1:
|
466 |
+
this.goBackToPreviousSlide("handleSwipeEvent");
|
467 |
+
break;
|
468 |
+
case 2:
|
469 |
+
this.goBackToPreviousBuild("handleSwipeEvent");
|
470 |
+
break;
|
471 |
+
default:
|
472 |
+
break;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
},
|
476 |
+
|
477 |
+
onMouseDown: function(mouseDownEvent) {
|
478 |
+
if (mouseDownEvent.leftClick) {
|
479 |
+
this.advanceToNextBuild("onMouseDown");
|
480 |
+
} else if (mouseDownEvent.rightClick) {
|
481 |
+
this.goBackToPreviousBuild("onMouseDown");
|
482 |
+
}
|
483 |
+
},
|
484 |
+
|
485 |
+
onKeyPress: function(key, modifier) {
|
486 |
+
if ((key >= kKeyCode_Numeric_0) && (key <= kKeyCode_Numeric_9)) {
|
487 |
+
key = kKeyCode_0 + (key - kKeyCode_Numeric_0);
|
488 |
+
}
|
489 |
+
|
490 |
+
key += (modifier.shiftKey ? kKeyModifier_Shift : 0);
|
491 |
+
key += (modifier.altKey ? kKeyModifier_Alt : 0);
|
492 |
+
key += (modifier.ctrlKey ? kKeyModifier_Ctrl : 0);
|
493 |
+
key += (modifier.metaKey ? kKeyModifier_Meta : 0);
|
494 |
+
|
495 |
+
if (this.isRecording) {
|
496 |
+
return;
|
497 |
+
}
|
498 |
+
|
499 |
+
var digitEncountered = false;
|
500 |
+
switch (key) {
|
501 |
+
case kKeyCode_Escape:
|
502 |
+
this.exitShow(true);
|
503 |
+
break;
|
504 |
+
|
505 |
+
/*
|
506 |
+
* case kKeyCode_Return + kKeyModifier_Ctrl:
|
507 |
+
* this.displayManager.showWaitingIndicator(); break;
|
508 |
+
*
|
509 |
+
* case kKeyCode_Return + kKeyModifier_Alt:
|
510 |
+
* this.displayManager.hideWaitingIndicator(); break;
|
511 |
+
*
|
512 |
+
* case kKeyCode_Return + kKeyModifier_Meta: this.debugDiagnosticDump();
|
513 |
+
* break;
|
514 |
+
*/
|
515 |
+
case kKeyCode_Slash:
|
516 |
+
case kKeyCode_Slash + kKeyModifier_Shift:
|
517 |
+
if (this.helpPlacard.isShowing) {
|
518 |
+
this.helpPlacard.hide();
|
519 |
+
} else {
|
520 |
+
this.helpPlacard.show();
|
521 |
+
}
|
522 |
+
break;
|
523 |
+
|
524 |
+
case kKeyCode_Q:
|
525 |
+
this.exitShow(true);
|
526 |
+
break;
|
527 |
+
|
528 |
+
case kKeyCode_S:
|
529 |
+
if (this.slideNumberController.isShowing) {
|
530 |
+
if (this.slideNumberTimeout) {
|
531 |
+
clearTimeout(this.slideNumberTimeout);
|
532 |
+
}
|
533 |
+
this.slideNumberTimeout = setTimeout(this.hideAndResetSlideNumberController.bind(this), 0);
|
534 |
+
}
|
535 |
+
|
536 |
+
if (this.slideNumberDisplay.isShowing) {
|
537 |
+
this.slideNumberDisplay.hide();
|
538 |
+
} else {
|
539 |
+
this.slideNumberDisplay.setSlideNumber(this.currentSlideIndex + 1);
|
540 |
+
this.slideNumberDisplay.show();
|
541 |
+
}
|
542 |
+
break;
|
543 |
+
|
544 |
+
case kKeyCode_Return:
|
545 |
+
if (this.accumulatingDigits) {
|
546 |
+
// return pressed while accumulating digits.
|
547 |
+
this.accumulatingDigits = false;
|
548 |
+
|
549 |
+
if (this.script.showMode != kShowModeHyperlinksOnly) {
|
550 |
+
if (this.digitAccumulator > this.script.slideCount) {
|
551 |
+
this.digitAccumulator = this.script.slideCount;
|
552 |
+
}
|
553 |
+
else if (this.digitAccumulator < 1) {
|
554 |
+
this.digitAccumulator = 1;
|
555 |
+
}
|
556 |
+
this.slideNumberController.setSlideNumber(this.digitAccumulator);
|
557 |
+
this.jumpToSlide(this.digitAccumulator);
|
558 |
+
} else {
|
559 |
+
debugMessage(kDebugShowController_OnKeyPress, "- can't do it, we're in hyperlinks only mode");
|
560 |
+
}
|
561 |
+
break;
|
562 |
+
}
|
563 |
+
// fall through
|
564 |
+
|
565 |
+
case kKeyCode_N:
|
566 |
+
case kKeyCode_Space:
|
567 |
+
case kKeyCode_DownArrow:
|
568 |
+
case kKeyCode_RightArrow:
|
569 |
+
case kKeyCode_PageDown:
|
570 |
+
// advance to next build...
|
571 |
+
this.advanceToNextBuild("onKeyPress");
|
572 |
+
break;
|
573 |
+
|
574 |
+
case kKeyCode_RightArrow + kKeyModifier_Shift:
|
575 |
+
case kKeyCode_CloseBracket:
|
576 |
+
// advance and skip build...
|
577 |
+
this.advanceAndSkipBuild("onKeyPress");
|
578 |
+
break;
|
579 |
+
|
580 |
+
case kKeyCode_DownArrow + kKeyModifier_Shift:
|
581 |
+
case kKeyCode_PageDown + kKeyModifier_Shift:
|
582 |
+
case kKeyCode_CloseBracket:
|
583 |
+
case kKeyCode_Equal + kKeyModifier_Shift:
|
584 |
+
case kKeyCode_Equal:
|
585 |
+
case kKeyCode_Plus:
|
586 |
+
// advance to next slide...
|
587 |
+
this.advanceToNextSlide("onKeyPress");
|
588 |
+
break;
|
589 |
+
|
590 |
+
case kKeyCode_LeftArrow + kKeyModifier_Shift:
|
591 |
+
case kKeyCode_PageUp + kKeyModifier_Shift:
|
592 |
+
case kKeyCode_OpenBracket:
|
593 |
+
// go back to previous build...
|
594 |
+
this.goBackToPreviousBuild("onKeyPress");
|
595 |
+
break;
|
596 |
+
|
597 |
+
case kKeyCode_P:
|
598 |
+
case kKeyCode_PageUp:
|
599 |
+
case kKeyCode_LeftArrow:
|
600 |
+
case kKeyCode_UpArrow:
|
601 |
+
case kKeyCode_UpArrow + kKeyModifier_Shift:
|
602 |
+
case kKeyCode_Hyphen:
|
603 |
+
case kKeyCode_Minus:
|
604 |
+
// go back to previous slide...
|
605 |
+
this.goBackToPreviousSlide("onKeyPress");
|
606 |
+
break;
|
607 |
+
|
608 |
+
case kKeyCode_Delete:
|
609 |
+
digitEncountered = true;
|
610 |
+
if (this.accumulatingDigits) {
|
611 |
+
if (this.digitAccumulator < 10) {
|
612 |
+
if (this.slideNumberTimeout) {
|
613 |
+
clearTimeout(this.slideNumberTimeout);
|
614 |
+
}
|
615 |
+
this.slideNumberTimeout = setTimeout(this.hideAndResetSlideNumberController.bind(this), 0);
|
616 |
+
}
|
617 |
+
else {
|
618 |
+
if (this.slideNumberTimeout) {
|
619 |
+
clearTimeout(this.slideNumberTimeout);
|
620 |
+
}
|
621 |
+
this.slideNumberTimeout = setTimeout(this.hideAndResetSlideNumberController.bind(this), 7000);
|
622 |
+
|
623 |
+
var digit = this.digitAccumulator.toString();
|
624 |
+
this.digitAccumulator = parseInt(digit.substring(0, digit.length - 1));
|
625 |
+
this.slideNumberController.setSlideNumber(this.digitAccumulator);
|
626 |
+
}
|
627 |
+
}
|
628 |
+
break;
|
629 |
+
|
630 |
+
case kKeyCode_Home:
|
631 |
+
// go back to first slide...
|
632 |
+
if (this.script.showMode != kShowModeHyperlinksOnly) {
|
633 |
+
this.jumpToSlide(1);
|
634 |
+
} else {
|
635 |
+
debugMessage(kDebugShowController_OnKeyPress, "- can't do it, we're in hyperlinks only mode");
|
636 |
+
}
|
637 |
+
break;
|
638 |
+
|
639 |
+
case kKeyCode_End:
|
640 |
+
// go back to last slide...
|
641 |
+
if (this.script.showMode != kShowModeHyperlinksOnly) {
|
642 |
+
this.jumpToSlide(this.script.slideCount);
|
643 |
+
} else {
|
644 |
+
debugMessage(kDebugShowController_OnKeyPress, "- can't do it, we're in hyperlinks only mode");
|
645 |
+
}
|
646 |
+
break;
|
647 |
+
|
648 |
+
default:
|
649 |
+
if (this.slideNumberTimeout) {
|
650 |
+
clearTimeout(this.slideNumberTimeout);
|
651 |
+
}
|
652 |
+
this.slideNumberTimeout = setTimeout(this.hideAndResetSlideNumberController.bind(this), 7000);
|
653 |
+
|
654 |
+
if ((key >= kKeyCode_0) && (key <= kKeyCode_9)) {
|
655 |
+
if (this.slideNumberDisplay.isShowing) {
|
656 |
+
this.slideNumberDisplay.hide();
|
657 |
+
}
|
658 |
+
|
659 |
+
digitEncountered = true;
|
660 |
+
if (this.accumulatingDigits === false) {
|
661 |
+
// digit entered, start accumulating digits...
|
662 |
+
this.accumulatingDigits = true;
|
663 |
+
this.digitAccumulator = 0;
|
664 |
+
}
|
665 |
+
|
666 |
+
if (this.digitAccumulator.toString().length < 4) {
|
667 |
+
this.digitAccumulator *= 10;
|
668 |
+
this.digitAccumulator += (key - kKeyCode_0);
|
669 |
+
|
670 |
+
this.slideNumberController.setSlideNumber(this.digitAccumulator);
|
671 |
+
if (!this.slideNumberController.isShowing) {
|
672 |
+
this.slideNumberController.show();
|
673 |
+
}
|
674 |
+
}
|
675 |
+
}
|
676 |
+
else {
|
677 |
+
digitEncountered = true;
|
678 |
+
}
|
679 |
+
break;
|
680 |
+
}
|
681 |
+
|
682 |
+
if (this.accumulatingDigits && (digitEncountered === false)) {
|
683 |
+
// non-digit entered, stop accumulating digits...
|
684 |
+
//this.accumulatingDigits = false;
|
685 |
+
//this.digitAccumulator = 0;
|
686 |
+
}
|
687 |
+
},
|
688 |
+
|
689 |
+
hideAndResetSlideNumberController: function() {
|
690 |
+
if (this.slideNumberTimeout) {
|
691 |
+
clearTimeout(this.slideNumberTimeout);
|
692 |
+
}
|
693 |
+
|
694 |
+
this.accumulatingDigits = false;
|
695 |
+
this.digitAccumulator = 0;
|
696 |
+
this.slideNumberController.hide();
|
697 |
+
},
|
698 |
+
|
699 |
+
hideSlideNumberDisplay: function() {
|
700 |
+
this.slideNumberDisplay.hide();
|
701 |
+
},
|
702 |
+
|
703 |
+
toggleFullscreen: function() {
|
704 |
+
// IE does not support fullscreen mode, return for now
|
705 |
+
if (isIE) {
|
706 |
+
return;
|
707 |
+
}
|
708 |
+
|
709 |
+
setTimeout((function() {
|
710 |
+
this.displayManager.stageArea.style.opacity = 0;
|
711 |
+
}).bind(this), 0);
|
712 |
+
|
713 |
+
// hide hud immediately
|
714 |
+
this.displayManager.hideHUD(true);
|
715 |
+
|
716 |
+
if (document.webkitIsFullScreen || document.mozFullScreen) {
|
717 |
+
this.isFullscreen = false;
|
718 |
+
(document.webkitCancelFullScreen && document.webkitCancelFullScreen())
|
719 |
+
|| (document.mozCancelFullScreen && document.mozCancelFullScreen());
|
720 |
+
} else {
|
721 |
+
this.isFullscreen = true;
|
722 |
+
(document.body.webkitRequestFullScreen && document.body.webkitRequestFullScreen())
|
723 |
+
|| (document.body.mozRequestFullScreen && document.body.mozRequestFullScreen());
|
724 |
+
}
|
725 |
+
},
|
726 |
+
|
727 |
+
// State Management
|
728 |
+
// ================
|
729 |
+
changeState: function(newState) {
|
730 |
+
if (newState != this.state) {
|
731 |
+
//this.accumulatingDigits = false;
|
732 |
+
//this.digitAccumulator = 0;
|
733 |
+
|
734 |
+
this.leavingState();
|
735 |
+
this.state = newState;
|
736 |
+
this.enteringState();
|
737 |
+
}
|
738 |
+
},
|
739 |
+
|
740 |
+
leavingState: function() {
|
741 |
+
switch (this.state) {
|
742 |
+
case kShowControllerState_Stopped:
|
743 |
+
break;
|
744 |
+
|
745 |
+
case kShowControllerState_Starting:
|
746 |
+
break;
|
747 |
+
|
748 |
+
case kShowControllerState_SettingUpScene:
|
749 |
+
break;
|
750 |
+
|
751 |
+
case kShowControllerState_IdleAtFinalState:
|
752 |
+
break;
|
753 |
+
|
754 |
+
case kShowControllerState_IdleAtInitialState:
|
755 |
+
break;
|
756 |
+
|
757 |
+
case kShowControllerState_WaitingToJump:
|
758 |
+
break;
|
759 |
+
|
760 |
+
case kShowControllerState_ReadyToJump:
|
761 |
+
break;
|
762 |
+
|
763 |
+
case kShowControllerState_WaitingToPlay:
|
764 |
+
this.displayManager.hideWaitingIndicator();
|
765 |
+
break;
|
766 |
+
|
767 |
+
case kShowControllerState_ReadyToPlay:
|
768 |
+
break;
|
769 |
+
|
770 |
+
case kShowControllerState_Playing:
|
771 |
+
break;
|
772 |
+
}
|
773 |
+
},
|
774 |
+
|
775 |
+
enteringState: function() {
|
776 |
+
switch (this.state) {
|
777 |
+
case kShowControllerState_Stopped:
|
778 |
+
break;
|
779 |
+
|
780 |
+
case kShowControllerState_Starting:
|
781 |
+
this.displayManager.showWaitingIndicator();
|
782 |
+
break;
|
783 |
+
|
784 |
+
case kShowControllerState_SettingUpScene:
|
785 |
+
break;
|
786 |
+
|
787 |
+
case kShowControllerState_IdleAtFinalState:
|
788 |
+
// unload slide cache not next to the current slide
|
789 |
+
this.unloadTextures();
|
790 |
+
|
791 |
+
case kShowControllerState_IdleAtInitialState:
|
792 |
+
this.updateSlideNumber();
|
793 |
+
|
794 |
+
runInNextEventLoop(this.doIdleProcessing.bind(this));
|
795 |
+
break;
|
796 |
+
|
797 |
+
case kShowControllerState_WaitingToJump:
|
798 |
+
// don't show spinner here, do it in pollForSceneToLoad after a few
|
799 |
+
// polls so the spinner doesn't come up right away
|
800 |
+
break;
|
801 |
+
|
802 |
+
case kShowControllerState_ReadyToJump:
|
803 |
+
break;
|
804 |
+
|
805 |
+
case kShowControllerState_WaitingToPlay:
|
806 |
+
this.displayManager.showWaitingIndicator();
|
807 |
+
break;
|
808 |
+
|
809 |
+
case kShowControllerState_ReadyToPlay:
|
810 |
+
break;
|
811 |
+
|
812 |
+
case kShowControllerState_Playing:
|
813 |
+
break;
|
814 |
+
}
|
815 |
+
},
|
816 |
+
|
817 |
+
preloadTextures: function() {
|
818 |
+
var script = this.script;
|
819 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
820 |
+
|
821 |
+
if (this.state === kShowControllerState_IdleAtFinalState) {
|
822 |
+
if (sceneIndexToUse < script.numScenes - 1) {
|
823 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
824 |
+
} else if (script.loopSlideshow) {
|
825 |
+
sceneIndexToUse = 0;
|
826 |
+
}
|
827 |
+
}
|
828 |
+
|
829 |
+
// preload textures
|
830 |
+
this.textureManager.loadScene(sceneIndexToUse);
|
831 |
+
},
|
832 |
+
|
833 |
+
unloadTextures: function() {
|
834 |
+
var script = this.script;
|
835 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
836 |
+
|
837 |
+
if (this.state === kShowControllerState_IdleAtFinalState) {
|
838 |
+
if (sceneIndexToUse < script.numScenes - 1) {
|
839 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
840 |
+
} else if (script.loopSlideshow) {
|
841 |
+
sceneIndexToUse = 0;
|
842 |
+
}
|
843 |
+
}
|
844 |
+
|
845 |
+
var currentSlideIndex = script.slideIndexFromSceneIndexLookup[sceneIndexToUse];
|
846 |
+
|
847 |
+
var slideCache = this.textureManager.slideCache;
|
848 |
+
|
849 |
+
for (var index in slideCache) {
|
850 |
+
// detect current slide index and its previous and next slide in slideCache buffer
|
851 |
+
if (index < currentSlideIndex - 1 || index > currentSlideIndex + 1) {
|
852 |
+
// remove slide cache
|
853 |
+
var cache = slideCache[index];
|
854 |
+
for (var textureId in cache.textureAssets) {
|
855 |
+
var canvas = cache.textureAssets[textureId];
|
856 |
+
if (canvas) {
|
857 |
+
// clear canvas object
|
858 |
+
var context = canvas.getContext("2d");
|
859 |
+
|
860 |
+
if (context) {
|
861 |
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
862 |
+
}
|
863 |
+
|
864 |
+
// remove reference
|
865 |
+
delete cache.textureAssets[textureId];
|
866 |
+
}
|
867 |
+
}
|
868 |
+
|
869 |
+
delete this.textureManager.slideCache[index].textureAssets;
|
870 |
+
delete this.textureManager.slideCache[index].textureRequests;
|
871 |
+
delete this.textureManager.slideCache[index].requested;
|
872 |
+
|
873 |
+
// call internal pdf document destroy method
|
874 |
+
if (cache.pdf) {
|
875 |
+
cache.pdf.destroy();
|
876 |
+
delete this.textureManager.slideCache[index].pdf;
|
877 |
+
}
|
878 |
+
|
879 |
+
// finally remove slide cache reference
|
880 |
+
delete this.textureManager.slideCache[index];
|
881 |
+
}
|
882 |
+
}
|
883 |
+
},
|
884 |
+
|
885 |
+
doIdleProcessing: function() {
|
886 |
+
// preload textures for next slide if applicable
|
887 |
+
this.preloadTextures();
|
888 |
+
|
889 |
+
if (this.queuedUserAction != null) {
|
890 |
+
// executing queued user action...
|
891 |
+
this.queuedUserAction();
|
892 |
+
this.queuedUserAction = null;
|
893 |
+
} else {
|
894 |
+
var stage = this.stageManager.stage;
|
895 |
+
|
896 |
+
if (stage.childNodes.length !== 0) {
|
897 |
+
this.updateNavigationButtons();
|
898 |
+
}
|
899 |
+
}
|
900 |
+
|
901 |
+
// create hyperlink in setTimeout using background thread
|
902 |
+
clearTimeout(this.createHyperlinksForCurrentStateTimeout);
|
903 |
+
this.createHyperlinksForCurrentStateTimeout = setTimeout((function() {this.createHyperlinksForCurrentState("idle");}).bind(this), 100);
|
904 |
+
},
|
905 |
+
|
906 |
+
truncatedSlideIndex: function(slideIndex) {
|
907 |
+
return this.truncatedIndex(slideIndex, this.script.lastSlideIndex, this.script.loopSlideshow);
|
908 |
+
},
|
909 |
+
|
910 |
+
truncatedSceneIndex: function(sceneIndex) {
|
911 |
+
return this.truncatedIndex(sceneIndex, this.script.lastSceneIndex, this.script.loopSlideshow);
|
912 |
+
},
|
913 |
+
|
914 |
+
truncatedIndex: function(index, lastIndex, isLooping) {
|
915 |
+
if (index < 0) {
|
916 |
+
if (isLooping) {
|
917 |
+
index = index + lastIndex + 1;
|
918 |
+
} else {
|
919 |
+
index = -1;
|
920 |
+
}
|
921 |
+
} else if (index > lastIndex) {
|
922 |
+
if (isLooping) {
|
923 |
+
index = index - lastIndex - 1;
|
924 |
+
} else {
|
925 |
+
index = -1;
|
926 |
+
}
|
927 |
+
}
|
928 |
+
return index;
|
929 |
+
},
|
930 |
+
|
931 |
+
advanceToNextBuild: function(context) {
|
932 |
+
// do not proceed if the script is not available
|
933 |
+
if (!this.script) {
|
934 |
+
return false;
|
935 |
+
}
|
936 |
+
|
937 |
+
if (this.script.showMode === kShowModeHyperlinksOnly && context != "currentSceneDidComplete") {
|
938 |
+
return false;
|
939 |
+
}
|
940 |
+
|
941 |
+
if (this.displayManager.infoPanelIsShowing) {
|
942 |
+
return false;
|
943 |
+
}
|
944 |
+
|
945 |
+
var result = false;
|
946 |
+
|
947 |
+
switch (this.state) {
|
948 |
+
case kShowControllerState_IdleAtFinalState:
|
949 |
+
if (this.nextSceneIndex === -1) {
|
950 |
+
if (this.delegate.getKPFJsonStringForShow) {
|
951 |
+
this.stopSoundTrack();
|
952 |
+
this.exitShow();
|
953 |
+
} else {
|
954 |
+
this.stopSoundTrack();
|
955 |
+
break;
|
956 |
+
}
|
957 |
+
}
|
958 |
+
// idle on final state, jump to next scene
|
959 |
+
result = true;
|
960 |
+
this.jumpToScene(this.nextSceneIndex, true);
|
961 |
+
break;
|
962 |
+
|
963 |
+
case kShowControllerState_IdleAtInitialState:
|
964 |
+
if (this.currentSceneIndex >= this.script.numScenes) {
|
965 |
+
if (this.script.loopSlideshow) {
|
966 |
+
// we're at the end but this IS a looping show, jump to start
|
967 |
+
result = true;
|
968 |
+
this.jumpToScene(0, false);
|
969 |
+
} else {
|
970 |
+
if (this.delegate.getKPFJsonStringForShow) {
|
971 |
+
this.stopSoundTrack();
|
972 |
+
this.exitShow();
|
973 |
+
} else {
|
974 |
+
this.stopSoundTrack();
|
975 |
+
break;
|
976 |
+
}
|
977 |
+
}
|
978 |
+
} else {
|
979 |
+
// we're sitting idle on initial state, preload next scene and play current scene
|
980 |
+
result = true;
|
981 |
+
this.playCurrentScene();
|
982 |
+
}
|
983 |
+
break;
|
984 |
+
|
985 |
+
default:
|
986 |
+
debugMessage(kDebugShowController_AdvanceToNextBuild, "nextSceneIndex: " + this.nextSceneIndex + " can't advance now, not in an idle state (currently in '" + this.state + "' state), queue up action to run in next idle time");
|
987 |
+
|
988 |
+
if (this.queuedUserAction == null) {
|
989 |
+
result = true;
|
990 |
+
this.queuedUserAction = this.advanceToNextBuild.bind(this, context);
|
991 |
+
}
|
992 |
+
break;
|
993 |
+
}
|
994 |
+
|
995 |
+
return result;
|
996 |
+
},
|
997 |
+
|
998 |
+
advanceToNextSlide: function(context) {
|
999 |
+
// do not proceed if the script is not available
|
1000 |
+
if (!this.script) {
|
1001 |
+
return false;
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
if (this.script.showMode == kShowModeHyperlinksOnly) {
|
1005 |
+
return;
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
if (this.displayManager.infoPanelIsShowing) {
|
1009 |
+
return;
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
1013 |
+
|
1014 |
+
switch (this.state) {
|
1015 |
+
case kShowControllerState_IdleAtFinalState:
|
1016 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
1017 |
+
// Fall through
|
1018 |
+
|
1019 |
+
case kShowControllerState_IdleAtInitialState:
|
1020 |
+
var currentSlideIndex = this.scriptManager.slideIndexFromSceneIndex(sceneIndexToUse);
|
1021 |
+
var nextSlideIndex ;
|
1022 |
+
|
1023 |
+
if (currentSlideIndex === this.script.slideCount - 1) {
|
1024 |
+
if (this.script.loopSlideshow) {
|
1025 |
+
nextSlideIndex = 0;
|
1026 |
+
} else {
|
1027 |
+
return;
|
1028 |
+
}
|
1029 |
+
} else {
|
1030 |
+
nextSlideIndex = this.currentSlideIndex + 1;
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
var sceneIndex = this.scriptManager.sceneIndexFromSlideIndex(nextSlideIndex);
|
1034 |
+
var event = this.script.events[sceneIndex];
|
1035 |
+
var automaticPlay = event.automaticPlay == 1 || event.automaticPlay == true;
|
1036 |
+
this.jumpToSlide(nextSlideIndex + 1, automaticPlay);
|
1037 |
+
|
1038 |
+
break;
|
1039 |
+
|
1040 |
+
default:
|
1041 |
+
debugMessage(kDebugShowController_AdvanceToNextSlide, "can't advance now, not in an idle state (currently in '" + this.state + "' state), queue up action to run in next idle time");
|
1042 |
+
|
1043 |
+
if (this.queuedUserAction == null) {
|
1044 |
+
this.queuedUserAction = this.advanceToNextSlide.bind(this, context);
|
1045 |
+
}
|
1046 |
+
break;
|
1047 |
+
}
|
1048 |
+
},
|
1049 |
+
|
1050 |
+
goBackToPreviousBuild: function(context) {
|
1051 |
+
// do not proceed if the script is not available
|
1052 |
+
if (!this.script) {
|
1053 |
+
return false;
|
1054 |
+
}
|
1055 |
+
|
1056 |
+
// going back to previous build, remove all media cache
|
1057 |
+
this.resetMediaCache();
|
1058 |
+
|
1059 |
+
if (this.script.showMode == kShowModeHyperlinksOnly) {
|
1060 |
+
return;
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
if (this.displayManager.infoPanelIsShowing) {
|
1064 |
+
return;
|
1065 |
+
}
|
1066 |
+
|
1067 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
1068 |
+
|
1069 |
+
switch (this.state) {
|
1070 |
+
case kShowControllerState_IdleAtFinalState:
|
1071 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
1072 |
+
// Fall through
|
1073 |
+
|
1074 |
+
case kShowControllerState_Playing:
|
1075 |
+
case kShowControllerState_IdleAtInitialState:
|
1076 |
+
var previousSceneIndex ;
|
1077 |
+
|
1078 |
+
if (sceneIndexToUse === 0) {
|
1079 |
+
if (this.script.loopSlideshow) {
|
1080 |
+
previousSceneIndex = this.script.events.length - 1;
|
1081 |
+
} else {
|
1082 |
+
return;
|
1083 |
+
}
|
1084 |
+
} else {
|
1085 |
+
previousSceneIndex = sceneIndexToUse - 1;
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
this.jumpToScene(previousSceneIndex, false);
|
1089 |
+
|
1090 |
+
break;
|
1091 |
+
|
1092 |
+
default:
|
1093 |
+
debugMessage(kDebugShowController_GoBackToPreviousBuild, "can't go back now, not in an idle state (currently in '" + this.state + "' state)");
|
1094 |
+
|
1095 |
+
if (this.queuedUserAction == null) {
|
1096 |
+
this.queuedUserAction = this.goBackToPreviousBuild.bind(this, context);
|
1097 |
+
}
|
1098 |
+
break;
|
1099 |
+
}
|
1100 |
+
},
|
1101 |
+
|
1102 |
+
advanceAndSkipBuild: function(context) {
|
1103 |
+
// do not proceed if the script is not available
|
1104 |
+
if (!this.script) {
|
1105 |
+
return false;
|
1106 |
+
}
|
1107 |
+
|
1108 |
+
if (this.script.showMode == kShowModeHyperlinksOnly) {
|
1109 |
+
return;
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
1113 |
+
|
1114 |
+
switch (this.state) {
|
1115 |
+
case kShowControllerState_IdleAtFinalState:
|
1116 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
1117 |
+
// Fall through
|
1118 |
+
case kShowControllerState_IdleAtInitialState:
|
1119 |
+
var nextSceneIndex;
|
1120 |
+
|
1121 |
+
if (sceneIndexToUse >= this.script.numScenes - 1) {
|
1122 |
+
if (this.script.loopSlideshow) {
|
1123 |
+
nextSceneIndex = 0;
|
1124 |
+
} else {
|
1125 |
+
return;
|
1126 |
+
}
|
1127 |
+
} else {
|
1128 |
+
nextSceneIndex = sceneIndexToUse + 1;
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
this.jumpToScene(nextSceneIndex, false);
|
1132 |
+
|
1133 |
+
break;
|
1134 |
+
|
1135 |
+
default:
|
1136 |
+
debugMessage(kDebugShowController_GoBackToPreviousBuild, "can't go back now, not in an idle state (currently in '" + this.state + "' state)");
|
1137 |
+
|
1138 |
+
if (this.queuedUserAction == null) {
|
1139 |
+
this.queuedUserAction = this.advanceAndSkipBuild.bind(this, context);
|
1140 |
+
}
|
1141 |
+
break;
|
1142 |
+
}
|
1143 |
+
},
|
1144 |
+
|
1145 |
+
goBackToPreviousSlide: function(context) {
|
1146 |
+
// do not proceed if the script is not available
|
1147 |
+
if (!this.script) {
|
1148 |
+
return false;
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
if (this.script.showMode == kShowModeHyperlinksOnly) {
|
1152 |
+
return;
|
1153 |
+
}
|
1154 |
+
|
1155 |
+
if (this.displayManager.infoPanelIsShowing) {
|
1156 |
+
return;
|
1157 |
+
}
|
1158 |
+
|
1159 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
1160 |
+
|
1161 |
+
switch (this.state) {
|
1162 |
+
case kShowControllerState_IdleAtFinalState:
|
1163 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
1164 |
+
// Fall through
|
1165 |
+
|
1166 |
+
case kShowControllerState_Playing:
|
1167 |
+
case kShowControllerState_IdleAtInitialState:
|
1168 |
+
var currentSlideIndex = this.scriptManager.slideIndexFromSceneIndex(sceneIndexToUse);
|
1169 |
+
var sceneIndexForCurrentSlideIndex = this.scriptManager.sceneIndexFromSlideIndex(currentSlideIndex);
|
1170 |
+
var previousSlideIndex;
|
1171 |
+
|
1172 |
+
if (currentSlideIndex === 0) {
|
1173 |
+
if (sceneIndexToUse > 0) {
|
1174 |
+
// if we are not on first build of the slide, go back to first build of the slide
|
1175 |
+
previousSlideIndex = 0;
|
1176 |
+
} else {
|
1177 |
+
if (this.script.loopSlideshow) {
|
1178 |
+
previousSlideIndex = this.script.slideCount - 1;
|
1179 |
+
} else {
|
1180 |
+
previousSlideIndex = 0;
|
1181 |
+
}
|
1182 |
+
}
|
1183 |
+
} else if (currentSlideIndex === -1 && sceneIndexToUse > 0) {
|
1184 |
+
previousSlideIndex = this.script.slideCount - 1;
|
1185 |
+
} else {
|
1186 |
+
if (sceneIndexToUse > sceneIndexForCurrentSlideIndex) {
|
1187 |
+
// if we are not on first build of the slide, go back to first build of the slide
|
1188 |
+
previousSlideIndex = this.currentSlideIndex;
|
1189 |
+
} else {
|
1190 |
+
// if we are on first build of the slide, go back to previous slide
|
1191 |
+
previousSlideIndex = this.currentSlideIndex - 1;
|
1192 |
+
}
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
this.jumpToSlide(previousSlideIndex + 1);
|
1196 |
+
|
1197 |
+
break;
|
1198 |
+
|
1199 |
+
default:
|
1200 |
+
debugMessage(kDebugShowController_GoBackToPreviousSlide, "can't go back now, not in an idle state (currently in '" + this.state + "' state)");
|
1201 |
+
|
1202 |
+
if (this.queuedUserAction == null) {
|
1203 |
+
this.queuedUserAction = this.goBackToPreviousSlide.bind(this, context);
|
1204 |
+
}
|
1205 |
+
break;
|
1206 |
+
}
|
1207 |
+
},
|
1208 |
+
|
1209 |
+
calculatePreviousSceneIndex: function(sceneIndex) {
|
1210 |
+
if (sceneIndex == -1) {
|
1211 |
+
previousSceneIndex = -1;
|
1212 |
+
}
|
1213 |
+
else {
|
1214 |
+
previousSceneIndex = sceneIndex - 1;
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
return previousSceneIndex;
|
1218 |
+
},
|
1219 |
+
|
1220 |
+
jumpToSlide: function(slideNumber, automaticPlay) {
|
1221 |
+
var slideIndex = slideNumber - 1;
|
1222 |
+
var sceneIndex = this.scriptManager.sceneIndexFromSlideIndex(slideIndex);
|
1223 |
+
|
1224 |
+
// we are jumping to slide, remove all media cache
|
1225 |
+
this.resetMediaCache();
|
1226 |
+
|
1227 |
+
// enable automatic play when the slide it advances to has automatic play
|
1228 |
+
// see <rdar://problem/12781266> Next slide does not auto advance when using keyboard to advance without transiti
|
1229 |
+
if (automaticPlay == null) {
|
1230 |
+
automaticPlay = false;
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
this.jumpToScene(sceneIndex, automaticPlay);
|
1234 |
+
},
|
1235 |
+
|
1236 |
+
jumpToScene: function(sceneIndex, playAnimations) {
|
1237 |
+
this.lastSlideViewedIndex = this.scriptManager.slideIndexFromSceneIndex(this.currentSceneIndex);
|
1238 |
+
if (sceneIndex === -1) {
|
1239 |
+
return;
|
1240 |
+
}
|
1241 |
+
|
1242 |
+
switch (this.state) {
|
1243 |
+
case kShowControllerState_Starting:
|
1244 |
+
// There is a bug in webkit - cursor not being able to change if sitting idle unless it has been moved
|
1245 |
+
// The workaround for the bug without moving the mouse cursor is to change DOM structure to force a redraw
|
1246 |
+
// References: http://code.google.com/p/chromium/issues/detail?id=26723
|
1247 |
+
var cssText = "position:absolute;background-color:transparent; left:0px; top:0px; width:" + this.displayManager.usableDisplayWidth +"px; height:" + this.displayManager.usableDisplayHeight + "px;";
|
1248 |
+
this.starting = true;
|
1249 |
+
this.maskElement = document.createElement("div");
|
1250 |
+
this.maskElement.setAttribute("style",cssText);
|
1251 |
+
document.body.appendChild(this.maskElement);
|
1252 |
+
|
1253 |
+
case kShowControllerState_IdleAtInitialState:
|
1254 |
+
case kShowControllerState_IdleAtFinalState:
|
1255 |
+
case kShowControllerState_ReadyToJump:
|
1256 |
+
break;
|
1257 |
+
|
1258 |
+
default:
|
1259 |
+
debugMessage(kDebugShowController_JumpToScene, "can't jump now, currently in '" + this.state + "' state which does not supports jumping...");
|
1260 |
+
return;
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
if (this.textureManager.isScenePreloaded(sceneIndex) === false) {
|
1264 |
+
this.changeState(kShowControllerState_WaitingToJump);
|
1265 |
+
|
1266 |
+
// loadScene with callback handler and params
|
1267 |
+
var sceneToLoadInfo = {
|
1268 |
+
sceneIndex: sceneIndex,
|
1269 |
+
automaticPlay: playAnimations
|
1270 |
+
};
|
1271 |
+
|
1272 |
+
this.waitForSceneToLoadTimeout = setTimeout(this.handleSceneDidNotLoad.bind(this, sceneToLoadInfo), kMaxSceneDownloadWaitTime);
|
1273 |
+
this.textureManager.loadScene(sceneIndex, this.handleSceneDidLoad.bind(this, sceneToLoadInfo));
|
1274 |
+
|
1275 |
+
return;
|
1276 |
+
}
|
1277 |
+
|
1278 |
+
this.changeState(kShowControllerState_SettingUpScene);
|
1279 |
+
|
1280 |
+
runInNextEventLoop(this.jumpToScene_partThree.bind(this, sceneIndex, playAnimations));
|
1281 |
+
},
|
1282 |
+
|
1283 |
+
handleSceneDidLoad: function(sceneToLoadInfo) {
|
1284 |
+
clearTimeout(this.waitForSceneToLoadTimeout);
|
1285 |
+
this.displayManager.setNextButtonEnabled(this.currentSceneIndex < (this.script.pageCount - 1));
|
1286 |
+
|
1287 |
+
switch (this.state) {
|
1288 |
+
case kShowControllerState_WaitingToJump:
|
1289 |
+
this.changeState(kShowControllerState_ReadyToJump);
|
1290 |
+
this.jumpToScene_partTwo(sceneToLoadInfo.sceneIndex, sceneToLoadInfo.automaticPlay);
|
1291 |
+
break;
|
1292 |
+
|
1293 |
+
default:
|
1294 |
+
break;
|
1295 |
+
}
|
1296 |
+
},
|
1297 |
+
|
1298 |
+
handleSceneDidNotLoad: function(sceneToLoadInfo) {
|
1299 |
+
clearTimeout(this.waitForSceneToLoadTimeout);
|
1300 |
+
this.queuedUserAction = null;
|
1301 |
+
|
1302 |
+
var tryAgain = this.promptUserToTryAgain(kUnableToReachiWorkTryAgain);
|
1303 |
+
|
1304 |
+
if (tryAgain) {
|
1305 |
+
// restarting player with sceneIndex
|
1306 |
+
var currentUrl = window.location.href;
|
1307 |
+
var croppedUrl;
|
1308 |
+
var indexOfRestartParam = currentUrl.indexOf("&restartingSceneIndex");
|
1309 |
+
|
1310 |
+
if (indexOfRestartParam === -1) {
|
1311 |
+
croppedUrl = currentUrl;
|
1312 |
+
} else {
|
1313 |
+
croppedUrl = currentUrl.substring(0, indexOfRestartParam);
|
1314 |
+
}
|
1315 |
+
|
1316 |
+
var newUrl = croppedUrl + "&restartingSceneIndex=" + sceneToLoadInfo.sceneIndex;
|
1317 |
+
window.location.replace(newUrl);
|
1318 |
+
} else {
|
1319 |
+
this.changeState(kShowControllerState_IdleAtFinalState);
|
1320 |
+
}
|
1321 |
+
},
|
1322 |
+
|
1323 |
+
jumpToScene_partTwo: function(sceneIndex, playAnimations) {
|
1324 |
+
this.changeState(kShowControllerState_SettingUpScene);
|
1325 |
+
|
1326 |
+
// state changed (UI controls should disable), run partThree in next event loop
|
1327 |
+
runInNextEventLoop(this.jumpToScene_partThree.bind(this, sceneIndex, playAnimations));
|
1328 |
+
},
|
1329 |
+
|
1330 |
+
jumpToScene_partThree: function(sceneIndex, playAnimations) {
|
1331 |
+
var delayBeforeNextPart = false;
|
1332 |
+
|
1333 |
+
if (delayBeforeNextPart) {
|
1334 |
+
runInNextEventLoop(this.jumpToScene_partFour.bind(this, sceneIndex, playAnimations));
|
1335 |
+
} else {
|
1336 |
+
this.jumpToScene_partFour(sceneIndex, playAnimations);
|
1337 |
+
}
|
1338 |
+
},
|
1339 |
+
|
1340 |
+
jumpToScene_partFour: function(sceneIndex, playAnimations) {
|
1341 |
+
this.displayScene(sceneIndex);
|
1342 |
+
|
1343 |
+
if (this.starting) {
|
1344 |
+
// There is a bug in webkit - cursor not being able to change if sitting idle unless it has been moved
|
1345 |
+
// The workaround for the bug without moving the mouse cursor is to change DOM structure to force a redraw
|
1346 |
+
// References: http://code.google.com/p/chromium/issues/detail?id=26723
|
1347 |
+
if (this.maskElement != null) {
|
1348 |
+
document.body.removeChild(this.maskElement);
|
1349 |
+
this.maskElement = null;
|
1350 |
+
this.starting = false;
|
1351 |
+
}
|
1352 |
+
|
1353 |
+
window.focus();
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
if (this.helpPlacard.isShowing) {
|
1357 |
+
this.helpPlacard.hide();
|
1358 |
+
}
|
1359 |
+
|
1360 |
+
if (this.slideNumberDisplay.isShowing) {
|
1361 |
+
this.slideNumberDisplay.hide();
|
1362 |
+
}
|
1363 |
+
|
1364 |
+
if (this.slideNumberController.isShowing) {
|
1365 |
+
if (this.slideNumberTimeout) {
|
1366 |
+
clearTimeout(this.slideNumberTimeout);
|
1367 |
+
}
|
1368 |
+
this.slideNumberTimeout = setTimeout(this.hideAndResetSlideNumberController.bind(this), 500);
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
if (playAnimations) {
|
1372 |
+
var script = this.script;
|
1373 |
+
|
1374 |
+
if (script.showMode === kShowModeAutoplay) {
|
1375 |
+
var event = script.events[sceneIndex];
|
1376 |
+
var effects = event.effects;
|
1377 |
+
|
1378 |
+
if (effects && effects.length > 0) {
|
1379 |
+
var delay = effects[0].type === "transition" ? script.autoplayTransitionDelay : script.autoplayBuildDelay;
|
1380 |
+
|
1381 |
+
setTimeout((function(){this.playCurrentScene();}).bind(this), delay * 1000);
|
1382 |
+
} else {
|
1383 |
+
this.playCurrentScene();
|
1384 |
+
}
|
1385 |
+
} else {
|
1386 |
+
this.playCurrentScene();
|
1387 |
+
}
|
1388 |
+
} else {
|
1389 |
+
this.changeState(kShowControllerState_IdleAtInitialState);
|
1390 |
+
|
1391 |
+
if (this.isRecording && !this.isRecordingStarted) {
|
1392 |
+
this.narrationManager.start();
|
1393 |
+
this.isRecordingStarted = true;
|
1394 |
+
}
|
1395 |
+
}
|
1396 |
+
},
|
1397 |
+
|
1398 |
+
displayScene: function(sceneIndex, hyperlinkEvent) {
|
1399 |
+
if (sceneIndex === -1) {
|
1400 |
+
return;
|
1401 |
+
}
|
1402 |
+
|
1403 |
+
// remove all css
|
1404 |
+
this.animationManager.deleteAllAnimations();
|
1405 |
+
|
1406 |
+
// clean up media cache if we are advancing to different slide
|
1407 |
+
var outgoingSlideIndex = this.scriptManager.slideIndexFromSceneIndex(this.currentSceneIndex);
|
1408 |
+
var incomingSlideIndex = hyperlinkEvent ? hyperlinkEvent.slideIndex : this.scriptManager.slideIndexFromSceneIndex(sceneIndex);
|
1409 |
+
|
1410 |
+
if (outgoingSlideIndex !== incomingSlideIndex) {
|
1411 |
+
this.resetMediaCache();
|
1412 |
+
}
|
1413 |
+
|
1414 |
+
// set currentSceneIndex
|
1415 |
+
this.setCurrentSceneIndexTo(sceneIndex);
|
1416 |
+
|
1417 |
+
if (hyperlinkEvent) {
|
1418 |
+
this.playbackController.renderEvent(hyperlinkEvent);
|
1419 |
+
} else {
|
1420 |
+
var slideIndex = this.script.slideIndexFromSceneIndexLookup[sceneIndex];
|
1421 |
+
var slideId = this.script.slideList[slideIndex];
|
1422 |
+
|
1423 |
+
var kpfEvent = new KPFEvent({
|
1424 |
+
"slideId": slideId,
|
1425 |
+
"slideIndex": slideIndex,
|
1426 |
+
"sceneIndex": sceneIndex,
|
1427 |
+
"event": this.script.events[sceneIndex],
|
1428 |
+
"animationSupported": this.animationSupported
|
1429 |
+
});
|
1430 |
+
|
1431 |
+
this.playbackController.renderEvent(kpfEvent);
|
1432 |
+
}
|
1433 |
+
|
1434 |
+
this.updateNavigationButtons();
|
1435 |
+
},
|
1436 |
+
|
1437 |
+
setCurrentSceneIndexTo: function(sceneIndex) {
|
1438 |
+
this.currentSceneIndex = sceneIndex;
|
1439 |
+
this.assignNextSceneIndex();
|
1440 |
+
|
1441 |
+
this.updateSlideNumber();
|
1442 |
+
this.updateNavigationButtons();
|
1443 |
+
},
|
1444 |
+
|
1445 |
+
assignNextSceneIndex: function() {
|
1446 |
+
this.nextSceneIndex = this.calculateNextSceneIndex(this.currentSceneIndex);
|
1447 |
+
},
|
1448 |
+
|
1449 |
+
calculateNextSceneIndex: function(sceneIndex) {
|
1450 |
+
var nextSceneIndex = this.calculateNextSceneIndex_internal(sceneIndex);
|
1451 |
+
|
1452 |
+
return nextSceneIndex;
|
1453 |
+
},
|
1454 |
+
|
1455 |
+
calculateNextSceneIndex_internal: function(sceneIndex) {
|
1456 |
+
var nextSceneIndex = -1;
|
1457 |
+
|
1458 |
+
if (sceneIndex < this.script.lastSceneIndex) {
|
1459 |
+
nextSceneIndex = sceneIndex + 1;
|
1460 |
+
} else {
|
1461 |
+
if (this.script.loopSlideshow) {
|
1462 |
+
nextSceneIndex = 0;
|
1463 |
+
} else {
|
1464 |
+
nextSceneIndex = -1;
|
1465 |
+
}
|
1466 |
+
}
|
1467 |
+
|
1468 |
+
return nextSceneIndex;
|
1469 |
+
},
|
1470 |
+
|
1471 |
+
updateSlideNumber: function() {
|
1472 |
+
var adjustedSceneIndex = this.currentSceneIndex;
|
1473 |
+
|
1474 |
+
if (this.state === kShowControllerState_IdleAtFinalState) {
|
1475 |
+
// because we're waiting at end state, we need to add one...
|
1476 |
+
adjustedSceneIndex = this.nextSceneIndex;
|
1477 |
+
}
|
1478 |
+
|
1479 |
+
var newSlideIndex = this.scriptManager.slideIndexFromSceneIndex(adjustedSceneIndex);
|
1480 |
+
|
1481 |
+
if (this.firstSlide) {
|
1482 |
+
this.displayManager.hideWaitingIndicator();
|
1483 |
+
|
1484 |
+
runInNextEventLoop((function() {
|
1485 |
+
this.startSoundTrack();
|
1486 |
+
this.displayManager.clearLaunchMode();
|
1487 |
+
}).bind(this));
|
1488 |
+
this.firstSlide = false;
|
1489 |
+
}
|
1490 |
+
|
1491 |
+
if (this.currentSlideIndex != newSlideIndex) {
|
1492 |
+
this.previousSlideIndex = this.currentSlideIndex;
|
1493 |
+
this.currentSlideIndex = newSlideIndex;
|
1494 |
+
|
1495 |
+
this.displayManager.updateSlideNumber(this.currentSlideIndex + 1, this.script.slideCount);
|
1496 |
+
this.delegate.propertyChanged(kPropertyName_currentSlide, this.currentSlideIndex + 1);
|
1497 |
+
|
1498 |
+
// fire SlideIndexDidChangeEvent
|
1499 |
+
document.fire(kSlideIndexDidChangeEvent, {
|
1500 |
+
slideIndex: this.currentSlideIndex
|
1501 |
+
});
|
1502 |
+
}
|
1503 |
+
},
|
1504 |
+
|
1505 |
+
updateNavigationButtons: function() {
|
1506 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
1507 |
+
|
1508 |
+
if (this.state === kShowControllerState_IdleAtFinalState) {
|
1509 |
+
sceneIndexToUse++;
|
1510 |
+
}
|
1511 |
+
|
1512 |
+
this.updateWindowHistory(sceneIndexToUse);
|
1513 |
+
|
1514 |
+
var enableBackwardButton = false;
|
1515 |
+
var enableForwardButton = false
|
1516 |
+
|
1517 |
+
if (this.script.lastSceneIndex === -1) {
|
1518 |
+
// this slideshow has only 1 slide with no builds, both buttons are
|
1519 |
+
// disabled
|
1520 |
+
enableForwardButton = false;
|
1521 |
+
enableBackwardButton = false;
|
1522 |
+
} else if (this.script.loopSlideshow) {
|
1523 |
+
// this is a looping slideshow, both buttons are ALWAYS enabled
|
1524 |
+
enableForwardButton = true;
|
1525 |
+
enableBackwardButton = true;
|
1526 |
+
} else {
|
1527 |
+
if (sceneIndexToUse > 0) {
|
1528 |
+
// sceneIndexToUse > 0, so enable backward button
|
1529 |
+
enableBackwardButton = true;
|
1530 |
+
}
|
1531 |
+
|
1532 |
+
if (sceneIndexToUse === 0 && this.script.lastSceneIndex === 0) {
|
1533 |
+
// sceneIndexToUse & lastSceneIndex are both 0 - show with 1
|
1534 |
+
// slide with 1 build, so enable forward button
|
1535 |
+
enableForwardButton = true;
|
1536 |
+
} else if (this.currentSceneIndex < this.script.lastSceneIndex) {
|
1537 |
+
// currentSceneIndex < lastSceneIndex, so enable forward button
|
1538 |
+
enableForwardButton = true;
|
1539 |
+
} else if (this.currentSceneIndex === this.script.lastSceneIndex) {
|
1540 |
+
if (this.state === kShowControllerState_IdleAtInitialState) {
|
1541 |
+
// currentSceneIndex === lastSceneIndex, but we're at the
|
1542 |
+
// intitial state, so enable forward button
|
1543 |
+
enableForwardButton = true;
|
1544 |
+
} else {
|
1545 |
+
// currentSceneIndex === lastSceneIndex, and we're at the
|
1546 |
+
// final state, so disable forward button
|
1547 |
+
enableForwardButton = false;
|
1548 |
+
}
|
1549 |
+
} else {
|
1550 |
+
// currentSceneIndex > lastSceneIndex, show with 1 slide and no
|
1551 |
+
// builds, so disable forward button
|
1552 |
+
enableForwardButton = false;
|
1553 |
+
}
|
1554 |
+
}
|
1555 |
+
|
1556 |
+
this.displayManager.setPreviousButtonEnabled(enableBackwardButton);
|
1557 |
+
this.displayManager.setNextButtonEnabled(enableForwardButton);
|
1558 |
+
},
|
1559 |
+
|
1560 |
+
playCurrentScene: function(hyperlinkEventInfo) {
|
1561 |
+
var previousState = this.state;
|
1562 |
+
var sceneIndexToJump;
|
1563 |
+
var delay = 0;
|
1564 |
+
var duration = this.playbackController.eventOverallEndTime();
|
1565 |
+
|
1566 |
+
this.changeState(kShowControllerState_Playing);
|
1567 |
+
|
1568 |
+
this.clearAllHyperlinks();
|
1569 |
+
|
1570 |
+
if (this.helpPlacard.isShowing) {
|
1571 |
+
this.helpPlacard.hide();
|
1572 |
+
}
|
1573 |
+
|
1574 |
+
if (this.slideNumberDisplay.isShowing) {
|
1575 |
+
this.slideNumberDisplay.hide();
|
1576 |
+
}
|
1577 |
+
|
1578 |
+
if (hyperlinkEventInfo) {
|
1579 |
+
sceneIndexToJump = hyperlinkEventInfo.sceneIndexToJump;
|
1580 |
+
|
1581 |
+
// clean up media cache if we are playing hyperlink transition
|
1582 |
+
this.resetMediaCache();
|
1583 |
+
} else {
|
1584 |
+
sceneIndexToJump = this.nextSceneIndex;
|
1585 |
+
|
1586 |
+
// clean up media cache if we are advancing to different slide
|
1587 |
+
var outgoingSlideIndex = this.scriptManager.slideIndexFromSceneIndex(this.currentSceneIndex);
|
1588 |
+
var incomingSlideIndex = this.scriptManager.slideIndexFromSceneIndex(sceneIndexToJump);
|
1589 |
+
|
1590 |
+
if (outgoingSlideIndex !== incomingSlideIndex) {
|
1591 |
+
this.resetMediaCache();
|
1592 |
+
}
|
1593 |
+
|
1594 |
+
// for transition, the delay time is no longer coded into animations.
|
1595 |
+
// set delay time and duration for automaticPlay transition
|
1596 |
+
if (this.playbackController.kpfEvent.event.automaticPlay == true && this.playbackController.kpfEvent.event.effects[0].type === "transition") {
|
1597 |
+
delay = this.playbackController.kpfEvent.event.effects[0].beginTime;
|
1598 |
+
duration = this.playbackController.kpfEvent.event.effects[0].duration;
|
1599 |
+
}
|
1600 |
+
}
|
1601 |
+
|
1602 |
+
if (this.animationSupported) {
|
1603 |
+
// animate events
|
1604 |
+
// Chrome chokes up in some animations if starting animations immediately after layer drawings all on the main thread
|
1605 |
+
// Start animations in a background thread will improve performance
|
1606 |
+
// see <rdar://problem/12636430> DEMO: Chrome performance issues with cube, flip, push
|
1607 |
+
clearTimeout(this.animateTimeout);
|
1608 |
+
|
1609 |
+
var effects = this.playbackController.kpfEvent.event.effects;
|
1610 |
+
|
1611 |
+
// if the event has no effects then no need to render effects
|
1612 |
+
if (effects.length === 0) {
|
1613 |
+
this.animateTimeout = setTimeout((function(){
|
1614 |
+
setTimeout(this.currentSceneDidComplete.bind(this, sceneIndexToJump), duration * 1000 + 100);
|
1615 |
+
}).bind(this), delay * 1000);
|
1616 |
+
} else {
|
1617 |
+
var renderedEffects;
|
1618 |
+
// for performance consideration, render the effects as soon as we start playing so the effects are prepared and ready to animate
|
1619 |
+
// for blinds there is an issue with incoming particles on top of ougoing particles
|
1620 |
+
// since we don't want to show incoming particles before the animations start, we will render the effect later after delay as an exception case
|
1621 |
+
if (effects[0].type === "transition") {
|
1622 |
+
if (isIE || isEdge) {
|
1623 |
+
// Blinds fallback to dissolve on IE so ok to render here without seeing particle in reverse order
|
1624 |
+
renderedEffects = this.playbackController.renderEffects();
|
1625 |
+
} else {
|
1626 |
+
if (effects[0].name != "com.apple.iWork.Keynote.BLTBlinds") {
|
1627 |
+
renderedEffects = this.playbackController.renderEffects();
|
1628 |
+
}
|
1629 |
+
}
|
1630 |
+
}
|
1631 |
+
|
1632 |
+
// account for transition delay and start animating the effects after transition delay
|
1633 |
+
this.animateTimeout = setTimeout((function(renderedEffects){
|
1634 |
+
if (renderedEffects == null) {
|
1635 |
+
renderedEffects = this.playbackController.renderEffects();
|
1636 |
+
}
|
1637 |
+
this.playbackController.animateEffects(renderedEffects);
|
1638 |
+
setTimeout(this.currentSceneDidComplete.bind(this, sceneIndexToJump), duration * 1000 + 100);
|
1639 |
+
}).bind(this, renderedEffects), delay * 1000);
|
1640 |
+
}
|
1641 |
+
} else {
|
1642 |
+
var automatic = this.script.events[this.currentSceneIndex].automaticPlay;
|
1643 |
+
|
1644 |
+
if (sceneIndexToJump === -1) {
|
1645 |
+
this.updateNavigationButtons();
|
1646 |
+
if (this.delegate.getKPFJsonStringForShow) {
|
1647 |
+
if (automatic) {
|
1648 |
+
setTimeout(this.exitShow.bind(this), 2000);
|
1649 |
+
} else {
|
1650 |
+
this.exitShow();
|
1651 |
+
}
|
1652 |
+
} else {
|
1653 |
+
this.changeState(kShowControllerState_IdleAtInitialState);
|
1654 |
+
}
|
1655 |
+
} else {
|
1656 |
+
// For IE9, animate current event means jump to next slide since there is no animated end state
|
1657 |
+
if (automatic) {
|
1658 |
+
// For IE9, do a flat 2 sec delay for any automatic event to jump to next scene
|
1659 |
+
setTimeout(
|
1660 |
+
(function(){
|
1661 |
+
this.changeState(kShowControllerState_IdleAtInitialState);
|
1662 |
+
this.jumpToScene(sceneIndexToJump, this.script.events[sceneIndexToJump].automaticPlay);
|
1663 |
+
}).bind(this), 2000);
|
1664 |
+
} else {
|
1665 |
+
// if it's not automatic then jump to next scene
|
1666 |
+
this.changeState(kShowControllerState_IdleAtInitialState);
|
1667 |
+
setTimeout(this.jumpToScene.bind(this, sceneIndexToJump, this.script.events[sceneIndexToJump].automaticPlay), 100);
|
1668 |
+
}
|
1669 |
+
}
|
1670 |
+
}
|
1671 |
+
|
1672 |
+
},
|
1673 |
+
|
1674 |
+
currentSceneDidComplete: function(sceneIndexToJump) {
|
1675 |
+
var script = this.script;
|
1676 |
+
var showMode = script.showMode;
|
1677 |
+
|
1678 |
+
// hide slide number display after playing current scene
|
1679 |
+
if (this.slideNumberDisplay.isShowing) {
|
1680 |
+
this.slideNumberDisplay.hide();
|
1681 |
+
}
|
1682 |
+
|
1683 |
+
// change state to final after animation completed
|
1684 |
+
this.changeState(kShowControllerState_IdleAtFinalState);
|
1685 |
+
|
1686 |
+
if (showMode == kShowModeHyperlinksOnly || (sceneIndexToJump != -1 && sceneIndexToJump != this.nextSceneIndex)) {
|
1687 |
+
// if the show mode is hyperlink only
|
1688 |
+
// or if we play hyperlink transition that jumps to a slide which is not its next slide
|
1689 |
+
// then jump to the slide after transition
|
1690 |
+
var event = script.events[sceneIndexToJump];
|
1691 |
+
var automaticPlay = event.automaticPlay == 1 || event.automaticPlay == true;
|
1692 |
+
this.jumpToScene(sceneIndexToJump, automaticPlay);
|
1693 |
+
} else if (this.nextSceneIndex === -1) {
|
1694 |
+
// if next index is -1
|
1695 |
+
this.updateNavigationButtons();
|
1696 |
+
if (this.delegate.getKPFJsonStringForShow) {
|
1697 |
+
this.stopSoundTrack();
|
1698 |
+
this.exitShow();
|
1699 |
+
} else {
|
1700 |
+
this.stopSoundTrack();
|
1701 |
+
}
|
1702 |
+
} else if (script.events[this.nextSceneIndex].automaticPlay || showMode === kShowModeAutoplay) {
|
1703 |
+
// invoking advanceToNextBuild() on next event loop
|
1704 |
+
runInNextEventLoop(this.advanceToNextBuild.bind(this, "currentSceneDidComplete"));
|
1705 |
+
}
|
1706 |
+
},
|
1707 |
+
|
1708 |
+
resetMediaCache: function() {
|
1709 |
+
this.resetMovieCache();
|
1710 |
+
this.resetAudioCache();
|
1711 |
+
},
|
1712 |
+
|
1713 |
+
resetMovieCache: function() {
|
1714 |
+
for (var movieId in this.movieCache) {
|
1715 |
+
delete this.movieCache[movieId].videoElement;
|
1716 |
+
delete this.movieCache[movieId];
|
1717 |
+
}
|
1718 |
+
|
1719 |
+
this.movieCache = null;
|
1720 |
+
},
|
1721 |
+
|
1722 |
+
resetAudioCache: function() {
|
1723 |
+
for (var audioId in this.audioCache) {
|
1724 |
+
this.audioCache[audioId].pause();
|
1725 |
+
this.audioCache[audioId].src = "";
|
1726 |
+
|
1727 |
+
delete this.audioCache[audioId];
|
1728 |
+
}
|
1729 |
+
this.audioCache = null;
|
1730 |
+
},
|
1731 |
+
|
1732 |
+
updateWindowHistory: function(sceneIndex) {
|
1733 |
+
// update url
|
1734 |
+
if (typeof(window.history.replaceState) != "undefined") {
|
1735 |
+
var currentUrl = document.URL.split("?");
|
1736 |
+
var fragments = currentUrl[0].split("#");
|
1737 |
+
if (window.location.protocol !== "file:") {
|
1738 |
+
window.history.replaceState(null, "Keynote", fragments[0] + "#" + sceneIndex + (currentUrl[1] ? "?" + currentUrl[1] : ""));
|
1739 |
+
}
|
1740 |
+
}
|
1741 |
+
},
|
1742 |
+
|
1743 |
+
startSoundTrack: function() {
|
1744 |
+
if (gMode === kModeMobile) {
|
1745 |
+
return;
|
1746 |
+
}
|
1747 |
+
|
1748 |
+
if (this.script.soundtrack == null) {
|
1749 |
+
return;
|
1750 |
+
}
|
1751 |
+
|
1752 |
+
if (this.script.soundtrack.tracks == null) {
|
1753 |
+
return;
|
1754 |
+
}
|
1755 |
+
|
1756 |
+
if (this.script.soundtrack.mode === kSoundTrackModeOff) {
|
1757 |
+
return;
|
1758 |
+
}
|
1759 |
+
|
1760 |
+
this.currentSoundTrackIndex = 0;
|
1761 |
+
this.playNextItemInSoundTrack();
|
1762 |
+
},
|
1763 |
+
|
1764 |
+
stopSoundTrack: function() {
|
1765 |
+
if (this.soundTrackPlayer) {
|
1766 |
+
this.soundTrackPlayer.stopObserving("ended");
|
1767 |
+
this.soundTrackPlayer.pause();
|
1768 |
+
this.soundTrackPlayer = null;
|
1769 |
+
}
|
1770 |
+
},
|
1771 |
+
|
1772 |
+
playNextItemInSoundTrack: function() {
|
1773 |
+
var soundtrackUrl = this.script.soundtrack.tracks[this.currentSoundTrackIndex];
|
1774 |
+
|
1775 |
+
this.soundTrackPlayer = new Audio();
|
1776 |
+
this.soundTrackPlayer.src = "../" + soundtrackUrl;
|
1777 |
+
this.soundTrackPlayer.volume = this.script.soundtrack.volume;
|
1778 |
+
this.soundTrackPlayer.observe("ended", this.soundTrackItemDidComplete.bind(this), false);
|
1779 |
+
this.soundTrackPlayer.load();
|
1780 |
+
this.soundTrackPlayer.play();
|
1781 |
+
},
|
1782 |
+
|
1783 |
+
soundTrackItemDidComplete: function() {
|
1784 |
+
// check to see if there's anything else to play
|
1785 |
+
this.currentSoundTrackIndex++;
|
1786 |
+
if (this.currentSoundTrackIndex < this.script.soundtrack.tracks.length) {
|
1787 |
+
this.playNextItemInSoundTrack();
|
1788 |
+
} else {
|
1789 |
+
if (this.script.soundtrack.mode === kSoundTrackModePlayOnce) {
|
1790 |
+
this.soundTrackPlayer = null;
|
1791 |
+
} else if (this.script.soundtrack.mode === kSoundTrackModeLooping) {
|
1792 |
+
// nope, but we're in loop mode so take it from the top
|
1793 |
+
this.startSoundTrack();
|
1794 |
+
}
|
1795 |
+
}
|
1796 |
+
},
|
1797 |
+
|
1798 |
+
processHyperlink: function(hyperlink) {
|
1799 |
+
var hyperlinkUrl = hyperlink.url;
|
1800 |
+
var hyperlinkEffect;
|
1801 |
+
|
1802 |
+
// perform hyperlink jump
|
1803 |
+
if (hyperlinkUrl.indexOf("?slide=") === 0) {
|
1804 |
+
var key = hyperlinkUrl.substring(7);
|
1805 |
+
var newSlideIndex = -1;
|
1806 |
+
|
1807 |
+
if (key === "first") {
|
1808 |
+
newSlideIndex = 0;
|
1809 |
+
} else if (key === "last") {
|
1810 |
+
newSlideIndex = this.script.slideCount - 1;
|
1811 |
+
} else {
|
1812 |
+
var sceneIndexToUse = this.currentSceneIndex;
|
1813 |
+
var nextSlideIndex = -1;
|
1814 |
+
switch (this.state) {
|
1815 |
+
case kShowControllerState_IdleAtFinalState:
|
1816 |
+
sceneIndexToUse = sceneIndexToUse + 1;
|
1817 |
+
case kShowControllerState_IdleAtInitialState:
|
1818 |
+
var currentSlideIndex = this.scriptManager.slideIndexFromSceneIndex(sceneIndexToUse);
|
1819 |
+
if (key === "next") {
|
1820 |
+
if (currentSlideIndex === this.script.slideCount - 1) {
|
1821 |
+
if (this.script.loopSlideshow) {
|
1822 |
+
nextSlideIndex = 0;
|
1823 |
+
} else {
|
1824 |
+
if (this.delegate.getKPFJsonStringForShow) {
|
1825 |
+
this.exitShow();
|
1826 |
+
}
|
1827 |
+
}
|
1828 |
+
} else {
|
1829 |
+
nextSlideIndex = currentSlideIndex + 1;
|
1830 |
+
}
|
1831 |
+
} else if (key === "previous") {
|
1832 |
+
if (currentSlideIndex === 0) {
|
1833 |
+
if (this.script.loopSlideshow) {
|
1834 |
+
nextSlideIndex = this.script.slideCount - 1;
|
1835 |
+
} else {
|
1836 |
+
nextSlideIndex = 0;
|
1837 |
+
}
|
1838 |
+
} else {
|
1839 |
+
nextSlideIndex = currentSlideIndex - 1;
|
1840 |
+
}
|
1841 |
+
}
|
1842 |
+
break;
|
1843 |
+
|
1844 |
+
default:
|
1845 |
+
break;
|
1846 |
+
}
|
1847 |
+
newSlideIndex = nextSlideIndex;
|
1848 |
+
|
1849 |
+
}
|
1850 |
+
|
1851 |
+
if (newSlideIndex != -1) {
|
1852 |
+
this.jumpToHyperlinkSlide(newSlideIndex, hyperlink);
|
1853 |
+
}
|
1854 |
+
} else if (hyperlinkUrl.indexOf("?slideid=") === 0) {
|
1855 |
+
// find by slideId
|
1856 |
+
var slideId = hyperlinkUrl.substring(9);
|
1857 |
+
var slideList = this.script.slideList;
|
1858 |
+
var newSlideIndex = -1;
|
1859 |
+
|
1860 |
+
for (var i = 0, length = slideList.length; i < length; i++) {
|
1861 |
+
if (slideList[i] === slideId) {
|
1862 |
+
newSlideIndex = i;
|
1863 |
+
break;
|
1864 |
+
}
|
1865 |
+
}
|
1866 |
+
|
1867 |
+
if (newSlideIndex != -1) {
|
1868 |
+
this.jumpToHyperlinkSlide(newSlideIndex, hyperlink);
|
1869 |
+
}
|
1870 |
+
} else if (hyperlinkUrl.indexOf("?action=retreat") === 0) {
|
1871 |
+
// jump to the last slide viewed
|
1872 |
+
if (this.lastSlideViewedIndex != -1) {
|
1873 |
+
this.jumpToHyperlinkSlide(this.lastSlideViewedIndex, hyperlink);
|
1874 |
+
}
|
1875 |
+
} else if (hyperlinkUrl.indexOf("?action=exitpresentation") === 0) {
|
1876 |
+
// exit show
|
1877 |
+
this.exitShow();
|
1878 |
+
} else if (hyperlinkUrl.indexOf("http:") === 0 || hyperlinkUrl.indexOf("https:") === 0) {
|
1879 |
+
// jump to a web page
|
1880 |
+
window.open(hyperlinkUrl, "_blank", null);
|
1881 |
+
} else if (hyperlinkUrl.indexOf("mailto:") === 0) {
|
1882 |
+
// email link
|
1883 |
+
window.location = hyperlinkUrl;
|
1884 |
+
}
|
1885 |
+
},
|
1886 |
+
|
1887 |
+
jumpToHyperlinkSlide: function(slideIndexToJump, hyperlink) {
|
1888 |
+
//var hyperlinkEffects = hyperlink.effects;
|
1889 |
+
var hyperlinkEvents = hyperlink.events;
|
1890 |
+
var sceneIndexToJump = this.script.sceneIndexFromSlideIndexLookup[slideIndexToJump];
|
1891 |
+
|
1892 |
+
if (hyperlinkEvents) {
|
1893 |
+
// if hyperlink has effect then display scene and use hyperlink event
|
1894 |
+
var slideIdToJump = this.script.slideList[slideIndexToJump];
|
1895 |
+
var hyperlinkEvent = hyperlinkEvents[slideIdToJump];
|
1896 |
+
|
1897 |
+
if (hyperlinkEvent) {
|
1898 |
+
var sceneIndexOfHyperlink = this.currentSceneIndex;
|
1899 |
+
|
1900 |
+
switch (this.state) {
|
1901 |
+
case kShowControllerState_IdleAtFinalState:
|
1902 |
+
if (sceneIndexOfHyperlink < this.script.numScenes - 1) {
|
1903 |
+
sceneIndexOfHyperlink = sceneIndexOfHyperlink + 1;
|
1904 |
+
} else {
|
1905 |
+
if (this.script.loopSlideshow) {
|
1906 |
+
sceneIndexOfHyperlink = 0;
|
1907 |
+
}
|
1908 |
+
}
|
1909 |
+
case kShowControllerState_IdleAtInitialState:
|
1910 |
+
var slideIndexOfHyperlink = this.script.slideIndexFromSceneIndexLookup[sceneIndexOfHyperlink];
|
1911 |
+
var slideIdOfHyperlink = this.script.slideList[slideIndexOfHyperlink];
|
1912 |
+
|
1913 |
+
var kpfEvent = new KPFEvent({
|
1914 |
+
"slideId": slideIdOfHyperlink,
|
1915 |
+
"slideIndex": slideIndexOfHyperlink,
|
1916 |
+
"sceneIndex": sceneIndexOfHyperlink,
|
1917 |
+
"event": hyperlinkEvent,
|
1918 |
+
"animationSupported": this.animationSupported
|
1919 |
+
});
|
1920 |
+
|
1921 |
+
// display scene that contains hyperlink and use hyperlink event
|
1922 |
+
this.displayScene(sceneIndexOfHyperlink, kpfEvent);
|
1923 |
+
|
1924 |
+
// play current hyperlink scene
|
1925 |
+
this.playCurrentScene({"sceneIndexToJump": sceneIndexToJump});
|
1926 |
+
|
1927 |
+
break;
|
1928 |
+
|
1929 |
+
default:
|
1930 |
+
return;
|
1931 |
+
}
|
1932 |
+
} else {
|
1933 |
+
// if no hyperlink effect, just jump to slide
|
1934 |
+
var event = this.script.events[sceneIndexToJump];
|
1935 |
+
var automaticPlay = event.automaticPlay == 1 || event.automaticPlay == true;
|
1936 |
+
this.jumpToSlide(slideIndexToJump + 1, automaticPlay);
|
1937 |
+
}
|
1938 |
+
} else {
|
1939 |
+
// if no hyperlink effect, just jump to slide
|
1940 |
+
var event = this.script.events[sceneIndexToJump];
|
1941 |
+
var automaticPlay = event.automaticPlay == 1 || event.automaticPlay == true;
|
1942 |
+
this.jumpToSlide(slideIndexToJump + 1, automaticPlay);
|
1943 |
+
}
|
1944 |
+
},
|
1945 |
+
|
1946 |
+
addMovieHyperlink: function(targetRectangle, url) {
|
1947 |
+
var newHyperlink = {
|
1948 |
+
targetRectangle: targetRectangle,
|
1949 |
+
url: url
|
1950 |
+
};
|
1951 |
+
this.movieHyperlinks.push(newHyperlink);
|
1952 |
+
},
|
1953 |
+
|
1954 |
+
clearMovieHyperlinks: function() {
|
1955 |
+
delete this.movieHyperlinks;
|
1956 |
+
this.movieHyperlinks = new Array();
|
1957 |
+
},
|
1958 |
+
|
1959 |
+
clearAllHyperlinks: function() {
|
1960 |
+
this.stageManager.clearAllHyperlinks();
|
1961 |
+
|
1962 |
+
delete this.activeHyperlinks;
|
1963 |
+
this.activeHyperlinks = new Array();
|
1964 |
+
},
|
1965 |
+
|
1966 |
+
findHyperlinkAtCoOrds: function(showCoOrds) {
|
1967 |
+
var numHyperlinks = this.activeHyperlinks != null ? this.activeHyperlinks.length : 0;
|
1968 |
+
|
1969 |
+
for (var i = numHyperlinks; i > 0; i--) {
|
1970 |
+
var hyperlink = this.activeHyperlinks[i - 1];
|
1971 |
+
var hyperlinkRect = hyperlink.targetRectangle;
|
1972 |
+
|
1973 |
+
hyperlinkLeft = Math.floor(hyperlinkRect.x);
|
1974 |
+
hyperlinkTop = Math.floor(hyperlinkRect.y);
|
1975 |
+
hyperlinkRight = hyperlinkLeft + Math.floor(hyperlinkRect.width);
|
1976 |
+
hyperlinkBottom = hyperlinkTop + Math.floor(hyperlinkRect.height);
|
1977 |
+
|
1978 |
+
if ((showCoOrds.pointX >= hyperlinkLeft) && (showCoOrds.pointX <= hyperlinkRight)
|
1979 |
+
&& (showCoOrds.pointY >= hyperlinkTop) && (showCoOrds.pointY <= hyperlinkBottom)) {
|
1980 |
+
return hyperlink;
|
1981 |
+
}
|
1982 |
+
}
|
1983 |
+
|
1984 |
+
return null;
|
1985 |
+
},
|
1986 |
+
|
1987 |
+
createHyperlinksForCurrentState: function(context) {
|
1988 |
+
var sceneIndexOfHyperlinks = -1;
|
1989 |
+
|
1990 |
+
switch (this.state) {
|
1991 |
+
case kShowControllerState_IdleAtInitialState:
|
1992 |
+
// use current scene index
|
1993 |
+
sceneIndexOfHyperlinks = this.currentSceneIndex;
|
1994 |
+
break;
|
1995 |
+
|
1996 |
+
case kShowControllerState_IdleAtFinalState:
|
1997 |
+
// idle at final state, grab hyperlink from appropriate scene
|
1998 |
+
if (this.currentSceneIndex < this.script.lastSceneIndex) {
|
1999 |
+
sceneIndexOfHyperlinks = this.currentSceneIndex + 1;
|
2000 |
+
} else {
|
2001 |
+
// check if hyperlinks only mode
|
2002 |
+
if (this.script.showMode == kShowModeHyperlinksOnly) {
|
2003 |
+
sceneIndexOfHyperlinks = this.currentSceneIndex;
|
2004 |
+
} else {
|
2005 |
+
// check if loop slide show
|
2006 |
+
if (this.script.loopSlideshow) {
|
2007 |
+
sceneIndexOfHyperlinks = 0;
|
2008 |
+
}
|
2009 |
+
}
|
2010 |
+
}
|
2011 |
+
break;
|
2012 |
+
|
2013 |
+
default:
|
2014 |
+
break;
|
2015 |
+
}
|
2016 |
+
|
2017 |
+
if (sceneIndexOfHyperlinks != -1) {
|
2018 |
+
this.clearAllHyperlinks();
|
2019 |
+
this.createHyperlinks(sceneIndexOfHyperlinks);
|
2020 |
+
}
|
2021 |
+
},
|
2022 |
+
|
2023 |
+
createHyperlinks: function(hyperlinkSceneIndex) {
|
2024 |
+
if (hyperlinkSceneIndex === -1) {
|
2025 |
+
return;
|
2026 |
+
}
|
2027 |
+
|
2028 |
+
var eventTimeLine = this.script.events[hyperlinkSceneIndex];
|
2029 |
+
if (eventTimeLine == null) {
|
2030 |
+
return;
|
2031 |
+
}
|
2032 |
+
|
2033 |
+
var hyperlinks = eventTimeLine.hyperlinks;
|
2034 |
+
if (hyperlinks == null) {
|
2035 |
+
return;
|
2036 |
+
}
|
2037 |
+
|
2038 |
+
var numHyperlinks = hyperlinks.length;
|
2039 |
+
var iHyperlink;
|
2040 |
+
var kMinHyperlinkWidth = 150;
|
2041 |
+
var kMinHyperlinkHeight = 50;
|
2042 |
+
var showWidth = this.displayManager.showWidth;
|
2043 |
+
var showHeight = this.displayManager.showHeight;
|
2044 |
+
|
2045 |
+
for (iHyperlink = 0; iHyperlink < numHyperlinks; iHyperlink++) {
|
2046 |
+
var hyperlink = hyperlinks[iHyperlink];
|
2047 |
+
var hyperlinkRect = hyperlink.targetRectangle;
|
2048 |
+
|
2049 |
+
var activeHyperlink = {
|
2050 |
+
targetRectangle: hyperlinkRect,
|
2051 |
+
events: hyperlink.events,
|
2052 |
+
url: hyperlink.url
|
2053 |
+
};
|
2054 |
+
|
2055 |
+
var spaceOnLeft = hyperlinkRect.x;
|
2056 |
+
var spaceOnTop = hyperlinkRect.y;
|
2057 |
+
var spaceOnRight = showWidth - (hyperlinkRect.x + hyperlinkRect.width);
|
2058 |
+
var spaceOnBottom = showHeight - (hyperlinkRect.y + hyperlinkRect.top);
|
2059 |
+
|
2060 |
+
if (gMode === kModeMobile) {
|
2061 |
+
if (hyperlinkRect.width < kMinHyperlinkWidth) {
|
2062 |
+
var deltaWidth = kMinHyperlinkWidth - hyperlinkRect.width;
|
2063 |
+
var leftShift = deltaWidth / 2;
|
2064 |
+
var rightShift = deltaWidth / 2;
|
2065 |
+
|
2066 |
+
if (spaceOnLeft < leftShift) {
|
2067 |
+
leftShift = spaceOnLeft;
|
2068 |
+
} else if (spaceOnRight < rightShift) {
|
2069 |
+
leftShift = leftShift + (rightShift - spaceOnRight);
|
2070 |
+
}
|
2071 |
+
|
2072 |
+
activeHyperlink.targetRectangle.x -= leftShift;
|
2073 |
+
activeHyperlink.targetRectangle.width += deltaWidth;
|
2074 |
+
}
|
2075 |
+
|
2076 |
+
if (hyperlinkRect.height < kMinHyperlinkHeight) {
|
2077 |
+
var deltaHeight = kMinHyperlinkHeight - hyperlinkRect.height;
|
2078 |
+
var topShift = deltaHeight / 2;
|
2079 |
+
var bottomShift = deltaHeight / 2;
|
2080 |
+
|
2081 |
+
if (spaceOnTop < topShift) {
|
2082 |
+
topShift = spaceOnTop;
|
2083 |
+
} else if (spaceOnBottom < bottomShift) {
|
2084 |
+
topShift = topShift + (rightShift - spaceOnRight);
|
2085 |
+
}
|
2086 |
+
|
2087 |
+
activeHyperlink.targetRectangle.y -= topShift;
|
2088 |
+
activeHyperlink.targetRectangle.height += deltaHeight;
|
2089 |
+
}
|
2090 |
+
}
|
2091 |
+
this.stageManager.addHyperlink(activeHyperlink.targetRectangle);
|
2092 |
+
this.activeHyperlinks[iHyperlink] = activeHyperlink;
|
2093 |
+
}
|
2094 |
+
|
2095 |
+
if (this.movieHyperlinks.length > 0) {
|
2096 |
+
for (var iMovieHyperlink = 0; iMovieHyperlink < this.movieHyperlinks.length; iMovieHyperlink++) {
|
2097 |
+
var movieHyperlink = this.movieHyperlinks[iMovieHyperlink];
|
2098 |
+
|
2099 |
+
this.stageManager.addHyperlink(movieHyperlink.targetRectangle);
|
2100 |
+
this.activeHyperlinks[iHyperlink++] = movieHyperlink;
|
2101 |
+
}
|
2102 |
+
}
|
2103 |
+
}
|
2104 |
+
|
2105 |
+
});
|
assets/player/SlideManager.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
|
2 |
-
oid sha256:9f45437168a14fc80c5963c21c38fa40f11af08a57189b52bd33a185557ddad4
|
3 |
-
size 1603
|
|
|
1 |
+
var SlideManager=Class.create({initialize:function(c){this.header=c.header;this.slides={};for(var a=0,b=this.header.slideList.length;a<b;a++){this.slides[this.header.slideList[a]]={downloaded:false,script:{},retry:0}}},getSlides:function(d,b){for(var a=0,c=d.length;a<c;a++){var e=d[a];this.slides[e].downloaded=true;this.slides[e].script=JSON.parse(b.getKPFJsonStringForSlideIndex(a));this.slides[e].originalScript=JSON.parse(b.getKPFJsonStringForSlideIndex(a));document.fire(kSlideDidDownloadEvent,{id:e})}},downloadSlides:function(c){for(var a=0,b=c.length;a<b;a++){this.downloadSlide(c[a])}},downloadSlide:function(b){var c="../"+b+"/"+b+".json";if(window.location.protocol==="file:"){c=c+"p";if(window.local_slide==null||window.local_slide==undefined){window.local_slide=(function(d){this.slideDidDownload(null,d,true)}).bind(this)}var a=document.createElement("script");a.setAttribute("src",c);document.head.appendChild(a)}else{new Ajax.Request(c,{method:"get",onSuccess:this.slideDidDownload.bind(this,b),onFailure:this.slideDidNotDownload.bind(this,b)})}},slideDidDownload:function(c,b,a){if(a){c=b.name;this.slides[c].script=b.json;this.slides[c].originalScript=JSON.parse(JSON.stringify(b.json))}else{this.slides[c].script=JSON.parse(b.responseText);this.slides[c].originalScript=JSON.parse(b.responseText)}this.slides[c].downloaded=true;document.fire(kSlideDidDownloadEvent,{id:c})},slideDidNotDownload:function(){var a=arguments[0];if(arguments[1].status!=200){if(this.slides[a].retry<1){this.downloadSlide(a);this.slides[a].retry++}else{document.fire(kSlideDidNotDownloadEvent,{id:a})}}}});
|
|
|
|
assets/player/SlideNumberController.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
|
2 |
-
oid sha256:804f3d0fb6dfbb0773a2f6f1906656da3305e02907f4a923e2b3aa82ba390e17
|
3 |
-
size 1574
|
|
|
1 |
+
var SlideNumberController=Class.create({initialize:function(a,b){this.domNode=a;this.width=120;this.height=110;this.slideNumberLabel=document.createElement("div");this.slideNumberLabel.setAttribute("class","slideNumberLabel");if(b){this.slideNumberLabel.innerHTML=b}else{this.slideNumberLabel.innerHTML="Press Return to go to slide:"}this.slideNumberDigit=document.createElement("div");this.slideNumberDigit.setAttribute("class","slideNumberDigit");this.domNode.appendChild(this.slideNumberLabel);this.domNode.appendChild(this.slideNumberDigit);this.isShowing=false},setPosition:function(b,a){this.domNode.style.left=b+"px";this.domNode.style.top=a+"px"},setSlideNumber:function(a){this.slideNumberDigit.innerHTML=a},show:function(){this.isShowing=true;this.domNode.style.display="block";this.domNode.style.opacity=1},hide:function(){this.isShowing=false;this.domNode.style.display="none";this.domNode.style.opacity=0}});var SlideNumberDisplay=Class.create({initialize:function(a){this.domNode=a;this.width=100;this.height=100;this.slideNumberDigit=document.createElement("div");this.slideNumberDigit.setAttribute("class","slideNumberDisplayDigit");this.domNode.appendChild(this.slideNumberDigit);this.isShowing=false},setPosition:function(b,a){this.domNode.style.left=b+"px";this.domNode.style.top=a+"px"},setSlideNumber:function(a){this.slideNumberDigit.innerHTML=a},show:function(a){this.isShowing=true;this.domNode.style.display="block";this.domNode.style.opacity=1},hide:function(){this.isShowing=false;this.domNode.style.display="none";this.domNode.style.opacity=0}});
|
|
|
|
assets/player/StageManager.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
|
2 |
-
oid sha256:6632cecf853f8167cc684c80fa9d0495fbf16ea15ab1a6863b3f28c7cd7b2b86
|
3 |
-
size 2482
|
|
|
1 |
+
var kStageIsReadyEvent="StageManager:StageIsReadyEvent";var StageManager=Class.create({initialize:function(a,b){this.textureManager=a;this.scriptManager=b;this.stage=document.getElementById("stage");this.hyperlinkPlane=document.getElementById("hyperlinkPlane");this.stageWidth=0;this.stageHeight=0;this.showWidth=0;this.showHeight=0;this.audioTrackOffset=0;this.audioTrackIconSize=0;document.observe(kShowSizeDidChangeEvent,this.handleShowSizeDidChangeEvent.bind(this));document.observe(kStageSizeDidChangeEvent,this.handleStageSizeDidChangeEvent.bind(this))},removeTexture:function(a){a.parentNode.removeChild(a)},addHyperlink:function(b){var a=document.createElement("div");setElementProperty(a,"pointer-events","all");a.setAttribute("class","hyperlink");a.style.left=b.x+"px";a.style.top=b.y+"px";a.style.width=b.width+"px";a.style.height=b.height+"px";this.hyperlinkPlane.appendChild(a)},clearAllHyperlinks:function(){var a;while(this.hyperlinkPlane.childNodes.length>0){this.hyperlinkPlane.removeChild(this.hyperlinkPlane.firstChild)}this.audioTrackOffset=this.audioTrackSpacer},handleStageSizeDidChangeEvent:function(a){this.stageWidth=a.memo.width;this.stageHeight=a.memo.height;this.adjustStageToFit(this.stage);this.adjustStageToFit(this.hyperlinkPlane)},handleShowSizeDidChangeEvent:function(a){this.showWidth=a.memo.width;this.showHeight=a.memo.height;this.adjustStageToFit(this.stage);this.adjustStageToFit(this.hyperlinkPlane);this.audioTrackIconSize=this.showHeight/4;this.audioTrackSpacer=this.audioTrackIconSize/4;this.audioTrackOffset=this.audioTrackSpacer},adjustStageToFit:function(b){if((this.showWidth!=0)&&(this.stageWidth!=0)){var d=this.stageHeight/this.showHeight;var f=this.stageWidth/this.showWidth;var a="scaleX("+f+") scaleY("+d+")";var e=20;var c=Math.tan(Math.PI/180*e/2)*15*(this.showWidth>this.showHeight?this.showHeight:this.showWidth);this.perspective=c;setElementProperty(b,kTransformOriginPropertyName,kTransformOriginCenterPropertyValue);setElementProperty(b,kTransformPropertyName,a);setElementProperty(b,kPerspectiveOriginPropertyName,kTransformOriginCenterPropertyValue);setElementProperty(b,kTransformStylePropertyName,kTransformStylePreserve3DPropertyValue);setElementPosition(b,(d-1)*this.showHeight/2,(f-1)*this.showWidth/2,this.showWidth,this.showHeight);document.fire(kStageIsReadyEvent,{})}},debugGetStageStatistics:function(){var a={numTextures:0,numPixels:0,numDegraded:0};this.debugRecursivelyWalkDomFrom(this.stage,a);return a}});
|
|
|
|
assets/player/TSDAnimation.js
CHANGED
@@ -1,3 +1,92 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* TSDAnimation.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2016 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Stuff from TSDAnimation.h
|
10 |
+
|
11 |
+
// Common acceleration values.
|
12 |
+
var KNAnimationActionAcceleration = {
|
13 |
+
kSFXActionAccelerationNone: 0,
|
14 |
+
kSFXActionAccelerationEaseIn: 1,
|
15 |
+
kSFXActionAccelerationEaseOut: 2,
|
16 |
+
kSFXActionAccelerationEaseBoth: 3,
|
17 |
+
kSFXActionAccelerationCustom: 4
|
18 |
+
};
|
19 |
+
|
20 |
+
//Standard action build effect names.
|
21 |
+
var KNActionOpacityName = "apple:action-opacity";
|
22 |
+
var KNActionMotionPathName = "apple:action-motion-path";
|
23 |
+
var KNActionRotationName = "apple:action-rotation";
|
24 |
+
var KNActionScaleName = "apple:action-scale";
|
25 |
+
|
26 |
+
// Emphasis action build effect names.
|
27 |
+
var KNActionPopName = "apple:action-pop";
|
28 |
+
var KNActionPulseName = "apple:action-pulse";
|
29 |
+
var KNActionBlinkName = "apple:action-blink";
|
30 |
+
var KNActionFlipName = "apple:action-flip";
|
31 |
+
var KNActionBounceName = "apple:action-bounce";
|
32 |
+
var KNActionJiggleName = "apple:action-jiggle";
|
33 |
+
|
34 |
+
//Global directions
|
35 |
+
var KNDirection = {
|
36 |
+
kKNDirectionNone: 0,
|
37 |
+
kKNDirectionLeftToRight: 11,
|
38 |
+
kKNDirectionRightToLeft: 12,
|
39 |
+
kKNDirectionTopToBottom: 13,
|
40 |
+
kKNDirectionBottomToTop: 14,
|
41 |
+
kKNDirectionUpperLeftToBottomRight: 21,
|
42 |
+
kKNDirectionUpperRightToBottomLeft: 22,
|
43 |
+
kKNDirectionLowerLeftToUpperRight: 23,
|
44 |
+
kKNDirectionLowerRightToUpperLeft: 24,
|
45 |
+
kKNDirectionClockwise: 31,
|
46 |
+
kKNDirectionCounterclockwise: 32,
|
47 |
+
kKNDirectionIn: 41,
|
48 |
+
kKNDirectionOut: 42,
|
49 |
+
kKNDirectionUp: 43,
|
50 |
+
kKNDirectionDown: 44,
|
51 |
+
kKNDirectionStartToEnd: 51,
|
52 |
+
kKNDirectionEndToStart: 52,
|
53 |
+
kKNDirectionMiddleToEnds: 53,
|
54 |
+
kKNDirectionEndsToMiddle: 54,
|
55 |
+
kKNDirectionRandom: 91,
|
56 |
+
kKNDirectionAlternating: 92,
|
57 |
+
kKNDirectionSimultaneous: 93,
|
58 |
+
kKNDirectionBCForward: 111,
|
59 |
+
kKNDirectionBCBackward: 112,
|
60 |
+
kKNDirectionBCRandom: 113,
|
61 |
+
kKNDirectionBCCenter: 114,
|
62 |
+
kKNDirectionBCEdges: 115,
|
63 |
+
kKNDirectionGravity: 121,
|
64 |
+
kKNDirectionNoGravity: 122
|
65 |
+
};
|
66 |
+
|
67 |
+
// end of TSDAnimation.h
|
68 |
+
|
69 |
+
// Stuff from TSDAnimation.m
|
70 |
+
var kKNAnimationStringTypeNone = "None";
|
71 |
+
var kKNAnimationStringTypeBuildIn = "In";
|
72 |
+
var kKNAnimationStringTypeBuildOut = "Out";
|
73 |
+
var kKNAnimationStringTypeTransition = "Transition";
|
74 |
+
var kKNAnimationStringTypeActionBuild = "Action";
|
75 |
+
|
76 |
+
function KNEffectIsActionEffect(effect) {
|
77 |
+
if ([KNActionOpacityName, KNActionMotionPathName, KNActionRotationName, KNActionScaleName].indexOf(effect) > -1) {
|
78 |
+
return true;
|
79 |
+
} else {
|
80 |
+
return false;
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
function KNEffectIsEmphasisEffect(effect) {
|
85 |
+
if ([KNActionPopName, KNActionPulseName, KNActionBlinkName, KNActionFlipName, KNActionBounceName, KNActionJiggleName].indexOf(effect) > -1) {
|
86 |
+
return true;
|
87 |
+
} else {
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
// end of TSDAnimation.m
|
assets/player/TextureManager.js
CHANGED
@@ -1,3 +1 @@
|
|
1 |
-
|
2 |
-
oid sha256:0fa34c7e1e40e795a04f8aabb1404f78603e8b4ca5c8c5f43c3147a3c3a3290e
|
3 |
-
size 8074
|
|
|
1 |
+
var TextureManager=Class.create({initialize:function(a){this.script=null;this.showUrl=a;this.slideCache={};this.sceneDidLoadCallbackHandler=null;this.viewScale=1;document.observe(kScriptDidDownloadEvent,(function(b){this.handleScriptDidDownloadEvent(b)}).bind(this),false)},setSceneDidLoadCallbackHandler:function(a,b){this.sceneDidLoadCallbackHandler={handler:a,sceneIndex:b}},processTextureDidLoadCallback:function(d,b){if(this.sceneDidLoadCallbackHandler==null){return}var c=this.sceneDidLoadCallbackHandler.sceneIndex;var a=this.script.slideIndexFromSceneIndexLookup[c];if(a!=b){return}if(this.isSlidePreloaded(b)){this.callSceneDidLoadCallback();setTimeout(function(){this.destroyPDFDocument(b)}.bind(this),5000)}},destroyPDFDocument:function(c){var b=this.slideCache[c];if(b){var a=b.pdf;if(a){a.destroy();delete this.slideCache[c].pdf}}},processSlideDidLoadCallback:function(b){if(this.sceneDidLoadCallbackHandler==null){return}var c=this.sceneDidLoadCallbackHandler.sceneIndex;var a=this.script.slideIndexFromSceneIndexLookup[c];if(a!=b){return}this.callSceneDidLoadCallback()},processSceneDidLoadCallback:function(a){if(this.sceneDidLoadCallbackHandler&&a===this.sceneDidLoadCallbackHandler.sceneIndex&&this.isScenePreloaded(a)){this.callSceneDidLoadCallback()}},callSceneDidLoadCallback:function(){this.sceneDidLoadCallbackHandler.handler();this.sceneDidLoadCallbackHandler=null},loadScene:function(c,a){if(c<0||c>this.script.numScenes){return}if(a){this.setSceneDidLoadCallbackHandler(a,c)}var b=this.script.slideIndexFromSceneIndexLookup[c];if(usePDF){this.requestPdfDocument(b)}else{this.requestSlideSvgmap(b)}},preloadScenes:function(a){for(var c in a){var b=this.script.slideIndexFromSceneIndexLookup[c];if(b==null){continue}if(this.slideCache.hasOwnProperty(b)===false){this.loadScene(c)}}},isSlidePreloaded:function(b){var a=false;if(this.slideCache[b]){a=true;for(var c in this.slideCache[b].textureRequests){if(this.slideCache[b].textureRequests[c]===false){a=false;break}}}return a},isScenePreloaded:function(c){var b=this.script.slideIndexFromSceneIndexLookup[c];var a=this.isSlidePreloaded(b);return a},handleScriptDidDownloadEvent:function(a){this.script=a.memo.script;this.delegate=a.memo.delegate},requestPdfDocument:function(g){if(!this.slideCache[g]){this.slideCache[g]={textureAssets:{},textureRequests:{},pdf:null,requested:false}}var f=this.script.slideList[g];if(!this.slideCache[g].requested){var d=this.script.slides[f];var i=d.assets;for(var a in i){var e=i[a];if(e.type==="texture"){this.slideCache[g].textureRequests[a]=false}}}else{if(this.isSlidePreloaded(g)){this.processSlideDidLoadCallback(g)}return}var b=this.showUrl+f+"/assets/"+f+".pdf";var c={slideId:f,slideIndex:g};this.slideCache[g].requested=true;if(window.location.protocol==="file:"){b=b+"p";if(window.local_pdf==null||window.local_pdf==undefined){window.local_pdf=function(j){this.handleRequestLocalPdfCallback(j)}.bind(this)}var h=document.createElement("script");h.setAttribute("src",b);document.head.appendChild(h)}else{PDFJS.getDocument(b).then(this.handleRequestPdfDocumentCompleted.bind(this,c))}},handleRequestLocalPdfCallback:function(b){var a=b.slide;var d=this.script.slideList.indexOf(a);var e=atob(b.pdf);var c={slideId:a,slideIndex:d};PDFJS.getDocument({data:e}).then(this.handleRequestPdfDocumentCompleted.bind(this,c))},handleRequestPdfDocumentCompleted:function(d,b){var i=d.slideId;var j=d.slideIndex;var f=this.script.slides[i];var l=f.assets;this.slideCache[j]["pdf"]=b;for(var a in l){var h=l[a];if(h.type!=="texture"){continue}var g=this.urlForTexture(a,i);var m=/(?:\.([^.]+))?$/;var c=m.exec(g)[1];if(c.toLowerCase()==="pdf"){var k=h.index+1;b.getPage(k).then(this.handleRequestPdfPageCompleted.bind(this,a,j))}else{var e=new Image();Event.observe(e,"load",this.handleImageOnloadEvent.bind(this,a,j));e.src=g}}},handleRequestPdfPageCompleted:function(a,i,h){var g=h.getViewport(pdfScaleFactor);var d=document.createElement("canvas");var c=d.getContext("2d");d.height=g.height;d.width=g.width;var e={canvasContext:c,background:"rgba(0, 0, 0, 0)",viewport:g};var f=this;var b=h.render(e);var j=b._internalRenderTask.callback;b._internalRenderTask.callback=function(k){j.call(this,k);f.slideCache[i].textureAssets[a]=d;f.slideCache[i].textureRequests[a]=true;f.processTextureDidLoadCallback(a,i)}},requestSlideSvgmap:function(g){if(!this.slideCache[g]){this.slideCache[g]={};this.slideCache[g].textureAssets={};this.slideCache[g].textureRequests={}}var f=this.script.slideList[g];if(!this.slideCache[g]["svgmap"]){var d=this.script.slides[f];var i=d.assets;for(var a in i){var e=i[a];if(e.type==="texture"){this.slideCache[g].textureRequests[a]=false}}}else{if(this.isSlidePreloaded(g)){this.processSlideDidLoadCallback(g)}return}var c=this.showUrl+f+"/assets/"+f+".svgmap";if(window.location.protocol==="file:"){c=c+"p";if(window.svgmap==null||window.svgmap==undefined){window.svgmap=this.handleRequestSlideSvgmapCompleted.bind(this,null,true)}var h=document.createElement("script");h.setAttribute("src",c);document.head.appendChild(h)}else{var b={slideId:f,slideIndex:g};new Ajax.Request(c,{method:"get",onSuccess:this.handleRequestSlideSvgmapCompleted.bind(this,b,false)})}},handleRequestSlideSvgmapCompleted:function(n,l,f){var d;var a;if(l){d=f.slide;a=f.svg}else{d=n.slideId;a=JSON.parse(f.responseText)}var o=this.script.slideList.indexOf(d);var b=this.script.slides[d];var e=b.assets;this.slideCache[o]["svgmap"]=a;for(var r in e){var j=e[r];if(j.type!=="texture"){continue}var h=this.urlForTexture(r,d);var m=h.split("/");var g=m.length;var c=m[g-1];var p=c.split(".");var i=p[p.length-1];if(i==="svgmap"){var k=a[j.index];var n={textureId:r,slideId:d,slideIndex:o};this.handleFetchCompleted(n,k)}else{var q=new Image();Event.observe(q,"load",this.handleImageOnloadEvent.bind(this,r,o));q.src=h}}},handleFetchCompleted:function(q,k){var a=this.viewScale;var s=q.textureId;var b=q.slideId;var r=q.slideIndex;var c=new DOMParser();var l=this.showUrl+b+"/assets/";var h=c.parseFromString(k,"text/xml");var g=h.documentElement.getAttribute("viewBox").split(" ");var f=g[2];var m=g[3];var d=h.getElementsByTagName("image");for(var n=0,e=d.length;n<e;n++){var p=d[n];var o=p.getAttributeNS("http://www.w3.org/1999/xlink","href");p.setAttributeNS("http://www.w3.org/1999/xlink","href",l+o)}var j=document.importNode(h.documentElement,true);j.setAttributeNS("http://www.w3.org/2000/svg","width",f);j.setAttributeNS("http://www.w3.org/2000/svg","height",m);this.slideCache[r].textureAssets[s]=j;this.slideCache[r].textureRequests[s]=true;this.processTextureDidLoadCallback(s,r)},handleImageOnloadEvent:function(d,c,b){b=b||window.event;var a=b.target||b.srcElement;this.slideCache[c].textureAssets[d]=a;this.slideCache[c].textureRequests[d]=true;this.processTextureDidLoadCallback(d,c)},getTextureObject:function(d,c){var a;var b=this.script.slideIndexFromSceneIndexLookup[d];if(this.slideCache[b]){a=this.slideCache[b].textureAssets[c]}return a},getTextureInfo:function(e,d){var c=this.script.slideIndexFromSceneIndexLookup[e];if(c==null){return null}var a=this.script.slideList[c];var b=this.script.slides[a].assets[d];return b},getTextureUrl:function(d,c){var b=this.script.slideIndexFromSceneIndexLookup[d];if(b==null){return null}var a=this.script.slideList[b];return this.urlForTexture(c,a)},getMovieUrl:function(d,c){var b=this.script.slideIndexFromSceneIndexLookup[d];if(b==null){return null}var a=this.script.slideList[b];return this.urlForAsset(c,a)},urlForAsset:function(e,c){var b="";var d=this.script.slides[c].assets[e];if(d==null){return b}var a;if(usePDF){a=d.url["native"]}else{a=d.url.web}if((a!=null)&&(a!="")){if(a.toLowerCase().substring(0,4)==="http"){b=a}else{b=this.showUrl+(c?c+"/":"")+a}}return b},urlForTexture:function(b,a){return this.generateUrl(b,a,false)},generateUrl:function(e,b){var a="";var c="";var d=this.script.slides[b].assets[e];if(!d){return a}if(usePDF){c=d.url["native"]}else{c=d.url.web}if((c!=null)&&(c!="")){if(c.toLowerCase().substring(0,4)==="http"){a=c}else{a=this.showUrl+(b?b+"/":"")+c}}return a}});
|
|
|
|
assets/player/TouchController.js
CHANGED
@@ -1,3 +1,276 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* TouchController.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Responsibility: Tungwei Cheng
|
6 |
+
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
// iPhone Event Name Constants:
|
10 |
+
// -----------------------------
|
11 |
+
var kTouchStartEventName = "touchstart";
|
12 |
+
var kTouchMoveEventName = "touchmove";
|
13 |
+
var kTouchEndEventName = "touchend";
|
14 |
+
var kTouchCancelEventName = "touchcancel";
|
15 |
+
var kGestureStartEventName = "gesturestart";
|
16 |
+
var kGestureEndEventName = "gestureend";
|
17 |
+
|
18 |
+
// Class: TouchController
|
19 |
+
// ===============================================================
|
20 |
+
var kSwipeEvent = "TouchController:SwipeEvent";
|
21 |
+
var kTapEvent = "TouchController:TapeEvent";
|
22 |
+
|
23 |
+
var TouchController = Class.create({
|
24 |
+
initialize: function() {
|
25 |
+
// observe touch events
|
26 |
+
document.observe(kTouchStartEventName, this.handleTouchStartEvent.bind(this));
|
27 |
+
document.observe(kTouchMoveEventName, this.handleTouchMoveEvent.bind(this));
|
28 |
+
document.observe(kTouchEndEventName, this.handleTouchEndEvent.bind(this));
|
29 |
+
document.observe(kTouchCancelEventName, this.handleTouchCancelEvent.bind(this));
|
30 |
+
|
31 |
+
// observe gesture events
|
32 |
+
document.observe(kGestureStartEventName, this.handleGestureStartEvent.bind(this));
|
33 |
+
document.observe(kGestureEndEventName, this.handleGestureEndEvent.bind(this));
|
34 |
+
|
35 |
+
this.swipeInProgress = false;
|
36 |
+
this.swipeFingerCount = 0;
|
37 |
+
|
38 |
+
this.swipeStartTime = 0;
|
39 |
+
this.swipeStartX = 0;
|
40 |
+
this.swipeStartY = 0;
|
41 |
+
|
42 |
+
this.preventDefault = true;
|
43 |
+
|
44 |
+
this.tapEventCallback = null;
|
45 |
+
|
46 |
+
this.setTrackArea(0, 0, 0, 0);
|
47 |
+
|
48 |
+
this.enableTouchTracking = true;
|
49 |
+
},
|
50 |
+
|
51 |
+
setTouchTrackingEnabled: function(isEnabled) {
|
52 |
+
this.enableTouchTracking = isEnabled;
|
53 |
+
},
|
54 |
+
|
55 |
+
setTrackArea: function(left, top, width, height) {
|
56 |
+
debugMessage(kDebugTouchController_SetTrackArea, "left: " + left + " top: " + top + " width: " + width + " height: " + height);
|
57 |
+
|
58 |
+
this.trackAreaLeft = left;
|
59 |
+
this.trackAreaTop = top;
|
60 |
+
this.trackAreaRight = left + width;
|
61 |
+
this.trackAreaBottom = top + height;
|
62 |
+
},
|
63 |
+
|
64 |
+
registerTapEventCallback: function(tapEventCallback) {
|
65 |
+
this.tapEventCallback = tapEventCallback;
|
66 |
+
},
|
67 |
+
|
68 |
+
isTouchWithinTrackArea: function(touch) {
|
69 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "checking...");
|
70 |
+
|
71 |
+
if (this.enableTouchTracking === false) {
|
72 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, tracking is disabled");
|
73 |
+
return false;
|
74 |
+
}
|
75 |
+
|
76 |
+
if (touch.clientX < this.trackAreaLeft) {
|
77 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, x < left");
|
78 |
+
return false;
|
79 |
+
}
|
80 |
+
|
81 |
+
if (touch.clientX > this.trackAreaRight) {
|
82 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, x > right");
|
83 |
+
return false;
|
84 |
+
}
|
85 |
+
|
86 |
+
if (touch.clientY < this.trackAreaTop) {
|
87 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, y < top");
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
|
91 |
+
if (touch.clientY > this.trackAreaBottom) {
|
92 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- nope, y > bottom");
|
93 |
+
return false;
|
94 |
+
}
|
95 |
+
|
96 |
+
debugMessage(kDebugTouchController_IsTouchWithinTrackArea, "- yes it is!");
|
97 |
+
return true;
|
98 |
+
},
|
99 |
+
|
100 |
+
handleTouchStartEvent: function(event) {
|
101 |
+
debugMessage(kDebugTouchController_HandleTouchStartEvent, "touch event has " + event.touches.length + " fingers...");
|
102 |
+
|
103 |
+
if (this.swipeInProgress === false) {
|
104 |
+
debugMessage(kDebugTouchController_HandleTouchStartEvent, "- this is the first finger down event...");
|
105 |
+
|
106 |
+
var startTouch = event.touches[0];
|
107 |
+
|
108 |
+
if (this.isTouchWithinTrackArea(startTouch)) {
|
109 |
+
debugMessage(kDebugTouchController_HandleTouchStartEvent, "- start tracking a swipt event...");
|
110 |
+
|
111 |
+
if (this.preventDefault) {
|
112 |
+
event.preventDefault();
|
113 |
+
}
|
114 |
+
|
115 |
+
this.swipeInProgress = true;
|
116 |
+
this.swipeFingerCount = event.touches.length;
|
117 |
+
|
118 |
+
this.swipeStartTime = new Date();
|
119 |
+
this.swipeStartX = startTouch.clientX;
|
120 |
+
this.swipeStartY = startTouch.clientY;
|
121 |
+
|
122 |
+
} else {
|
123 |
+
debugMessage(kDebugTouchController_HandleTouchStartEvent, "- but it is outside of the track area");
|
124 |
+
}
|
125 |
+
} else {
|
126 |
+
debugMessage(kDebugTouchController_HandleTouchStartEvent, "- this is a subsequent finger down event. update finger count...");
|
127 |
+
if (event.touches.length > this.swipeFingerCount) {
|
128 |
+
this.swipeFingerCount = event.touches.length;
|
129 |
+
debugMessage(kDebugTouchController_HandleTouchStartEvent, "- this.swipeFingerCount:" + this.swipeFingerCount);
|
130 |
+
}
|
131 |
+
}
|
132 |
+
},
|
133 |
+
|
134 |
+
handleTouchMoveEvent: function(event) {
|
135 |
+
if (this.preventDefault) {
|
136 |
+
event.preventDefault();
|
137 |
+
}
|
138 |
+
|
139 |
+
debugMessage(kDebugTouchController_HandleTouchCancelEvent, "");
|
140 |
+
},
|
141 |
+
|
142 |
+
handleTouchEndEvent: function(event) {
|
143 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "touch event has " + event.touches.length + " fingers...");
|
144 |
+
|
145 |
+
if (this.swipeInProgress) {
|
146 |
+
if (this.preventDefault) {
|
147 |
+
event.preventDefault();
|
148 |
+
}
|
149 |
+
|
150 |
+
if (event.touches.length === 0) {
|
151 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- " + this.swipeFingerCount + " finger swipe is complete.");
|
152 |
+
|
153 |
+
var endTouch = event.changedTouches[0];
|
154 |
+
|
155 |
+
var viewport = document.viewport.getDimensions();
|
156 |
+
var minSwipeDistance = viewport.width / 3.0;
|
157 |
+
var maxVerticalMagnitude = viewport.height / 3.0;
|
158 |
+
var maxHorizontalMagnitude = viewport.width / 3.0;
|
159 |
+
|
160 |
+
var deltaX = endTouch.clientX - this.swipeStartX;
|
161 |
+
var deltaY = endTouch.clientY - this.swipeStartY;
|
162 |
+
|
163 |
+
var magnitudeX = Math.abs(deltaX);
|
164 |
+
var magnitudeY = Math.abs(deltaY);
|
165 |
+
|
166 |
+
var touchEndTime = new Date();
|
167 |
+
|
168 |
+
var elapsedTime = touchEndTime - this.swipeStartTime;
|
169 |
+
var tapIsGood = false;
|
170 |
+
var swipeIsGood = false;
|
171 |
+
|
172 |
+
// First Check for a "tap"
|
173 |
+
|
174 |
+
var kMaxTapTime = 400;
|
175 |
+
var kMaxTapMagnitude = 20;
|
176 |
+
|
177 |
+
if (elapsedTime < kMaxTapTime) {
|
178 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- elapsed time was short enough to be a tap, check its magnitude...");
|
179 |
+
|
180 |
+
if ((magnitudeX < kMaxTapMagnitude) && (magnitudeY < kMaxTapMagnitude)) {
|
181 |
+
tapIsGood = true;
|
182 |
+
} else {
|
183 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- magnitude time too big to be a tap, check if it's a swipe...");
|
184 |
+
}
|
185 |
+
} else {
|
186 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- elapsed time too long to be a tap, check if it's a swipe...");
|
187 |
+
}
|
188 |
+
|
189 |
+
if (elapsedTime > 800) {
|
190 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- elapsed time too long to be a swipe, ignoring...");
|
191 |
+
} else {
|
192 |
+
if (magnitudeX > magnitudeY) {
|
193 |
+
if (magnitudeY > maxVerticalMagnitude) {
|
194 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- vertical magnitude too high, ignoring...");
|
195 |
+
} else {
|
196 |
+
swipeIsGood = true;
|
197 |
+
}
|
198 |
+
} else {
|
199 |
+
if (magnitudeX > maxHorizontalMagnitude) {
|
200 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- horizontal magnitude too high, ignoring...");
|
201 |
+
} else {
|
202 |
+
swipeIsGood = true;
|
203 |
+
}
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
if (tapIsGood) {
|
208 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- it's a " + this.swipeFingerCount + " finger tap");
|
209 |
+
|
210 |
+
if (this.tapEventCallback) {
|
211 |
+
var event = {};
|
212 |
+
|
213 |
+
event.memo = {};
|
214 |
+
event.memo.fingers = this.swipeFingerCount;
|
215 |
+
event.memo.pointX = endTouch.clientX;
|
216 |
+
event.memo.pointY = endTouch.clientY;
|
217 |
+
|
218 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- invoking callback with pointX: " + endTouch.clientX + " pointY: " + endTouch.clientY + "...");
|
219 |
+
|
220 |
+
this.tapEventCallback(event);
|
221 |
+
|
222 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- back from callback");
|
223 |
+
} else {
|
224 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- firing TapEvent...");
|
225 |
+
|
226 |
+
document.fire(kTapEvent, {
|
227 |
+
fingers: this.swipeFingerCount,
|
228 |
+
pointX: endTouch.clientX,
|
229 |
+
pointY: endTouch.clientY
|
230 |
+
});
|
231 |
+
}
|
232 |
+
} else if (swipeIsGood) {
|
233 |
+
var direction;
|
234 |
+
|
235 |
+
if (magnitudeX > magnitudeY) {
|
236 |
+
direction = (deltaX < 0 ? "left" : "right");
|
237 |
+
} else {
|
238 |
+
direction = (deltaY < 0 ? "up" : "down");
|
239 |
+
}
|
240 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- it's a " + this.swipeFingerCount + " finger swipe in the " + direction + " direction");
|
241 |
+
document.fire(kSwipeEvent, {
|
242 |
+
direction: direction,
|
243 |
+
fingers: this.swipeFingerCount
|
244 |
+
});
|
245 |
+
}
|
246 |
+
|
247 |
+
this.swipeInProgress = false;
|
248 |
+
this.swipeFingerCount = 0;
|
249 |
+
}
|
250 |
+
} else {
|
251 |
+
debugMessage(kDebugTouchController_HandleTouchEndEvent, "- false alarm. swipe has already ended.");
|
252 |
+
}
|
253 |
+
},
|
254 |
+
|
255 |
+
handleTouchCancelEvent: function(event) {
|
256 |
+
debugMessage(kDebugTouchController_HandleTouchCancelEvent, "");
|
257 |
+
|
258 |
+
this.swipeInProgress = false;
|
259 |
+
},
|
260 |
+
|
261 |
+
handleGestureStartEvent: function(event) {
|
262 |
+
debugMessage(kDebugTouchController_HandleGestureStartEvent, "");
|
263 |
+
|
264 |
+
if (this.preventDefault) {
|
265 |
+
event.preventDefault();
|
266 |
+
}
|
267 |
+
},
|
268 |
+
|
269 |
+
handleGestureEndEvent: function(event) {
|
270 |
+
debugMessage(kDebugTouchController_HandleGestureEndEvent, "");
|
271 |
+
|
272 |
+
if (this.preventDefault) {
|
273 |
+
event.preventDefault();
|
274 |
+
}
|
275 |
+
}
|
276 |
+
});
|
assets/player/Utilities.js
CHANGED
@@ -1,3 +1,286 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* Utilities.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Responsibility: Tungwei Cheng
|
6 |
+
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var s = Class.create({
|
10 |
+
initialize: function(){}
|
11 |
+
});
|
12 |
+
|
13 |
+
function getMobileOSVersionInfo() {
|
14 |
+
var match = navigator.userAgent.match(/iPhone OS ([\d_]+)/) || navigator.userAgent.match(/iPad OS ([\d_]+)/) || navigator.userAgent.match(/CPU OS ([\d_]+)/);
|
15 |
+
var versionInfo = { major: 0, minor: 0, point: 0 };
|
16 |
+
|
17 |
+
if (match) {
|
18 |
+
var release = match[1].split('_');
|
19 |
+
versionInfo.major = parseInt(release[0]);
|
20 |
+
|
21 |
+
if (release.length > 1) {
|
22 |
+
versionInfo.minor = parseInt(release[1]);
|
23 |
+
}
|
24 |
+
|
25 |
+
if (release.length > 2) {
|
26 |
+
versionInfo.point = parseInt(release[2]);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
return versionInfo;
|
31 |
+
}
|
32 |
+
|
33 |
+
function isMobileSafari() {
|
34 |
+
if (navigator.userAgent.indexOf('iPod') != -1) {
|
35 |
+
return true;
|
36 |
+
}
|
37 |
+
else if (navigator.userAgent.indexOf('iPhone') != -1) {
|
38 |
+
return true;
|
39 |
+
}
|
40 |
+
else if (navigator.userAgent.indexOf('iPad') != -1) {
|
41 |
+
return true;
|
42 |
+
}
|
43 |
+
else {
|
44 |
+
return false;
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
function isiPad() {
|
49 |
+
return (navigator.userAgent.indexOf('iPad') != -1);
|
50 |
+
}
|
51 |
+
|
52 |
+
function getUrlParameter(paramterName) {
|
53 |
+
paramterName = paramterName.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
|
54 |
+
|
55 |
+
var regExpPattern = "[\\?&]" + paramterName + "=([^&#]*)";
|
56 |
+
var regExp = new RegExp(regExpPattern);
|
57 |
+
var results = regExp.exec(window.location.href);
|
58 |
+
|
59 |
+
if (results == null) {
|
60 |
+
return "";
|
61 |
+
} else {
|
62 |
+
return results[1];
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
function setElementProperty(node, propertyName, propertyValue) {
|
67 |
+
if (browserPrefix == "ms") {
|
68 |
+
node.style[propertyName] = propertyValue;
|
69 |
+
} else {
|
70 |
+
node.style.setProperty(propertyName, propertyValue, null);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
function setElementOpaque(element) {
|
75 |
+
element.style.opacity = 1;
|
76 |
+
}
|
77 |
+
|
78 |
+
function setElementTransparent(element) {
|
79 |
+
element.style.opacity = 0;
|
80 |
+
}
|
81 |
+
|
82 |
+
function setElementPosition(element, top, left, width, height) {
|
83 |
+
if (element == null) {
|
84 |
+
window.console.log("null element passed to setElementPosition " + top + ", " + left + ", " + width + ", " + height);
|
85 |
+
return;
|
86 |
+
}
|
87 |
+
element.style.top = top + "px";
|
88 |
+
element.style.left = left + "px";
|
89 |
+
element.style.width = width + "px";
|
90 |
+
element.style.height = height + "px";
|
91 |
+
}
|
92 |
+
|
93 |
+
function setElementRect(element, rect) {
|
94 |
+
if (element == null) {
|
95 |
+
return;
|
96 |
+
}
|
97 |
+
element.style.top = rect.y;
|
98 |
+
element.style.left = rect.x;
|
99 |
+
element.style.width = rect.width;
|
100 |
+
element.style.height = rect.height;
|
101 |
+
}
|
102 |
+
|
103 |
+
function centerElementInDiv (element, elementWidth, elementHeight, divWidth, divHeight) {
|
104 |
+
if (element == null) {
|
105 |
+
return;
|
106 |
+
}
|
107 |
+
|
108 |
+
var top = (divHeight - elementHeight) / 2;
|
109 |
+
var left = (divWidth - elementWidth) / 2;
|
110 |
+
|
111 |
+
setElementPosition( element, top, left, elementWidth, elementHeight );
|
112 |
+
}
|
113 |
+
|
114 |
+
function showElement(element) {
|
115 |
+
if (element == null) {
|
116 |
+
return;
|
117 |
+
}
|
118 |
+
element.style.visibility = "visible";
|
119 |
+
}
|
120 |
+
|
121 |
+
function hideElement(element) {
|
122 |
+
if (element == null) {
|
123 |
+
return;
|
124 |
+
}
|
125 |
+
element.style.visibility = "hidden";
|
126 |
+
}
|
127 |
+
|
128 |
+
function runInNextEventLoop(codeBlock) {
|
129 |
+
setTimeout(codeBlock, 100);
|
130 |
+
}
|
131 |
+
|
132 |
+
function ensureScaleFactorNotZero(scaleFactor) {
|
133 |
+
// Mobile Safari doesn't like scale values of 0, force them to be 0.01
|
134 |
+
if (scaleFactor == 0) {
|
135 |
+
return 0.000001;
|
136 |
+
} else {
|
137 |
+
return scaleFactor;
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
function scaleSizeWithinSize(sourceWidth, sourceHeight, destinationWidth, destinationHeight) {
|
142 |
+
var scaledSize = {};
|
143 |
+
var sourceAspectRatio = sourceWidth / sourceHeight;
|
144 |
+
var destinationAspectRatio = destinationWidth / destinationHeight;
|
145 |
+
|
146 |
+
if (sourceAspectRatio > destinationAspectRatio) {
|
147 |
+
scaledSize.width = destinationWidth;
|
148 |
+
scaledSize.height = sourceHeight * ( destinationWidth / sourceWidth );
|
149 |
+
} else if (sourceAspectRatio < destinationAspectRatio) {
|
150 |
+
scaledSize.width = sourceWidth * ( destinationHeight / sourceHeight );
|
151 |
+
scaledSize.height = destinationHeight
|
152 |
+
} else {
|
153 |
+
scaledSize.width = destinationWidth;
|
154 |
+
scaledSize.height = destinationHeight
|
155 |
+
}
|
156 |
+
|
157 |
+
return scaledSize;
|
158 |
+
}
|
159 |
+
|
160 |
+
function parseTransformMatrix(transformMatrix) {
|
161 |
+
var parsedMatrix = [1,0,0,1,0,0];
|
162 |
+
|
163 |
+
if (transformMatrix.indexOf( "matrix(" ) == 0) {
|
164 |
+
var arrayString = transformMatrix.substring(7, transformMatrix.length - 1);
|
165 |
+
|
166 |
+
parsedMatrix = arrayString.split(",");
|
167 |
+
}
|
168 |
+
|
169 |
+
return parsedMatrix;
|
170 |
+
}
|
171 |
+
|
172 |
+
function escapeTextureId(textureId) {
|
173 |
+
var escapedTextureId = textureId.replace( /\./g, "-" );
|
174 |
+
|
175 |
+
return escapedTextureId;
|
176 |
+
}
|
177 |
+
|
178 |
+
function unEscapeTextureId(textureId) {
|
179 |
+
var escapedTextureId = textureId.replace( /\-/g, "." );
|
180 |
+
|
181 |
+
return escapedTextureId;
|
182 |
+
}
|
183 |
+
|
184 |
+
var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
|
185 |
+
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
|
186 |
+
function LZ(x) {return(x<0||x>9?"":"0")+x;}
|
187 |
+
|
188 |
+
Object.extend(Date.prototype, {
|
189 |
+
// ------------------------------------------------------------------
|
190 |
+
// formatDate (date_object, format)
|
191 |
+
// Returns a date in the output format specified.
|
192 |
+
// The format string uses the same abbreviations as in getDateFromFormat()
|
193 |
+
//
|
194 |
+
// ------------------------------------------------------------------
|
195 |
+
format: function(format) {
|
196 |
+
format=format+"";
|
197 |
+
var date = this ;
|
198 |
+
var result="";
|
199 |
+
var i_format=0;
|
200 |
+
var c="";
|
201 |
+
var token="";
|
202 |
+
var y=date.getFullYear()+"";
|
203 |
+
var M=date.getMonth()+1;
|
204 |
+
var d=date.getDate();
|
205 |
+
var E=date.getDay();
|
206 |
+
var H=date.getHours();
|
207 |
+
var m=date.getMinutes();
|
208 |
+
var s=date.getSeconds();
|
209 |
+
var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
|
210 |
+
// Convert real date parts into formatted versions
|
211 |
+
var value=new Object();
|
212 |
+
if (y.length < 4) {
|
213 |
+
y=""+(y-0+1900);
|
214 |
+
}
|
215 |
+
value["y"]=""+y;
|
216 |
+
value["yyyy"]=y;
|
217 |
+
value["yy"]=y.substring(2,4);
|
218 |
+
value["M"]=M;
|
219 |
+
value["MM"]=LZ(M);
|
220 |
+
value["MMM"]=MONTH_NAMES[M-1];
|
221 |
+
value["NNN"]=MONTH_NAMES[M+11];
|
222 |
+
value["d"]=d;
|
223 |
+
value["dd"]=LZ(d);
|
224 |
+
value["E"]=DAY_NAMES[E+7];
|
225 |
+
value["EE"]=DAY_NAMES[E];
|
226 |
+
value["H"]=H;
|
227 |
+
value["HH"]=LZ(H);
|
228 |
+
if (H==0) {
|
229 |
+
value["h"]=12;
|
230 |
+
} else if (H>12) {
|
231 |
+
value["h"]=H-12;
|
232 |
+
} else {
|
233 |
+
value["h"]=H;
|
234 |
+
}
|
235 |
+
value["hh"]=LZ(value["h"]);
|
236 |
+
if (H>11) {
|
237 |
+
value["K"]=H-12;
|
238 |
+
} else {
|
239 |
+
value["K"]=H;
|
240 |
+
}
|
241 |
+
value["k"]=H+1;
|
242 |
+
value["KK"]=LZ(value["K"]);
|
243 |
+
value["kk"]=LZ(value["k"]);
|
244 |
+
if (H > 11) {
|
245 |
+
value["a"]="PM";
|
246 |
+
} else {
|
247 |
+
value["a"]="AM";
|
248 |
+
}
|
249 |
+
value["m"]=m;
|
250 |
+
value["mm"]=LZ(m);
|
251 |
+
value["s"]=s;
|
252 |
+
value["ss"]=LZ(s);
|
253 |
+
while (i_format < format.length) {
|
254 |
+
c=format.charAt(i_format);
|
255 |
+
token="";
|
256 |
+
while ((format.charAt(i_format)==c) && (i_format < format.length)) {
|
257 |
+
token += format.charAt(i_format++);
|
258 |
+
}
|
259 |
+
|
260 |
+
if (value[token] != null) {
|
261 |
+
result=result + value[token];
|
262 |
+
} else {
|
263 |
+
result=result + token;
|
264 |
+
}
|
265 |
+
}
|
266 |
+
return result;
|
267 |
+
}
|
268 |
+
});
|
269 |
+
|
270 |
+
function getHecklerElementsByTagName(xml, tagName) {
|
271 |
+
return getElementsByTagNameNS(xml, tagName, 'urn:iwork:property', 'X:');
|
272 |
+
}
|
273 |
+
|
274 |
+
function getElementsByTagNameNS(xml, tagName, ns, prefix) {
|
275 |
+
var nodes = null;
|
276 |
+
if (xml.getElementsByTagNameNS) {
|
277 |
+
nodes = xml.getElementsByTagNameNS(ns, tagName);
|
278 |
+
} else {
|
279 |
+
// IE7 Does not support getElementsByTagNameNS
|
280 |
+
// So we have to do this silly IE7 workaround and prefix the Heckler
|
281 |
+
// namespace to everything
|
282 |
+
nodes = xml.getElementsByTagName(prefix + tagName);
|
283 |
+
}
|
284 |
+
|
285 |
+
return nodes;
|
286 |
+
}
|
assets/player/gl/KNWebGLObjects.js
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
assets/player/gl/KNWebGLParticleObjects.js
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
assets/player/gl/KNWebGLShader.js
CHANGED
@@ -1,3 +1,1326 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* KNWebGLShader.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2016-2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var KNWebGLShader = {};
|
10 |
+
|
11 |
+
KNWebGLShader.defaultTexture = {
|
12 |
+
attribNames: ["Position", "TexCoord"],
|
13 |
+
uniformNames: ["MVPMatrix", "Texture"],
|
14 |
+
vertex: "\
|
15 |
+
#ifdef GL_ES\n\
|
16 |
+
precision highp float;\n\
|
17 |
+
#endif\n\
|
18 |
+
uniform mat4 MVPMatrix;\n\
|
19 |
+
attribute vec4 Position;\n\
|
20 |
+
attribute vec2 TexCoord;\n\
|
21 |
+
varying vec2 v_TexCoord;\n\
|
22 |
+
void main()\n\
|
23 |
+
{\n\
|
24 |
+
v_TexCoord = TexCoord;\n\
|
25 |
+
gl_Position = (MVPMatrix * Position);\n\
|
26 |
+
}\
|
27 |
+
",
|
28 |
+
fragment: "\
|
29 |
+
#ifdef GL_ES\n\
|
30 |
+
precision mediump float;\n\
|
31 |
+
#endif\n\
|
32 |
+
uniform sampler2D Texture;\n\
|
33 |
+
varying vec2 v_TexCoord;\n\
|
34 |
+
void main()\n\
|
35 |
+
{\n\
|
36 |
+
gl_FragColor = texture2D(Texture, v_TexCoord);\n\
|
37 |
+
}\
|
38 |
+
"
|
39 |
+
};
|
40 |
+
|
41 |
+
KNWebGLShader.defaultTextureAndOpacity = {
|
42 |
+
attribNames: ["Position", "TexCoord"],
|
43 |
+
uniformNames: ["MVPMatrix", "Texture", "Opacity"],
|
44 |
+
vertex: "\
|
45 |
+
#ifdef GL_ES\n\
|
46 |
+
precision highp float;\n\
|
47 |
+
#endif\n\
|
48 |
+
uniform mat4 MVPMatrix;\n\
|
49 |
+
attribute vec4 Position;\n\
|
50 |
+
attribute vec2 TexCoord;\n\
|
51 |
+
varying vec2 v_TexCoord;\n\
|
52 |
+
void main()\n\
|
53 |
+
{\n\
|
54 |
+
v_TexCoord = TexCoord;\n\
|
55 |
+
gl_Position = (MVPMatrix * Position);\n\
|
56 |
+
}\
|
57 |
+
",
|
58 |
+
fragment: "\
|
59 |
+
#ifdef GL_ES\n\
|
60 |
+
precision mediump float;\n\
|
61 |
+
#endif\n\
|
62 |
+
uniform sampler2D Texture;\n\
|
63 |
+
uniform float Opacity;\n\
|
64 |
+
varying vec2 v_TexCoord;\n\
|
65 |
+
void main()\n\
|
66 |
+
{\n\
|
67 |
+
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
|
68 |
+
gl_FragColor = vec4(Opacity) * texColor;\n\
|
69 |
+
}\
|
70 |
+
"
|
71 |
+
};
|
72 |
+
|
73 |
+
KNWebGLShader.contents = {
|
74 |
+
attribNames: ["Position", "TexCoord"],
|
75 |
+
uniformNames: ["MVPMatrix", "Texture", "Texture2", "mixFactor"],
|
76 |
+
vertex: "\
|
77 |
+
#ifdef GL_ES\n\
|
78 |
+
precision highp float;\n\
|
79 |
+
#endif\n\
|
80 |
+
uniform mat4 MVPMatrix;\n\
|
81 |
+
attribute vec4 Position;\n\
|
82 |
+
attribute vec2 TexCoord;\n\
|
83 |
+
varying vec2 v_TexCoord;\n\
|
84 |
+
void main()\n\
|
85 |
+
{\n\
|
86 |
+
v_TexCoord = TexCoord;\n\
|
87 |
+
gl_Position = (MVPMatrix * Position);\n\
|
88 |
+
}\
|
89 |
+
",
|
90 |
+
fragment: "\
|
91 |
+
#ifdef GL_ES\n\
|
92 |
+
precision mediump float;\n\
|
93 |
+
#endif\n\
|
94 |
+
uniform sampler2D Texture;\n\
|
95 |
+
uniform sampler2D Texture2;\n\
|
96 |
+
uniform float mixFactor;\n\
|
97 |
+
varying vec2 v_TexCoord;\n\
|
98 |
+
void main()\n\
|
99 |
+
{\n\
|
100 |
+
vec4 outgoingColor = texture2D(Texture2, v_TexCoord);\n\
|
101 |
+
vec4 incomingColor = texture2D(Texture, v_TexCoord);\n\
|
102 |
+
vec4 result = mix(outgoingColor, incomingColor, mixFactor);\n\
|
103 |
+
gl_FragColor = result;\n\
|
104 |
+
}\
|
105 |
+
"
|
106 |
+
};
|
107 |
+
|
108 |
+
KNWebGLShader.iris = {
|
109 |
+
attribNames: ["Position", "TexCoord"],
|
110 |
+
uniformNames: ["PercentForAlpha", "Scale", "Mix", "Texture", "MVPMatrix", "Opacity"],
|
111 |
+
vertex: "\
|
112 |
+
#ifdef GL_ES\n\
|
113 |
+
precision highp float;\n\
|
114 |
+
#endif\n\
|
115 |
+
uniform mat4 MVPMatrix;\n\
|
116 |
+
attribute vec4 Position;\n\
|
117 |
+
attribute vec2 TexCoord;\n\
|
118 |
+
varying vec2 v_TexCoord;\n\
|
119 |
+
void main()\n\
|
120 |
+
{\n\
|
121 |
+
v_TexCoord = TexCoord;\n\
|
122 |
+
gl_Position = MVPMatrix * Position;\n\
|
123 |
+
}\
|
124 |
+
",
|
125 |
+
fragment: "\
|
126 |
+
#ifdef GL_ES\n\
|
127 |
+
precision mediump float;\n\
|
128 |
+
#endif\n\
|
129 |
+
uniform sampler2D Texture;\n\
|
130 |
+
uniform float Opacity;\n\
|
131 |
+
uniform float PercentForAlpha;\n\
|
132 |
+
uniform float Scale;\n\
|
133 |
+
uniform float Mix;\n\
|
134 |
+
varying vec2 v_TexCoord;\n\
|
135 |
+
void main()\n\
|
136 |
+
{\n\
|
137 |
+
vec4 incomingTexColor = texture2D(Texture, v_TexCoord);\n\
|
138 |
+
vec4 clear = vec4(0.0, 0.0, 0.0, 0.0);\n\
|
139 |
+
float tolerance = PercentForAlpha/5.0;\n\
|
140 |
+
vec2 powers = vec2((v_TexCoord.x - 0.5) * Scale,v_TexCoord.y - 0.5);\n\
|
141 |
+
powers *= powers;\n\
|
142 |
+
float radiusSqrd = PercentForAlpha * PercentForAlpha;\n\
|
143 |
+
float dist = (powers.x+powers.y)/((0.5*Scale)*(0.5*Scale)+0.25);\n\
|
144 |
+
float gradient = smoothstep(radiusSqrd, radiusSqrd+tolerance, dist);\n\
|
145 |
+
gl_FragColor = vec4(Opacity) * mix(clear, incomingTexColor, abs(Mix - gradient));\n\
|
146 |
+
}\
|
147 |
+
"
|
148 |
+
};
|
149 |
+
|
150 |
+
KNWebGLShader.twist = {
|
151 |
+
attribNames: ["Position", "TexCoord", "Normal"],
|
152 |
+
uniformNames: ["TextureMatrix", "SpecularColor", "FlipNormals", "MVPMatrix", "Texture"],
|
153 |
+
vertex: "\
|
154 |
+
#ifdef GL_ES\n\
|
155 |
+
precision highp float;\n\
|
156 |
+
#endif\n\
|
157 |
+
uniform mat4 MVPMatrix;\n\
|
158 |
+
uniform mat3 TextureMatrix;\n\
|
159 |
+
uniform float SpecularColor;\n\
|
160 |
+
uniform mediump float FlipNormals;\n\
|
161 |
+
attribute vec3 Position;\n\
|
162 |
+
attribute vec3 Normal;\n\
|
163 |
+
attribute vec2 TexCoord;\n\
|
164 |
+
varying vec2 v_TexCoord;\n\
|
165 |
+
varying vec3 v_DiffuseColor;\n\
|
166 |
+
varying vec3 v_SpecularColor;\n\
|
167 |
+
const vec3 c_AmbientColor = vec3(0.2);\n\
|
168 |
+
const vec3 c_DiffuseColor = vec3(1);\n\
|
169 |
+
const float c_LightExponent = 32.0;\n\
|
170 |
+
const vec3 c_LightDirection = vec3(0.1580, +0.5925, 0.7900);\n\
|
171 |
+
const vec3 c_LightHalfPlane = vec3(0.0835, +0.3131, 0.9460);\n\
|
172 |
+
void main()\n\
|
173 |
+
{\n\
|
174 |
+
vec3 thisNormal = Normal * FlipNormals;\n\
|
175 |
+
// Lighting\n\
|
176 |
+
float ndotl = max(0.0, dot(thisNormal, c_LightDirection));\n\
|
177 |
+
float ndoth = max(0.0, dot(thisNormal, c_LightHalfPlane));\n\
|
178 |
+
v_DiffuseColor = (c_AmbientColor + ndotl * c_DiffuseColor);\n\
|
179 |
+
v_SpecularColor = (ndoth <= 0.0) ? vec3(0) : (pow(ndoth, c_LightExponent) * vec3(SpecularColor));\n\
|
180 |
+
gl_Position = MVPMatrix * vec4(Position, 1.0);\n\
|
181 |
+
v_TexCoord = (TextureMatrix * vec3(TexCoord,1.0)).xy;\n\
|
182 |
+
}\
|
183 |
+
",
|
184 |
+
fragment: "\
|
185 |
+
#ifdef GL_ES\n\
|
186 |
+
precision mediump float;\n\
|
187 |
+
#endif\n\
|
188 |
+
uniform sampler2D Texture;\n\
|
189 |
+
varying vec2 v_TexCoord;\n\
|
190 |
+
varying vec3 v_DiffuseColor;\n\
|
191 |
+
varying vec3 v_SpecularColor;\n\
|
192 |
+
void main()\n\
|
193 |
+
{\n\
|
194 |
+
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
|
195 |
+
// Lighting\n\
|
196 |
+
texColor.xyz = texColor.xyz * v_DiffuseColor + v_SpecularColor;\n\
|
197 |
+
gl_FragColor = texColor;\n\
|
198 |
+
}\
|
199 |
+
"
|
200 |
+
};
|
201 |
+
|
202 |
+
KNWebGLShader.colorPlanes = {
|
203 |
+
attribNames: ["Position", "TexCoord"],
|
204 |
+
uniformNames: ["MVPMatrix", "FlipTexCoords", "Texture", "ColorMask"],
|
205 |
+
vertex: "\
|
206 |
+
#ifdef GL_ES\n\
|
207 |
+
precision highp float;\n\
|
208 |
+
#endif\n\
|
209 |
+
uniform mat4 MVPMatrix;\n\
|
210 |
+
uniform vec2 FlipTexCoords;\n\
|
211 |
+
attribute vec2 Position;\n\
|
212 |
+
attribute vec2 TexCoord;\n\
|
213 |
+
varying vec2 v_TexCoord;\n\
|
214 |
+
void main()\n\
|
215 |
+
{\n\
|
216 |
+
v_TexCoord = vec2(FlipTexCoords.x == 0.0 ? TexCoord.x : 1.0-TexCoord.x, FlipTexCoords.y == 0.0 ? TexCoord.y : 1.0-TexCoord.y);\n\
|
217 |
+
gl_Position = MVPMatrix * vec4(Position, 0,1);\n\
|
218 |
+
}\
|
219 |
+
",
|
220 |
+
fragment: "\
|
221 |
+
#ifdef GL_ES\n\
|
222 |
+
precision mediump float;\n\
|
223 |
+
#endif\n\
|
224 |
+
uniform sampler2D Texture;\n\
|
225 |
+
uniform vec4 ColorMask;\n\
|
226 |
+
varying vec2 v_TexCoord;\n\
|
227 |
+
void main()\n\
|
228 |
+
{\n\
|
229 |
+
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
|
230 |
+
texColor *= ColorMask;\n\
|
231 |
+
gl_FragColor = texColor;\n\
|
232 |
+
}\
|
233 |
+
"
|
234 |
+
};
|
235 |
+
|
236 |
+
KNWebGLShader.flop = {
|
237 |
+
attribNames: ["Position", "TexCoord", "Normal"],
|
238 |
+
uniformNames: ["TextureMatrix", "FlipNormals", "MVPMatrix", "Texture"],
|
239 |
+
vertex: "\
|
240 |
+
\n\
|
241 |
+
#ifdef GL_ES\n\
|
242 |
+
precision highp float;\n\
|
243 |
+
#endif\n\
|
244 |
+
\n\
|
245 |
+
uniform mat4 MVPMatrix;\n\
|
246 |
+
uniform mat3 TextureMatrix;\n\
|
247 |
+
uniform float FlipNormals;\n\
|
248 |
+
\n\
|
249 |
+
attribute vec3 Position;\n\
|
250 |
+
attribute vec3 Normal;\n\
|
251 |
+
attribute vec2 TexCoord;\n\
|
252 |
+
\n\
|
253 |
+
varying vec2 v_TexCoord;\n\
|
254 |
+
varying vec3 v_DiffuseColor;\n\
|
255 |
+
\n\
|
256 |
+
const vec3 c_AmbientColor = vec3(0.1);\n\
|
257 |
+
const vec3 c_DiffuseColor = vec3(1);\n\
|
258 |
+
const float c_LightExponent = 32.0;\n\
|
259 |
+
\n\
|
260 |
+
const vec3 c_LightDirection = vec3(0.000, +0.000, 0.900);\n\
|
261 |
+
\n\
|
262 |
+
void main()\n\
|
263 |
+
{\n\
|
264 |
+
vec3 thisNormal = Normal * FlipNormals;\n\
|
265 |
+
\n\
|
266 |
+
// Lighting\n\
|
267 |
+
vec3 lightDirection = vec3(c_LightDirection.x,c_LightDirection.y,c_LightDirection.z);\n\
|
268 |
+
\n\
|
269 |
+
float ndotl = max(0.0, dot(thisNormal, lightDirection));\n\
|
270 |
+
\n\
|
271 |
+
v_DiffuseColor = (c_AmbientColor + ndotl * c_DiffuseColor);\n\
|
272 |
+
\n\
|
273 |
+
gl_Position = MVPMatrix * vec4(Position, 1);\n\
|
274 |
+
v_TexCoord = (TextureMatrix * vec3(TexCoord,1)).xy;\n\
|
275 |
+
}\
|
276 |
+
",
|
277 |
+
fragment: "\
|
278 |
+
\n\
|
279 |
+
#ifdef GL_ES\n\
|
280 |
+
precision mediump float;\n\
|
281 |
+
#endif\n\
|
282 |
+
\n\
|
283 |
+
uniform sampler2D Texture;\n\
|
284 |
+
\n\
|
285 |
+
varying vec2 v_TexCoord;\n\
|
286 |
+
varying vec3 v_DiffuseColor;\n\
|
287 |
+
\n\
|
288 |
+
void main()\n\
|
289 |
+
{\n\
|
290 |
+
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
|
291 |
+
\n\
|
292 |
+
// Lighting\n\
|
293 |
+
texColor.xyz = texColor.xyz * v_DiffuseColor;\n\
|
294 |
+
gl_FragColor = texColor;\n\
|
295 |
+
}\
|
296 |
+
"
|
297 |
+
};
|
298 |
+
|
299 |
+
KNWebGLShader.anvilsmoke = {
|
300 |
+
attribNames: ["Rotation", "Speed", "Scale", "LifeSpan", "ParticleTexCoord", "Center", "Position"],
|
301 |
+
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix"],
|
302 |
+
vertex: "\
|
303 |
+
\n\
|
304 |
+
uniform mat4 MVPMatrix;\n\
|
305 |
+
uniform float Percent;\n\
|
306 |
+
uniform float Opacity;\n\
|
307 |
+
\n\
|
308 |
+
attribute vec2 Position;\n\
|
309 |
+
attribute vec2 Center;\n\
|
310 |
+
attribute vec2 ParticleTexCoord;\n\
|
311 |
+
attribute vec3 Rotation;\n\
|
312 |
+
attribute vec3 Speed;\n\
|
313 |
+
attribute float Scale;\n\
|
314 |
+
attribute vec2 LifeSpan;\n\
|
315 |
+
\n\
|
316 |
+
varying vec4 v_Color;\n\
|
317 |
+
varying vec2 v_TexCoord;\n\
|
318 |
+
\n\
|
319 |
+
const float Pi = 3.1415926;\n\
|
320 |
+
const float Pi_2 = 1.5707963;\n\
|
321 |
+
const float TwoPi = 6.2831852;\n\
|
322 |
+
\n\
|
323 |
+
const float sineConstB = 1.2732396; /* = 4./Pi; */\n\
|
324 |
+
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */\n\
|
325 |
+
\n\
|
326 |
+
vec3 fastSine(vec3 angle)\n\
|
327 |
+
{\n\
|
328 |
+
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
|
329 |
+
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
|
330 |
+
}\n\
|
331 |
+
\n\
|
332 |
+
mat3 fastRotationMatrix(vec3 theRotation)\n\
|
333 |
+
{\n\
|
334 |
+
vec3 sinXYZ = fastSine(theRotation);\n\
|
335 |
+
vec3 cosXYZ = fastSine(Pi_2 - theRotation);\n\
|
336 |
+
mat3 rotMatrix = mat3( cosXYZ.y*cosXYZ.z, sinXYZ.x*sinXYZ.y*cosXYZ.z+cosXYZ.x*sinXYZ.z, -cosXYZ.x*sinXYZ.y*cosXYZ.z+sinXYZ.x*sinXYZ.z,\n\
|
337 |
+
-cosXYZ.y*sinXYZ.z, -sinXYZ.x*sinXYZ.y*sinXYZ.z+cosXYZ.x*cosXYZ.z, cosXYZ.x*sinXYZ.y*sinXYZ.z+sinXYZ.x*cosXYZ.z,\n\
|
338 |
+
sinXYZ.y, -sinXYZ.x*cosXYZ.y, cosXYZ.x*cosXYZ.y);\n\
|
339 |
+
return rotMatrix;\n\
|
340 |
+
}\n\
|
341 |
+
\n\
|
342 |
+
void main()\n\
|
343 |
+
{\n\
|
344 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
345 |
+
realPercent = clamp(realPercent, 0.0, 1.0);\n\
|
346 |
+
realPercent = sqrt(realPercent);\n\
|
347 |
+
\n\
|
348 |
+
/* SCALE */\n\
|
349 |
+
vec4 originalPosition = vec4(Position,0,1);\n\
|
350 |
+
vec4 center = vec4(Center, 0,1);\n\
|
351 |
+
vec3 scaleDirectionVec = vec3(originalPosition.xy-center.xy,0) * Scale * mix(0.1, 1.0, realPercent);\n\
|
352 |
+
\n\
|
353 |
+
/* ROTATE */\n\
|
354 |
+
mat3 rotMatrix = fastRotationMatrix(Rotation * realPercent);\n\
|
355 |
+
vec3 rotatedVec = rotMatrix * scaleDirectionVec;\n\
|
356 |
+
vec4 position = center + vec4(rotatedVec,0);\n\
|
357 |
+
\n\
|
358 |
+
float speedAdjust = realPercent;\n\
|
359 |
+
vec3 thisSpeed = Speed;\n\
|
360 |
+
thisSpeed.x *= sqrt(realPercent);\n\
|
361 |
+
thisSpeed.y *= realPercent*realPercent;\n\
|
362 |
+
position += vec4(thisSpeed, 0);\n\
|
363 |
+
\n\
|
364 |
+
float thisOpacity = Opacity;\n\
|
365 |
+
thisOpacity *= (1.0 - realPercent); /* fade out gradually */\n\
|
366 |
+
thisOpacity *= min(1.0, realPercent*20.0); /* fade in quickly */\n\
|
367 |
+
\n\
|
368 |
+
/* output */\n\
|
369 |
+
gl_Position = MVPMatrix * position;\n\
|
370 |
+
//v_Color = vec4(1.0, 1.0, 1.0, thisOpacity); //we applied a fix here, might not work everywhere\n\
|
371 |
+
v_Color = vec4(thisOpacity);\n\
|
372 |
+
v_TexCoord = ParticleTexCoord;\n\
|
373 |
+
}\n\
|
374 |
+
",
|
375 |
+
fragment: "\
|
376 |
+
\n\
|
377 |
+
#ifdef GL_ES\n\
|
378 |
+
precision mediump float;\n\
|
379 |
+
#endif\n\
|
380 |
+
uniform sampler2D ParticleTexture;\n\
|
381 |
+
\n\
|
382 |
+
varying vec4 v_Color;\n\
|
383 |
+
varying vec2 v_TexCoord;\n\
|
384 |
+
\n\
|
385 |
+
void main()\n\
|
386 |
+
{\n\
|
387 |
+
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
|
388 |
+
\n\
|
389 |
+
texColor *= v_Color;\n\
|
390 |
+
\n\
|
391 |
+
gl_FragColor = texColor;\n\
|
392 |
+
}\n\
|
393 |
+
"
|
394 |
+
};
|
395 |
+
|
396 |
+
KNWebGLShader.anvilspeck = {
|
397 |
+
attribNames: ["Speed", "Scale", "LifeSpan", "ParticleTexCoord", "Center", "Position"],
|
398 |
+
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix"],
|
399 |
+
vertex: "\
|
400 |
+
\n\
|
401 |
+
uniform mat4 MVPMatrix;\n\
|
402 |
+
uniform float Percent;\n\
|
403 |
+
uniform float Opacity;\n\
|
404 |
+
\n\
|
405 |
+
attribute vec2 Position;\n\
|
406 |
+
attribute vec2 Center;\n\
|
407 |
+
attribute vec2 ParticleTexCoord;\n\
|
408 |
+
attribute vec3 Speed;\n\
|
409 |
+
attribute float Scale;\n\
|
410 |
+
attribute vec2 LifeSpan;\n\
|
411 |
+
\n\
|
412 |
+
varying vec4 v_Color;\n\
|
413 |
+
varying vec2 v_TexCoord;\n\
|
414 |
+
\n\
|
415 |
+
const float Pi = 3.1415926;\n\
|
416 |
+
const float Pi_2 = 1.5707963;\n\
|
417 |
+
const float TwoPi = 6.2831852;\n\
|
418 |
+
\n\
|
419 |
+
const float sineConstB = 1.2732396; /* = 4./Pi; */\n\
|
420 |
+
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */\n\
|
421 |
+
\n\
|
422 |
+
vec3 fastSine(vec3 angle)\n\
|
423 |
+
{\n\
|
424 |
+
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
|
425 |
+
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
|
426 |
+
}\n\
|
427 |
+
\n\
|
428 |
+
void main()\n\
|
429 |
+
{\n\
|
430 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
431 |
+
realPercent = clamp(realPercent, 0.0, 1.0);\n\
|
432 |
+
\n\
|
433 |
+
/* SCALE */\n\
|
434 |
+
vec4 originalPosition = vec4(Position,0,1);\n\
|
435 |
+
vec4 center = vec4(Center, 0,1);\n\
|
436 |
+
vec3 thisScale = Scale * vec3(1, Speed.z, 1) * mix(0.1, 1.0, realPercent);\n\
|
437 |
+
vec3 scaleDirectionVec = vec3(originalPosition.xy-center.xy,0) * thisScale;\n\
|
438 |
+
\n\
|
439 |
+
vec4 position = center + vec4(scaleDirectionVec,0);\n\
|
440 |
+
\n\
|
441 |
+
float speedAdjust = realPercent;\n\
|
442 |
+
vec3 thisPos = vec3(Speed.x * realPercent,\n\
|
443 |
+
Speed.y * fastSine(Pi*0.85*vec3(realPercent,0,0)).x, /* arc with gravity */\n\
|
444 |
+
0);\n\
|
445 |
+
position += vec4(thisPos, 0);\n\
|
446 |
+
\n\
|
447 |
+
float thisOpacity = Opacity;\n\
|
448 |
+
thisOpacity *= (1.0 - realPercent); /* fade out gradually */\n\
|
449 |
+
thisOpacity *= min(1.0, realPercent*20.0); /* fade in quickly */\n\
|
450 |
+
\n\
|
451 |
+
/* output */\n\
|
452 |
+
gl_Position = MVPMatrix * position;\n\
|
453 |
+
v_Color = vec4(thisOpacity);\n\
|
454 |
+
v_TexCoord = ParticleTexCoord;\n\
|
455 |
+
}\
|
456 |
+
",
|
457 |
+
fragment: "\
|
458 |
+
\n\
|
459 |
+
#ifdef GL_ES\n\
|
460 |
+
precision mediump float;\n\
|
461 |
+
#endif\n\
|
462 |
+
uniform sampler2D ParticleTexture;\n\
|
463 |
+
\n\
|
464 |
+
varying vec4 v_Color;\n\
|
465 |
+
varying vec2 v_TexCoord;\n\
|
466 |
+
\n\
|
467 |
+
void main()\n\
|
468 |
+
{\n\
|
469 |
+
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
|
470 |
+
\n\
|
471 |
+
texColor *= v_Color;\n\
|
472 |
+
\n\
|
473 |
+
gl_FragColor = texColor;\n\
|
474 |
+
}\
|
475 |
+
"
|
476 |
+
};
|
477 |
+
|
478 |
+
KNWebGLShader.flame = {
|
479 |
+
attribNames: ["Rotation", "Speed", "LifeSpan", "ParticleTexCoord", "Center", "Position"],
|
480 |
+
uniformNames: ["Percent", "Duration", "Opacity", "RotationMax", "SpeedMax", "ParticleTexture", "MVPMatrix"],
|
481 |
+
vertex: "\
|
482 |
+
\n\
|
483 |
+
precision highp float;\n\
|
484 |
+
\n\
|
485 |
+
uniform mat4 MVPMatrix;\n\
|
486 |
+
uniform float Percent;\n\
|
487 |
+
uniform float Duration;\n\
|
488 |
+
\n\
|
489 |
+
attribute vec3 Rotation;\n\
|
490 |
+
attribute vec3 Speed;\n\
|
491 |
+
uniform float Opacity;\n\
|
492 |
+
attribute vec2 LifeSpan;\n\
|
493 |
+
attribute vec2 ParticleTexCoord;\n\
|
494 |
+
attribute vec2 Position;\n\
|
495 |
+
attribute vec2 Center;\n\
|
496 |
+
\n\
|
497 |
+
uniform mediump float RotationMax;\n\
|
498 |
+
uniform mediump float SpeedMax;\n\
|
499 |
+
\n\
|
500 |
+
varying vec4 v_Color;\n\
|
501 |
+
varying vec2 v_TexCoord;\n\
|
502 |
+
\n\
|
503 |
+
const float Pi = 3.1415926;\n\
|
504 |
+
const float Pi_2 = 1.5707963;\n\
|
505 |
+
const float TwoPi = 6.2831852;\n\
|
506 |
+
\n\
|
507 |
+
const float sineConstB = 1.2732396; /* = 4./Pi; */\n\
|
508 |
+
const float sineConstC = -0.40528476; /* = -4./(Pi*Pi); */\n\
|
509 |
+
\n\
|
510 |
+
float fastSine(float angle)\n\
|
511 |
+
{\n\
|
512 |
+
float theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
|
513 |
+
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
|
514 |
+
}\n\
|
515 |
+
\n\
|
516 |
+
const vec4 kStartColor = vec4( 1.0, 1.0, 1.0, 0.0 ); /* white */\n\
|
517 |
+
const vec4 kMidColor = vec4( 0.97, 1.0, 0.32, 0.0 ); /* yellow */\n\
|
518 |
+
const vec4 kEndColor = vec4( 0.9, 0.0, 0.0, 0.0 ); /* red */\n\
|
519 |
+
const float kColorMidPoint = 0.1;\n\
|
520 |
+
\n\
|
521 |
+
vec4 flameColor(float aPercent)\n\
|
522 |
+
{\n\
|
523 |
+
float thePercent = aPercent;\n\
|
524 |
+
/* CONSTANTS */\n\
|
525 |
+
float beginCutoff = 0.4/Duration; /* start slow (not bright white) */\n\
|
526 |
+
float smokeCutoff = 1.0 - (0.95/Duration); /* end with black, basically */\n\
|
527 |
+
float alphaCutoff = 1.0 - 0.5/Duration; /* fade out towards the end */\n\
|
528 |
+
\n\
|
529 |
+
float alpha = (thePercent < alphaCutoff) ? 1.0 : (1.0-(thePercent-alphaCutoff)/(1.0-alphaCutoff));\n\
|
530 |
+
vec4 theColor = vec4(0,0,0, alpha * 0.75);\n\
|
531 |
+
\n\
|
532 |
+
if (Percent < beginCutoff) {\n\
|
533 |
+
float colorCutoff = beginCutoff*3.0;\n\
|
534 |
+
thePercent += mix(colorCutoff, 0.0, Percent/beginCutoff);\n\
|
535 |
+
}\n\
|
536 |
+
\n\
|
537 |
+
if (thePercent < kColorMidPoint) {\n\
|
538 |
+
float newPercent = thePercent/kColorMidPoint;\n\
|
539 |
+
theColor += mix(kStartColor, kMidColor, newPercent);\n\
|
540 |
+
} else {\n\
|
541 |
+
float newPercent = (thePercent-kColorMidPoint)/(1.0-kColorMidPoint);\n\
|
542 |
+
theColor += mix(kMidColor, kEndColor, newPercent);\n\
|
543 |
+
}\n\
|
544 |
+
\n\
|
545 |
+
if (Percent > smokeCutoff) {\n\
|
546 |
+
/* smoke */\n\
|
547 |
+
float smokeAmount = (Percent - smokeCutoff)/(1.0 - smokeCutoff);\n\
|
548 |
+
smokeAmount = sqrt(smokeAmount);\n\
|
549 |
+
smokeAmount *= (0.25+thePercent*thePercent);\n\
|
550 |
+
theColor = vec4(theColor.rgb * max(0.0, 1.0-smokeAmount), theColor.a);\n\
|
551 |
+
}\n\
|
552 |
+
\n\
|
553 |
+
return theColor;\n\
|
554 |
+
}\n\
|
555 |
+
\n\
|
556 |
+
void main()\n\
|
557 |
+
{\n\
|
558 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
559 |
+
bool shouldDiscard = realPercent < 0.0 || realPercent > 1.0;\n\
|
560 |
+
realPercent = clamp(realPercent, 0.0, 1.0);\n\
|
561 |
+
\n\
|
562 |
+
vec4 scaleDirectionVec = vec4(Position-Center,0,0);\n\
|
563 |
+
\n\
|
564 |
+
/* ROTATE */\n\
|
565 |
+
float halfPercent = realPercent/2.0;\n\
|
566 |
+
vec3 thisRotation = Rotation * RotationMax;\n\
|
567 |
+
float theRotation = thisRotation.x + thisRotation.z * (halfPercent * (halfPercent + 1.0));\n\
|
568 |
+
float sinRot = fastSine(theRotation);\n\
|
569 |
+
float cosRot = fastSine(Pi_2 - theRotation);\n\
|
570 |
+
mat3 rotMatrix = mat3(cosRot,-sinRot,0, sinRot,cosRot,0, 0,0,1);\n\
|
571 |
+
vec3 rotatedVec = rotMatrix * scaleDirectionVec.xyz;\n\
|
572 |
+
\n\
|
573 |
+
/* SCALE */\n\
|
574 |
+
float scaleAdjust = (0.1 + 1.0-(1.0-realPercent)*(1.0-realPercent));\n\
|
575 |
+
vec4 position = vec4(Center,0,1) + vec4(rotatedVec * scaleAdjust * (shouldDiscard ? 0.001 : 1.0), 0);\n\
|
576 |
+
\n\
|
577 |
+
/* POSITION */\n\
|
578 |
+
vec3 thisSpeed = Speed * SpeedMax;\n\
|
579 |
+
vec4 upVector = vec4(0.0, realPercent*realPercent * -thisSpeed.y, 0.0, 0.0);\n\
|
580 |
+
position += upVector;\n\
|
581 |
+
\n\
|
582 |
+
v_Color = flameColor(realPercent)*Opacity;\n\
|
583 |
+
gl_Position = MVPMatrix * position;\n\
|
584 |
+
v_TexCoord = ParticleTexCoord;\n\
|
585 |
+
}\
|
586 |
+
",
|
587 |
+
fragment: "\
|
588 |
+
\n\
|
589 |
+
#ifdef GL_ES\n\
|
590 |
+
precision mediump float;\n\
|
591 |
+
#endif\n\
|
592 |
+
uniform sampler2D ParticleTexture;\n\
|
593 |
+
\n\
|
594 |
+
varying vec4 v_Color;\n\
|
595 |
+
varying vec2 v_TexCoord;\n\
|
596 |
+
\n\
|
597 |
+
void main()\n\
|
598 |
+
{\n\
|
599 |
+
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
|
600 |
+
\n\
|
601 |
+
texColor *= v_Color;\n\
|
602 |
+
\n\
|
603 |
+
gl_FragColor = texColor;\n\
|
604 |
+
}\n\
|
605 |
+
"
|
606 |
+
};
|
607 |
+
|
608 |
+
KNWebGLShader.confetti = {
|
609 |
+
attribNames: ["Rotation", "Speed", "TexCoord", "Center", "Position"],
|
610 |
+
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix"],
|
611 |
+
vertex: "\
|
612 |
+
\n\
|
613 |
+
precision highp float;\n\
|
614 |
+
uniform mat4 MVPMatrix;\n\
|
615 |
+
\n\
|
616 |
+
uniform float Percent;\n\
|
617 |
+
uniform mediump float Opacity;\n\
|
618 |
+
\n\
|
619 |
+
attribute vec2 Position;\n\
|
620 |
+
attribute vec2 Center;\n\
|
621 |
+
attribute vec2 TexCoord;\n\
|
622 |
+
attribute vec3 Rotation;\n\
|
623 |
+
attribute vec3 Speed;\n\
|
624 |
+
\n\
|
625 |
+
varying vec4 v_Color;\n\
|
626 |
+
varying vec2 v_TexCoord;\n\
|
627 |
+
\n\
|
628 |
+
const float Pi = 3.1415926;\n\
|
629 |
+
const float Pi_2 = 1.5707963;\n\
|
630 |
+
const float TwoPi = 6.2831852;\n\
|
631 |
+
\n\
|
632 |
+
const float sineConstB = 1.2732396;\n\
|
633 |
+
const float sineConstC = -0.40528476;\n\
|
634 |
+
\n\
|
635 |
+
vec3 fastSine(vec3 angle)\n\
|
636 |
+
{\n\
|
637 |
+
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
|
638 |
+
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
|
639 |
+
}\n\
|
640 |
+
\n\
|
641 |
+
mat3 fastRotationMatrix(vec3 theRotation)\n\
|
642 |
+
{\n\
|
643 |
+
vec3 sinXYZ = fastSine(theRotation);\n\
|
644 |
+
vec3 cosXYZ = fastSine(Pi_2 - theRotation);\n\
|
645 |
+
mat3 rotMatrix = mat3( cosXYZ.y*cosXYZ.z, sinXYZ.x*sinXYZ.y*cosXYZ.z+cosXYZ.x*sinXYZ.z, -cosXYZ.x*sinXYZ.y*cosXYZ.z+sinXYZ.x*sinXYZ.z,\n\
|
646 |
+
-cosXYZ.y*sinXYZ.z, -sinXYZ.x*sinXYZ.y*sinXYZ.z+cosXYZ.x*cosXYZ.z, cosXYZ.x*sinXYZ.y*sinXYZ.z+sinXYZ.x*cosXYZ.z,\n\
|
647 |
+
sinXYZ.y, -sinXYZ.x*cosXYZ.y, cosXYZ.x*cosXYZ.y);\n\
|
648 |
+
return rotMatrix;\n\
|
649 |
+
}\n\
|
650 |
+
\n\
|
651 |
+
void main()\n\
|
652 |
+
{\n\
|
653 |
+
/* SCALE */\n\
|
654 |
+
vec4 originalPosition = vec4(Position, 0, 1);\n\
|
655 |
+
vec3 scaleDirectionVec = vec3(Position-Center,0);\n\
|
656 |
+
\n\
|
657 |
+
/* ROTATE */\n\
|
658 |
+
mat3 rotMatrix = fastRotationMatrix(Rotation * Percent);\n\
|
659 |
+
vec3 rotatedVec = scaleDirectionVec * rotMatrix;\n\
|
660 |
+
vec4 position = vec4(Center,0,1) + vec4(rotatedVec,0);\n\
|
661 |
+
\n\
|
662 |
+
float colorAdjust = abs((rotMatrix * vec3(0,0,1)).z);\n\
|
663 |
+
\n\
|
664 |
+
float speedAdjust = Percent;\n\
|
665 |
+
position += vec4(Speed, 0) * speedAdjust;\n\
|
666 |
+
\n\
|
667 |
+
/* output */\n\
|
668 |
+
gl_Position = MVPMatrix * position;\n\
|
669 |
+
v_Color = vec4(vec3(colorAdjust), Opacity);\n\
|
670 |
+
v_TexCoord = TexCoord;\n\
|
671 |
+
}\
|
672 |
+
",
|
673 |
+
fragment: "\
|
674 |
+
\n\
|
675 |
+
precision mediump float;\n\
|
676 |
+
\n\
|
677 |
+
uniform sampler2D ParticleTexture;\n\
|
678 |
+
//uniform float Opacity;\n\
|
679 |
+
\n\
|
680 |
+
varying vec4 v_Color;\n\
|
681 |
+
varying vec2 v_TexCoord;\n\
|
682 |
+
\n\
|
683 |
+
void main()\n\
|
684 |
+
{\n\
|
685 |
+
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
|
686 |
+
\n\
|
687 |
+
texColor *= v_Color;\n\
|
688 |
+
//texColor.a = Opacity;\n\
|
689 |
+
\n\
|
690 |
+
gl_FragColor = texColor;\n\
|
691 |
+
}\
|
692 |
+
"
|
693 |
+
};
|
694 |
+
|
695 |
+
KNWebGLShader.diffuse = {
|
696 |
+
attribNames: ["Rotation", "Speed", "TexCoord", "Center", "Position", "LifeSpan"],
|
697 |
+
uniformNames: ["Percent", "Opacity", "ParticleTexture", "MVPMatrix", "RotationMax", "SpeedMax"],
|
698 |
+
vertex: "\
|
699 |
+
\n\
|
700 |
+
precision highp float;\n\
|
701 |
+
\n\
|
702 |
+
uniform mat4 MVPMatrix;\n\
|
703 |
+
\n\
|
704 |
+
uniform float Percent;\n\
|
705 |
+
uniform mediump float Opacity;\n\
|
706 |
+
\n\
|
707 |
+
attribute vec2 Position;\n\
|
708 |
+
attribute vec2 Center;\n\
|
709 |
+
attribute vec2 TexCoord;\n\
|
710 |
+
\n\
|
711 |
+
attribute mediump vec3 Rotation;\n\
|
712 |
+
uniform mediump float RotationMax;\n\
|
713 |
+
attribute mediump vec3 Speed;\n\
|
714 |
+
uniform mediump float SpeedMax;\n\
|
715 |
+
attribute mediump vec2 LifeSpan;\n\
|
716 |
+
\n\
|
717 |
+
varying vec4 v_Color;\n\
|
718 |
+
varying vec2 v_TexCoord;\n\
|
719 |
+
\n\
|
720 |
+
const float Pi = 3.1415926;\n\
|
721 |
+
const float Pi_2 = 1.5707963;\n\
|
722 |
+
const float TwoPi = 6.2831852;\n\
|
723 |
+
\n\
|
724 |
+
const float sineConstB = 1.2732396;\n\
|
725 |
+
const float sineConstC = -0.40528476;\n\
|
726 |
+
\n\
|
727 |
+
vec3 fastSine(vec3 angle)\n\
|
728 |
+
{\n\
|
729 |
+
vec3 theAngle = mod(angle + Pi, TwoPi) - Pi;\n\
|
730 |
+
return sineConstB * theAngle + sineConstC * theAngle * abs(theAngle);\n\
|
731 |
+
}\n\
|
732 |
+
\n\
|
733 |
+
mat3 fastRotationMatrix(vec3 theRotation)\n\
|
734 |
+
{\n\
|
735 |
+
vec3 sinXYZ = fastSine(theRotation);\n\
|
736 |
+
vec3 cosXYZ = fastSine(Pi_2 - theRotation);\n\
|
737 |
+
mat3 rotMatrix = mat3( cosXYZ.y*cosXYZ.z, sinXYZ.x*sinXYZ.y*cosXYZ.z+cosXYZ.x*sinXYZ.z, -cosXYZ.x*sinXYZ.y*cosXYZ.z+sinXYZ.x*sinXYZ.z,\n\
|
738 |
+
-cosXYZ.y*sinXYZ.z, -sinXYZ.x*sinXYZ.y*sinXYZ.z+cosXYZ.x*cosXYZ.z, cosXYZ.x*sinXYZ.y*sinXYZ.z+sinXYZ.x*cosXYZ.z,\n\
|
739 |
+
sinXYZ.y, -sinXYZ.x*cosXYZ.y, cosXYZ.x*cosXYZ.y);\n\
|
740 |
+
return rotMatrix;\n\
|
741 |
+
}\n\
|
742 |
+
\n\
|
743 |
+
void main()\n\
|
744 |
+
{\n\
|
745 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
746 |
+
float doDiscard = (realPercent > 1.0) ? 0.0 : 1.0;\n\
|
747 |
+
realPercent = clamp(realPercent, 0.0,1.0);\n\
|
748 |
+
float revPercent = 1.0-realPercent;\n\
|
749 |
+
\n\
|
750 |
+
//SCALE\n\
|
751 |
+
vec4 originalPosition = vec4(Position, 0, 1);\n\
|
752 |
+
vec3 scaleDirectionVec = vec3(Position-Center,0);\n\
|
753 |
+
\n\
|
754 |
+
//ROTATE\n\
|
755 |
+
vec3 thisRotation = Rotation * RotationMax;\n\
|
756 |
+
mat3 rotMatrix = fastRotationMatrix(thisRotation * realPercent);\n\
|
757 |
+
vec3 rotatedVec = scaleDirectionVec * rotMatrix;\n\
|
758 |
+
vec4 position = vec4(Center,0,1) + vec4(rotatedVec,0) * doDiscard;\n\
|
759 |
+
\n\
|
760 |
+
vec3 thisSpeed = Speed * SpeedMax;\n\
|
761 |
+
float l2r = -thisSpeed.x/abs(thisSpeed.x);\n\
|
762 |
+
float reverseVector = l2r*(thisSpeed.x+abs(thisSpeed.y)) * realPercent/8.0;\n\
|
763 |
+
\n\
|
764 |
+
float speedMultiplier = 1.-pow(revPercent, 2.0);\n\
|
765 |
+
vec3 dist = thisSpeed * speedMultiplier;\n\
|
766 |
+
dist.x += reverseVector;\n\
|
767 |
+
position.xyz += dist;\n\
|
768 |
+
\n\
|
769 |
+
float colorAdjust = abs((rotMatrix * vec3(0,0,1)).z);\n\
|
770 |
+
\n\
|
771 |
+
//output\n\
|
772 |
+
gl_Position = MVPMatrix * position;\n\
|
773 |
+
v_Color = vec4(vec3(colorAdjust), 1) * (revPercent*Opacity);\n\
|
774 |
+
v_TexCoord = TexCoord;\n\
|
775 |
+
}\
|
776 |
+
",
|
777 |
+
fragment: "\
|
778 |
+
\n\
|
779 |
+
precision mediump float;\n\
|
780 |
+
\n\
|
781 |
+
uniform sampler2D Texture;\n\
|
782 |
+
uniform float Opacity;\n\
|
783 |
+
\n\
|
784 |
+
varying vec4 v_Color;\n\
|
785 |
+
varying vec2 v_TexCoord;\n\
|
786 |
+
\n\
|
787 |
+
void main()\n\
|
788 |
+
{\n\
|
789 |
+
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
|
790 |
+
\n\
|
791 |
+
texColor *= v_Color;\n\
|
792 |
+
\n\
|
793 |
+
gl_FragColor = texColor;\n\
|
794 |
+
}\
|
795 |
+
"
|
796 |
+
};
|
797 |
+
|
798 |
+
KNWebGLShader.fireworks = {
|
799 |
+
attribNames: ["Color", "Speed", "LifeSpan", "Scale", "ParticleTexCoord", "Center", "Position"],
|
800 |
+
uniformNames: ["Percent", "PreviousPercent", "Gravity", "StartScale", "ShouldSparkle", "SparklePeriod", "ParticleBurstTiming", "PreviousParticleBurstTiming", "SpeedMax", "ParticleTexture", "Opacity", "MVPMatrix"],
|
801 |
+
vertex: "\
|
802 |
+
\n\
|
803 |
+
precision highp float;\n\
|
804 |
+
\n\
|
805 |
+
uniform mat4 MVPMatrix;\n\
|
806 |
+
\n\
|
807 |
+
uniform float Percent;\n\
|
808 |
+
uniform float PreviousPercent;\n\
|
809 |
+
uniform float Gravity;\n\
|
810 |
+
uniform float StartScale;\n\
|
811 |
+
uniform float ShouldSparkle;\n\
|
812 |
+
uniform float SparklePeriod;\n\
|
813 |
+
uniform float ParticleBurstTiming;\n\
|
814 |
+
uniform float PreviousParticleBurstTiming;\n\
|
815 |
+
uniform float SpeedMax;\n\
|
816 |
+
\n\
|
817 |
+
attribute vec2 Position;\n\
|
818 |
+
attribute vec2 Center;\n\
|
819 |
+
attribute vec2 ParticleTexCoord;\n\
|
820 |
+
\n\
|
821 |
+
attribute vec4 Color;\n\
|
822 |
+
attribute vec3 Speed;\n\
|
823 |
+
attribute vec2 LifeSpan;\n\
|
824 |
+
attribute float Scale;\n\
|
825 |
+
\n\
|
826 |
+
varying vec4 v_Color;\n\
|
827 |
+
varying vec2 v_TexCoord;\n\
|
828 |
+
\n\
|
829 |
+
void main()\n\
|
830 |
+
{\n\
|
831 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
832 |
+
realPercent = clamp(realPercent, 0.0, 1.0);\n\
|
833 |
+
\n\
|
834 |
+
float prevRealPercent = (PreviousPercent-LifeSpan.x)/LifeSpan.y;\n\
|
835 |
+
prevRealPercent = clamp(prevRealPercent, 0.0,1.0);\n\
|
836 |
+
\n\
|
837 |
+
vec4 center = vec4(Center,0,1);\n\
|
838 |
+
vec4 scaleDirectionVec = vec4(Position-Center,0,0);\n\
|
839 |
+
\n\
|
840 |
+
// TRANSLATE\n\
|
841 |
+
vec3 translation = Speed * (SpeedMax * ParticleBurstTiming); // (1.0-pow(1.0-realPercent, ExplosionPower));\n\
|
842 |
+
translation.y -= Gravity * (Percent - LifeSpan.x); // Gravity is in terms of global percent, not particle system percent\n\
|
843 |
+
\n\
|
844 |
+
vec3 prevTranslation = Speed * (SpeedMax * PreviousParticleBurstTiming);\n\
|
845 |
+
prevTranslation.y -= Gravity * (PreviousPercent - LifeSpan.x); // Gravity is in terms of global percent, not particle system percent\n\
|
846 |
+
\n\
|
847 |
+
vec3 blurOffset = translation - prevTranslation; // Blur in direction of velocity\n\
|
848 |
+
\n\
|
849 |
+
// project centerVec onto translationOffset to get direction\n\
|
850 |
+
blurOffset *= (dot(blurOffset, scaleDirectionVec.xyz) >= 0.0 ? 1.0 : -1.0);\n\
|
851 |
+
\n\
|
852 |
+
center.xyz += translation;\n\
|
853 |
+
\n\
|
854 |
+
// SCALE\n\
|
855 |
+
float scalePercent = (1.0-(1.0-realPercent)*(1.0-realPercent));\n\
|
856 |
+
float scaleAdjust = mix(StartScale, Scale, scalePercent);\n\
|
857 |
+
// scale down to zero, unless we're sparkling\n\
|
858 |
+
scaleAdjust *= (ShouldSparkle>0.5 ? 0.25 : 1.0-scalePercent);\n\
|
859 |
+
vec4 position = center + scaleDirectionVec * scaleAdjust;\n\
|
860 |
+
position += vec4(blurOffset,0);\n\
|
861 |
+
\n\
|
862 |
+
// SPARKLE\n\
|
863 |
+
float sparkleOpacity = fract(realPercent*realPercent * SparklePeriod);\n\
|
864 |
+
sparkleOpacity = smoothstep(0.0, 1.0, sparkleOpacity);\n\
|
865 |
+
\n\
|
866 |
+
// COLOR\n\
|
867 |
+
vec4 color = mix(vec4(1), Color, scalePercent * (ShouldSparkle<0.5 ? 1.0 : 0.5)); // white to color\n\
|
868 |
+
color *= (ShouldSparkle<0.5 ? 1.0 : sparkleOpacity); // apply sparkle opacity\n\
|
869 |
+
color *= (realPercent>=1.0 ? 0.0 : 1.0);\n\
|
870 |
+
v_Color = color;\n\
|
871 |
+
\n\
|
872 |
+
gl_Position = MVPMatrix * position;\n\
|
873 |
+
v_TexCoord = ParticleTexCoord;\n\
|
874 |
+
}\
|
875 |
+
",
|
876 |
+
fragment: "\
|
877 |
+
\n\
|
878 |
+
precision mediump float;\n\
|
879 |
+
\n\
|
880 |
+
uniform sampler2D ParticleTexture;\n\
|
881 |
+
uniform float Opacity;\n\
|
882 |
+
\n\
|
883 |
+
varying vec4 v_Color;\n\
|
884 |
+
varying vec2 v_TexCoord;\n\
|
885 |
+
//varying float particleTexPercent;\n\
|
886 |
+
\n\
|
887 |
+
void main()\n\
|
888 |
+
{\n\
|
889 |
+
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
|
890 |
+
\n\
|
891 |
+
texColor *= v_Color * Opacity;\n\
|
892 |
+
//texColor.a *= Opacity;\n\
|
893 |
+
\n\
|
894 |
+
//texColor = vec4(v_TexCoord, 0, 1);\n\
|
895 |
+
\n\
|
896 |
+
gl_FragColor = texColor;\n\
|
897 |
+
}\
|
898 |
+
"
|
899 |
+
};
|
900 |
+
|
901 |
+
KNWebGLShader.fireworkstrails = {
|
902 |
+
attribNames: [ "Position", "TexCoord"],
|
903 |
+
uniformNames: ["Texture", "Opacity", "NoiseAmount", "NoiseSeed", "NoiseMax", "MVPMatrix"],
|
904 |
+
vertex: "\
|
905 |
+
\n\
|
906 |
+
precision highp float;\n\
|
907 |
+
\n\
|
908 |
+
uniform mat4 MVPMatrix;\n\
|
909 |
+
\n\
|
910 |
+
attribute vec2 Position;\n\
|
911 |
+
attribute vec2 TexCoord;\n\
|
912 |
+
\n\
|
913 |
+
varying vec2 v_TexCoord;\n\
|
914 |
+
\n\
|
915 |
+
void main()\n\
|
916 |
+
{\n\
|
917 |
+
gl_Position = MVPMatrix * vec4(Position, 0,1);\n\
|
918 |
+
v_TexCoord = TexCoord;\n\
|
919 |
+
}\
|
920 |
+
",
|
921 |
+
fragment: "\
|
922 |
+
precision mediump float;\n\
|
923 |
+
\n\
|
924 |
+
uniform sampler2D Texture;\n\
|
925 |
+
uniform float Opacity;\n\
|
926 |
+
uniform float NoiseAmount;\n\
|
927 |
+
uniform vec2 NoiseSeed;\n\
|
928 |
+
uniform float NoiseMax;\n\
|
929 |
+
\n\
|
930 |
+
//varying vec4 v_Color;\n\
|
931 |
+
varying vec2 v_TexCoord;\n\
|
932 |
+
//varying float particleTexPercent;\n\
|
933 |
+
\n\
|
934 |
+
float rand(vec2 co){\n\
|
935 |
+
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n\
|
936 |
+
}\n\
|
937 |
+
\n\
|
938 |
+
float inverseSquare(float a) {\n\
|
939 |
+
return 1.0-(1.0-a)*(1.0-a);\n\
|
940 |
+
}\n\
|
941 |
+
\n\
|
942 |
+
void main()\n\
|
943 |
+
{\n\
|
944 |
+
vec4 texColor = texture2D(Texture, v_TexCoord);\n\
|
945 |
+
\n\
|
946 |
+
//texColor = bloom(texColor);\n\
|
947 |
+
\n\
|
948 |
+
// Dither transparency to add noise\n\
|
949 |
+
float randomNoise = NoiseMax*rand(v_TexCoord*NoiseSeed);\n\
|
950 |
+
float randomAmount = NoiseAmount * 1.5*max(0.0, texColor.a-0.3333);\n\
|
951 |
+
\n\
|
952 |
+
float thisOpacity = Opacity * mix(1.0, randomNoise, randomAmount);\n\
|
953 |
+
texColor *= thisOpacity;\n\
|
954 |
+
\n\
|
955 |
+
//texColor = vec4(v_TexCoord, 0, 1);\n\
|
956 |
+
\n\
|
957 |
+
gl_FragColor = texColor;\n\
|
958 |
+
}\
|
959 |
+
"
|
960 |
+
};
|
961 |
+
|
962 |
+
KNWebGLShader.horizontalGaussianBlur = {
|
963 |
+
attribNames: [ "Position"],
|
964 |
+
uniformNames: ["Texture", "TextureSize", "MVPMatrix"],
|
965 |
+
vertex: "\
|
966 |
+
\n\
|
967 |
+
precision highp float;\n\
|
968 |
+
\n\
|
969 |
+
uniform mat4 MVPMatrix;\n\
|
970 |
+
\n\
|
971 |
+
attribute vec2 Position;\n\
|
972 |
+
\n\
|
973 |
+
void main()\n\
|
974 |
+
{\n\
|
975 |
+
gl_Position = MVPMatrix * vec4(Position, 0, 1);\n\
|
976 |
+
}\
|
977 |
+
",
|
978 |
+
fragment: "\
|
979 |
+
precision highp float;\n\
|
980 |
+
\n\
|
981 |
+
uniform sampler2D Texture;\n\
|
982 |
+
uniform vec2 TextureSize;\n\
|
983 |
+
\n\
|
984 |
+
const vec2 offset1 = vec2(1.3846153846, 0);\n\
|
985 |
+
const vec2 offset2 = vec2(3.2307692308, 0);\n\
|
986 |
+
const float weight0 = 0.2270270270;\n\
|
987 |
+
const float weight1 = 0.3162162162;\n\
|
988 |
+
const float weight2 = 0.0702702703;\n\
|
989 |
+
\n\
|
990 |
+
void main()\n\
|
991 |
+
{\n\
|
992 |
+
vec4 color = texture2D(Texture, gl_FragCoord.xy*TextureSize) * weight0;\n\
|
993 |
+
\n\
|
994 |
+
color += texture2D(Texture, (gl_FragCoord.xy + offset1)*TextureSize) * weight1;\n\
|
995 |
+
color += texture2D(Texture, (gl_FragCoord.xy - offset1)*TextureSize) * weight1;\n\
|
996 |
+
\n\
|
997 |
+
color += texture2D(Texture, (gl_FragCoord.xy + offset2)*TextureSize) * weight2;\n\
|
998 |
+
color += texture2D(Texture, (gl_FragCoord.xy - offset2)*TextureSize) * weight2;\n\
|
999 |
+
\n\
|
1000 |
+
gl_FragColor = color;\n\
|
1001 |
+
}\
|
1002 |
+
"
|
1003 |
+
};
|
1004 |
+
|
1005 |
+
KNWebGLShader.verticalGaussianBlur = {
|
1006 |
+
attribNames: [ "Position"],
|
1007 |
+
uniformNames: ["Texture", "TextureSize", "MVPMatrix"],
|
1008 |
+
vertex: "\
|
1009 |
+
\n\
|
1010 |
+
precision highp float;\n\
|
1011 |
+
\n\
|
1012 |
+
uniform mat4 MVPMatrix;\n\
|
1013 |
+
\n\
|
1014 |
+
attribute vec2 Position;\n\
|
1015 |
+
\n\
|
1016 |
+
void main()\n\
|
1017 |
+
{\n\
|
1018 |
+
gl_Position = MVPMatrix * vec4(Position, 0, 1);\n\
|
1019 |
+
}\
|
1020 |
+
",
|
1021 |
+
fragment: "\
|
1022 |
+
precision highp float;\n\
|
1023 |
+
\n\
|
1024 |
+
uniform sampler2D Texture;\n\
|
1025 |
+
uniform vec2 TextureSize;\n\
|
1026 |
+
\n\
|
1027 |
+
const vec2 offset1 = vec2(0, 1.3846153846);\n\
|
1028 |
+
const vec2 offset2 = vec2(0, 3.2307692308);\n\
|
1029 |
+
const float weight0 = 0.2270270270;\n\
|
1030 |
+
const float weight1 = 0.3162162162;\n\
|
1031 |
+
const float weight2 = 0.0702702703;\n\
|
1032 |
+
\n\
|
1033 |
+
void main()\n\
|
1034 |
+
{\n\
|
1035 |
+
vec4 color = texture2D(Texture, gl_FragCoord.xy*TextureSize) * weight0;\n\
|
1036 |
+
\n\
|
1037 |
+
color += texture2D(Texture, (gl_FragCoord.xy + offset1)*TextureSize) * weight1;\n\
|
1038 |
+
color += texture2D(Texture, (gl_FragCoord.xy - offset1)*TextureSize) * weight1;\n\
|
1039 |
+
\n\
|
1040 |
+
color += texture2D(Texture, (gl_FragCoord.xy + offset2)*TextureSize) * weight2;\n\
|
1041 |
+
color += texture2D(Texture, (gl_FragCoord.xy - offset2)*TextureSize) * weight2;\n\
|
1042 |
+
\n\
|
1043 |
+
gl_FragColor = color;\n\
|
1044 |
+
}\
|
1045 |
+
"
|
1046 |
+
};
|
1047 |
+
|
1048 |
+
KNWebGLShader.bloom = {
|
1049 |
+
attribNames: [ "Position", "TexCoord"],
|
1050 |
+
uniformNames: ["Texture", "BlurTexture", "BloomAmount", "MVPMatrix"],
|
1051 |
+
vertex: "\
|
1052 |
+
\n\
|
1053 |
+
precision highp float;\n\
|
1054 |
+
\n\
|
1055 |
+
uniform mat4 MVPMatrix;\n\
|
1056 |
+
\n\
|
1057 |
+
attribute vec2 Position;\n\
|
1058 |
+
attribute vec2 TexCoord;\n\
|
1059 |
+
\n\
|
1060 |
+
varying vec2 v_TexCoord;\n\
|
1061 |
+
\n\
|
1062 |
+
void main()\n\
|
1063 |
+
{\n\
|
1064 |
+
v_TexCoord = TexCoord;\n\
|
1065 |
+
gl_Position = MVPMatrix * vec4(Position, 0, 1);\n\
|
1066 |
+
}\
|
1067 |
+
",
|
1068 |
+
fragment: "\
|
1069 |
+
precision mediump float;\n\
|
1070 |
+
\n\
|
1071 |
+
uniform sampler2D Texture;\n\
|
1072 |
+
uniform sampler2D BlurTexture;\n\
|
1073 |
+
uniform float BloomAmount;\n\
|
1074 |
+
\n\
|
1075 |
+
varying vec2 v_TexCoord;\n\
|
1076 |
+
\n\
|
1077 |
+
void main()\n\
|
1078 |
+
{\n\
|
1079 |
+
vec4 color = texture2D(Texture, v_TexCoord);\n\
|
1080 |
+
vec4 blurColor = texture2D(BlurTexture, v_TexCoord);\n\
|
1081 |
+
\n\
|
1082 |
+
color += (blurColor + color) * BloomAmount;\n\
|
1083 |
+
gl_FragColor = color;\n\
|
1084 |
+
}\
|
1085 |
+
"
|
1086 |
+
};
|
1087 |
+
|
1088 |
+
KNWebGLShader.shimmerObject = {
|
1089 |
+
attribNames: [ "Position", "Center", "TexCoord", "Color", "Speed"],
|
1090 |
+
uniformNames: ["Percent", "Opacity", "RotationMatrix", "SpeedMax", "Texture", "MVPMatrix"],
|
1091 |
+
vertex: "\
|
1092 |
+
\n\
|
1093 |
+
precision highp float;\n\
|
1094 |
+
\n\
|
1095 |
+
uniform mat4 MVPMatrix;\n\
|
1096 |
+
uniform float Percent;\n\
|
1097 |
+
uniform float Opacity;\n\
|
1098 |
+
\n\
|
1099 |
+
uniform mat3 RotationMatrix;\n\
|
1100 |
+
\n\
|
1101 |
+
attribute vec2 Position;\n\
|
1102 |
+
attribute vec2 Center;\n\
|
1103 |
+
attribute vec2 TexCoord;\n\
|
1104 |
+
attribute vec4 Color;\n\
|
1105 |
+
\n\
|
1106 |
+
attribute vec3 Speed;\n\
|
1107 |
+
uniform float SpeedMax;\n\
|
1108 |
+
\n\
|
1109 |
+
varying vec4 v_Color;\n\
|
1110 |
+
varying vec2 v_TexCoord;\n\
|
1111 |
+
\n\
|
1112 |
+
void main()\n\
|
1113 |
+
{\n\
|
1114 |
+
float thisPercent = Percent;\n\
|
1115 |
+
float invPercent = 1.0-thisPercent;\n\
|
1116 |
+
float thisPercent2 = thisPercent*thisPercent;\n\
|
1117 |
+
\n\
|
1118 |
+
/* CENTER */\n\
|
1119 |
+
vec3 scaleDirectionVec = vec3((Position.x-Center.x),(Position.y-Center.y),0);\n\
|
1120 |
+
\n\
|
1121 |
+
/* ROTATE */\n\
|
1122 |
+
vec3 rotatedVec = RotationMatrix * scaleDirectionVec.xyz;\n\
|
1123 |
+
\n\
|
1124 |
+
/* SCALE */\n\
|
1125 |
+
float scale = invPercent;\n\
|
1126 |
+
vec4 position = vec4(Center.xy,0,1) + vec4(rotatedVec,0) * scale;\n\
|
1127 |
+
\n\
|
1128 |
+
vec3 thisSpeed = Speed * SpeedMax;\n\
|
1129 |
+
position.xyz += thisSpeed * thisPercent*(3.0 + mix(thisPercent2*thisPercent, 1.0-invPercent*invPercent, thisPercent2));\n\
|
1130 |
+
\n\
|
1131 |
+
vec4 outColor = Color;\n\
|
1132 |
+
outColor = vec4(Opacity);\n\
|
1133 |
+
\n\
|
1134 |
+
/* output */\n\
|
1135 |
+
gl_Position = MVPMatrix * position;\n\
|
1136 |
+
v_Color = outColor;\n\
|
1137 |
+
v_TexCoord = TexCoord;\n\
|
1138 |
+
}\n\
|
1139 |
+
",
|
1140 |
+
fragment: "\
|
1141 |
+
precision mediump float;\n\
|
1142 |
+
\n\
|
1143 |
+
uniform sampler2D Texture;\n\
|
1144 |
+
\n\
|
1145 |
+
varying vec4 v_Color;\n\
|
1146 |
+
varying vec2 v_TexCoord;\n\
|
1147 |
+
\n\
|
1148 |
+
void main()\n\
|
1149 |
+
{\n\
|
1150 |
+
vec4 color = texture2D(Texture, v_TexCoord);\n\
|
1151 |
+
\n\
|
1152 |
+
color *= v_Color;\n\
|
1153 |
+
\n\
|
1154 |
+
gl_FragColor = color;\n\
|
1155 |
+
}\
|
1156 |
+
"
|
1157 |
+
};
|
1158 |
+
|
1159 |
+
KNWebGLShader.shimmerParticle = {
|
1160 |
+
attribNames: [ "Position", "Center", "ParticleTexCoord", "Color", "LifeSpan", "Speed", "Scale"],
|
1161 |
+
uniformNames: ["Percent", "Opacity", "ParticleScalePercent", "RotationMatrix", "SpeedMax", "ParticleTexture", "MVPMatrix"],
|
1162 |
+
vertex: "\
|
1163 |
+
\n\
|
1164 |
+
precision highp float;\n\
|
1165 |
+
\n\
|
1166 |
+
uniform mat4 MVPMatrix;\n\
|
1167 |
+
uniform float Percent;\n\
|
1168 |
+
uniform float Opacity;\n\
|
1169 |
+
\n\
|
1170 |
+
uniform float ParticleScalePercent;\n\
|
1171 |
+
uniform mat3 RotationMatrix;\n\
|
1172 |
+
\n\
|
1173 |
+
attribute vec2 Position;\n\
|
1174 |
+
attribute vec2 Center;\n\
|
1175 |
+
attribute vec2 ParticleTexCoord;\n\
|
1176 |
+
attribute vec4 Color;\n\
|
1177 |
+
attribute vec2 LifeSpan;\n\
|
1178 |
+
\n\
|
1179 |
+
attribute vec3 Speed;\n\
|
1180 |
+
uniform float SpeedMax;\n\
|
1181 |
+
attribute float Scale;\n\
|
1182 |
+
\n\
|
1183 |
+
varying vec4 v_Color;\n\
|
1184 |
+
varying vec2 v_TexCoord;\n\
|
1185 |
+
\n\
|
1186 |
+
float scaleUpDown(float x) {\n\
|
1187 |
+
float result = 1.0 - abs(2.0*(x-0.5));\n\
|
1188 |
+
result *= result;\n\
|
1189 |
+
return result;\n\
|
1190 |
+
}\n\
|
1191 |
+
\n\
|
1192 |
+
void main()\n\
|
1193 |
+
{\n\
|
1194 |
+
/* LIFESPAN */\n\
|
1195 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
1196 |
+
float doDiscard = (realPercent > 1.0 || realPercent < 0.0) ? 0.0 : 1.0;\n\
|
1197 |
+
realPercent = clamp(realPercent, 0.0,1.0);\n\
|
1198 |
+
float realPercent2 = realPercent*realPercent;\n\
|
1199 |
+
float invPercent2 = 1.0-realPercent;\n\
|
1200 |
+
invPercent2 *= invPercent2;\n\
|
1201 |
+
\n\
|
1202 |
+
vec3 scaleDirectionVec = vec3((Position.x-Center.x),(Position.y-Center.y),0);\n\
|
1203 |
+
\n\
|
1204 |
+
/* ROTATE */\n\
|
1205 |
+
vec3 rotatedVec = RotationMatrix * scaleDirectionVec.xyz;\n\
|
1206 |
+
\n\
|
1207 |
+
/* SCALE */\n\
|
1208 |
+
float scalePercent = (LifeSpan.x <= 0.001 ? ParticleScalePercent : scaleUpDown(realPercent));\n\
|
1209 |
+
float scale = scalePercent * Scale * doDiscard;\n\
|
1210 |
+
vec4 position = vec4(Center,0,1) + vec4(rotatedVec,0) * scale;\n\
|
1211 |
+
\n\
|
1212 |
+
vec3 thisSpeed = Speed * SpeedMax;\n\
|
1213 |
+
position.xyz += thisSpeed * realPercent*(3.0 + mix(realPercent*realPercent2, 1.0-invPercent2, realPercent2));\n\
|
1214 |
+
\n\
|
1215 |
+
// Only adjust opacity on particles that last the duration of the animation\n\
|
1216 |
+
float thisOpacity = (LifeSpan.x <= 0.001 ? Opacity : 1.0);\n\
|
1217 |
+
vec4 color = vec4(Color.rgb, 1) * thisOpacity;\n\
|
1218 |
+
\n\
|
1219 |
+
v_Color = color;\n\
|
1220 |
+
v_TexCoord = ParticleTexCoord;\n\
|
1221 |
+
gl_Position = MVPMatrix * position;\n\
|
1222 |
+
}\n\
|
1223 |
+
",
|
1224 |
+
fragment: "\
|
1225 |
+
precision mediump float;\n\
|
1226 |
+
\n\
|
1227 |
+
uniform sampler2D ParticleTexture;\n\
|
1228 |
+
\n\
|
1229 |
+
varying vec4 v_Color;\n\
|
1230 |
+
varying vec2 v_TexCoord;\n\
|
1231 |
+
\n\
|
1232 |
+
void main()\n\
|
1233 |
+
{\n\
|
1234 |
+
vec4 color = texture2D(ParticleTexture, v_TexCoord);\n\
|
1235 |
+
\n\
|
1236 |
+
color *= v_Color;\n\
|
1237 |
+
\n\
|
1238 |
+
gl_FragColor = color;\n\
|
1239 |
+
}\
|
1240 |
+
"
|
1241 |
+
};
|
1242 |
+
|
1243 |
+
KNWebGLShader.sparkle = {
|
1244 |
+
attribNames: ["Scale", "LifeSpan", "Speed", "ParticleTexCoord", "Center", "Position"],
|
1245 |
+
uniformNames: ["Percent", "Opacity", "Color", "SpeedMax", "ParticleTexture", "MVPMatrix"],
|
1246 |
+
vertex: "\
|
1247 |
+
\n\
|
1248 |
+
precision highp float;\n\
|
1249 |
+
\n\
|
1250 |
+
uniform mat4 MVPMatrix;\n\
|
1251 |
+
uniform float Percent;\n\
|
1252 |
+
\n\
|
1253 |
+
attribute vec2 Position;\n\
|
1254 |
+
attribute vec2 Center;\n\
|
1255 |
+
uniform float Opacity;\n\
|
1256 |
+
attribute vec2 ParticleTexCoord;\n\
|
1257 |
+
uniform vec4 Color;\n\
|
1258 |
+
\n\
|
1259 |
+
attribute mediump vec3 Speed;\n\
|
1260 |
+
uniform mediump float SpeedMax;\n\
|
1261 |
+
attribute mediump float Scale;\n\
|
1262 |
+
attribute mediump vec2 LifeSpan;\n\
|
1263 |
+
\n\
|
1264 |
+
varying vec4 v_Color;\n\
|
1265 |
+
varying vec2 v_TexCoord;\n\
|
1266 |
+
\n\
|
1267 |
+
float ReverseSquareOfFloat(float f) {\n\
|
1268 |
+
return 1.0 - (1.0-f)*(1.0-f);\n\
|
1269 |
+
}\n\
|
1270 |
+
\n\
|
1271 |
+
void main()\n\
|
1272 |
+
{\n\
|
1273 |
+
float doDiscard = 0.0;\n\
|
1274 |
+
float realPercent = (Percent-LifeSpan.x)/LifeSpan.y;\n\
|
1275 |
+
if (realPercent < 0.0 || realPercent > 1.0) {\n\
|
1276 |
+
doDiscard = 1.0;\n\
|
1277 |
+
realPercent = 1.0;\n\
|
1278 |
+
}\n\
|
1279 |
+
\n\
|
1280 |
+
vec4 position;\n\
|
1281 |
+
vec4 scaleDirectionVec = vec4((Position.x-Center.x),(Position.y-Center.y),0,0);\n\
|
1282 |
+
\n\
|
1283 |
+
// SCALE\n\
|
1284 |
+
float scaleAdjust = realPercent;\n\
|
1285 |
+
if (scaleAdjust < 0.1) {\n\
|
1286 |
+
scaleAdjust /= 0.1;\n\
|
1287 |
+
scaleAdjust = sqrt(scaleAdjust);\n\
|
1288 |
+
} else {\n\
|
1289 |
+
scaleAdjust = 1.0-(scaleAdjust-0.1)/0.9;\n\
|
1290 |
+
scaleAdjust = scaleAdjust*scaleAdjust*scaleAdjust;\n\
|
1291 |
+
}\n\
|
1292 |
+
scaleAdjust *= (doDiscard==0.0 ? 1.0 : 0.0);\n\
|
1293 |
+
position = vec4(Center,0,1) + scaleDirectionVec * scaleAdjust * Scale;\n\
|
1294 |
+
\n\
|
1295 |
+
// POSITION\n\
|
1296 |
+
vec3 thisSpeed = Speed * SpeedMax;\n\
|
1297 |
+
position += vec4(thisSpeed, 0) * realPercent;\n\
|
1298 |
+
\n\
|
1299 |
+
float invPercent = 1.0 - realPercent;\n\
|
1300 |
+
vec3 rgbColor = mix(Color.rgb, vec3(1,1,1), invPercent*invPercent*invPercent);\n\
|
1301 |
+
\n\
|
1302 |
+
/* output */\n\
|
1303 |
+
gl_Position = MVPMatrix * position;\n\
|
1304 |
+
v_Color = vec4(rgbColor, (1.0-realPercent*realPercent)*Opacity);\n\
|
1305 |
+
v_TexCoord = ParticleTexCoord;\n\
|
1306 |
+
}\
|
1307 |
+
",
|
1308 |
+
fragment: "\
|
1309 |
+
\n\
|
1310 |
+
precision mediump float;\n\
|
1311 |
+
\n\
|
1312 |
+
uniform sampler2D ParticleTexture;\n\
|
1313 |
+
\n\
|
1314 |
+
varying vec4 v_Color;\n\
|
1315 |
+
varying vec2 v_TexCoord;\n\
|
1316 |
+
\n\
|
1317 |
+
void main()\n\
|
1318 |
+
{\n\
|
1319 |
+
vec4 texColor = texture2D(ParticleTexture, v_TexCoord);\n\
|
1320 |
+
\n\
|
1321 |
+
texColor *= v_Color;\n\
|
1322 |
+
\n\
|
1323 |
+
gl_FragColor = texColor;\n\
|
1324 |
+
}\
|
1325 |
+
"
|
1326 |
+
};
|
assets/player/gl/KNWebGLUtil.js
CHANGED
@@ -1,3 +1,1145 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* KNWebGLUtil.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2016-2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var KNWebGLUtil = {};
|
10 |
+
|
11 |
+
KNWebGLUtil.setupProgram = function(gl, programName) {
|
12 |
+
var shader = KNWebGLShader[programName];
|
13 |
+
var vertexShader = this.loadShader(gl, gl.VERTEX_SHADER, shader.vertex);
|
14 |
+
var fragmentShader = this.loadShader(gl, gl.FRAGMENT_SHADER, shader.fragment);
|
15 |
+
var shaderProgram = this.createShaderProgram(gl, vertexShader, fragmentShader);
|
16 |
+
|
17 |
+
// creates uniforms and attribs but does not enable attribs.
|
18 |
+
var attribs = {};
|
19 |
+
var uniforms = {};
|
20 |
+
|
21 |
+
for (var i = 0, length = shader.uniformNames.length; i < length; i++) {
|
22 |
+
var uniformName = shader.uniformNames[i];
|
23 |
+
uniforms[uniformName] = gl.getUniformLocation(shaderProgram, uniformName);
|
24 |
+
}
|
25 |
+
|
26 |
+
for (var i = 0, length = shader.attribNames.length; i < length; i++) {
|
27 |
+
var attribName = shader.attribNames[i];
|
28 |
+
attribs[attribName] = gl.getAttribLocation(shaderProgram, attribName);
|
29 |
+
}
|
30 |
+
|
31 |
+
// create a program object
|
32 |
+
var program = {
|
33 |
+
shaderProgram: shaderProgram,
|
34 |
+
uniforms: uniforms,
|
35 |
+
attribs: attribs
|
36 |
+
};
|
37 |
+
|
38 |
+
// use this program for rendering
|
39 |
+
gl.useProgram(shaderProgram);
|
40 |
+
|
41 |
+
return program;
|
42 |
+
};
|
43 |
+
|
44 |
+
KNWebGLUtil.loadShader = function(gl, type, shaderSource) {
|
45 |
+
var shader = gl.createShader(type);
|
46 |
+
gl.shaderSource(shader, shaderSource);
|
47 |
+
gl.compileShader(shader);
|
48 |
+
|
49 |
+
// Check the compile status
|
50 |
+
var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
|
51 |
+
if (!compiled) {
|
52 |
+
// error during compilation
|
53 |
+
var error = gl.getShaderInfoLog(shader);
|
54 |
+
console.log("*** Error compiling shader '" + shader + "':" + error);
|
55 |
+
gl.deleteShader(shader);
|
56 |
+
return null;
|
57 |
+
}
|
58 |
+
|
59 |
+
return shader;
|
60 |
+
};
|
61 |
+
|
62 |
+
KNWebGLUtil.createShaderProgram = function(gl, vertexShader, fragmentShader) {
|
63 |
+
// create shader program
|
64 |
+
var shaderProgram = gl.createProgram();
|
65 |
+
|
66 |
+
// Attach the shaders to the program
|
67 |
+
gl.attachShader(shaderProgram, vertexShader);
|
68 |
+
gl.attachShader(shaderProgram, fragmentShader);
|
69 |
+
|
70 |
+
// Link the program
|
71 |
+
gl.linkProgram(shaderProgram);
|
72 |
+
|
73 |
+
var linked = gl.getProgramParameter(shaderProgram, gl.LINK_STATUS);
|
74 |
+
if (!linked) {
|
75 |
+
var error = gl.getProgramInfoLog(shaderProgram);
|
76 |
+
console.log("Error in program linking:" + error);
|
77 |
+
gl.deleteProgram(shaderProgram);
|
78 |
+
}
|
79 |
+
|
80 |
+
return shaderProgram;
|
81 |
+
};
|
82 |
+
|
83 |
+
KNWebGLUtil.createTexture = function(gl, image) {
|
84 |
+
var texture = gl.createTexture();
|
85 |
+
|
86 |
+
// bind WebGLTexture object to gl.TEXTURE_2D target
|
87 |
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
88 |
+
|
89 |
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
90 |
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
|
91 |
+
|
92 |
+
// upload texture data to GPU
|
93 |
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
94 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
95 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
96 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
97 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
98 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
99 |
+
|
100 |
+
return texture;
|
101 |
+
};
|
102 |
+
|
103 |
+
KNWebGLUtil.bindTextureWithImage = function(gl, image) {
|
104 |
+
var texture = gl.createTexture();
|
105 |
+
|
106 |
+
// bind WebGLTexture object to gl.TEXTURE_2D target
|
107 |
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
108 |
+
|
109 |
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
110 |
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
111 |
+
|
112 |
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
113 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
114 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
115 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
116 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
117 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
118 |
+
|
119 |
+
return texture;
|
120 |
+
};
|
121 |
+
|
122 |
+
KNWebGLUtil.bindDynamicBufferWithData = function(gl, attribLoc, buffer, data, size) {
|
123 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
124 |
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.DYNAMIC_DRAW);
|
125 |
+
|
126 |
+
// we need to enable attrib loc to work with data buffer
|
127 |
+
gl.enableVertexAttribArray(attribLoc);
|
128 |
+
gl.vertexAttribPointer(attribLoc, size, gl.FLOAT, false, 0, 0);
|
129 |
+
};
|
130 |
+
|
131 |
+
KNWebGLUtil.bindBufferWithData = function(gl, attribLoc, buffer, data, size, bufferUsage) {
|
132 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
133 |
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), bufferUsage);
|
134 |
+
|
135 |
+
// we need to enable attrib loc to work with data buffer
|
136 |
+
gl.enableVertexAttribArray(attribLoc);
|
137 |
+
gl.vertexAttribPointer(attribLoc, size, gl.FLOAT, false, 0, 0);
|
138 |
+
};
|
139 |
+
|
140 |
+
//attribute buffer insertion
|
141 |
+
KNWebGLUtil.setPoint2DAtIndexForAttribute = function(point, index, attribute) {
|
142 |
+
//attribute cannot become an object. we need to create an object where we can place this. BUMMER
|
143 |
+
attribute[index*2] = point.x;
|
144 |
+
attribute[index*2+1] = point.y;
|
145 |
+
attribute.size = 2;
|
146 |
+
};
|
147 |
+
|
148 |
+
KNWebGLUtil.setPoint3DAtIndexForAttribute = function(point, index, attribute) {
|
149 |
+
attribute[index*3] = point.x;
|
150 |
+
attribute[index*3+1] = point.y;
|
151 |
+
attribute[index*3+2] = point.z;
|
152 |
+
attribute.size = 3;
|
153 |
+
};
|
154 |
+
|
155 |
+
KNWebGLUtil.setPoint4DAtIndexForAttribute = function(point, index, attribute) {
|
156 |
+
attribute[index*4] = point.x;
|
157 |
+
attribute[index*4+1] = point.y;
|
158 |
+
attribute[index*4+2] = point.z;
|
159 |
+
attribute[index*4+3] = point.w;
|
160 |
+
attribute.size = 4;
|
161 |
+
};
|
162 |
+
|
163 |
+
KNWebGLUtil.setFloatAtIndexForAttribute = function(f, index, attribute) {
|
164 |
+
attribute[index] = f;
|
165 |
+
};
|
166 |
+
|
167 |
+
KNWebGLUtil.getPoint2DForArrayAtIndex = function(attrib, index) {
|
168 |
+
var point = {};
|
169 |
+
point.x = attrib[index*2];
|
170 |
+
point.y = attrib[index*2 + 1];
|
171 |
+
return point;
|
172 |
+
};
|
173 |
+
|
174 |
+
KNWebGLUtil.getPoint3DForArrayAtIndex = function(attrib, index) {
|
175 |
+
var point = {};
|
176 |
+
point.x = attrib[index*3];
|
177 |
+
point.y = attrib[index*3 + 1];
|
178 |
+
point.z = attrib[index*3 + 2];
|
179 |
+
return point;
|
180 |
+
};
|
181 |
+
|
182 |
+
KNWebGLUtil.getPoint4DForArrayAtIndex = function(attrib, index) {
|
183 |
+
var point = {};
|
184 |
+
point.x = attrib[index*4];
|
185 |
+
point.y = attrib[index*4 + 1];
|
186 |
+
point.z = attrib[index*4 + 2];
|
187 |
+
point.w = attrib[index*4 + 3];
|
188 |
+
return point;
|
189 |
+
};
|
190 |
+
|
191 |
+
KNWebGLUtil.bindAllAvailableAttributesToBuffers = function(gl, attribs, bufferdata, size, buffer, bufferUsage) {
|
192 |
+
for (var obj in attribs) {
|
193 |
+
var attribute = attribs[obj];
|
194 |
+
if (buffer[obj] == undefined) {
|
195 |
+
buffer[obj] = gl.createBuffer();
|
196 |
+
}
|
197 |
+
|
198 |
+
KNWebGLUtil.bindBufferWithData(gl, attribute, buffer[obj], bufferdata[obj], size[obj], bufferUsage);
|
199 |
+
}
|
200 |
+
};
|
201 |
+
|
202 |
+
// We need to enable attribs before binding.
|
203 |
+
// This also sets the program to the given program.
|
204 |
+
// This never needs to be called in single program animations
|
205 |
+
KNWebGLUtil.enableAttribs = function(gl, program) {
|
206 |
+
var attribs = program.attribs;
|
207 |
+
gl.useProgram(program.shaderProgram);
|
208 |
+
for (var obj in attribs) {
|
209 |
+
gl.enableVertexAttribArray(attribs[obj]);
|
210 |
+
}
|
211 |
+
};
|
212 |
+
|
213 |
+
/*
|
214 |
+
* WebGraphics is not a container for any data. It should only computer and return values.
|
215 |
+
*
|
216 |
+
* makePoint(x, y): returns a object with .x and .y properties attached
|
217 |
+
*
|
218 |
+
* randomBetween(a, b): returns a random number between a (lower bound) and b (upper bound)
|
219 |
+
*
|
220 |
+
* mix(x, y, a): returns a linear intern between x and y using a as a weight between them
|
221 |
+
*
|
222 |
+
* clamp(x, minVal, maxVal) : clamps x between a min and max value
|
223 |
+
*/
|
224 |
+
var WebGraphics = {};
|
225 |
+
|
226 |
+
WebGraphics.makePoint = function(x, y) {
|
227 |
+
var obj = {};
|
228 |
+
obj.x = x;
|
229 |
+
obj.y = y;
|
230 |
+
return obj;
|
231 |
+
};
|
232 |
+
|
233 |
+
WebGraphics.makePoint3D = function(x, y, z) {
|
234 |
+
var obj = {};
|
235 |
+
obj.x = x;
|
236 |
+
obj.y = y;
|
237 |
+
obj.z = z;
|
238 |
+
return obj;
|
239 |
+
};
|
240 |
+
|
241 |
+
WebGraphics.makePoint4D = function(x, y, z, w) {
|
242 |
+
var obj = {};
|
243 |
+
obj.x = x;
|
244 |
+
obj.y = y;
|
245 |
+
obj.z = z;
|
246 |
+
obj.w = w;
|
247 |
+
return obj;
|
248 |
+
};
|
249 |
+
|
250 |
+
WebGraphics.makeRect = function(x,y, width, height) {
|
251 |
+
var obj = {};
|
252 |
+
obj.x = x;
|
253 |
+
obj.y = y;
|
254 |
+
obj.width = width;
|
255 |
+
obj.height = height;
|
256 |
+
return obj;
|
257 |
+
};
|
258 |
+
|
259 |
+
WebGraphics.makeSize = function(width, height) {
|
260 |
+
var obj = {};
|
261 |
+
obj.width = width;
|
262 |
+
obj.height = height;
|
263 |
+
return obj;
|
264 |
+
};
|
265 |
+
|
266 |
+
WebGraphics.setOrigin = function(obj, point) {
|
267 |
+
obj.x = point.x;
|
268 |
+
obj.y = point.y;
|
269 |
+
return obj;
|
270 |
+
};
|
271 |
+
|
272 |
+
WebGraphics.multiplyPoint3DByScalar = function(point, scalar) {
|
273 |
+
var obj = {};
|
274 |
+
obj.x = point.x * scalar;
|
275 |
+
obj.y = point.y * scalar;
|
276 |
+
obj.z = point.z * scalar;
|
277 |
+
return obj;
|
278 |
+
};
|
279 |
+
|
280 |
+
WebGraphics.multiplyPoint4DByScalar = function(point, scalar) {
|
281 |
+
var obj = {};
|
282 |
+
obj.x = point.x * scalar;
|
283 |
+
obj.y = point.y * scalar;
|
284 |
+
obj.z = point.z * scalar;
|
285 |
+
obj.w = point.w * scalar;
|
286 |
+
return obj;
|
287 |
+
};
|
288 |
+
|
289 |
+
WebGraphics.addPoint3DToPoint3D = function(a, b) {
|
290 |
+
var obj = {};
|
291 |
+
obj.x = a.x + b.x;
|
292 |
+
obj.y = a.y + b.y;
|
293 |
+
obj.z = a.z + b.z;
|
294 |
+
return obj;
|
295 |
+
};
|
296 |
+
|
297 |
+
WebGraphics.point3DNormalize = function(pt3d) {
|
298 |
+
var length = Math.sqrt(pt3d.x * pt3d.x + pt3d.y * pt3d.y + pt3d.z * pt3d.z);
|
299 |
+
var obj = {};
|
300 |
+
obj.z = pt3d.z / length;
|
301 |
+
obj.y = pt3d.y / length;
|
302 |
+
obj.x = pt3d.x / length;
|
303 |
+
return obj;
|
304 |
+
};
|
305 |
+
|
306 |
+
WebGraphics.randomBetween = function(min, max) {
|
307 |
+
var x = Math.random();
|
308 |
+
x *= (max - min);
|
309 |
+
x += min;
|
310 |
+
return x;
|
311 |
+
};
|
312 |
+
|
313 |
+
WebGraphics.doubleBetween = function(randMin, randMax) {
|
314 |
+
var result = 0;
|
315 |
+
|
316 |
+
var bottom, top;
|
317 |
+
if (randMin < randMax) {
|
318 |
+
bottom = randMin;
|
319 |
+
top = randMax;
|
320 |
+
} else {
|
321 |
+
bottom = randMax;
|
322 |
+
top = randMin;
|
323 |
+
}
|
324 |
+
|
325 |
+
// rnd: random in range [0.0 -> 1.0)
|
326 |
+
// RandBetween(bottom, top) = ((top - bottom) * rnd) + bottom
|
327 |
+
|
328 |
+
// To avoid overflows, distribute the multiplication:
|
329 |
+
// = top*rand - bottom*rand + bottom
|
330 |
+
|
331 |
+
var rnd = Math.random();
|
332 |
+
var topMult = top * rnd;
|
333 |
+
var bottomMult = bottom * rnd;
|
334 |
+
|
335 |
+
if ((bottom >= 0.0) == (top >= 0.0)) {
|
336 |
+
// Both are the same sign, do the subtraction first to avoid overflow.
|
337 |
+
result = topMult - bottomMult;
|
338 |
+
result = result + bottom;
|
339 |
+
} else {
|
340 |
+
// The signs differ, add bottom in first to avoid overflow.
|
341 |
+
result = topMult + bottom;
|
342 |
+
result = result - bottomMult;
|
343 |
+
}
|
344 |
+
|
345 |
+
return result;
|
346 |
+
}
|
347 |
+
|
348 |
+
WebGraphics.mix = function(x, y, a) {
|
349 |
+
return x * (1 - a) + (y * a);
|
350 |
+
};
|
351 |
+
|
352 |
+
WebGraphics.clamp = function(x, minVal, maxVal) {
|
353 |
+
return Math.min(Math.max(x, minVal), maxVal);
|
354 |
+
};
|
355 |
+
|
356 |
+
WebGraphics.sineMap = function(x) {
|
357 |
+
return (Math.sin(x * Math.PI - (Math.PI / 2)) + 1) * 0.5;
|
358 |
+
};
|
359 |
+
|
360 |
+
WebGraphics.createMatrix4 = function() {
|
361 |
+
//creates and identity matrix, column-major matrix library, it is not necessary to use this to get an ortho matrix
|
362 |
+
var obj = new Float32Array(16);
|
363 |
+
obj[0] = 1;
|
364 |
+
obj[1] = 0;
|
365 |
+
obj[2] = 0;
|
366 |
+
obj[3] = 0;
|
367 |
+
obj[4] = 0;
|
368 |
+
obj[5] = 1;
|
369 |
+
obj[6] = 0;
|
370 |
+
obj[7] = 0;
|
371 |
+
obj[8] = 0;
|
372 |
+
obj[9] = 0;
|
373 |
+
obj[10] = 1;
|
374 |
+
obj[11] = 0;
|
375 |
+
obj[12] = 0;
|
376 |
+
obj[13] = 0;
|
377 |
+
obj[14] = 0;
|
378 |
+
obj[15] = 1;
|
379 |
+
return obj;
|
380 |
+
};
|
381 |
+
|
382 |
+
WebGraphics.makeIdentityMatrix4 = function() {
|
383 |
+
return WebGraphics.createMatrix4();
|
384 |
+
};
|
385 |
+
|
386 |
+
WebGraphics.makeOrthoMatrix4 = function(left, right, bottom, top, near, far) {
|
387 |
+
var matrix = new Float32Array(16);
|
388 |
+
var rl = right - left;
|
389 |
+
var tb = top - bottom;
|
390 |
+
var fn = far - near;
|
391 |
+
matrix[0] = 2 / rl;
|
392 |
+
matrix[1] = 0;
|
393 |
+
matrix[2] = 0;
|
394 |
+
matrix[3] = 0;
|
395 |
+
matrix[4] = 0;
|
396 |
+
matrix[5] = 2 / tb;
|
397 |
+
matrix[6] = 0;
|
398 |
+
matrix[7] = 0;
|
399 |
+
matrix[8] = 0;
|
400 |
+
matrix[9] = 0;
|
401 |
+
matrix[10] = -2 /fn;
|
402 |
+
matrix[11] = 0;
|
403 |
+
matrix[12] = -(right + left) / rl;
|
404 |
+
matrix[13] = -(top - bottom) / tb;
|
405 |
+
matrix[14] = -(far + near) / fn;
|
406 |
+
matrix[15] = 1;
|
407 |
+
return matrix;
|
408 |
+
};
|
409 |
+
|
410 |
+
WebGraphics.makeFrustumMatrix4 = function(left, right, bottom, top, near, far) {
|
411 |
+
var rl = right - left;
|
412 |
+
var tb = top - bottom;
|
413 |
+
var fn = far - near;
|
414 |
+
var m = new Float32Array(16);
|
415 |
+
m[0] = (near * 2) / rl; //11
|
416 |
+
m[1] = 0; //21
|
417 |
+
m[2] = 0; //31
|
418 |
+
m[3] = 0; //41
|
419 |
+
m[4] = 0; //12
|
420 |
+
m[5] = (near * 2) / tb; //22
|
421 |
+
m[6] = 0; //32
|
422 |
+
m[7] = 0; //42
|
423 |
+
m[8] = (right + left) / rl;
|
424 |
+
m[9] = (top + bottom) / tb;
|
425 |
+
m[10] = -(far + near) / fn;
|
426 |
+
m[11] = -1;
|
427 |
+
m[12] = 0;
|
428 |
+
m[13] = 0;
|
429 |
+
m[14] = (-2 * far * near) / fn;
|
430 |
+
m[15] = 0;
|
431 |
+
return m;
|
432 |
+
};
|
433 |
+
|
434 |
+
WebGraphics.makePerspectiveMatrix4 = function(fovy, aspect, near, far) {
|
435 |
+
var top = near * Math.tan(fovy * Math.PI / 360.0);
|
436 |
+
var right = top * aspect;
|
437 |
+
return WebGraphics.makeFrustumMatrix4(-right, right, -top, top, near, far);
|
438 |
+
};
|
439 |
+
|
440 |
+
WebGraphics.multiplyMatrix4 = function(a, b) {
|
441 |
+
//a*b
|
442 |
+
var m = new Float32Array(16);
|
443 |
+
var a11 = a[0], a12 = a[4], a13 = a[8], a14 = a[12], a21 = a[1], a22 = a[5], a23 = a[9], a24 = a[13],
|
444 |
+
a31 = a[2], a32 = a[6], a33 = a[10], a34 = a[14], a41 = a[3], a42 = a[7], a43 = a[11], a44 = a[15];
|
445 |
+
var b11 = b[0], b12 = b[4], b13 = b[8], b14 = b[12], b21 = b[1], b22 = b[5], b23 = b[9], b24 = b[13],
|
446 |
+
b31 = b[2], b32 = b[6], b33 = b[10], b34 = b[14], b41 = b[3], b42 = b[7], b43 = b[11], b44 = b[15];
|
447 |
+
m[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
|
448 |
+
m[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
|
449 |
+
m[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
|
450 |
+
m[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
|
451 |
+
m[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
|
452 |
+
m[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
|
453 |
+
m[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
|
454 |
+
m[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
|
455 |
+
m[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
|
456 |
+
m[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
|
457 |
+
m[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
|
458 |
+
m[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
|
459 |
+
m[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
|
460 |
+
m[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
|
461 |
+
m[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
|
462 |
+
m[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
|
463 |
+
return m;
|
464 |
+
};
|
465 |
+
WebGraphics.scaleMatrix4 = function(m4, sx, sy, sz) {
|
466 |
+
var m = WebGraphics.createMatrix4();
|
467 |
+
m[0] = sx;
|
468 |
+
m[5] = sy;
|
469 |
+
m[10] = sz;
|
470 |
+
return WebGraphics.multiplyMatrix4(m4, m);
|
471 |
+
};
|
472 |
+
|
473 |
+
WebGraphics.translateMatrix4 = function(m4, tx, ty, tz) {
|
474 |
+
var m = WebGraphics.createMatrix4();
|
475 |
+
m[12] = tx;
|
476 |
+
m[13] = ty;
|
477 |
+
m[14] = tz;
|
478 |
+
return WebGraphics.multiplyMatrix4(m4, m);
|
479 |
+
};
|
480 |
+
|
481 |
+
WebGraphics.rotateMatrix4AboutXYZ = function(m4, theta, x, y, z) {
|
482 |
+
var point3d = WebGraphics.makePoint3D(x, y, z);
|
483 |
+
point3d = WebGraphics.point3DNormalize(point3d);
|
484 |
+
var ux = point3d.x;
|
485 |
+
var uy = point3d.y;
|
486 |
+
var uz = point3d.z;
|
487 |
+
var cos = Math.cos(theta);
|
488 |
+
var oneMinusCos = 1 - cos;
|
489 |
+
var sin = Math.sin(theta);
|
490 |
+
var m = WebGraphics.createMatrix4();
|
491 |
+
m[0] = cos + (ux * ux) * oneMinusCos;
|
492 |
+
m[1] = ux * uy * oneMinusCos + (uz * sin);
|
493 |
+
m[2] = uz * ux * oneMinusCos - uy * sin;
|
494 |
+
m[4] = ux * uy * oneMinusCos - uz * sin;
|
495 |
+
m[5] = cos + (uy * uy) * oneMinusCos;
|
496 |
+
m[6] = uz * uy * oneMinusCos + ux * sin;
|
497 |
+
m[8] = ux * uy * oneMinusCos + uy * sin;
|
498 |
+
m[9] = uy * uz * oneMinusCos - ux * sin;
|
499 |
+
m[10] = cos + (uz * uz) * oneMinusCos;
|
500 |
+
return WebGraphics.multiplyMatrix4(m4, m);
|
501 |
+
};
|
502 |
+
|
503 |
+
WebGraphics.colorWithHSBA = function(hue, saturation, brightness, alpha) {
|
504 |
+
var hueTimesSix, frac, p1, p2, p3, red, blue, green;
|
505 |
+
var obj = {"hue": hue, "saturation": saturation, "brightness": brightness, "alpha": alpha};
|
506 |
+
if (hue == 1.0) {
|
507 |
+
hue = 0.0;
|
508 |
+
}
|
509 |
+
hueTimesSix = hue * 6.0;
|
510 |
+
frac = hueTimesSix - Math.floor(hueTimesSix);
|
511 |
+
p1 = brightness * (1-saturation);
|
512 |
+
p2 = brightness * (1.0 - (saturation * frac));
|
513 |
+
p3 = brightness * (1.0 - (saturation * (1.0 - frac)));
|
514 |
+
switch (parseInt(hueTimesSix)) {
|
515 |
+
case 0:
|
516 |
+
red = brightness;
|
517 |
+
green = p3;
|
518 |
+
blue = p1;
|
519 |
+
break;
|
520 |
+
case 1:
|
521 |
+
red = p2;
|
522 |
+
green = brightness;
|
523 |
+
blue = p1;
|
524 |
+
break;
|
525 |
+
case 2:
|
526 |
+
red = p1;
|
527 |
+
green = brightness;
|
528 |
+
blue = p3;
|
529 |
+
break;
|
530 |
+
case 3:
|
531 |
+
red = p1;
|
532 |
+
green = p2;
|
533 |
+
blue = brightness;
|
534 |
+
break;
|
535 |
+
case 4:
|
536 |
+
red = p3;
|
537 |
+
green = p1;
|
538 |
+
blue = brightness;
|
539 |
+
break;
|
540 |
+
case 5:
|
541 |
+
red = brightness;
|
542 |
+
green = p1;
|
543 |
+
blue = p2;
|
544 |
+
break;
|
545 |
+
}
|
546 |
+
obj.red = red;
|
547 |
+
obj.blue = blue;
|
548 |
+
obj.green = green;
|
549 |
+
return obj;
|
550 |
+
};
|
551 |
+
|
552 |
+
WebGraphics.makeMat3WithAffineTransform = function(affineTransform) {
|
553 |
+
var obj = new Float32Array(9);
|
554 |
+
obj[0] = affineTransform[0];
|
555 |
+
obj[1] = affineTransform[1];
|
556 |
+
obj[2] = 0;
|
557 |
+
obj[3] = affineTransform[2];
|
558 |
+
obj[4] = affineTransform[3];
|
559 |
+
obj[5] = 0;
|
560 |
+
obj[6] = affineTransform[4];
|
561 |
+
obj[7] = affineTransform[5];
|
562 |
+
obj[8] = 1;
|
563 |
+
return obj;
|
564 |
+
};
|
565 |
+
|
566 |
+
/*
|
567 |
+
* High performance vector container for math
|
568 |
+
* Copyright (c) 2011 Apple, Inc
|
569 |
+
*/
|
570 |
+
vector3 = function(vec) {
|
571 |
+
this.create(vec);
|
572 |
+
};
|
573 |
+
|
574 |
+
vector3.prototype = {
|
575 |
+
create: function(vec) {
|
576 |
+
var m = this.$matrix = {};
|
577 |
+
if (!vec) {
|
578 |
+
m.m11 = 0;
|
579 |
+
m.m12 = 0;
|
580 |
+
m.m13 = 0;
|
581 |
+
} else {
|
582 |
+
m.m11 = vec[0];
|
583 |
+
m.m12 = vec[1];
|
584 |
+
m.m13 = vec[2];
|
585 |
+
}
|
586 |
+
},
|
587 |
+
|
588 |
+
subtract: function(vec) {
|
589 |
+
var m = this.$matrix;
|
590 |
+
var mm = vec.$matrix;
|
591 |
+
m.m11 -= mm.m11;
|
592 |
+
m.m12 -= mm.m12;
|
593 |
+
m.m13 -= mm.m13;
|
594 |
+
},
|
595 |
+
|
596 |
+
add: function(vec) {
|
597 |
+
var m = this.$matrix;
|
598 |
+
var mm = vec.$matrix;
|
599 |
+
m.m11 += mm.m11;
|
600 |
+
m.m12 += mm.m12;
|
601 |
+
m.m13 += mm.m13;
|
602 |
+
},
|
603 |
+
|
604 |
+
normalize: function() {
|
605 |
+
var m = this.$matrix;
|
606 |
+
var length = Math.sqrt((m.m11 * m.m11) + (m.m12 * m.m12) + (m.m13 * m.m13));
|
607 |
+
if (length > 0) {
|
608 |
+
m.m11 /= length;
|
609 |
+
m.m12 /= length;
|
610 |
+
m.m13 /= length;
|
611 |
+
}
|
612 |
+
},
|
613 |
+
|
614 |
+
scale: function(scalar) {
|
615 |
+
var m = this.$matrix;
|
616 |
+
m.m11 *= scalar;
|
617 |
+
m.m12 *= scalar;
|
618 |
+
m.m13 *= scalar;
|
619 |
+
},
|
620 |
+
|
621 |
+
cross: function(vec) {
|
622 |
+
var m = this.$matrix;
|
623 |
+
var mm = vec.$matrix;
|
624 |
+
var a1 = mm.m11, a2 = mm.m12, a3 = mm.m13;
|
625 |
+
var m1 = m.m11, m2 = m.m12, m3 = m.m13;
|
626 |
+
m.m11 = m2 * a3 - m3 * a2;
|
627 |
+
m.m12 = m3 * a1 - m1 * a3;
|
628 |
+
m.m13 = m1 * a2 - m2 * a1;
|
629 |
+
},
|
630 |
+
|
631 |
+
getArray: function() {
|
632 |
+
var m = this.$matrix;
|
633 |
+
|
634 |
+
return [m.m11, m.m12, m.m13];
|
635 |
+
}
|
636 |
+
};
|
637 |
+
|
638 |
+
// Matrix3, 3x3 Matrix Class
|
639 |
+
// Matrix3 stores row-major order, simply transverse to get a webGL acceptable array
|
640 |
+
Matrix3 = function() {
|
641 |
+
this.identity();
|
642 |
+
};
|
643 |
+
|
644 |
+
Matrix3.prototype = {
|
645 |
+
identity: function() {
|
646 |
+
this.$matrix = {
|
647 |
+
m11: 1, m12: 0, m13: 0,
|
648 |
+
m21: 0, m22: 1, m23: 0,
|
649 |
+
m31: 0, m32: 0, m33: 1
|
650 |
+
};
|
651 |
+
},
|
652 |
+
|
653 |
+
affineScale: function(sx, sy) {
|
654 |
+
var m = this.$matrix;
|
655 |
+
m.m11 = sx;
|
656 |
+
m.m22 = sy;
|
657 |
+
},
|
658 |
+
|
659 |
+
affineTranslate: function(tx, ty) {
|
660 |
+
var m = this.$matrix;
|
661 |
+
m.m13 = tx;
|
662 |
+
m.m23 = ty;
|
663 |
+
},
|
664 |
+
|
665 |
+
transformTranslate: function(tx, ty) {
|
666 |
+
var matrix = new Matrix3();
|
667 |
+
matrix.affineTranslate(tx, ty);
|
668 |
+
this.multiply(matrix.getArray());
|
669 |
+
},
|
670 |
+
|
671 |
+
multiply: function(mat) {
|
672 |
+
var m = this.$matrix;
|
673 |
+
var m0 = m.m11, m1 = m.m12, m2 = m.m13, m3 = m.m21, m4 = m.m22, m5 = m.m23, m6 = m.m31, m7 = m.m32, m8 = m.m33;
|
674 |
+
m.m11 = m0 * mat[0] + m1 * mat[3] + m2 * mat[6];
|
675 |
+
m.m12 = m0 * mat[1] + m1 * mat[4] + m2 * mat[7];
|
676 |
+
m.m13 = m0 * mat[2] + m1 * mat[5] + m2 * mat[8];
|
677 |
+
m.m21 = m3 * mat[0] + m4 * mat[3] + m5 * mat[6];
|
678 |
+
m.m22 = m3 * mat[1] + m4 * mat[4] + m5 * mat[7];
|
679 |
+
m.m23 = m3 * mat[2] + m4 * mat[5] + m5 * mat[8];
|
680 |
+
m.m31 = m6 * mat[0] + m7 * mat[3] + m8 * mat[6];
|
681 |
+
m.m32 = m6 * mat[1] + m7 * mat[4] + m8 * mat[7];
|
682 |
+
m.m33 = m6 * mat[2] + m7 * mat[5] + m8 * mat[8];
|
683 |
+
},
|
684 |
+
|
685 |
+
getArray: function() {
|
686 |
+
// this is row major order, for WebGL you'll need to transverse this
|
687 |
+
var m = this.$matrix;
|
688 |
+
|
689 |
+
return [m.m11, m.m12, m.m13, m.m21, m.m22, m.m23, m.m31, m.m32, m.m33];
|
690 |
+
},
|
691 |
+
|
692 |
+
getFloat32Array: function() {
|
693 |
+
return new Float32Array(this.getArray());
|
694 |
+
},
|
695 |
+
|
696 |
+
getColumnMajorArray: function() {
|
697 |
+
// this is row major order, for WebGL you'll need to transverse this
|
698 |
+
var m = this.$matrix;
|
699 |
+
|
700 |
+
return [m.m11, m.m21, m.m31, m.m12, m.m22, m.m32, m.m13, m.m23, m.m33 ];
|
701 |
+
},
|
702 |
+
|
703 |
+
getColumnMajorFloat32Array: function() {
|
704 |
+
return new Float32Array(this.getColumnMajorArray());
|
705 |
+
}
|
706 |
+
|
707 |
+
};
|
708 |
+
|
709 |
+
Matrix4 = function() {
|
710 |
+
this.identity();
|
711 |
+
};
|
712 |
+
|
713 |
+
Matrix4.prototype = {
|
714 |
+
identity: function() {
|
715 |
+
this.$matrix = {
|
716 |
+
m11: 1, m12: 0, m13: 0, m14: 0,
|
717 |
+
m21: 0, m22: 1, m23: 0, m24: 0,
|
718 |
+
m31: 0, m32: 0, m33: 1, m34: 0,
|
719 |
+
m41: 0, m42: 0, m43: 0, m44: 1
|
720 |
+
};
|
721 |
+
},
|
722 |
+
|
723 |
+
translate: function(x, y, z) {
|
724 |
+
var matrix = new Matrix4();
|
725 |
+
var m = matrix.$matrix;
|
726 |
+
m.m14 = x;
|
727 |
+
m.m24 = y;
|
728 |
+
m.m34 = z;
|
729 |
+
this.multiply(matrix);
|
730 |
+
/*
|
731 |
+
* this.$matrix.m41 = this.$matrix.m11*x + this.$matrix.m21*y +
|
732 |
+
* this.$matrix.m31*z + this.$matrix.m41; this.$matrix.m42 =
|
733 |
+
* this.$matrix.m12*x + this.$matrix.m22*y + this.$matrix.m32*z +
|
734 |
+
* this.$matrix.m42; this.$matrix.m43 = this.$matrix.m13*x +
|
735 |
+
* this.$matrix.m23*y + this.$matrix.m33*z + this.$matrix.m43;
|
736 |
+
* this.$matrix.m44 = this.$matrix.m14*x + this.$matrix.m24*y +
|
737 |
+
* this.$matrix.m34*z + this.$matrix.m44;
|
738 |
+
*/
|
739 |
+
},
|
740 |
+
|
741 |
+
scale: function(x, y, z) {
|
742 |
+
var matrix = new Matrix4();
|
743 |
+
var m = matrix.$matrix;
|
744 |
+
m.m11 = x;
|
745 |
+
m.m22 = y;
|
746 |
+
m.m33 = z;
|
747 |
+
this.multiply(matrix);
|
748 |
+
},
|
749 |
+
|
750 |
+
multiply: function(mat) {
|
751 |
+
var m = this.$matrix;
|
752 |
+
var mm = mat.$matrix;
|
753 |
+
var m11 = (mm.m11 * m.m11 + mm.m21 * m.m12 + mm.m31 * m.m13 + mm.m41 * m.m14);
|
754 |
+
var m12 = (mm.m12 * m.m11 + mm.m22 * m.m12 + mm.m32 * m.m13 + mm.m42 * m.m14);
|
755 |
+
var m13 = (mm.m13 * m.m11 + mm.m23 * m.m12 + mm.m33 * m.m13 + mm.m43 * m.m14);
|
756 |
+
var m14 = (mm.m14 * m.m11 + mm.m24 * m.m12 + mm.m34 * m.m13 + mm.m44 * m.m14);
|
757 |
+
|
758 |
+
var m21 = (mm.m11 * m.m21 + mm.m21 * m.m22 + mm.m31 * m.m23 + mm.m41 * m.m24);
|
759 |
+
var m22 = (mm.m12 * m.m21 + mm.m22 * m.m22 + mm.m32 * m.m23 + mm.m42 * m.m24);
|
760 |
+
var m23 = (mm.m13 * m.m21 + mm.m23 * m.m22 + mm.m33 * m.m23 + mm.m43 * m.m24);
|
761 |
+
var m24 = (mm.m14 * m.m21 + mm.m24 * m.m22 + mm.m34 * m.m23 + mm.m44 * m.m24);
|
762 |
+
|
763 |
+
var m31 = (mm.m11 * m.m31 + mm.m21 * m.m32 + mm.m31 * m.m33 + mm.m41 * m.m34);
|
764 |
+
var m32 = (mm.m12 * m.m31 + mm.m22 * m.m32 + mm.m32 * m.m33 + mm.m42 * m.m34);
|
765 |
+
var m33 = (mm.m13 * m.m31 + mm.m23 * m.m32 + mm.m33 * m.m33 + mm.m43 * m.m34);
|
766 |
+
var m34 = (mm.m14 * m.m31 + mm.m24 * m.m32 + mm.m34 * m.m33 + mm.m44 * m.m34);
|
767 |
+
|
768 |
+
var m41 = (mm.m11 * m.m41 + mm.m21 * m.m42 + mm.m31 * m.m43 + mm.m41 * m.m44);
|
769 |
+
var m42 = (mm.m12 * m.m41 + mm.m22 * m.m42 + mm.m32 * m.m43 + mm.m42 * m.m44);
|
770 |
+
var m43 = (mm.m13 * m.m41 + mm.m23 * m.m42 + mm.m33 * m.m43 + mm.m43 * m.m44);
|
771 |
+
var m44 = (mm.m14 * m.m41 + mm.m24 * m.m42 + mm.m34 * m.m43 + mm.m44 * m.m44);
|
772 |
+
|
773 |
+
m.m11 = m11;
|
774 |
+
m.m12 = m12;
|
775 |
+
m.m13 = m13;
|
776 |
+
m.m14 = m14;
|
777 |
+
|
778 |
+
m.m21 = m21;
|
779 |
+
m.m22 = m22;
|
780 |
+
m.m23 = m23;
|
781 |
+
m.m24 = m24;
|
782 |
+
|
783 |
+
m.m31 = m31;
|
784 |
+
m.m32 = m32;
|
785 |
+
m.m33 = m33;
|
786 |
+
m.m34 = m34;
|
787 |
+
|
788 |
+
m.m41 = m41;
|
789 |
+
m.m42 = m42;
|
790 |
+
m.m43 = m43;
|
791 |
+
m.m44 = m44;
|
792 |
+
},
|
793 |
+
|
794 |
+
perspective: function(fovy, aspect, near, far) {
|
795 |
+
var top = near * Math.tan(fovy * Math.PI / 360.0);
|
796 |
+
var right = top * aspect;
|
797 |
+
return this.frustum(-right, right, -top, top, near, far);
|
798 |
+
},
|
799 |
+
|
800 |
+
ortho: function(left, right, bottom, top, near, far) {
|
801 |
+
var rl = right - left;
|
802 |
+
var tb = top - bottom;
|
803 |
+
var fn = far - near;
|
804 |
+
var m = this.$matrix;
|
805 |
+
m.m11 = 2 / rl;
|
806 |
+
m.m12 = 0;
|
807 |
+
m.m13 = 0;
|
808 |
+
m.m14 = -(right + left) / rl;
|
809 |
+
m.m21 = 0;
|
810 |
+
m.m22 = 2 / tb;
|
811 |
+
m.m23 = 0;
|
812 |
+
m.m24 = -(top + bottom) / tb;
|
813 |
+
m.m31 = 0;
|
814 |
+
m.m32 = 0;
|
815 |
+
m.m33 = -2 / fn;
|
816 |
+
m.m34 = -(far + near) / fn;
|
817 |
+
m.m41 = 0;
|
818 |
+
m.m42 = 0;
|
819 |
+
m.m43 = 0;
|
820 |
+
m.m44 = 1;
|
821 |
+
},
|
822 |
+
|
823 |
+
frustum: function(left, right, bottom, top, near, far) {
|
824 |
+
var rl = right - left;
|
825 |
+
var tb = top - bottom;
|
826 |
+
var fn = far - near;
|
827 |
+
var m = this.$matrix;
|
828 |
+
m.m11 = (near * 2) / rl;
|
829 |
+
m.m12 = 0;
|
830 |
+
m.m13 = (right + left) / rl;
|
831 |
+
m.m14 = 0;
|
832 |
+
m.m21 = 0;
|
833 |
+
m.m22 = (near * 2) / tb;
|
834 |
+
m.m23 = (top + bottom) / tb;
|
835 |
+
m.m24 = 0;
|
836 |
+
m.m31 = 0;
|
837 |
+
m.m32 = 0;
|
838 |
+
m.m33 = -(far + near) / fn;
|
839 |
+
m.m34 = (-2 * far * near) / fn;
|
840 |
+
m.m41 = 0;
|
841 |
+
m.m42 = 0;
|
842 |
+
m.m43 = -1;
|
843 |
+
m.m44 = 0;
|
844 |
+
},
|
845 |
+
|
846 |
+
getArray: function() {
|
847 |
+
// this is row major order, for WebGL you'll need to transverse this
|
848 |
+
var m = this.$matrix;
|
849 |
+
|
850 |
+
return [m.m11, m.m12, m.m13, m.m14,
|
851 |
+
m.m21, m.m22, m.m23, m.m24,
|
852 |
+
m.m31, m.m32, m.m33, m.m34,
|
853 |
+
m.m41, m.m42, m.m43, m.m44];
|
854 |
+
},
|
855 |
+
|
856 |
+
getFloat32Array: function() {
|
857 |
+
return new Float32Array(this.getArray());
|
858 |
+
},
|
859 |
+
|
860 |
+
getColumnMajorArray: function() {
|
861 |
+
// this is row major order, for WebGL you'll need to transverse this
|
862 |
+
var m = this.$matrix;
|
863 |
+
|
864 |
+
return [m.m11, m.m21, m.m31, m.m41,
|
865 |
+
m.m12, m.m22, m.m32, m.m42,
|
866 |
+
m.m13, m.m23, m.m33, m.m43,
|
867 |
+
m.m14, m.m24, m.m34, m.m44];
|
868 |
+
},
|
869 |
+
|
870 |
+
getColumnMajorFloat32Array: function() {
|
871 |
+
return new Float32Array(this.getColumnMajorArray());
|
872 |
+
}
|
873 |
+
};
|
874 |
+
|
875 |
+
function TSUMix(a, b, x) {
|
876 |
+
return a + (b - a) * x;
|
877 |
+
}
|
878 |
+
|
879 |
+
//sinusoidal timing function
|
880 |
+
function TSUSineMap(x) {
|
881 |
+
return (Math.sin(x * Math.PI - (Math.PI / 2)) + 1) * 0.5;
|
882 |
+
}
|
883 |
+
|
884 |
+
//function for Twist sizing
|
885 |
+
function TwistFX(location, percent) {
|
886 |
+
var twist = 4.0 / 10.25;
|
887 |
+
var x = (1 + twist) * percent - twist * location;
|
888 |
+
if (x < 0) {
|
889 |
+
return 0;
|
890 |
+
}
|
891 |
+
else if (x > 1) {
|
892 |
+
return 1;
|
893 |
+
}
|
894 |
+
else {
|
895 |
+
return TSUSineMap(x);
|
896 |
+
}
|
897 |
+
}
|
898 |
+
|
899 |
+
//CGAffineTransformMakeRotation
|
900 |
+
function CGAffineTransformMakeRotation(angle) {
|
901 |
+
var sine, consine;
|
902 |
+
|
903 |
+
sine = Math.sin(angle);
|
904 |
+
cosine = Math.cos(angle);
|
905 |
+
|
906 |
+
return [cosine, sine, -sine, cosine, 0, 0];
|
907 |
+
}
|
908 |
+
|
909 |
+
//CGAffineTransformEqualToTransform
|
910 |
+
function CGAffineTransformEqualToTransform(t1, t2) {
|
911 |
+
return t1.a === t2.a && t1.b === t2.b && t1.c === t2.c && t1.d === t2.d && t1.tx === t2.tx && t1.ty === t2.ty;
|
912 |
+
}
|
913 |
+
|
914 |
+
//CATransform3DEqualToTransform
|
915 |
+
function CATransform3DEqualToTransform(a, b) {
|
916 |
+
var result = a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];
|
917 |
+
|
918 |
+
return result;
|
919 |
+
}
|
920 |
+
|
921 |
+
//CGPointMake
|
922 |
+
function CGPointMake(x, y) {
|
923 |
+
var p = {
|
924 |
+
x: x,
|
925 |
+
y: y
|
926 |
+
};
|
927 |
+
|
928 |
+
return p;
|
929 |
+
}
|
930 |
+
|
931 |
+
//CGRectIntersection
|
932 |
+
function CGRectIntersection(r1, r2) {
|
933 |
+
var r = {
|
934 |
+
"origin": {
|
935 |
+
"x": 0,
|
936 |
+
"y": 0
|
937 |
+
},
|
938 |
+
"size": {
|
939 |
+
"width": 0,
|
940 |
+
"height": 0
|
941 |
+
}
|
942 |
+
};
|
943 |
+
|
944 |
+
var x1, x2, y1, y2;
|
945 |
+
|
946 |
+
x1 = Math.max(r1.origin.x, r2.origin.x);
|
947 |
+
x2 = Math.min(r1.origin.x + r1.size.width, r2.origin.x + r2.size.width);
|
948 |
+
|
949 |
+
if (x1 > x2) {
|
950 |
+
return r;
|
951 |
+
}
|
952 |
+
|
953 |
+
y1 = Math.max(r1.origin.y, r2.origin.y);
|
954 |
+
y2 = Math.min(r1.origin.y + r1.size.height, r2.origin.y + r2.size.height);
|
955 |
+
|
956 |
+
if (y1 > y2) {
|
957 |
+
return r;
|
958 |
+
}
|
959 |
+
|
960 |
+
r.origin.x = x1;
|
961 |
+
r.size.width = x2 - x1;
|
962 |
+
r.origin.y = y1;
|
963 |
+
r.size.height = y2 - y1;
|
964 |
+
|
965 |
+
return r;
|
966 |
+
}
|
967 |
+
|
968 |
+
// CGRectIntegral
|
969 |
+
function CGRectIntegral(rect) {
|
970 |
+
var r = {
|
971 |
+
"origin": {
|
972 |
+
"x": 0,
|
973 |
+
"y": 0
|
974 |
+
},
|
975 |
+
"size": {
|
976 |
+
"width": 0,
|
977 |
+
"height": 0
|
978 |
+
}
|
979 |
+
};
|
980 |
+
|
981 |
+
r.origin.x = Math.floor(rect.origin.x);
|
982 |
+
r.origin.y = Math.floor(rect.origin.y);
|
983 |
+
r.size.width = Math.ceil(rect.origin.x + rect.size.width) - r.origin.x;
|
984 |
+
r.size.height = Math.ceil(rect.origin.y + rect.size.height) - r.origin.y;
|
985 |
+
return r;
|
986 |
+
}
|
987 |
+
|
988 |
+
// CGRectGetMinX
|
989 |
+
function CGRectGetMinX(rect) {
|
990 |
+
return rect.origin.x;
|
991 |
+
}
|
992 |
+
|
993 |
+
// CGRectGetMinY
|
994 |
+
function CGRectGetMinY(rect) {
|
995 |
+
return rect.origin.y;
|
996 |
+
}
|
997 |
+
|
998 |
+
// CGRectGetMidX
|
999 |
+
function CGRectGetMidX(rect) {
|
1000 |
+
return rect.origin.x + rect.size.width / 2;
|
1001 |
+
}
|
1002 |
+
|
1003 |
+
// CGRectGetMidY
|
1004 |
+
function CGRectGetMidY(rect) {
|
1005 |
+
return rect.origin.y + rect.size.height / 2;
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
// CGRectGetMaxX
|
1009 |
+
function CGRectGetMaxX(rect) {
|
1010 |
+
return rect.origin.x + rect.size.width;
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
// CGRectGetMaxY
|
1014 |
+
function CGRectGetMaxY(rect) {
|
1015 |
+
return rect.origin.y + rect.size.height;
|
1016 |
+
}
|
1017 |
+
|
1018 |
+
// CGRectEqualToRect
|
1019 |
+
function CGRectEqualToRect(rect1, rect2) {
|
1020 |
+
return (rect1.origin.x == rect2.origin.x) && (rect1.origin.y == rect2.origin.y) && (rect1.size.width == rect2.size.width) && (rect1.size.height == rect2.size.height);
|
1021 |
+
}
|
1022 |
+
|
1023 |
+
// CGRectMake
|
1024 |
+
function CGRectMake(x, y, width, height) {
|
1025 |
+
var r = {
|
1026 |
+
"origin": {
|
1027 |
+
"x": x,
|
1028 |
+
"y": y
|
1029 |
+
},
|
1030 |
+
"size": {
|
1031 |
+
"width": width,
|
1032 |
+
"height": height
|
1033 |
+
}
|
1034 |
+
};
|
1035 |
+
|
1036 |
+
return r;
|
1037 |
+
}
|
1038 |
+
|
1039 |
+
// CGSizeMake
|
1040 |
+
function CGSizeMake(width, height) {
|
1041 |
+
var sizeOut = {};
|
1042 |
+
sizeOut.width = width;
|
1043 |
+
sizeOut.height = height;
|
1044 |
+
|
1045 |
+
return sizeOut;
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
// CGSizeEqualToSize
|
1049 |
+
function CGSizeEqualToSize (size1, size2) {
|
1050 |
+
return size1.width === size2.width && size1.height === size2.height;
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
// CGSizeZero
|
1054 |
+
var CGSizeZero = {
|
1055 |
+
"width": 0,
|
1056 |
+
"height": 0
|
1057 |
+
};
|
1058 |
+
|
1059 |
+
// CGRectZero
|
1060 |
+
var CGRectZero = {
|
1061 |
+
"origin": {
|
1062 |
+
"x": 0,
|
1063 |
+
"y": 0
|
1064 |
+
},
|
1065 |
+
"size": {
|
1066 |
+
"width": 0,
|
1067 |
+
"height": 0
|
1068 |
+
}
|
1069 |
+
};
|
1070 |
+
|
1071 |
+
// TSDRectUnit
|
1072 |
+
var TSDRectUnit = {
|
1073 |
+
"origin": {
|
1074 |
+
"x": 0,
|
1075 |
+
"y": 0
|
1076 |
+
},
|
1077 |
+
"size": {
|
1078 |
+
"width": 1,
|
1079 |
+
"height": 1
|
1080 |
+
}
|
1081 |
+
};
|
1082 |
+
|
1083 |
+
//TSDMixFloats
|
1084 |
+
function TSDMixFloats(a, b, fraction) {
|
1085 |
+
return a * (1.0 - fraction) + b * fraction;
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
// TSDCenterOfRect
|
1089 |
+
function TSDCenterOfRect(rect) {
|
1090 |
+
return WebGraphics.makePoint(CGRectGetMidX(rect), CGRectGetMidY(rect));
|
1091 |
+
}
|
1092 |
+
|
1093 |
+
// TSDPointFromNormalizedRect
|
1094 |
+
function TSDPointFromNormalizedRect(pt, rect) {
|
1095 |
+
return WebGraphics.makePoint(rect.origin.x + pt.x * rect.size.width, rect.origin.y + pt.y * rect.size.height);
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
// TSDRectWithPoints
|
1099 |
+
function TSDRectWithPoints(a, b) {
|
1100 |
+
// smallest rect enclosing two points
|
1101 |
+
var minX = Math.min(a.x, b.x);
|
1102 |
+
var maxX = Math.max(a.x, b.x);
|
1103 |
+
var minY = Math.min(a.y, b.y);
|
1104 |
+
var maxY = Math.max(a.y, b.y);
|
1105 |
+
|
1106 |
+
return CGRectMake(minX, minY, maxX - minX, maxY - minY);
|
1107 |
+
}
|
1108 |
+
|
1109 |
+
function TSDGLColor(r, g, b, a) {
|
1110 |
+
var color = {
|
1111 |
+
r: r,
|
1112 |
+
g: g,
|
1113 |
+
b: b,
|
1114 |
+
a: a
|
1115 |
+
};
|
1116 |
+
|
1117 |
+
return color;
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
var TSD8bitColorDenominator = 0.003906402593851;
|
1121 |
+
|
1122 |
+
/// Creates a TSDGLColor4f from a 32-bit BGRA-encoded unsigned int
|
1123 |
+
function TSDGLColor4fMakeWithUInt(anInt) {
|
1124 |
+
var color = WebGraphics.makePoint4D(
|
1125 |
+
((anInt & 0x00ff0000) >> 16) * TSD8bitColorDenominator,
|
1126 |
+
((anInt & 0x0000ff00) >> 8) * TSD8bitColorDenominator,
|
1127 |
+
((anInt & 0x000000ff)) * TSD8bitColorDenominator,
|
1128 |
+
((anInt & 0xff000000) >> 24) * TSD8bitColorDenominator
|
1129 |
+
);
|
1130 |
+
|
1131 |
+
return color;
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
// TSUReverseSquare
|
1135 |
+
function TSUReverseSquare(x) {
|
1136 |
+
var reverse = 1.0 - x;
|
1137 |
+
return 1.0 - reverse * reverse;
|
1138 |
+
}
|
1139 |
+
|
1140 |
+
window.requestAnimFrame = (function() {
|
1141 |
+
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame
|
1142 |
+
|| window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) {
|
1143 |
+
window.setTimeout(callback, 1000 / 60);
|
1144 |
+
};
|
1145 |
+
})();
|
assets/player/gl/ParameterGroup.js
CHANGED
@@ -1,3 +1,153 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* ParameterGroup.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var KNAnimParameterGroup = Class.create({
|
10 |
+
initialize: function(name) {
|
11 |
+
this.parameterGroup = ParameterGroup[name];
|
12 |
+
|
13 |
+
this.animationCurves = {};
|
14 |
+
},
|
15 |
+
|
16 |
+
doubleForKey: function(key) {
|
17 |
+
var result = this.parameterGroup[key].dblValue;
|
18 |
+
|
19 |
+
if (!result) {
|
20 |
+
result = this.parameterGroup[key];
|
21 |
+
}
|
22 |
+
|
23 |
+
return result;
|
24 |
+
},
|
25 |
+
|
26 |
+
boolForKey: function(key) {
|
27 |
+
var result = this.parameterGroup[key].dblValue;
|
28 |
+
|
29 |
+
if (!result) {
|
30 |
+
result = this.parameterGroup[key];
|
31 |
+
}
|
32 |
+
|
33 |
+
return result > 0;
|
34 |
+
},
|
35 |
+
|
36 |
+
doubleForAnimationCurve: function(key, percent) {
|
37 |
+
var path = this.pathForAnimationCurve(key);
|
38 |
+
var result = path.yValueFromXValue(percent);
|
39 |
+
|
40 |
+
return result;
|
41 |
+
},
|
42 |
+
|
43 |
+
pathForAnimationCurve: function(key) {
|
44 |
+
var bezierCurve = this.animationCurves[key];
|
45 |
+
|
46 |
+
if (!bezierCurve) {
|
47 |
+
var parameter = this.parameterGroup[key];
|
48 |
+
bezierCurve = new CubicBezierPath(parameter.controlPoints[0], parameter.controlPoints[1]);
|
49 |
+
|
50 |
+
this.animationCurves[key] = bezierCurve;
|
51 |
+
}
|
52 |
+
|
53 |
+
return bezierCurve;
|
54 |
+
}
|
55 |
+
});
|
56 |
+
|
57 |
+
// Bezier Curve with Newton's method for solving
|
58 |
+
var CubicBezierPath = Class.create({
|
59 |
+
initialize: function(p1, p2) {
|
60 |
+
var cx = this.cx = 3 * p1.x;
|
61 |
+
var bx = this.bx = 3 * (p2.x - p1.x) - cx;
|
62 |
+
var ax = this.ax = 1 - cx - bx;
|
63 |
+
|
64 |
+
var cy = this.cy = 3 * p1.y;
|
65 |
+
var by = this.by = 3 * (p2.y - p1.y) - cy;
|
66 |
+
var ay = this.ay = 1 - cy - by;
|
67 |
+
|
68 |
+
// loop 5 times maximum
|
69 |
+
this.iteration = 5;
|
70 |
+
|
71 |
+
// the tolerance accepted
|
72 |
+
this.epsilon = 1e-4;
|
73 |
+
},
|
74 |
+
|
75 |
+
bezierCurveX: function(t) {
|
76 |
+
return t * (this.cx + t * (this.bx + t * this.ax));
|
77 |
+
},
|
78 |
+
|
79 |
+
bezierCurveY: function(t) {
|
80 |
+
return t * (this.cy + t * (this.by + t * this.ay));
|
81 |
+
},
|
82 |
+
|
83 |
+
bezierCurveDerivativeX: function(t) {
|
84 |
+
return this.cx + t * (2 * this.bx + 3 * this.ax * t);
|
85 |
+
},
|
86 |
+
|
87 |
+
solveXForT: function(t) {
|
88 |
+
var epsilon = this.epsilon;
|
89 |
+
var x0 = t;
|
90 |
+
var x1;
|
91 |
+
|
92 |
+
for (var i = 0, length = this.iteration; i < length; i++) {
|
93 |
+
x1 = this.bezierCurveX(x0) - t;
|
94 |
+
|
95 |
+
if (Math.abs(x1) < epsilon) {
|
96 |
+
break;
|
97 |
+
}
|
98 |
+
|
99 |
+
x0 = x0 - (x1 / this.bezierCurveDerivativeX(x0));
|
100 |
+
}
|
101 |
+
|
102 |
+
return x0;
|
103 |
+
},
|
104 |
+
|
105 |
+
yValueFromXValue: function(xValue) {
|
106 |
+
return this.bezierCurveY(this.solveXForT(xValue));
|
107 |
+
}
|
108 |
+
|
109 |
+
});
|
110 |
+
|
111 |
+
var ParameterGroup = {
|
112 |
+
"Fireworks": {
|
113 |
+
"FireworkSizeMax": 0.3,
|
114 |
+
"FireworkDurationMax": 2,
|
115 |
+
"ParticleTrailsDitherMax": 2,
|
116 |
+
"SparkleStartTime": 0.5,
|
117 |
+
"TextOpacityEndTime": 0.6,
|
118 |
+
"ParticleTransparency": {
|
119 |
+
"dblValue": 0,
|
120 |
+
"controlPoints": [{"x": 1, "y": 0}, {"x": 0.718446, "y": 1}]
|
121 |
+
},
|
122 |
+
"TextOpacityTiming": {
|
123 |
+
"dblValue": 0,
|
124 |
+
"controlPoints": [{"x": 1, "y": 0}, {"x": 0.825627, "y": 1}]
|
125 |
+
},
|
126 |
+
"BloomBlurScale":4,
|
127 |
+
"Gravity": 20,
|
128 |
+
"ParticleBurstTiming": {
|
129 |
+
"dblValue": 0,
|
130 |
+
"controlPoints": [{"x": 0, "y": 1}, {"x": 0.551894, "y": 0.993738}]
|
131 |
+
},
|
132 |
+
"ParticleSizeStart": 0.5,
|
133 |
+
"ParticleTrailsDitherAmount": 0.5,
|
134 |
+
"CenterBurstOpacity": 1,
|
135 |
+
"BloomPower": 3,
|
136 |
+
"ParticleSizeMax": 0.5,
|
137 |
+
"ParticleSizeMin": 3,
|
138 |
+
"CenterBurstScaleMin": 0.15,
|
139 |
+
"TrailsFadeOutMax": 0.1,
|
140 |
+
"CenterBurstScaleMax": 0.3,
|
141 |
+
"TrailsFadeOutMin": 0.03,
|
142 |
+
"TextOpacityBeginTime": 0.1,
|
143 |
+
"ParticleCount": 200,
|
144 |
+
"SparklePeriod": 13,
|
145 |
+
"ParticleColorRandomness": 0.09,
|
146 |
+
"FireworkSpeedMax": 1,
|
147 |
+
"FireworkDurationMin": 1,
|
148 |
+
"FireworkSizeMin": 0.15,
|
149 |
+
"ParticleLifeSpanMinDuration": 0.5,
|
150 |
+
"FireworkSpeedMin": 0.8,
|
151 |
+
"FireworksCount": 2
|
152 |
+
}
|
153 |
+
};
|
assets/player/gl/TSDGLBloomEffect.js
CHANGED
@@ -1,3 +1,170 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* TSDGLBloomEffect.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var kShaderUniformBloomAmount = "BloomAmount";
|
10 |
+
var kShaderUniformBlurTexture = "BlurTexture";
|
11 |
+
|
12 |
+
var TSDGLBloomEffect = Class.create({
|
13 |
+
initialize: function(gl) {
|
14 |
+
this.gl = gl;
|
15 |
+
},
|
16 |
+
|
17 |
+
initWithEffectSize: function(effectSize, blurScale) {
|
18 |
+
this._effectSize = effectSize;
|
19 |
+
|
20 |
+
// blurScale must be >= 1.0
|
21 |
+
this._blurBufferSize = CGSizeMake(Math.max(16, Math.ceil(effectSize.width / blurScale)), Math.max(16, Math.ceil(effectSize.height / blurScale)));;
|
22 |
+
|
23 |
+
this.p_setupShaders();
|
24 |
+
this.p_setupBuffers();
|
25 |
+
},
|
26 |
+
|
27 |
+
p_setupShaders: function() {
|
28 |
+
var gl = this.gl;
|
29 |
+
var _blurBufferSize = this._blurBufferSize;
|
30 |
+
|
31 |
+
var blurTextureSize = WebGraphics.makePoint(1.0 / _blurBufferSize.width, 1.0 / _blurBufferSize.height);
|
32 |
+
var blurTransform = WebGraphics.makeOrthoMatrix4(0, _blurBufferSize.width, 0, _blurBufferSize.height, -1, +1);
|
33 |
+
|
34 |
+
// shader 1: horizontal blur shader
|
35 |
+
var _blurHorizontalShader = this._blurHorizontalShader = new TSDGLShader(gl);
|
36 |
+
_blurHorizontalShader.initWithDefaultHorizontalBlurShader();
|
37 |
+
_blurHorizontalShader.setMat4WithTransform3D(blurTransform, kTSDGLShaderUniformMVPMatrix);
|
38 |
+
_blurHorizontalShader.setPoint2D(blurTextureSize, kTSDGLShaderUniformTextureSize);
|
39 |
+
|
40 |
+
// shader 2: vertical blur shader
|
41 |
+
var _blurVerticalShader = this._blurVerticalShader = new TSDGLShader(gl);
|
42 |
+
_blurVerticalShader.initWithDefaultVerticalBlurShader();
|
43 |
+
_blurVerticalShader.setMat4WithTransform3D(blurTransform, kTSDGLShaderUniformMVPMatrix);
|
44 |
+
_blurVerticalShader.setPoint2D(blurTextureSize, kTSDGLShaderUniformTextureSize);
|
45 |
+
|
46 |
+
// shader 3: transfer shader
|
47 |
+
var _fboTransferShader = this._fboTransferShader = new TSDGLShader(gl);
|
48 |
+
_fboTransferShader.initWithDefaultTextureShader();
|
49 |
+
_fboTransferShader.setMat4WithTransform3D(blurTransform, kTSDGLShaderUniformMVPMatrix);
|
50 |
+
|
51 |
+
// shader 4: bloom effect shader
|
52 |
+
var _bloomShader = this._bloomShader = new TSDGLShader(gl);
|
53 |
+
_bloomShader.initWithShaderFileNames("bloom", "bloom");
|
54 |
+
_bloomShader.setGLint(0, kTSDGLShaderUniformTexture);
|
55 |
+
_bloomShader.setGLint(1, kShaderUniformBlurTexture);
|
56 |
+
},
|
57 |
+
|
58 |
+
p_setupBuffers: function() {
|
59 |
+
var gl = this.gl;
|
60 |
+
var _effectSize = this._effectSize;
|
61 |
+
var _blurBufferSize = this._blurBufferSize;
|
62 |
+
var meshSize = CGSizeMake(2, 2);
|
63 |
+
var effectRect = CGRectMake(0, 0, _effectSize.width, _effectSize.height);
|
64 |
+
var blurBufferRect = CGRectMake(0, 0, _blurBufferSize.width, _blurBufferSize.height);
|
65 |
+
|
66 |
+
// buffer 1: bloom effect
|
67 |
+
var _dataBuffer = this._dataBuffer = new TSDGLDataBuffer(gl);
|
68 |
+
_dataBuffer.initWithVertexRect(effectRect, TSDRectUnit, meshSize, false, false);
|
69 |
+
|
70 |
+
// buffer 2: blur buffer
|
71 |
+
var _blurDataBuffer = this._blurDataBuffer = new TSDGLDataBuffer(gl);
|
72 |
+
_blurDataBuffer.initWithVertexRect(blurBufferRect, CGRectZero, meshSize, true, false);
|
73 |
+
|
74 |
+
// buffer 3: transfer buffer
|
75 |
+
var _blurTransferDataBuffer = this._blurTransferDataBuffer = new TSDGLDataBuffer(gl);
|
76 |
+
_blurTransferDataBuffer.initWithVertexRect(blurBufferRect, TSDRectUnit, meshSize, false, false);
|
77 |
+
|
78 |
+
// initialize color framebuffer with one texture for storing incoming rendering
|
79 |
+
this._colorFramebuffer = new TSDGLFrameBuffer(gl, _effectSize, 1);
|
80 |
+
|
81 |
+
// initialize blur framebuffer with two textures for blurring operations
|
82 |
+
this._blurFramebuffer = new TSDGLFrameBuffer(gl, _blurBufferSize, 2);
|
83 |
+
},
|
84 |
+
|
85 |
+
bindFramebuffer: function() {
|
86 |
+
this._colorFramebuffer.bindFramebuffer();
|
87 |
+
},
|
88 |
+
|
89 |
+
unbindFramebufferAndBindGLFramebuffer: function(previousFramebuffer) {
|
90 |
+
this._colorFramebuffer.unbindFramebufferAndBindGLFramebuffer(previousFramebuffer);
|
91 |
+
},
|
92 |
+
|
93 |
+
p_blurColorBufferWithPreviousFramebuffer: function(previousFramebuffer) {
|
94 |
+
var gl = this.gl;
|
95 |
+
var _blurFramebuffer = this._blurFramebuffer;
|
96 |
+
var _blurBufferSize = this._blurBufferSize;
|
97 |
+
|
98 |
+
_blurFramebuffer.bindFramebuffer();
|
99 |
+
|
100 |
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
101 |
+
|
102 |
+
gl.viewport(0, 0, _blurBufferSize.width, _blurBufferSize.height);
|
103 |
+
|
104 |
+
// Step 1: Transfer color to blur buffer
|
105 |
+
|
106 |
+
gl.bindTexture(gl.TEXTURE_2D, this._colorFramebuffer.currentGLTexture());
|
107 |
+
|
108 |
+
this._blurTransferDataBuffer.drawWithShader(this._fboTransferShader, true);
|
109 |
+
|
110 |
+
// Step 2: Blur horizontally
|
111 |
+
|
112 |
+
var blurTexture = _blurFramebuffer.currentGLTexture();
|
113 |
+
_blurFramebuffer.setCurrentTextureToNext();
|
114 |
+
|
115 |
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
116 |
+
|
117 |
+
gl.bindTexture(gl.TEXTURE_2D, blurTexture);
|
118 |
+
|
119 |
+
this._blurDataBuffer.drawWithShader(this._blurHorizontalShader, true);
|
120 |
+
|
121 |
+
// Step 3: Blur Vertically
|
122 |
+
|
123 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
124 |
+
|
125 |
+
blurTexture = _blurFramebuffer.currentGLTexture();
|
126 |
+
_blurFramebuffer.setCurrentTextureToNext();
|
127 |
+
|
128 |
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
129 |
+
|
130 |
+
gl.bindTexture(gl.TEXTURE_2D, blurTexture);
|
131 |
+
|
132 |
+
this._blurDataBuffer.drawWithShader(this._blurVerticalShader, true);
|
133 |
+
|
134 |
+
_blurFramebuffer.unbindFramebufferAndBindGLFramebuffer(previousFramebuffer);
|
135 |
+
|
136 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
137 |
+
},
|
138 |
+
|
139 |
+
drawBloomEffectWithMVPMatrix: function(MVPMatrix, bloomAmount, currentGLFramebuffer) {
|
140 |
+
var gl = this.gl;
|
141 |
+
var _effectSize = this._effectSize;
|
142 |
+
var oldViewportRect = gl.getParameter(gl.VIEWPORT);
|
143 |
+
|
144 |
+
// Blur color buffer into blur FBO
|
145 |
+
this.p_blurColorBufferWithPreviousFramebuffer(currentGLFramebuffer);
|
146 |
+
|
147 |
+
// change viewport back to effect size
|
148 |
+
gl.viewport(0, 0, _effectSize.width, _effectSize.height);
|
149 |
+
|
150 |
+
// Draw Bloom
|
151 |
+
gl.activeTexture(gl.TEXTURE1);
|
152 |
+
gl.bindTexture(gl.TEXTURE_2D, this._blurFramebuffer.currentGLTexture());
|
153 |
+
gl.activeTexture(gl.TEXTURE0);
|
154 |
+
gl.bindTexture(gl.TEXTURE_2D, this._colorFramebuffer.currentGLTexture());
|
155 |
+
|
156 |
+
var _bloomShader = this._bloomShader;
|
157 |
+
_bloomShader.setMat4WithTransform3D(MVPMatrix, kTSDGLShaderUniformMVPMatrix);
|
158 |
+
_bloomShader.setGLFloat(bloomAmount, kShaderUniformBloomAmount);
|
159 |
+
|
160 |
+
this._dataBuffer.drawWithShader(_bloomShader, true);
|
161 |
+
|
162 |
+
gl.activeTexture(gl.TEXTURE1);
|
163 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
164 |
+
gl.activeTexture(gl.TEXTURE0);
|
165 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
166 |
+
|
167 |
+
// change viewport back to original size
|
168 |
+
gl.viewport(oldViewportRect[0], oldViewportRect[1], oldViewportRect[2], oldViewportRect[3]);
|
169 |
+
}
|
170 |
+
});
|
assets/player/gl/TSDGLDataBuffer.js
CHANGED
@@ -1,3 +1,823 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* TSDGLDataBuffer.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var CHAR_MAX = 127;
|
10 |
+
var UCHAR_MAX = 255;
|
11 |
+
var SHRT_MAX = 32767;
|
12 |
+
var USHRT_MAX = 65535;
|
13 |
+
|
14 |
+
/* Boolean */
|
15 |
+
var GL_FALSE = 0;
|
16 |
+
var GL_TRUE = 1;
|
17 |
+
|
18 |
+
/* BeginMode */
|
19 |
+
var GL_POINTS = 0x0000;
|
20 |
+
var GL_LINES = 0x0001;
|
21 |
+
var GL_LINE_LOOP = 0x0002;
|
22 |
+
var GL_LINE_STRIP = 0x0003;
|
23 |
+
var GL_TRIANGLES = 0x0004;
|
24 |
+
var GL_TRIANGLE_STRIP = 0x0005;
|
25 |
+
var GL_TRIANGLE_FAN = 0x0006;
|
26 |
+
|
27 |
+
/* DataType */
|
28 |
+
var GL_BYTE = 0x1400;
|
29 |
+
var GL_UNSIGNED_BYTE = 0x1401;
|
30 |
+
var GL_SHORT = 0x1402;
|
31 |
+
var GL_UNSIGNED_SHORT = 0x1403;
|
32 |
+
var GL_INT = 0x1404;
|
33 |
+
var GL_UNSIGNED_INT = 0x1405;
|
34 |
+
var GL_FLOAT = 0x1406;
|
35 |
+
var GL_DOUBLE = 0x140A;
|
36 |
+
|
37 |
+
var GL_STREAM_DRAW = 0x88E0;
|
38 |
+
var GL_STATIC_DRAW = 0x88E4;
|
39 |
+
var GL_DYNAMIC_DRAW = 0x88E8;
|
40 |
+
|
41 |
+
var GL_FLOAT_VEC2 = 0x8B50;
|
42 |
+
var GL_FLOAT_VEC3 = 0x8B51;
|
43 |
+
var GL_FLOAT_VEC4 = 0x8B52;
|
44 |
+
var GL_INT_VEC2 = 0x8B53;
|
45 |
+
var GL_INT_VEC3 = 0x8B54;
|
46 |
+
var GL_INT_VEC4 = 0x8B55;
|
47 |
+
var GL_BOOL = 0x8B56;
|
48 |
+
var GL_BOOL_VEC2 = 0x8B57;
|
49 |
+
var GL_BOOL_VEC3 = 0x8B58;
|
50 |
+
var GL_BOOL_VEC4 = 0x8B59;
|
51 |
+
var GL_FLOAT_MAT2 = 0x8B5A;
|
52 |
+
var GL_FLOAT_MAT3 = 0x8B5B;
|
53 |
+
var GL_FLOAT_MAT4 = 0x8B5C;
|
54 |
+
var GL_SAMPLER_1D = 0x8B5D;
|
55 |
+
var GL_SAMPLER_2D = 0x8B5E;
|
56 |
+
var GL_SAMPLER_3D = 0x8B5F;
|
57 |
+
var GL_SAMPLER_CUBE = 0x8B60;
|
58 |
+
|
59 |
+
var TSDGLDataBufferDataTypeUnknown = 0;
|
60 |
+
var TSDGLDataBufferDataTypeByte = GL_BYTE;
|
61 |
+
var TSDGLDataBufferDataTypeUnsignedByte = GL_UNSIGNED_BYTE;
|
62 |
+
var TSDGLDataBufferDataTypeShort = GL_SHORT;
|
63 |
+
var TSDGLDataBufferDataTypeUnsignedShort = GL_UNSIGNED_SHORT;
|
64 |
+
var TSDGLDataBufferDataTypeFloat = GL_FLOAT;
|
65 |
+
|
66 |
+
function TSDGLDataBufferDataTypeAsGLEnum(dataType) {
|
67 |
+
var result = 0;
|
68 |
+
switch (dataType) {
|
69 |
+
case TSDGLDataBufferDataTypeByte:
|
70 |
+
result = GL_BYTE;
|
71 |
+
break;
|
72 |
+
case TSDGLDataBufferDataTypeUnsignedByte:
|
73 |
+
result = GL_UNSIGNED_BYTE;
|
74 |
+
break;
|
75 |
+
case TSDGLDataBufferDataTypeUnsignedShort:
|
76 |
+
result = GL_UNSIGNED_SHORT;
|
77 |
+
break;
|
78 |
+
case TSDGLDataBufferDataTypeShort:
|
79 |
+
result = GL_SHORT;
|
80 |
+
break;
|
81 |
+
case TSDGLDataBufferDataTypeFloat:
|
82 |
+
result = GL_FLOAT;
|
83 |
+
break;
|
84 |
+
case TSDGLDataBufferDataTypeUnknown:
|
85 |
+
console.log("Unknown TSDGLdataBufferDataType!");
|
86 |
+
break;
|
87 |
+
}
|
88 |
+
|
89 |
+
return result;
|
90 |
+
}
|
91 |
+
|
92 |
+
function TSDGLDataBufferDataTypeSize(dataType) {
|
93 |
+
var result = 0;
|
94 |
+
switch (dataType) {
|
95 |
+
case GL_BYTE:
|
96 |
+
result = 1;
|
97 |
+
break;
|
98 |
+
case GL_UNSIGNED_BYTE:
|
99 |
+
result = 1;
|
100 |
+
break;
|
101 |
+
case GL_SHORT:
|
102 |
+
result = 2;
|
103 |
+
break;
|
104 |
+
case GL_UNSIGNED_SHORT:
|
105 |
+
result = 2;
|
106 |
+
break;
|
107 |
+
case GL_FLOAT:
|
108 |
+
result = 4;
|
109 |
+
break;
|
110 |
+
default:
|
111 |
+
break;
|
112 |
+
}
|
113 |
+
|
114 |
+
return result;
|
115 |
+
}
|
116 |
+
|
117 |
+
function TSDGLPoint2DByteFromPoint2D(aPoint, isNormalized) {
|
118 |
+
var x = TSDGLbyteFromFloat(aPoint.x, isNormalized);
|
119 |
+
var y = TSDGLbyteFromFloat(aPoint.y, isNormalized);
|
120 |
+
|
121 |
+
var p = new Int8Array(2);
|
122 |
+
p.set([x, y], 0);
|
123 |
+
|
124 |
+
return p;
|
125 |
+
}
|
126 |
+
|
127 |
+
function TSDGLbyteFromFloat(aFloat, isNormalized) {
|
128 |
+
if (isNormalized) {
|
129 |
+
aFloat *= CHAR_MAX;
|
130 |
+
}
|
131 |
+
|
132 |
+
return aFloat;
|
133 |
+
}
|
134 |
+
|
135 |
+
function TSDGLPoint2DUnsignedByteFromPoint2D(aPoint, isNormalized) {
|
136 |
+
var x = TSDGLubyteFromFloat(aPoint.x, isNormalized);
|
137 |
+
var y = TSDGLubyteFromFloat(aPoint.y, isNormalized);
|
138 |
+
|
139 |
+
var p = new Uint8Array(2);
|
140 |
+
|
141 |
+
p.set([x, y], 0);
|
142 |
+
|
143 |
+
return p;
|
144 |
+
}
|
145 |
+
|
146 |
+
function TSDGLubyteFromFloat(aFloat, isNormalized) {
|
147 |
+
if (isNormalized) {
|
148 |
+
aFloat *= UCHAR_MAX;
|
149 |
+
}
|
150 |
+
|
151 |
+
return aFloat;
|
152 |
+
}
|
153 |
+
|
154 |
+
function TSDGLPoint2DShortFromPoint2D(aPoint, isNormalized) {
|
155 |
+
var x = TSDGLshortFromFloat(aPoint.x, isNormalized);
|
156 |
+
var y = TSDGLshortFromFloat(aPoint.y, isNormalized);
|
157 |
+
|
158 |
+
var p = new Int16Array(4);
|
159 |
+
p.set([x, y], 0);
|
160 |
+
|
161 |
+
return p;
|
162 |
+
}
|
163 |
+
|
164 |
+
function TSDGLshortFromFloat(aFloat, isNormalized) {
|
165 |
+
if (isNormalized) {
|
166 |
+
aFloat *= SHRT_MAX;
|
167 |
+
}
|
168 |
+
|
169 |
+
return aFloat;
|
170 |
+
}
|
171 |
+
|
172 |
+
function TSDGLPoint2DUnsignedShortFromPoint2D(aPoint, isNormalized) {
|
173 |
+
var x = TSDGLushortFromFloat(aPoint.x, isNormalized);
|
174 |
+
var y = TSDGLushortFromFloat(aPoint.y, isNormalized);
|
175 |
+
|
176 |
+
var p = new Uint16Array(4);
|
177 |
+
p.set([x, y], 0);
|
178 |
+
|
179 |
+
return p;
|
180 |
+
}
|
181 |
+
|
182 |
+
function TSDGLushortFromFloat(aFloat, isNormalized) {
|
183 |
+
if (isNormalized) {
|
184 |
+
aFloat *= USHRT_MAX;
|
185 |
+
}
|
186 |
+
return aFloat;
|
187 |
+
}
|
188 |
+
|
189 |
+
function TSDGLDataBufferSetGLPoint2DWithDataType(mGLData, bufferOffset, dataType, isNormalized, aPoint2D) {
|
190 |
+
switch (dataType) {
|
191 |
+
case TSDGLDataBufferDataTypeByte:
|
192 |
+
var value = TSDGLPoint2DByteFromPoint2D(aPoint2D, isNormalized);
|
193 |
+
var typedArray = new Int8Array(mGLData);
|
194 |
+
typedArray.set(value, bufferOffset);
|
195 |
+
|
196 |
+
break;
|
197 |
+
|
198 |
+
case TSDGLDataBufferDataTypeUnsignedByte:
|
199 |
+
var value = TSDGLPoint2DUnsignedByteFromPoint2D(aPoint2D, isNormalized);
|
200 |
+
var typedArray = new Uint8Array(mGLData);
|
201 |
+
typedArray.set(value, bufferOffset);
|
202 |
+
|
203 |
+
break;
|
204 |
+
|
205 |
+
case TSDGLDataBufferDataTypeShort:
|
206 |
+
var value = TSDGLPoint2DShortFromPoint2D(aPoint2D, isNormalized);
|
207 |
+
var typedArray = new Int16Array(mGLData);
|
208 |
+
typedArray.set(value, bufferOffset/2);
|
209 |
+
|
210 |
+
break;
|
211 |
+
|
212 |
+
case TSDGLDataBufferDataTypeUnsignedShort:
|
213 |
+
var value = TSDGLPoint2DUnsignedShortFromPoint2D(aPoint2D, isNormalized);
|
214 |
+
var typedArray = new Uint16Array(mGLData);
|
215 |
+
typedArray.set(value, bufferOffset/2);
|
216 |
+
|
217 |
+
break;
|
218 |
+
|
219 |
+
case TSDGLDataBufferDataTypeFloat:
|
220 |
+
var typedArray = new Float32Array(mGLData);
|
221 |
+
typedArray.set([aPoint2D.x, aPoint2D.y], bufferOffset/4);
|
222 |
+
|
223 |
+
break;
|
224 |
+
case TSDGLDataBufferDataTypeUnknown:
|
225 |
+
console.log("Unknown data type!");
|
226 |
+
break;
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
var TSDGLDataBufferAttribute = Class.create({
|
231 |
+
initialize: function(name, bufferUsage, dataType, normalized, componentCount) {
|
232 |
+
this.locationInShader = -1;
|
233 |
+
this.bufferOffset = null;
|
234 |
+
this.dataArrayBuffer = null;
|
235 |
+
this.dataBuffer = null;
|
236 |
+
|
237 |
+
this.initWithName(name, bufferUsage, dataType, normalized, componentCount);
|
238 |
+
},
|
239 |
+
|
240 |
+
initWithName: function(attributeName, bufferUsage, dataType, isNormalized, componentCount) {
|
241 |
+
this.name = attributeName;
|
242 |
+
this.bufferUsage = bufferUsage;
|
243 |
+
this.dataType = dataType;
|
244 |
+
|
245 |
+
if (this.dataType === GL_SHORT) {
|
246 |
+
this.dataType = GL_FLOAT;
|
247 |
+
}
|
248 |
+
|
249 |
+
this.componentCount = componentCount;
|
250 |
+
this.isNormalized = isNormalized;
|
251 |
+
|
252 |
+
this.locationInShader = -1;
|
253 |
+
}
|
254 |
+
});
|
255 |
+
|
256 |
+
var TSDGLDataArrayBuffer = Class.create({
|
257 |
+
initialize: function(gl) {
|
258 |
+
this.gl = gl;
|
259 |
+
|
260 |
+
this._vertexAttributes = null;
|
261 |
+
this.mVertexCount = 0;
|
262 |
+
|
263 |
+
// data type size in bytes
|
264 |
+
this._dataTypeSizeInBytes = 0;
|
265 |
+
|
266 |
+
// GL_STATIC_DRAW, GL_STREAM_DRAW, etc
|
267 |
+
this._bufferUsage = 0;
|
268 |
+
|
269 |
+
this.mNeedsUpdateFirstIndex = [];
|
270 |
+
this.mNeedsUpdateLastIndex = [];
|
271 |
+
|
272 |
+
this.mGLData = null;
|
273 |
+
|
274 |
+
// GL vertex data buffer
|
275 |
+
this.mGLDataBufferHasBeenSetup = false;
|
276 |
+
|
277 |
+
this.mGLDataBuffers = [];
|
278 |
+
|
279 |
+
this.mAttributeOffsetsDictionary = null;
|
280 |
+
|
281 |
+
this.GLDataBufferEntrySize = 0;
|
282 |
+
|
283 |
+
// for double-buffering
|
284 |
+
this.bufferCount = 1;
|
285 |
+
this.currentBufferIndex = 0;
|
286 |
+
},
|
287 |
+
|
288 |
+
initWithVertexAttributes: function(attributes, vertexCount, bufferCount) {
|
289 |
+
this._vertexAttributes = attributes.slice();
|
290 |
+
this.mVertexCount = vertexCount;
|
291 |
+
this.mAttributeOffsetsDictionary = {};
|
292 |
+
|
293 |
+
// Sort the attributes into buffers by buffer usage type
|
294 |
+
var bufferSizeIfFloats = 0;
|
295 |
+
|
296 |
+
var bufferOffset = 0;
|
297 |
+
|
298 |
+
for (var i = 0, length = this._vertexAttributes.length; i < length; i++) {
|
299 |
+
var attribute = this._vertexAttributes[i];
|
300 |
+
|
301 |
+
// Assign data array buffer to attribute
|
302 |
+
attribute.dataArrayBuffer = this;
|
303 |
+
|
304 |
+
var dataTypeSizeInBytes = TSDGLDataBufferDataTypeSize(attribute.dataType);
|
305 |
+
|
306 |
+
if (this._bufferUsage === 0) {
|
307 |
+
this._bufferUsage = attribute.bufferUsage;
|
308 |
+
}
|
309 |
+
|
310 |
+
// Assign buffer offset
|
311 |
+
attribute.bufferOffset = bufferOffset;
|
312 |
+
|
313 |
+
var paddedSize = attribute.componentCount * dataTypeSizeInBytes;
|
314 |
+
|
315 |
+
paddedSize = (paddedSize + 3) & ~3;
|
316 |
+
|
317 |
+
bufferOffset += paddedSize;
|
318 |
+
|
319 |
+
bufferSizeIfFloats += attribute.componentCount * 4;
|
320 |
+
}
|
321 |
+
|
322 |
+
// Create the buffer data (if necessary)
|
323 |
+
this.GLDataBufferEntrySize = bufferOffset;
|
324 |
+
|
325 |
+
// We need to give the arraybuffer a size
|
326 |
+
if (this.GLDataBufferEntrySize > 0) {
|
327 |
+
this.mGLData = new ArrayBuffer(this.mVertexCount * this.GLDataBufferEntrySize);
|
328 |
+
}
|
329 |
+
|
330 |
+
this.bufferCount = bufferCount;
|
331 |
+
|
332 |
+
this.mNeedsUpdateFirstIndex = [];
|
333 |
+
this.mNeedsUpdateLastIndex = [];
|
334 |
+
|
335 |
+
for (var i = 0; i < bufferCount; i++) {
|
336 |
+
this.mNeedsUpdateFirstIndex[i] = -1;
|
337 |
+
this.mNeedsUpdateLastIndex[i] = -1;
|
338 |
+
}
|
339 |
+
},
|
340 |
+
|
341 |
+
p_setupGLDataBufferIfNecessary: function() {
|
342 |
+
var gl = this.gl;
|
343 |
+
|
344 |
+
// Sets up GL buffers
|
345 |
+
if (this.mGLDataBufferHasBeenSetup) {
|
346 |
+
return;
|
347 |
+
}
|
348 |
+
|
349 |
+
for (var i = 0; i < this.bufferCount; i++) {
|
350 |
+
this.mGLDataBuffers[i] = gl.createBuffer();
|
351 |
+
|
352 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.mGLDataBuffers[i]);
|
353 |
+
|
354 |
+
gl.bufferData(gl.ARRAY_BUFFER, this.mGLData, this._bufferUsage);
|
355 |
+
|
356 |
+
this.mNeedsUpdateFirstIndex[i] = -1;
|
357 |
+
this.mNeedsUpdateLastIndex[i] = -1;
|
358 |
+
}
|
359 |
+
|
360 |
+
this.mGLDataBufferHasBeenSetup = true;
|
361 |
+
},
|
362 |
+
|
363 |
+
updateDataBufferIfNecessary: function() {
|
364 |
+
this.p_setupGLDataBufferIfNecessary();
|
365 |
+
|
366 |
+
if (!this.hasUpdatedData()) {
|
367 |
+
// Nothing needs to be updated!
|
368 |
+
return;
|
369 |
+
}
|
370 |
+
|
371 |
+
if (this._bufferUsage == GL_STATIC_DRAW) {
|
372 |
+
console.log("We're GL_STATIC_DRAW but trying (and FAILING) to update the array after initial setup!");
|
373 |
+
return;
|
374 |
+
}
|
375 |
+
|
376 |
+
var gl = this.gl;
|
377 |
+
// Combine all buffer's updated ranges, in case they're not the same...
|
378 |
+
var firstIndex = Number.MAX_SAFE_INTEGER;
|
379 |
+
var lastIndex = -1;
|
380 |
+
|
381 |
+
for (var i = 0; i < this.bufferCount; i++) {
|
382 |
+
var thisFirstIndex = this.mNeedsUpdateFirstIndex[i];
|
383 |
+
if (thisFirstIndex !== -1) {
|
384 |
+
firstIndex = Math.min(firstIndex, thisFirstIndex);
|
385 |
+
}
|
386 |
+
var thisLastIndex = this.mNeedsUpdateLastIndex[i];
|
387 |
+
if (thisLastIndex !== -1) {
|
388 |
+
lastIndex = Math.max(lastIndex, this.mNeedsUpdateLastIndex[i]);
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
var offset = firstIndex;
|
393 |
+
var size = lastIndex + 1 - firstIndex;
|
394 |
+
offset *= this.GLDataBufferEntrySize;
|
395 |
+
size *= this.GLDataBufferEntrySize;
|
396 |
+
|
397 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.mGLDataBuffers[this.currentBufferIndex]);
|
398 |
+
gl.bufferSubData(gl.ARRAY_BUFFER, offset, this.mGLData);
|
399 |
+
|
400 |
+
this.mNeedsUpdateFirstIndex[this.currentBufferIndex] = -1;
|
401 |
+
this.mNeedsUpdateLastIndex[this.currentBufferIndex] = -1;
|
402 |
+
},
|
403 |
+
|
404 |
+
p_bufferOffsetOfAttribute: function(attribute, index, component) {
|
405 |
+
var bufferOffset = index * this.GLDataBufferEntrySize;
|
406 |
+
|
407 |
+
bufferOffset += attribute.bufferOffset;
|
408 |
+
|
409 |
+
if (component !== 0) {
|
410 |
+
bufferOffset += TSDGLDataBufferDataTypeSize(attribute.dataType) * component;
|
411 |
+
}
|
412 |
+
|
413 |
+
return bufferOffset;
|
414 |
+
},
|
415 |
+
|
416 |
+
setGLPoint2D: function(aPoint2D, attribute, index) {
|
417 |
+
var bufferOffset = this.p_bufferOffsetOfAttribute(attribute, index, 0);
|
418 |
+
TSDGLDataBufferSetGLPoint2DWithDataType(this.mGLData, bufferOffset, attribute.dataType, attribute.isNormalized, aPoint2D);
|
419 |
+
|
420 |
+
this.addIndexNeedsUpdate(index);
|
421 |
+
},
|
422 |
+
|
423 |
+
enableVertexAttributeArrayBuffersWithShader: function(shader) {
|
424 |
+
var gl = this.gl;
|
425 |
+
|
426 |
+
this.updateDataBufferIfNecessary();
|
427 |
+
|
428 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, this.mGLDataBuffers[this.currentBufferIndex]);
|
429 |
+
|
430 |
+
for (var i = 0, length = this._vertexAttributes.length; i < length; i++) {
|
431 |
+
var attribute = this._vertexAttributes[i];
|
432 |
+
var locationInShader = attribute.locationInShader;
|
433 |
+
|
434 |
+
if (locationInShader === -1) {
|
435 |
+
locationInShader = shader.locationForAttribute(attribute.name);
|
436 |
+
|
437 |
+
if (locationInShader === -1) {
|
438 |
+
console.log("Could not find attribute " + attribute.name + "in shader!");
|
439 |
+
}
|
440 |
+
|
441 |
+
attribute.locationInShader = locationInShader;
|
442 |
+
}
|
443 |
+
|
444 |
+
var stride = 0;
|
445 |
+
|
446 |
+
if (this._vertexAttributes.length > 1) {
|
447 |
+
// we're not tight-packed, so need to specify how many elements to skip when iterating
|
448 |
+
stride = this.GLDataBufferEntrySize;
|
449 |
+
}
|
450 |
+
|
451 |
+
var dataType = TSDGLDataBufferDataTypeAsGLEnum(attribute.dataType);
|
452 |
+
|
453 |
+
gl.enableVertexAttribArray(locationInShader);
|
454 |
+
gl.vertexAttribPointer(locationInShader, attribute.componentCount, dataType, attribute.isNormalized ? GL_TRUE : GL_FALSE, stride, attribute.bufferOffset);
|
455 |
+
}
|
456 |
+
},
|
457 |
+
|
458 |
+
disableVertexAttributeArrayBuffersWithShader: function(shader) {
|
459 |
+
var gl = this.gl;
|
460 |
+
|
461 |
+
for (var i = 0, length = this._vertexAttributes.length; i < length; i++) {
|
462 |
+
var attribute = this._vertexAttributes[i];
|
463 |
+
gl.disableVertexAttribArray(attribute.locationInShader);
|
464 |
+
}
|
465 |
+
|
466 |
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
467 |
+
},
|
468 |
+
|
469 |
+
hasUpdatedData: function() {
|
470 |
+
for (var i = 0; i < this.bufferCount; i++) {
|
471 |
+
if (this.mNeedsUpdateFirstIndex[i] !== -1) {
|
472 |
+
return true;
|
473 |
+
}
|
474 |
+
}
|
475 |
+
return false;
|
476 |
+
},
|
477 |
+
|
478 |
+
addIndexNeedsUpdate: function(index) {
|
479 |
+
var currentBufferIndex = this.currentBufferIndex;
|
480 |
+
var mNeedsUpdateFirstIndex = this.mNeedsUpdateFirstIndex;
|
481 |
+
var mNeedsUpdateLastIndex = this.mNeedsUpdateLastIndex;
|
482 |
+
|
483 |
+
mNeedsUpdateFirstIndex[currentBufferIndex] = (mNeedsUpdateFirstIndex[currentBufferIndex] == -1) ? index : Math.min(mNeedsUpdateFirstIndex[currentBufferIndex], index);
|
484 |
+
mNeedsUpdateLastIndex[currentBufferIndex] = (mNeedsUpdateLastIndex[currentBufferIndex] == -1) ? index : Math.max(mNeedsUpdateLastIndex[currentBufferIndex], index);
|
485 |
+
}
|
486 |
+
|
487 |
+
});
|
488 |
+
|
489 |
+
var TSDGLDataBuffer = Class.create({
|
490 |
+
initialize: function(gl) {
|
491 |
+
this.gl = gl;
|
492 |
+
|
493 |
+
this.mCurrentBufferIndex = 0;
|
494 |
+
this.mArrayBuffers = [];
|
495 |
+
this.mAttributeToArrayBuffersDictionary = {};
|
496 |
+
|
497 |
+
// Element array buffer
|
498 |
+
this.mElementArrayCount = 0;
|
499 |
+
this.mGLElementData = null;
|
500 |
+
this.mGLElementDataBufferWasSetup = false;
|
501 |
+
this.mGLElementDataBuffer = null;
|
502 |
+
|
503 |
+
this.mGLElementMeshSize = {
|
504 |
+
width: 0,
|
505 |
+
height: 0
|
506 |
+
}
|
507 |
+
|
508 |
+
this.mGLElementQuadParticleCount = 0;
|
509 |
+
},
|
510 |
+
|
511 |
+
p_setupGLElementArrayBufferIfNecessary: function() {
|
512 |
+
var gl = this.gl;
|
513 |
+
|
514 |
+
if (this.mGLElementDataBufferWasSetup) {
|
515 |
+
return;
|
516 |
+
}
|
517 |
+
|
518 |
+
if (!this.mGLElementData) {
|
519 |
+
this.mGLElementDataBufferWasSetup = true;
|
520 |
+
return;
|
521 |
+
}
|
522 |
+
|
523 |
+
var useIndexCounter = false;
|
524 |
+
var indexCounter = 0;
|
525 |
+
|
526 |
+
if (!CGSizeEqualToSize(this.mGLElementMeshSize, CGSizeZero)) {
|
527 |
+
useIndexCounter = true;
|
528 |
+
|
529 |
+
// set up grid-based element array data
|
530 |
+
for (var y = 0; y < this.mGLElementMeshSize.height - 1; ++y) {
|
531 |
+
for (var x = 0; x < this.mGLElementMeshSize.width; ++x) {
|
532 |
+
this.setGLushort((y + 0) * this.mGLElementMeshSize.width + x, indexCounter++);
|
533 |
+
this.setGLushort((y + 1) * this.mGLElementMeshSize.width + x, indexCounter++);
|
534 |
+
}
|
535 |
+
}
|
536 |
+
} else if (this.mGLElementQuadParticleCount != 0) {
|
537 |
+
useIndexCounter = true;
|
538 |
+
this.drawMode = GL_TRIANGLES;
|
539 |
+
|
540 |
+
// set up quad particle-based element array data
|
541 |
+
for (var i = 0; i < this.mGLElementQuadParticleCount; ++i) {
|
542 |
+
// First triangle
|
543 |
+
this.setGLushort((4 * i + 0), indexCounter++);
|
544 |
+
this.setGLushort((4 * i + 1), indexCounter++);
|
545 |
+
this.setGLushort((4 * i + 2), indexCounter++);
|
546 |
+
|
547 |
+
// Second triangle
|
548 |
+
this.setGLushort((4 * i + 0), indexCounter++);
|
549 |
+
this.setGLushort((4 * i + 2), indexCounter++);
|
550 |
+
this.setGLushort((4 * i + 3), indexCounter++);
|
551 |
+
}
|
552 |
+
}
|
553 |
+
|
554 |
+
this.mGLElementDataBuffer = gl.createBuffer();
|
555 |
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.mGLElementDataBuffer);
|
556 |
+
|
557 |
+
this.mGLElementDataBufferWasSetup = true;
|
558 |
+
},
|
559 |
+
|
560 |
+
newDataBufferWithVertexAttributes: function(attributes, meshSize, isDoubleBuffered) {
|
561 |
+
var vertexCount = meshSize.width * meshSize.height;
|
562 |
+
var indexCount = meshSize.width * 2 * (meshSize.height - 1);
|
563 |
+
|
564 |
+
this.initWithVertexAttributesDesignated(attributes, vertexCount, indexCount, isDoubleBuffered);
|
565 |
+
|
566 |
+
this.mGLElementMeshSize = meshSize;
|
567 |
+
},
|
568 |
+
|
569 |
+
initWithVertexAttributes: function(attributes, meshSize) {
|
570 |
+
var vertexCount = meshSize.width * meshSize.height;
|
571 |
+
var indexCount = meshSize.width * 2 * (meshSize.height - 1);
|
572 |
+
|
573 |
+
this.initWithVertexAttributesDesignated(attributes, vertexCount, indexCount, false);
|
574 |
+
|
575 |
+
this.mGLElementMeshSize = meshSize;
|
576 |
+
},
|
577 |
+
|
578 |
+
initWithVertexAttributesDesignated: function(attributes, vertexCount, indexElementCount, isDoubleBuffered) {
|
579 |
+
this._doubleBuffered = isDoubleBuffered;
|
580 |
+
this.drawMode = GL_TRIANGLE_STRIP;
|
581 |
+
this._vertexAttributes = attributes;
|
582 |
+
this._vertexCount = vertexCount;
|
583 |
+
|
584 |
+
this.mArrayBuffers = [];
|
585 |
+
this.mAttributeToArrayBuffersDictionary = {};
|
586 |
+
|
587 |
+
var attributesToArrange = attributes.slice();
|
588 |
+
|
589 |
+
while (attributesToArrange.length > 0) {
|
590 |
+
var thisAttribute = attributesToArrange[0];
|
591 |
+
var currentAttributes = [];
|
592 |
+
|
593 |
+
for (var i = 0, length = attributesToArrange.length; i < length; i++) {
|
594 |
+
var attribute = attributesToArrange[i];
|
595 |
+
|
596 |
+
if (attribute.bufferUsage == thisAttribute.bufferUsage) {
|
597 |
+
currentAttributes.push(attribute);
|
598 |
+
}
|
599 |
+
}
|
600 |
+
|
601 |
+
var bufferCount = ((isDoubleBuffered && thisAttribute.bufferUsage !== GL_STATIC_DRAW) ? 2 : 1);
|
602 |
+
|
603 |
+
var arrayBuffer = new TSDGLDataArrayBuffer(this.gl);
|
604 |
+
|
605 |
+
arrayBuffer.initWithVertexAttributes(currentAttributes, vertexCount, bufferCount);
|
606 |
+
|
607 |
+
for (var i = 0, length = currentAttributes.length; i < length; i++) {
|
608 |
+
var attribute = currentAttributes[i];
|
609 |
+
|
610 |
+
// this will cause circular reference
|
611 |
+
attribute.dataBuffer = this;
|
612 |
+
this.mAttributeToArrayBuffersDictionary[attribute.name] = arrayBuffer;
|
613 |
+
}
|
614 |
+
|
615 |
+
this.mArrayBuffers.push(arrayBuffer);
|
616 |
+
|
617 |
+
for (var i = 0, length = currentAttributes.length; i < length; i++) {
|
618 |
+
var element = currentAttributes[i];
|
619 |
+
attributesToArrange.splice(attributesToArrange.indexOf(element), 1);
|
620 |
+
}
|
621 |
+
}
|
622 |
+
|
623 |
+
if (indexElementCount > 0) {
|
624 |
+
this.mElementArrayCount = indexElementCount;
|
625 |
+
|
626 |
+
this.mGLElementData = new ArrayBuffer(this.mElementArrayCount * 2);
|
627 |
+
}
|
628 |
+
|
629 |
+
|
630 |
+
},
|
631 |
+
|
632 |
+
initWithVertexRect: function(vertexRect, textureRect, meshSize, isTextureFlipped, includeCenterAttribute) {
|
633 |
+
var gl = this.gl;
|
634 |
+
|
635 |
+
var shouldSetupTexCoords = !CGRectEqualToRect(textureRect, CGRectZero);
|
636 |
+
|
637 |
+
var quadAttributes = [];
|
638 |
+
var positionAttribute = new TSDGLDataBufferAttribute("Position", GL_STATIC_DRAW, GL_FLOAT, false, 2);
|
639 |
+
|
640 |
+
quadAttributes.push(positionAttribute);
|
641 |
+
|
642 |
+
var texCoordAttribute;
|
643 |
+
if (shouldSetupTexCoords) {
|
644 |
+
var dataType = GL_SHORT;
|
645 |
+
|
646 |
+
if (CGRectEqualToRect(textureRect, CGRectMake(0, 0, 1, 1)) && CGSizeEqualToSize(meshSize, CGSizeMake(2, 2))) {
|
647 |
+
// If we're just passing in the unit rectangle, we can use lower precision texcoords!
|
648 |
+
dataType = GL_UNSIGNED_BYTE;
|
649 |
+
}
|
650 |
+
|
651 |
+
texCoordAttribute = new TSDGLDataBufferAttribute("TexCoord", GL_STATIC_DRAW, dataType, true, 2);
|
652 |
+
|
653 |
+
quadAttributes.push(texCoordAttribute);
|
654 |
+
}
|
655 |
+
|
656 |
+
var centerAttribute;
|
657 |
+
if (includeCenterAttribute) {
|
658 |
+
centerAttribute = new TSDGLDataBufferAttribute("Center", GL_STATIC_DRAW, GL_FLOAT, false, 2);
|
659 |
+
|
660 |
+
quadAttributes.push(centerAttribute);
|
661 |
+
}
|
662 |
+
|
663 |
+
this.initWithVertexAttributes(quadAttributes, meshSize);
|
664 |
+
|
665 |
+
var index = 0;
|
666 |
+
|
667 |
+
// This is TSDGLPoint2D in native which is a struct of float type
|
668 |
+
var center = TSDCenterOfRect(vertexRect);
|
669 |
+
|
670 |
+
var verticesWide = parseInt(meshSize.width - 1);
|
671 |
+
var verticesHigh = parseInt(meshSize.height - 1);
|
672 |
+
|
673 |
+
for (var row = 0; row <= verticesHigh; ++row) {
|
674 |
+
for (var col = 0; col <= verticesWide; ++col) {
|
675 |
+
var point = WebGraphics.makePoint(col / verticesWide, row / verticesHigh);
|
676 |
+
|
677 |
+
// This is TSDGLPoint2D in native which is a struct of float type
|
678 |
+
var vertex = TSDPointFromNormalizedRect(point, vertexRect);
|
679 |
+
|
680 |
+
this.setGLPoint2D(vertex, positionAttribute, index);
|
681 |
+
|
682 |
+
if (shouldSetupTexCoords) {
|
683 |
+
var texCoord = TSDPointFromNormalizedRect(point, textureRect);
|
684 |
+
if (isTextureFlipped) {
|
685 |
+
texCoord = WebGraphics.makePoint(texCoord.x, 1.0 - texCoord.y);
|
686 |
+
}
|
687 |
+
this.setGLPoint2D(texCoord, texCoordAttribute, index);
|
688 |
+
}
|
689 |
+
if (includeCenterAttribute) {
|
690 |
+
this.setGLPoint2D(center, centerAttribute, index);
|
691 |
+
}
|
692 |
+
|
693 |
+
index++;
|
694 |
+
}
|
695 |
+
}
|
696 |
+
|
697 |
+
},
|
698 |
+
|
699 |
+
setGLPoint2D: function(aPoint2D, attribute, index) {
|
700 |
+
attribute.dataArrayBuffer.setGLPoint2D(aPoint2D, attribute, index);
|
701 |
+
},
|
702 |
+
|
703 |
+
setGLushort: function(aShort, index) {
|
704 |
+
var bufferOffset = index;
|
705 |
+
var typedArray = new Uint16Array(this.mGLElementData);
|
706 |
+
|
707 |
+
typedArray.set([aShort], bufferOffset);
|
708 |
+
},
|
709 |
+
|
710 |
+
enableElementArrayBuffer: function() {
|
711 |
+
var gl = this.gl;
|
712 |
+
|
713 |
+
this.p_setupGLElementArrayBufferIfNecessary();
|
714 |
+
|
715 |
+
if (this.mGLElementDataBufferWasSetup) {
|
716 |
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.mGLElementDataBuffer);
|
717 |
+
}
|
718 |
+
},
|
719 |
+
|
720 |
+
disableElementArrayBuffer: function() {
|
721 |
+
var gl = this.gl;
|
722 |
+
|
723 |
+
if (this.mGLElementDataBufferWasSetup) {
|
724 |
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
725 |
+
}
|
726 |
+
},
|
727 |
+
|
728 |
+
enableDataBufferWithShader: function(shader) {
|
729 |
+
// Vertex Array Object is an expension in WebGL and currently not implemented in Safari
|
730 |
+
if (!shader.isActive) {
|
731 |
+
shader.activate();
|
732 |
+
}
|
733 |
+
|
734 |
+
for (var i = 0, length = this.mArrayBuffers.length; i < length; i++) {
|
735 |
+
var buffer = this.mArrayBuffers[i];
|
736 |
+
buffer.enableVertexAttributeArrayBuffersWithShader(shader);
|
737 |
+
}
|
738 |
+
|
739 |
+
this.enableElementArrayBuffer();
|
740 |
+
|
741 |
+
this._enabledShader = shader;
|
742 |
+
this._isEnabled = true;
|
743 |
+
},
|
744 |
+
|
745 |
+
disableDataBufferWithShader: function(shader) {
|
746 |
+
if (!this._isEnabled) {
|
747 |
+
return;
|
748 |
+
}
|
749 |
+
|
750 |
+
this.disableElementArrayBuffer();
|
751 |
+
|
752 |
+
for (var i = 0, length = this.mArrayBuffers.length; i < length; i++) {
|
753 |
+
var buffer = this.mArrayBuffers[i];
|
754 |
+
buffer.disableVertexAttributeArrayBuffersWithShader(shader);
|
755 |
+
}
|
756 |
+
|
757 |
+
this._enabledShader = null;
|
758 |
+
this._isEnabled = false;
|
759 |
+
|
760 |
+
},
|
761 |
+
|
762 |
+
drawWithShader: function(shader, shouldDeactivateShader) {
|
763 |
+
var gl = this.gl;
|
764 |
+
var range = {
|
765 |
+
location: 0,
|
766 |
+
length: this.mElementArrayCount > 0 ? this.mElementArrayCount : this._vertexCount
|
767 |
+
};
|
768 |
+
|
769 |
+
this.enableDataBufferWithShader(shader);
|
770 |
+
|
771 |
+
if (this.mGLElementDataBufferWasSetup && this.mElementArrayCount > 0) {
|
772 |
+
// we need to send element data to element array buffer, e.g. [0, 2, 1, 3]
|
773 |
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.mGLElementData, gl.STATIC_DRAW);
|
774 |
+
|
775 |
+
if (!CGSizeEqualToSize(this.mGLElementMeshSize, CGSizeZero)) {
|
776 |
+
// Draw mesh by rows
|
777 |
+
var width = this.mGLElementMeshSize.width;
|
778 |
+
|
779 |
+
for (var y = 0; y < this.mGLElementMeshSize.height - 1; ++y) {
|
780 |
+
// location is vertex location, so need to multiply by two to get index location
|
781 |
+
gl.drawElements(this.drawMode, width * 2, gl.UNSIGNED_SHORT, 2 * y * width * 2);
|
782 |
+
}
|
783 |
+
} else {
|
784 |
+
// just draw everything
|
785 |
+
gl.drawElements(this.drawMode, range.length, gl.UNSIGNED_SHORT, 2 * range.location);
|
786 |
+
}
|
787 |
+
} else {
|
788 |
+
// No element data; just pass vertices straight down
|
789 |
+
gl.drawArrays(this.drawMode, range.location, range.length);
|
790 |
+
}
|
791 |
+
|
792 |
+
this.disableDataBufferWithShader(shader);
|
793 |
+
|
794 |
+
// Swap buffers
|
795 |
+
if (this.isDoubleBuffered) {
|
796 |
+
this.mCurrentBufferIndex = (this.mCurrentBufferIndex + 1) % 2;
|
797 |
+
|
798 |
+
for (var i = 0, length = this.mArrayBuffers.length; i < length; i++) {
|
799 |
+
var buffer = this.mArrayBuffers[i];
|
800 |
+
|
801 |
+
if (buffer.bufferCount != 1) {
|
802 |
+
buffer.currentBufferIndex = this.mCurrentBufferIndex;
|
803 |
+
}
|
804 |
+
}
|
805 |
+
}
|
806 |
+
|
807 |
+
if (shouldDeactivateShader) {
|
808 |
+
shader.deactivate();
|
809 |
+
}
|
810 |
+
},
|
811 |
+
|
812 |
+
vertexAttributeNamed: function(attributeName) {
|
813 |
+
for (var attrib in this._vertexAttributes) {
|
814 |
+
var attribute = this._vertexAttributes[attrib];
|
815 |
+
|
816 |
+
if (attribute.name === attributeName) {
|
817 |
+
return attribute;
|
818 |
+
}
|
819 |
+
}
|
820 |
+
|
821 |
+
return null;
|
822 |
+
}
|
823 |
+
});
|
assets/player/gl/TSDGLFrameBuffer.js
CHANGED
@@ -1,3 +1,116 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* TSDGLFrameBuffer.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
var TSDGLFrameBuffer = Class.create({
|
10 |
+
initialize: function(gl, size, textureCount) {
|
11 |
+
this.gl = gl;
|
12 |
+
|
13 |
+
// framebuffer size
|
14 |
+
this.size = size;
|
15 |
+
|
16 |
+
// number of framebuffer-attachable texture images
|
17 |
+
this.textureCount = textureCount;
|
18 |
+
|
19 |
+
// current texture index
|
20 |
+
this.currentTextureIndex = 0;
|
21 |
+
|
22 |
+
// create framebuffer-attachable texture images
|
23 |
+
this.setupFramebuffer(gl, size, textureCount);
|
24 |
+
},
|
25 |
+
|
26 |
+
setupFramebuffer: function(gl, size, textureCount) {
|
27 |
+
// create and bind frame buffer object
|
28 |
+
var buffer = this.buffer = gl.createFramebuffer();
|
29 |
+
|
30 |
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffer);
|
31 |
+
|
32 |
+
var textures = this.textures = [];
|
33 |
+
|
34 |
+
// set up framebuffer texture(s)
|
35 |
+
for (var i = 0; i < textureCount; i++) {
|
36 |
+
var texture = gl.createTexture();
|
37 |
+
|
38 |
+
// bind texture
|
39 |
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
40 |
+
|
41 |
+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
42 |
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
43 |
+
|
44 |
+
// setup texture parameters
|
45 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
46 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
47 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
48 |
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
49 |
+
|
50 |
+
// specify the texture size for memory allocation
|
51 |
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size.width, size.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
52 |
+
|
53 |
+
// unbind texture
|
54 |
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
55 |
+
|
56 |
+
textures.push(texture);
|
57 |
+
}
|
58 |
+
|
59 |
+
// bind current texture to the framebuffer
|
60 |
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textures[this.currentTextureIndex], 0);
|
61 |
+
|
62 |
+
// unbind framebuffer
|
63 |
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
64 |
+
},
|
65 |
+
|
66 |
+
currentGLTexture: function() {
|
67 |
+
var texture = this.textures[this.currentTextureIndex];
|
68 |
+
|
69 |
+
return texture;
|
70 |
+
},
|
71 |
+
|
72 |
+
setCurrentTextureToNext: function() {
|
73 |
+
var textureCount = this.textureCount;
|
74 |
+
|
75 |
+
if (this.textureCount > 0) {
|
76 |
+
var currentTextureIndex = this.currentTextureIndex;
|
77 |
+
var nextTextureIndex = (currentTextureIndex + 1) % textureCount;
|
78 |
+
|
79 |
+
this.currentTextureIndex = nextTextureIndex;
|
80 |
+
|
81 |
+
// bind the framebuffer to the next texture
|
82 |
+
this.bindFramebuffer();
|
83 |
+
}
|
84 |
+
},
|
85 |
+
|
86 |
+
bindFramebuffer: function() {
|
87 |
+
var gl = this.gl;
|
88 |
+
|
89 |
+
//bind framebuffer
|
90 |
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this.buffer);
|
91 |
+
|
92 |
+
// bind current texture
|
93 |
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.textures[this.currentTextureIndex], 0);
|
94 |
+
},
|
95 |
+
|
96 |
+
currentGLFramebuffer: function() {
|
97 |
+
var gl = this.gl;
|
98 |
+
var framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
99 |
+
|
100 |
+
return framebuffer;
|
101 |
+
},
|
102 |
+
|
103 |
+
unbindFramebufferAndBindGLFramebuffer: function(currentGLFramebuffer) {
|
104 |
+
var gl = this.gl;
|
105 |
+
gl.bindFramebuffer(gl.FRAMEBUFFER, currentGLFramebuffer);
|
106 |
+
}
|
107 |
+
|
108 |
+
});
|
109 |
+
|
110 |
+
TSDGLFrameBuffer.currentGLFramebuffer = function(gl) {
|
111 |
+
// use getParameter in WebGL as there is no getIntegerv implementation
|
112 |
+
var framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
|
113 |
+
|
114 |
+
// this will return null if drawing buffer is the display default
|
115 |
+
return framebuffer;
|
116 |
+
};
|
assets/player/gl/TSDGLShader.js
CHANGED
@@ -1,3 +1,520 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* TSDGLShader.js
|
3 |
+
* Keynote HTML Player
|
4 |
+
*
|
5 |
+
* Created by Tungwei Cheng
|
6 |
+
* Copyright (c) 2018 Apple Inc. All rights reserved.
|
7 |
+
*/
|
8 |
+
|
9 |
+
// Uniforms
|
10 |
+
var kTSDGLShaderUniformColor = "Color";
|
11 |
+
var kTSDGLShaderUniformDuration = "Duration";
|
12 |
+
var kTSDGLShaderUniformMotionBlurVector = "MotionBlurVector";
|
13 |
+
var kTSDGLShaderUniformMVPMatrix = "MVPMatrix";
|
14 |
+
var kTSDGLShaderUniformOpacity = "Opacity";
|
15 |
+
var kTSDGLShaderUniformParticleTexture = "ParticleTexture";
|
16 |
+
var kTSDGLShaderUniformPercent = "Percent";
|
17 |
+
var kTSDGLShaderUniformPreviousMVPMatrix = "PreviousMVPMatrix";
|
18 |
+
var kTSDGLShaderUniformTexture = "Texture";
|
19 |
+
var kTSDGLShaderUniformTextureMatrix = "TextureMatrix";
|
20 |
+
var kTSDGLShaderUniformTextureSize = "TextureSize";
|
21 |
+
var kTSDGLShaderUniformTexture2 = "Texture2";
|
22 |
+
var kTSDGLShaderUniformTexture2Matrix = "Texture2Matrix";
|
23 |
+
var kTSDGLShaderUniformTexture2Size = "Texture2Size";
|
24 |
+
var kTSDGLShaderUniformVelocityScale = "VelocityScale";
|
25 |
+
var kTSDGLShaderUniformVelocityTexture = "VelocityTexture";
|
26 |
+
|
27 |
+
// Attributes
|
28 |
+
var kTSDGLShaderAttributeCenter = "Center"; // center point of this particle
|
29 |
+
var kTSDGLShaderAttributeColor = "Color";
|
30 |
+
var kTSDGLShaderAttributeLifeSpan = "LifeSpan";
|
31 |
+
var kTSDGLShaderAttributeNormal = "Normal";
|
32 |
+
var kTSDGLShaderAttributeParticleTexCoord = "ParticleTexCoord";
|
33 |
+
var kTSDGLShaderAttributePosition = "Position";
|
34 |
+
var kTSDGLShaderAttributePreviousPosition = "PreviousPosition";
|
35 |
+
var kTSDGLShaderAttributeRotation = "Rotation";
|
36 |
+
var kTSDGLShaderAttributeScale = "Scale";
|
37 |
+
var kTSDGLShaderAttributeSpeed = "Speed";
|
38 |
+
var kTSDGLShaderAttributeTexCoord = "TexCoord";
|
39 |
+
var kTSDGLShaderUniformRotationMax = "RotationMax";
|
40 |
+
var kTSDGLShaderUniformSpeedMax = "SpeedMax";
|
41 |
+
|
42 |
+
var TSDGLShaderQualifierType = {
|
43 |
+
Unknown: 0, ///< ERROR
|
44 |
+
Int: 1, // < GLSL type "int"
|
45 |
+
Float: 2, // < GLSL type "float"
|
46 |
+
Vec2: 3, // < GLSL type "vec2"
|
47 |
+
Vec3: 4, // < GLSL type "vec3"
|
48 |
+
Vec4: 5, // < GLSL type "vec4"
|
49 |
+
Mat3: 6, // < GLSL type "mat3"
|
50 |
+
Mat4: 7 // < GLSL type "mat4"
|
51 |
+
};
|
52 |
+
|
53 |
+
function TSDGLShaderQualifierTypeFromGLenum(type) {
|
54 |
+
var result = TSDGLShaderQualifierType.Unknown;
|
55 |
+
|
56 |
+
switch (type) {
|
57 |
+
case GL_FLOAT:
|
58 |
+
result = TSDGLShaderQualifierType.Float;
|
59 |
+
break;
|
60 |
+
case GL_FLOAT_VEC2:
|
61 |
+
result = TSDGLShaderQualifierType.Vec2;
|
62 |
+
break;
|
63 |
+
case GL_FLOAT_VEC3:
|
64 |
+
result = TSDGLShaderQualifierType.Vec3;
|
65 |
+
break;
|
66 |
+
case GL_FLOAT_VEC4:
|
67 |
+
result = TSDGLShaderQualifierType.Vec4;
|
68 |
+
break;
|
69 |
+
case GL_BOOL:
|
70 |
+
case GL_SAMPLER_2D:
|
71 |
+
case GL_INT:
|
72 |
+
result = TSDGLShaderQualifierType.Int;
|
73 |
+
break;
|
74 |
+
case GL_FLOAT_MAT3:
|
75 |
+
result = TSDGLShaderQualifierType.Mat3;
|
76 |
+
break;
|
77 |
+
case GL_FLOAT_MAT4:
|
78 |
+
result = TSDGLShaderQualifierType.Mat4;
|
79 |
+
break;
|
80 |
+
|
81 |
+
case GL_INT_VEC2:
|
82 |
+
case GL_INT_VEC3:
|
83 |
+
case GL_INT_VEC4:
|
84 |
+
case GL_BOOL_VEC2:
|
85 |
+
case GL_BOOL_VEC3:
|
86 |
+
case GL_BOOL_VEC4:
|
87 |
+
case GL_FLOAT_MAT2:
|
88 |
+
case GL_SAMPLER_CUBE:
|
89 |
+
default:
|
90 |
+
console.log("Unimplemented GLenum type " + type);
|
91 |
+
break;
|
92 |
+
}
|
93 |
+
|
94 |
+
return result;
|
95 |
+
}
|
96 |
+
|
97 |
+
var TSDGLShader = Class.create({
|
98 |
+
initialize: function(gl) {
|
99 |
+
this.gl = gl;
|
100 |
+
|
101 |
+
this._uniforms = {};
|
102 |
+
this.name = "";
|
103 |
+
this.programObject = null;
|
104 |
+
this.isActive = false;
|
105 |
+
|
106 |
+
this._uniformsNeedingUpdate = [];
|
107 |
+
},
|
108 |
+
|
109 |
+
initWithDefaultTextureShader: function() {
|
110 |
+
this.initWithShaderFileNames("defaultTexture", "defaultTexture");
|
111 |
+
this.setGLint(0, kTSDGLShaderUniformTexture);
|
112 |
+
},
|
113 |
+
|
114 |
+
initWithDefaultTextureAndOpacityShader: function() {
|
115 |
+
this.initWithShaderFileNames("defaultTexture", "defaultTextureAndOpacity");
|
116 |
+
},
|
117 |
+
|
118 |
+
initWithDefaultHorizontalBlurShader: function() {
|
119 |
+
this.initWithShaderFileNames("horizontalGaussianBlur", "horizontalGaussianBlur");
|
120 |
+
this.setGLint(0, kTSDGLShaderUniformTexture);
|
121 |
+
},
|
122 |
+
|
123 |
+
initWithDefaultVerticalBlurShader: function() {
|
124 |
+
this.initWithShaderFileNames("verticalGaussianBlur", "verticalGaussianBlur");
|
125 |
+
this.setGLint(0, kTSDGLShaderUniformTexture);
|
126 |
+
},
|
127 |
+
|
128 |
+
initWithContentsShader: function() {
|
129 |
+
this.initWithShaderFileNames("contents", "contents");
|
130 |
+
},
|
131 |
+
|
132 |
+
initWithShaderFileNames: function(vertexShaderFileName, fragmentShaderFileName) {
|
133 |
+
var vertexString = KNWebGLShader[vertexShaderFileName].vertex;
|
134 |
+
var fragmentString = KNWebGLShader[fragmentShaderFileName].fragment;
|
135 |
+
|
136 |
+
this.initWithShaders(vertexString, fragmentString);
|
137 |
+
},
|
138 |
+
|
139 |
+
initWithShaders: function(vertexString, fragmentString) {
|
140 |
+
var gl = this.gl;
|
141 |
+
|
142 |
+
var vertexShader = KNWebGLUtil.loadShader(gl, gl.VERTEX_SHADER, vertexString);
|
143 |
+
var fragmentShader = KNWebGLUtil.loadShader(gl, gl.FRAGMENT_SHADER, fragmentString);
|
144 |
+
|
145 |
+
this.programObject = KNWebGLUtil.createShaderProgram(gl, vertexShader, fragmentShader);
|
146 |
+
|
147 |
+
this.p_updateUniformsAndAttributesFromShader();
|
148 |
+
},
|
149 |
+
|
150 |
+
p_updateUniformsAndAttributesFromShader: function() {
|
151 |
+
var gl = this.gl;
|
152 |
+
var programObject = this.programObject;
|
153 |
+
var uniformsCount = -1;
|
154 |
+
|
155 |
+
uniformsCount = gl.getProgramParameter(programObject, gl.ACTIVE_UNIFORMS);
|
156 |
+
|
157 |
+
for (var i = 0; i < uniformsCount; i++) {
|
158 |
+
var activeInfo = gl.getActiveUniform(programObject, i);
|
159 |
+
var name = activeInfo.name;
|
160 |
+
var type = activeInfo.type;
|
161 |
+
var size = activeInfo.size;
|
162 |
+
|
163 |
+
// Add uniform to cache
|
164 |
+
var qualifierType = TSDGLShaderQualifierTypeFromGLenum(type);
|
165 |
+
this.shaderQualifierForUniform(name, qualifierType);
|
166 |
+
}
|
167 |
+
|
168 |
+
// Update attributes
|
169 |
+
var attributesCount = -1;
|
170 |
+
|
171 |
+
attributesCount = gl.getProgramParameter(programObject, gl.ACTIVE_ATTRIBUTES);
|
172 |
+
|
173 |
+
for (var i = 0; i < attributesCount; i++) {
|
174 |
+
var activeInfo = gl.getActiveAttrib(programObject, i);
|
175 |
+
var name = activeInfo.name;
|
176 |
+
var type = activeInfo.type;
|
177 |
+
var size = activeInfo.size;
|
178 |
+
|
179 |
+
// Add attribute location to cache
|
180 |
+
this.locationForAttribute(name);
|
181 |
+
}
|
182 |
+
},
|
183 |
+
|
184 |
+
shaderQualifierForUniform: function(uniform, qualifierType) {
|
185 |
+
var gl = this.gl;
|
186 |
+
var qualifier = this._uniforms[uniform];
|
187 |
+
|
188 |
+
if (!qualifier) {
|
189 |
+
switch (qualifierType) {
|
190 |
+
case TSDGLShaderQualifierType.Unknown:
|
191 |
+
console.log("Unknown Shader Qualifier Type!");
|
192 |
+
break;
|
193 |
+
case TSDGLShaderQualifierType.Int:
|
194 |
+
qualifier = new TSDGLShaderQualifierInt(gl, uniform);
|
195 |
+
break;
|
196 |
+
case TSDGLShaderQualifierType.Float:
|
197 |
+
qualifier = new TSDGLShaderQualifierFloat(gl, uniform);
|
198 |
+
break;
|
199 |
+
case TSDGLShaderQualifierType.Vec2:
|
200 |
+
qualifier = new TSDGLShaderQualifierPoint2D(gl, uniform);
|
201 |
+
break;
|
202 |
+
case TSDGLShaderQualifierType.Vec3:
|
203 |
+
qualifier = new TSDGLShaderQualifierPoint3D(gl, uniform);
|
204 |
+
break;
|
205 |
+
case TSDGLShaderQualifierType.Vec4:
|
206 |
+
qualifier = new TSDGLShaderQualifierPoint4D(gl, uniform);
|
207 |
+
break;
|
208 |
+
case TSDGLShaderQualifierType.Mat3:
|
209 |
+
qualifier = new TSDGLShaderQualifierMat3(gl, uniform);
|
210 |
+
break;
|
211 |
+
case TSDGLShaderQualifierType.Mat4:
|
212 |
+
qualifier = new TSDGLShaderQualifierMat4(gl, uniform);
|
213 |
+
break;
|
214 |
+
}
|
215 |
+
|
216 |
+
qualifier.updateUniformLocationWithShaderProgramObject(this.programObject);
|
217 |
+
this._uniforms[uniform] = qualifier;
|
218 |
+
}
|
219 |
+
|
220 |
+
return qualifier;
|
221 |
+
},
|
222 |
+
|
223 |
+
setGLint: function(newInt, uniform) {
|
224 |
+
var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Int);
|
225 |
+
|
226 |
+
qualifier.setProposedGLintValue(newInt);
|
227 |
+
|
228 |
+
if (qualifier._needsUpdate) {
|
229 |
+
this._uniformsNeedingUpdate.push(qualifier);
|
230 |
+
}
|
231 |
+
|
232 |
+
this.p_setQualifiersIfNecessary();
|
233 |
+
},
|
234 |
+
|
235 |
+
setGLFloat: function(newFloat, uniform) {
|
236 |
+
var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Float);
|
237 |
+
|
238 |
+
qualifier.setProposedGLfloatValue(newFloat);
|
239 |
+
|
240 |
+
if (qualifier._needsUpdate) {
|
241 |
+
this._uniformsNeedingUpdate.push(qualifier);
|
242 |
+
}
|
243 |
+
|
244 |
+
this.p_setQualifiersIfNecessary();
|
245 |
+
},
|
246 |
+
|
247 |
+
setPoint2D: function(newPoint2D, uniform) {
|
248 |
+
var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Vec2);
|
249 |
+
|
250 |
+
qualifier.setProposedGLPoint2DValue(newPoint2D);
|
251 |
+
|
252 |
+
if (qualifier._needsUpdate) {
|
253 |
+
this._uniformsNeedingUpdate.push(qualifier);
|
254 |
+
}
|
255 |
+
|
256 |
+
this.p_setQualifiersIfNecessary();
|
257 |
+
},
|
258 |
+
|
259 |
+
setMat4WithTransform3D: function(aTransform3D, uniform) {
|
260 |
+
var qualifier = this.shaderQualifierForUniform(uniform, TSDGLShaderQualifierType.Mat4);
|
261 |
+
|
262 |
+
qualifier.setProposedTransform3D(aTransform3D);
|
263 |
+
|
264 |
+
if (qualifier._needsUpdate) {
|
265 |
+
this._uniformsNeedingUpdate.push(qualifier);
|
266 |
+
}
|
267 |
+
|
268 |
+
this.p_setQualifiersIfNecessary();
|
269 |
+
},
|
270 |
+
|
271 |
+
locationForUniform: function(uniform) {
|
272 |
+
var location;
|
273 |
+
var shaderQualifier = this._uniforms[uniform];
|
274 |
+
|
275 |
+
if (shaderQualifier) {
|
276 |
+
location = shaderQualifier._uniformLocation;
|
277 |
+
}
|
278 |
+
|
279 |
+
if (!location) {
|
280 |
+
location = this.gl.getUniformLocation(this.programObject, uniform);
|
281 |
+
}
|
282 |
+
|
283 |
+
return location;
|
284 |
+
},
|
285 |
+
|
286 |
+
locationForAttribute: function(attribute) {
|
287 |
+
if (!this._attributeLocations) {
|
288 |
+
this._attributeLocations = {};
|
289 |
+
}
|
290 |
+
|
291 |
+
var location = this._attributeLocations[attribute];
|
292 |
+
|
293 |
+
if (location === undefined) {
|
294 |
+
location = -1;
|
295 |
+
}
|
296 |
+
|
297 |
+
if (location < 0) {
|
298 |
+
location = this.gl.getAttribLocation(this.programObject, attribute);
|
299 |
+
this._attributeLocations[attribute] = location;
|
300 |
+
}
|
301 |
+
|
302 |
+
return location;
|
303 |
+
},
|
304 |
+
|
305 |
+
p_setQualifiersIfNecessary: function() {
|
306 |
+
if (!this.isActive) {
|
307 |
+
return;
|
308 |
+
}
|
309 |
+
if (this._uniformsNeedingUpdate.length === 0) {
|
310 |
+
return;
|
311 |
+
}
|
312 |
+
|
313 |
+
// Look through all the newly-set qualifiers
|
314 |
+
for (var i = 0, length = this._uniformsNeedingUpdate.length; i < length; i++) {
|
315 |
+
var proposedQualifier = this._uniformsNeedingUpdate[i];
|
316 |
+
|
317 |
+
if (proposedQualifier._uniformLocation === -1) {
|
318 |
+
proposedQualifier.updateUniformLocationWithShaderProgramObject(this.programObject);
|
319 |
+
}
|
320 |
+
|
321 |
+
proposedQualifier.setGLUniformWithShader(this.gl, this);
|
322 |
+
}
|
323 |
+
|
324 |
+
this._uniformsNeedingUpdate = [];
|
325 |
+
},
|
326 |
+
|
327 |
+
activate: function() {
|
328 |
+
var gl = this.gl;
|
329 |
+
|
330 |
+
if (!this.isActive) {
|
331 |
+
gl.useProgram(this.programObject);
|
332 |
+
this.isActive = true;
|
333 |
+
}
|
334 |
+
|
335 |
+
this.p_setQualifiersIfNecessary();
|
336 |
+
},
|
337 |
+
|
338 |
+
deactivate: function() {
|
339 |
+
if (this.isActive) {
|
340 |
+
//gl.useProgram(0);
|
341 |
+
this.isActive = false;
|
342 |
+
}
|
343 |
+
}
|
344 |
+
|
345 |
+
});
|
346 |
+
|
347 |
+
var TSDGLShaderQualifier = Class.create({
|
348 |
+
initialize: function(gl, qualifierName) {
|
349 |
+
this.gl = gl;
|
350 |
+
this._uniformLocation = -1;
|
351 |
+
this._needsUpdate = true;
|
352 |
+
this._name = qualifierName;
|
353 |
+
},
|
354 |
+
|
355 |
+
updateUniformLocationWithShaderProgramObject: function(shaderProgramObject) {
|
356 |
+
if (this._uniformLocation === -1) {
|
357 |
+
this._uniformLocation = this.gl.getUniformLocation(shaderProgramObject, this._name);
|
358 |
+
}
|
359 |
+
}
|
360 |
+
});
|
361 |
+
|
362 |
+
var TSDGLShaderQualifierInt = Class.create(TSDGLShaderQualifier, {
|
363 |
+
initialize: function($super, gl, qualifierName) {
|
364 |
+
this._GLintValue = 0;
|
365 |
+
this._proposedGLintValue = 0;
|
366 |
+
|
367 |
+
$super(gl, qualifierName);
|
368 |
+
},
|
369 |
+
|
370 |
+
setProposedGLintValue: function(proposedGLintValue) {
|
371 |
+
if (this._proposedGLintValue !== proposedGLintValue) {
|
372 |
+
this._proposedGLintValue = proposedGLintValue;
|
373 |
+
this._needsUpdate = true;
|
374 |
+
}
|
375 |
+
},
|
376 |
+
|
377 |
+
setGLUniformWithShader: function(gl, shader) {
|
378 |
+
gl.uniform1i(this._uniformLocation, this._proposedGLintValue);
|
379 |
+
this._GLintValue = this._proposedGLintValue;
|
380 |
+
this._needsUpdate = false;
|
381 |
+
}
|
382 |
+
});
|
383 |
+
|
384 |
+
var TSDGLShaderQualifierFloat = Class.create(TSDGLShaderQualifier, {
|
385 |
+
initialize: function($super, gl, qualifierName) {
|
386 |
+
this._GLfloatValue = 0;
|
387 |
+
this._proposedGLfloatValue = 0;
|
388 |
+
|
389 |
+
$super(gl, qualifierName);
|
390 |
+
},
|
391 |
+
|
392 |
+
setProposedGLfloatValue: function(proposedGLfloatValue) {
|
393 |
+
if (this._proposedGLfloatValue !== proposedGLfloatValue) {
|
394 |
+
this._proposedGLfloatValue = proposedGLfloatValue;
|
395 |
+
this._needsUpdate = true;
|
396 |
+
}
|
397 |
+
},
|
398 |
+
|
399 |
+
setGLUniformWithShader: function(gl, shader) {
|
400 |
+
gl.uniform1f(this._uniformLocation, this._proposedGLfloatValue);
|
401 |
+
this._GLfloatValue = this._proposedGLfloatValue;
|
402 |
+
this._needsUpdate = false;
|
403 |
+
}
|
404 |
+
});
|
405 |
+
|
406 |
+
var TSDGLShaderQualifierPoint2D = Class.create(TSDGLShaderQualifier, {
|
407 |
+
initialize: function($super, gl, qualifierName) {
|
408 |
+
this._GLPoint2DValue = {};
|
409 |
+
this._proposedGLPoint2DValue = {};
|
410 |
+
|
411 |
+
$super(gl, qualifierName);
|
412 |
+
},
|
413 |
+
|
414 |
+
setProposedGLPoint2DValue: function(proposedGLPoint2DValue) {
|
415 |
+
if (!(this._proposedGLPoint2DValue.x === proposedGLPoint2DValue.x && this._proposedGLPoint2DValue.y === proposedGLPoint2DValue.y)) {
|
416 |
+
this._proposedGLPoint2DValue = proposedGLPoint2DValue;
|
417 |
+
this._needsUpdate = true;
|
418 |
+
}
|
419 |
+
},
|
420 |
+
|
421 |
+
setGLUniformWithShader: function(gl, shader) {
|
422 |
+
gl.uniform2fv(this._uniformLocation, [this._proposedGLPoint2DValue.x, this._proposedGLPoint2DValue.y]);
|
423 |
+
this._GLPoint2DValue = this._proposedGLPoint2DValue;
|
424 |
+
this._needsUpdate = false;
|
425 |
+
}
|
426 |
+
});
|
427 |
+
|
428 |
+
var TSDGLShaderQualifierPoint3D = Class.create(TSDGLShaderQualifier, {
|
429 |
+
initialize: function($super, gl, qualifierName) {
|
430 |
+
this._GLPoint3DValue = {};
|
431 |
+
this._proposedGLPoint3DValue = {};
|
432 |
+
|
433 |
+
$super(gl, qualifierName);
|
434 |
+
},
|
435 |
+
|
436 |
+
setProposedGLPoint3DValue: function(proposedGLPoint3DValue) {
|
437 |
+
if (!(this._proposedGLPoint3DValue.x === proposedGLPoint3DValue.x && this._proposedGLPoint3DValue.y === proposedGLPoint3DValue.y && this._proposedGLPoint3DValue.z === proposedGLPoint3DValue.z)) {
|
438 |
+
this._proposedGLPoint3DValue = proposedGLPoint3DValue;
|
439 |
+
this._needsUpdate = true;
|
440 |
+
}
|
441 |
+
},
|
442 |
+
|
443 |
+
setGLUniformWithShader: function(gl, shader) {
|
444 |
+
gl.uniform3fv(this._uniformLocation, [this._proposedGLPoint3DValue.x, this._proposedGLPoint3DValue.y, this._proposedGLPoint3DValue.z]);
|
445 |
+
this._GLPoint3DValue = this._proposedGLPoint3DValue;
|
446 |
+
this._needsUpdate = false;
|
447 |
+
}
|
448 |
+
});
|
449 |
+
|
450 |
+
var TSDGLShaderQualifierPoint4D = Class.create(TSDGLShaderQualifier, {
|
451 |
+
initialize: function($super, gl, qualifierName) {
|
452 |
+
this._GLPoint4DValue = {};
|
453 |
+
this._proposedGLPoint4DValue = {};
|
454 |
+
|
455 |
+
$super(gl, qualifierName);
|
456 |
+
},
|
457 |
+
|
458 |
+
setProposedGLPoint4DValue: function(proposedGLPoint4DValue) {
|
459 |
+
if (!(this._proposedGLPoint4DValue.x === proposedGLPoint4DValue.x && this._proposedGLPoint4DValue.y === proposedGLPoint4DValue.y && this._proposedGLPoint4DValue.z === proposedGLPoint4DValue.z && this._proposedGLPoint4DValue.w === proposedGLPoint4DValue.w)) {
|
460 |
+
this._proposedGLPoint4DValue = proposedGLPoint4DValue;
|
461 |
+
this._needsUpdate = true;
|
462 |
+
}
|
463 |
+
},
|
464 |
+
|
465 |
+
setGLUniformWithShader: function(gl, shader) {
|
466 |
+
gl.uniform4fv(this._uniformLocation, [this._proposedGLPoint4DValue.x, this._proposedGLPoint4DValue.y, this._proposedGLPoint4DValue.z, this._proposedGLPoint4DValue.w]);
|
467 |
+
this._GLPoint4DValue = this._proposedGLPoint4DValue;
|
468 |
+
this._needsUpdate = false;
|
469 |
+
}
|
470 |
+
});
|
471 |
+
|
472 |
+
var TSDGLShaderQualifierMat3 = Class.create(TSDGLShaderQualifier, {
|
473 |
+
initialize: function($super, gl, qualifierName) {
|
474 |
+
this._affineTransform = new Float32Array(9) ;
|
475 |
+
this._proposedAffineTransform = new Float32Array(9);
|
476 |
+
|
477 |
+
$super(gl, qualifierName);
|
478 |
+
},
|
479 |
+
|
480 |
+
setProposedAffineTransform: function(proposedAffineTransform) {
|
481 |
+
if (!CGAffineTransformEqualToTransform(this._proposedAffineTransform, proposedAffineTransform)) {
|
482 |
+
this._proposedAffineTransform = proposedAffineTransform;
|
483 |
+
this._needsUpdate = true;
|
484 |
+
}
|
485 |
+
},
|
486 |
+
|
487 |
+
setGLUniformWithShader: function(gl, shader) {
|
488 |
+
var mat = [
|
489 |
+
this._proposedAffineTransform.a, this._proposedAffineTransform.b, 0,
|
490 |
+
this._proposedAffineTransform.c, this._proposedAffineTransform.d, 0,
|
491 |
+
this._proposedAffineTransform.tx, this._proposedAffineTransform.ty, 1
|
492 |
+
];
|
493 |
+
|
494 |
+
gl.uniformMatrix3fv(this._uniformLocation, false, mat);
|
495 |
+
this._affineTransform = this._proposedAffineTransform;
|
496 |
+
this._needsUpdate = false;
|
497 |
+
}
|
498 |
+
});
|
499 |
+
|
500 |
+
var TSDGLShaderQualifierMat4 = Class.create(TSDGLShaderQualifier, {
|
501 |
+
initialize: function($super, gl, qualifierName) {
|
502 |
+
this._transform3D = new Float32Array(16);
|
503 |
+
this._proposedTransform3D = new Float32Array(16);
|
504 |
+
|
505 |
+
$super(gl, qualifierName);
|
506 |
+
},
|
507 |
+
|
508 |
+
setProposedTransform3D: function(proposedTransform3D) {
|
509 |
+
if (!CATransform3DEqualToTransform(this._proposedTransform3D, proposedTransform3D)) {
|
510 |
+
this._proposedTransform3D = proposedTransform3D;
|
511 |
+
this._needsUpdate = true;
|
512 |
+
}
|
513 |
+
},
|
514 |
+
|
515 |
+
setGLUniformWithShader: function(gl, shader) {
|
516 |
+
gl.uniformMatrix4fv(this._uniformLocation, false, this._proposedTransform3D);
|
517 |
+
this._transform3D = this._proposedTransform3D;
|
518 |
+
this._needsUpdate = false;
|
519 |
+
}
|
520 |
+
});
|
assets/player/pdfjs/bcmaps.js
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
assets/player/pdfjs/pdf.js
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
assets/player/pdfjs/pdf_worker.js
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
assets/player/pdfjs/web/compatibility.js
CHANGED
@@ -1,3 +1,593 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/* Copyright 2012 Mozilla Foundation
|
2 |
+
*
|
3 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
4 |
+
* you may not use this file except in compliance with the License.
|
5 |
+
* You may obtain a copy of the License at
|
6 |
+
*
|
7 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
8 |
+
*
|
9 |
+
* Unless required by applicable law or agreed to in writing, software
|
10 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
11 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12 |
+
* See the License for the specific language governing permissions and
|
13 |
+
* limitations under the License.
|
14 |
+
*/
|
15 |
+
/* globals VBArray, PDFJS */
|
16 |
+
|
17 |
+
'use strict';
|
18 |
+
|
19 |
+
// Initializing PDFJS global object here, it case if we need to change/disable
|
20 |
+
// some PDF.js features, e.g. range requests
|
21 |
+
if (typeof PDFJS === 'undefined') {
|
22 |
+
(typeof window !== 'undefined' ? window : this).PDFJS = {};
|
23 |
+
}
|
24 |
+
|
25 |
+
// Checking if the typed arrays are supported
|
26 |
+
// Support: iOS<6.0 (subarray), IE<10, Android<4.0
|
27 |
+
(function checkTypedArrayCompatibility() {
|
28 |
+
if (typeof Uint8Array !== 'undefined') {
|
29 |
+
// Support: iOS<6.0
|
30 |
+
if (typeof Uint8Array.prototype.subarray === 'undefined') {
|
31 |
+
Uint8Array.prototype.subarray = function subarray(start, end) {
|
32 |
+
return new Uint8Array(this.slice(start, end));
|
33 |
+
};
|
34 |
+
Float32Array.prototype.subarray = function subarray(start, end) {
|
35 |
+
return new Float32Array(this.slice(start, end));
|
36 |
+
};
|
37 |
+
}
|
38 |
+
|
39 |
+
// Support: Android<4.1
|
40 |
+
if (typeof Float64Array === 'undefined') {
|
41 |
+
window.Float64Array = Float32Array;
|
42 |
+
}
|
43 |
+
return;
|
44 |
+
}
|
45 |
+
|
46 |
+
function subarray(start, end) {
|
47 |
+
return new TypedArray(this.slice(start, end));
|
48 |
+
}
|
49 |
+
|
50 |
+
function setArrayOffset(array, offset) {
|
51 |
+
if (arguments.length < 2) {
|
52 |
+
offset = 0;
|
53 |
+
}
|
54 |
+
for (var i = 0, n = array.length; i < n; ++i, ++offset) {
|
55 |
+
this[offset] = array[i] & 0xFF;
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
function TypedArray(arg1) {
|
60 |
+
var result, i, n;
|
61 |
+
if (typeof arg1 === 'number') {
|
62 |
+
result = [];
|
63 |
+
for (i = 0; i < arg1; ++i) {
|
64 |
+
result[i] = 0;
|
65 |
+
}
|
66 |
+
} else if ('slice' in arg1) {
|
67 |
+
result = arg1.slice(0);
|
68 |
+
} else {
|
69 |
+
result = [];
|
70 |
+
for (i = 0, n = arg1.length; i < n; ++i) {
|
71 |
+
result[i] = arg1[i];
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
result.subarray = subarray;
|
76 |
+
result.buffer = result;
|
77 |
+
result.byteLength = result.length;
|
78 |
+
result.set = setArrayOffset;
|
79 |
+
|
80 |
+
if (typeof arg1 === 'object' && arg1.buffer) {
|
81 |
+
result.buffer = arg1.buffer;
|
82 |
+
}
|
83 |
+
return result;
|
84 |
+
}
|
85 |
+
|
86 |
+
window.Uint8Array = TypedArray;
|
87 |
+
window.Int8Array = TypedArray;
|
88 |
+
|
89 |
+
// we don't need support for set, byteLength for 32-bit array
|
90 |
+
// so we can use the TypedArray as well
|
91 |
+
window.Uint32Array = TypedArray;
|
92 |
+
window.Int32Array = TypedArray;
|
93 |
+
window.Uint16Array = TypedArray;
|
94 |
+
window.Float32Array = TypedArray;
|
95 |
+
window.Float64Array = TypedArray;
|
96 |
+
})();
|
97 |
+
|
98 |
+
// URL = URL || webkitURL
|
99 |
+
// Support: Safari<7, Android 4.2+
|
100 |
+
(function normalizeURLObject() {
|
101 |
+
if (!window.URL) {
|
102 |
+
window.URL = window.webkitURL;
|
103 |
+
}
|
104 |
+
})();
|
105 |
+
|
106 |
+
// Object.defineProperty()?
|
107 |
+
// Support: Android<4.0, Safari<5.1
|
108 |
+
(function checkObjectDefinePropertyCompatibility() {
|
109 |
+
if (typeof Object.defineProperty !== 'undefined') {
|
110 |
+
var definePropertyPossible = true;
|
111 |
+
try {
|
112 |
+
// some browsers (e.g. safari) cannot use defineProperty() on DOM objects
|
113 |
+
// and thus the native version is not sufficient
|
114 |
+
Object.defineProperty(new Image(), 'id', { value: 'test' });
|
115 |
+
// ... another test for android gb browser for non-DOM objects
|
116 |
+
var Test = function Test() {};
|
117 |
+
Test.prototype = { get id() { } };
|
118 |
+
Object.defineProperty(new Test(), 'id',
|
119 |
+
{ value: '', configurable: true, enumerable: true, writable: false });
|
120 |
+
} catch (e) {
|
121 |
+
definePropertyPossible = false;
|
122 |
+
}
|
123 |
+
if (definePropertyPossible) {
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
Object.defineProperty = function objectDefineProperty(obj, name, def) {
|
129 |
+
delete obj[name];
|
130 |
+
if ('get' in def) {
|
131 |
+
obj.__defineGetter__(name, def['get']);
|
132 |
+
}
|
133 |
+
if ('set' in def) {
|
134 |
+
obj.__defineSetter__(name, def['set']);
|
135 |
+
}
|
136 |
+
if ('value' in def) {
|
137 |
+
obj.__defineSetter__(name, function objectDefinePropertySetter(value) {
|
138 |
+
this.__defineGetter__(name, function objectDefinePropertyGetter() {
|
139 |
+
return value;
|
140 |
+
});
|
141 |
+
return value;
|
142 |
+
});
|
143 |
+
obj[name] = def.value;
|
144 |
+
}
|
145 |
+
};
|
146 |
+
})();
|
147 |
+
|
148 |
+
|
149 |
+
// No XMLHttpRequest#response?
|
150 |
+
// Support: IE<11, Android <4.0
|
151 |
+
(function checkXMLHttpRequestResponseCompatibility() {
|
152 |
+
var xhrPrototype = XMLHttpRequest.prototype;
|
153 |
+
var xhr = new XMLHttpRequest();
|
154 |
+
if (!('overrideMimeType' in xhr)) {
|
155 |
+
// IE10 might have response, but not overrideMimeType
|
156 |
+
// Support: IE10
|
157 |
+
Object.defineProperty(xhrPrototype, 'overrideMimeType', {
|
158 |
+
value: function xmlHttpRequestOverrideMimeType(mimeType) {}
|
159 |
+
});
|
160 |
+
}
|
161 |
+
if ('responseType' in xhr) {
|
162 |
+
return;
|
163 |
+
}
|
164 |
+
|
165 |
+
// The worker will be using XHR, so we can save time and disable worker.
|
166 |
+
PDFJS.disableWorker = true;
|
167 |
+
|
168 |
+
Object.defineProperty(xhrPrototype, 'responseType', {
|
169 |
+
get: function xmlHttpRequestGetResponseType() {
|
170 |
+
return this._responseType || 'text';
|
171 |
+
},
|
172 |
+
set: function xmlHttpRequestSetResponseType(value) {
|
173 |
+
if (value === 'text' || value === 'arraybuffer') {
|
174 |
+
this._responseType = value;
|
175 |
+
if (value === 'arraybuffer' &&
|
176 |
+
typeof this.overrideMimeType === 'function') {
|
177 |
+
this.overrideMimeType('text/plain; charset=x-user-defined');
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
});
|
182 |
+
|
183 |
+
// Support: IE9
|
184 |
+
if (typeof VBArray !== 'undefined') {
|
185 |
+
Object.defineProperty(xhrPrototype, 'response', {
|
186 |
+
get: function xmlHttpRequestResponseGet() {
|
187 |
+
if (this.responseType === 'arraybuffer') {
|
188 |
+
return new Uint8Array(new VBArray(this.responseBody).toArray());
|
189 |
+
} else {
|
190 |
+
return this.responseText;
|
191 |
+
}
|
192 |
+
}
|
193 |
+
});
|
194 |
+
return;
|
195 |
+
}
|
196 |
+
|
197 |
+
Object.defineProperty(xhrPrototype, 'response', {
|
198 |
+
get: function xmlHttpRequestResponseGet() {
|
199 |
+
if (this.responseType !== 'arraybuffer') {
|
200 |
+
return this.responseText;
|
201 |
+
}
|
202 |
+
var text = this.responseText;
|
203 |
+
var i, n = text.length;
|
204 |
+
var result = new Uint8Array(n);
|
205 |
+
for (i = 0; i < n; ++i) {
|
206 |
+
result[i] = text.charCodeAt(i) & 0xFF;
|
207 |
+
}
|
208 |
+
return result.buffer;
|
209 |
+
}
|
210 |
+
});
|
211 |
+
})();
|
212 |
+
|
213 |
+
// window.btoa (base64 encode function) ?
|
214 |
+
// Support: IE<10
|
215 |
+
(function checkWindowBtoaCompatibility() {
|
216 |
+
if ('btoa' in window) {
|
217 |
+
return;
|
218 |
+
}
|
219 |
+
|
220 |
+
var digits =
|
221 |
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
222 |
+
|
223 |
+
window.btoa = function windowBtoa(chars) {
|
224 |
+
var buffer = '';
|
225 |
+
var i, n;
|
226 |
+
for (i = 0, n = chars.length; i < n; i += 3) {
|
227 |
+
var b1 = chars.charCodeAt(i) & 0xFF;
|
228 |
+
var b2 = chars.charCodeAt(i + 1) & 0xFF;
|
229 |
+
var b3 = chars.charCodeAt(i + 2) & 0xFF;
|
230 |
+
var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
|
231 |
+
var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
|
232 |
+
var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
|
233 |
+
buffer += (digits.charAt(d1) + digits.charAt(d2) +
|
234 |
+
digits.charAt(d3) + digits.charAt(d4));
|
235 |
+
}
|
236 |
+
return buffer;
|
237 |
+
};
|
238 |
+
})();
|
239 |
+
|
240 |
+
// window.atob (base64 encode function)?
|
241 |
+
// Support: IE<10
|
242 |
+
(function checkWindowAtobCompatibility() {
|
243 |
+
if ('atob' in window) {
|
244 |
+
return;
|
245 |
+
}
|
246 |
+
|
247 |
+
// https://github.com/davidchambers/Base64.js
|
248 |
+
var digits =
|
249 |
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
250 |
+
window.atob = function (input) {
|
251 |
+
input = input.replace(/=+$/, '');
|
252 |
+
if (input.length % 4 === 1) {
|
253 |
+
throw new Error('bad atob input');
|
254 |
+
}
|
255 |
+
for (
|
256 |
+
// initialize result and counters
|
257 |
+
var bc = 0, bs, buffer, idx = 0, output = '';
|
258 |
+
// get next character
|
259 |
+
buffer = input.charAt(idx++);
|
260 |
+
// character found in table?
|
261 |
+
// initialize bit storage and add its ascii value
|
262 |
+
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
263 |
+
// and if not first of each 4 characters,
|
264 |
+
// convert the first 8 bits to one ascii character
|
265 |
+
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
266 |
+
) {
|
267 |
+
// try to find character in table (0-63, not found => -1)
|
268 |
+
buffer = digits.indexOf(buffer);
|
269 |
+
}
|
270 |
+
return output;
|
271 |
+
};
|
272 |
+
})();
|
273 |
+
|
274 |
+
// Function.prototype.bind?
|
275 |
+
// Support: Android<4.0, iOS<6.0
|
276 |
+
(function checkFunctionPrototypeBindCompatibility() {
|
277 |
+
if (typeof Function.prototype.bind !== 'undefined') {
|
278 |
+
return;
|
279 |
+
}
|
280 |
+
|
281 |
+
Function.prototype.bind = function functionPrototypeBind(obj) {
|
282 |
+
var fn = this, headArgs = Array.prototype.slice.call(arguments, 1);
|
283 |
+
var bound = function functionPrototypeBindBound() {
|
284 |
+
var args = headArgs.concat(Array.prototype.slice.call(arguments));
|
285 |
+
return fn.apply(obj, args);
|
286 |
+
};
|
287 |
+
return bound;
|
288 |
+
};
|
289 |
+
})();
|
290 |
+
|
291 |
+
// HTMLElement dataset property
|
292 |
+
// Support: IE<11, Safari<5.1, Android<4.0
|
293 |
+
(function checkDatasetProperty() {
|
294 |
+
var div = document.createElement('div');
|
295 |
+
if ('dataset' in div) {
|
296 |
+
return; // dataset property exists
|
297 |
+
}
|
298 |
+
|
299 |
+
Object.defineProperty(HTMLElement.prototype, 'dataset', {
|
300 |
+
get: function() {
|
301 |
+
if (this._dataset) {
|
302 |
+
return this._dataset;
|
303 |
+
}
|
304 |
+
|
305 |
+
var dataset = {};
|
306 |
+
for (var j = 0, jj = this.attributes.length; j < jj; j++) {
|
307 |
+
var attribute = this.attributes[j];
|
308 |
+
if (attribute.name.substring(0, 5) !== 'data-') {
|
309 |
+
continue;
|
310 |
+
}
|
311 |
+
var key = attribute.name.substring(5).replace(/\-([a-z])/g,
|
312 |
+
function(all, ch) {
|
313 |
+
return ch.toUpperCase();
|
314 |
+
});
|
315 |
+
dataset[key] = attribute.value;
|
316 |
+
}
|
317 |
+
|
318 |
+
Object.defineProperty(this, '_dataset', {
|
319 |
+
value: dataset,
|
320 |
+
writable: false,
|
321 |
+
enumerable: false
|
322 |
+
});
|
323 |
+
return dataset;
|
324 |
+
},
|
325 |
+
enumerable: true
|
326 |
+
});
|
327 |
+
})();
|
328 |
+
|
329 |
+
// HTMLElement classList property
|
330 |
+
// Support: IE<10, Android<4.0, iOS<5.0
|
331 |
+
(function checkClassListProperty() {
|
332 |
+
var div = document.createElement('div');
|
333 |
+
if ('classList' in div) {
|
334 |
+
return; // classList property exists
|
335 |
+
}
|
336 |
+
|
337 |
+
function changeList(element, itemName, add, remove) {
|
338 |
+
var s = element.className || '';
|
339 |
+
var list = s.split(/\s+/g);
|
340 |
+
if (list[0] === '') {
|
341 |
+
list.shift();
|
342 |
+
}
|
343 |
+
var index = list.indexOf(itemName);
|
344 |
+
if (index < 0 && add) {
|
345 |
+
list.push(itemName);
|
346 |
+
}
|
347 |
+
if (index >= 0 && remove) {
|
348 |
+
list.splice(index, 1);
|
349 |
+
}
|
350 |
+
element.className = list.join(' ');
|
351 |
+
return (index >= 0);
|
352 |
+
}
|
353 |
+
|
354 |
+
var classListPrototype = {
|
355 |
+
add: function(name) {
|
356 |
+
changeList(this.element, name, true, false);
|
357 |
+
},
|
358 |
+
contains: function(name) {
|
359 |
+
return changeList(this.element, name, false, false);
|
360 |
+
},
|
361 |
+
remove: function(name) {
|
362 |
+
changeList(this.element, name, false, true);
|
363 |
+
},
|
364 |
+
toggle: function(name) {
|
365 |
+
changeList(this.element, name, true, true);
|
366 |
+
}
|
367 |
+
};
|
368 |
+
|
369 |
+
Object.defineProperty(HTMLElement.prototype, 'classList', {
|
370 |
+
get: function() {
|
371 |
+
if (this._classList) {
|
372 |
+
return this._classList;
|
373 |
+
}
|
374 |
+
|
375 |
+
var classList = Object.create(classListPrototype, {
|
376 |
+
element: {
|
377 |
+
value: this,
|
378 |
+
writable: false,
|
379 |
+
enumerable: true
|
380 |
+
}
|
381 |
+
});
|
382 |
+
Object.defineProperty(this, '_classList', {
|
383 |
+
value: classList,
|
384 |
+
writable: false,
|
385 |
+
enumerable: false
|
386 |
+
});
|
387 |
+
return classList;
|
388 |
+
},
|
389 |
+
enumerable: true
|
390 |
+
});
|
391 |
+
})();
|
392 |
+
|
393 |
+
// Check console compatibility
|
394 |
+
// In older IE versions the console object is not available
|
395 |
+
// unless console is open.
|
396 |
+
// Support: IE<10
|
397 |
+
(function checkConsoleCompatibility() {
|
398 |
+
if (!('console' in window)) {
|
399 |
+
window.console = {
|
400 |
+
log: function() {},
|
401 |
+
error: function() {},
|
402 |
+
warn: function() {}
|
403 |
+
};
|
404 |
+
} else if (!('bind' in console.log)) {
|
405 |
+
// native functions in IE9 might not have bind
|
406 |
+
console.log = (function(fn) {
|
407 |
+
return function(msg) { return fn(msg); };
|
408 |
+
})(console.log);
|
409 |
+
console.error = (function(fn) {
|
410 |
+
return function(msg) { return fn(msg); };
|
411 |
+
})(console.error);
|
412 |
+
console.warn = (function(fn) {
|
413 |
+
return function(msg) { return fn(msg); };
|
414 |
+
})(console.warn);
|
415 |
+
}
|
416 |
+
})();
|
417 |
+
|
418 |
+
// Check onclick compatibility in Opera
|
419 |
+
// Support: Opera<15
|
420 |
+
(function checkOnClickCompatibility() {
|
421 |
+
// workaround for reported Opera bug DSK-354448:
|
422 |
+
// onclick fires on disabled buttons with opaque content
|
423 |
+
function ignoreIfTargetDisabled(event) {
|
424 |
+
if (isDisabled(event.target)) {
|
425 |
+
event.stopPropagation();
|
426 |
+
}
|
427 |
+
}
|
428 |
+
function isDisabled(node) {
|
429 |
+
return node.disabled || (node.parentNode && isDisabled(node.parentNode));
|
430 |
+
}
|
431 |
+
if (navigator.userAgent.indexOf('Opera') !== -1) {
|
432 |
+
// use browser detection since we cannot feature-check this bug
|
433 |
+
document.addEventListener('click', ignoreIfTargetDisabled, true);
|
434 |
+
}
|
435 |
+
})();
|
436 |
+
|
437 |
+
// Checks if possible to use URL.createObjectURL()
|
438 |
+
// Support: IE
|
439 |
+
(function checkOnBlobSupport() {
|
440 |
+
// sometimes IE loosing the data created with createObjectURL(), see #3977
|
441 |
+
if (navigator.userAgent.indexOf('Trident') >= 0) {
|
442 |
+
PDFJS.disableCreateObjectURL = true;
|
443 |
+
}
|
444 |
+
})();
|
445 |
+
|
446 |
+
// Checks if navigator.language is supported
|
447 |
+
(function checkNavigatorLanguage() {
|
448 |
+
if ('language' in navigator) {
|
449 |
+
return;
|
450 |
+
}
|
451 |
+
PDFJS.locale = navigator.userLanguage || 'en-US';
|
452 |
+
})();
|
453 |
+
|
454 |
+
(function checkRangeRequests() {
|
455 |
+
// Safari has issues with cached range requests see:
|
456 |
+
// https://github.com/mozilla/pdf.js/issues/3260
|
457 |
+
// Last tested with version 6.0.4.
|
458 |
+
// Support: Safari 6.0+
|
459 |
+
var isSafari = Object.prototype.toString.call(
|
460 |
+
window.HTMLElement).indexOf('Constructor') > 0;
|
461 |
+
|
462 |
+
// Older versions of Android (pre 3.0) has issues with range requests, see:
|
463 |
+
// https://github.com/mozilla/pdf.js/issues/3381.
|
464 |
+
// Make sure that we only match webkit-based Android browsers,
|
465 |
+
// since Firefox/Fennec works as expected.
|
466 |
+
// Support: Android<3.0
|
467 |
+
var regex = /Android\s[0-2][^\d]/;
|
468 |
+
var isOldAndroid = regex.test(navigator.userAgent);
|
469 |
+
|
470 |
+
// Range requests are broken in Chrome 39 and 40, https://crbug.com/442318
|
471 |
+
var isChromeWithRangeBug = /Chrome\/(39|40)\./.test(navigator.userAgent);
|
472 |
+
|
473 |
+
if (isSafari || isOldAndroid || isChromeWithRangeBug) {
|
474 |
+
PDFJS.disableRange = true;
|
475 |
+
PDFJS.disableStream = true;
|
476 |
+
}
|
477 |
+
})();
|
478 |
+
|
479 |
+
// Check if the browser supports manipulation of the history.
|
480 |
+
// Support: IE<10, Android<4.2
|
481 |
+
(function checkHistoryManipulation() {
|
482 |
+
// Android 2.x has so buggy pushState support that it was removed in
|
483 |
+
// Android 3.0 and restored as late as in Android 4.2.
|
484 |
+
// Support: Android 2.x
|
485 |
+
if (!history.pushState || navigator.userAgent.indexOf('Android 2.') >= 0) {
|
486 |
+
PDFJS.disableHistory = true;
|
487 |
+
}
|
488 |
+
})();
|
489 |
+
|
490 |
+
// Support: IE<11, Chrome<21, Android<4.4, Safari<6
|
491 |
+
(function checkSetPresenceInImageData() {
|
492 |
+
// IE < 11 will use window.CanvasPixelArray which lacks set function.
|
493 |
+
if (window.CanvasPixelArray) {
|
494 |
+
if (typeof window.CanvasPixelArray.prototype.set !== 'function') {
|
495 |
+
window.CanvasPixelArray.prototype.set = function(arr) {
|
496 |
+
for (var i = 0, ii = this.length; i < ii; i++) {
|
497 |
+
this[i] = arr[i];
|
498 |
+
}
|
499 |
+
};
|
500 |
+
}
|
501 |
+
} else {
|
502 |
+
// Old Chrome and Android use an inaccessible CanvasPixelArray prototype.
|
503 |
+
// Because we cannot feature detect it, we rely on user agent parsing.
|
504 |
+
var polyfill = false, versionMatch;
|
505 |
+
if (navigator.userAgent.indexOf('Chrom') >= 0) {
|
506 |
+
versionMatch = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
|
507 |
+
// Chrome < 21 lacks the set function.
|
508 |
+
polyfill = versionMatch && parseInt(versionMatch[2]) < 21;
|
509 |
+
} else if (navigator.userAgent.indexOf('Android') >= 0) {
|
510 |
+
// Android < 4.4 lacks the set function.
|
511 |
+
// Android >= 4.4 will contain Chrome in the user agent,
|
512 |
+
// thus pass the Chrome check above and not reach this block.
|
513 |
+
polyfill = /Android\s[0-4][^\d]/g.test(navigator.userAgent);
|
514 |
+
} else if (navigator.userAgent.indexOf('Safari') >= 0) {
|
515 |
+
versionMatch = navigator.userAgent.
|
516 |
+
match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//);
|
517 |
+
// Safari < 6 lacks the set function.
|
518 |
+
polyfill = versionMatch && parseInt(versionMatch[1]) < 6;
|
519 |
+
}
|
520 |
+
|
521 |
+
if (polyfill) {
|
522 |
+
var contextPrototype = window.CanvasRenderingContext2D.prototype;
|
523 |
+
var createImageData = contextPrototype.createImageData;
|
524 |
+
contextPrototype.createImageData = function(w, h) {
|
525 |
+
var imageData = createImageData.call(this, w, h);
|
526 |
+
imageData.data.set = function(arr) {
|
527 |
+
for (var i = 0, ii = this.length; i < ii; i++) {
|
528 |
+
this[i] = arr[i];
|
529 |
+
}
|
530 |
+
};
|
531 |
+
return imageData;
|
532 |
+
};
|
533 |
+
// this closure will be kept referenced, so clear its vars
|
534 |
+
contextPrototype = null;
|
535 |
+
}
|
536 |
+
}
|
537 |
+
})();
|
538 |
+
|
539 |
+
// Support: IE<10, Android<4.0, iOS
|
540 |
+
(function checkRequestAnimationFrame() {
|
541 |
+
function fakeRequestAnimationFrame(callback) {
|
542 |
+
window.setTimeout(callback, 20);
|
543 |
+
}
|
544 |
+
|
545 |
+
var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
|
546 |
+
if (isIOS) {
|
547 |
+
// requestAnimationFrame on iOS is broken, replacing with fake one.
|
548 |
+
window.requestAnimationFrame = fakeRequestAnimationFrame;
|
549 |
+
return;
|
550 |
+
}
|
551 |
+
if ('requestAnimationFrame' in window) {
|
552 |
+
return;
|
553 |
+
}
|
554 |
+
window.requestAnimationFrame =
|
555 |
+
window.mozRequestAnimationFrame ||
|
556 |
+
window.webkitRequestAnimationFrame ||
|
557 |
+
fakeRequestAnimationFrame;
|
558 |
+
})();
|
559 |
+
|
560 |
+
(function checkCanvasSizeLimitation() {
|
561 |
+
var isIOS = /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
|
562 |
+
var isAndroid = /Android/g.test(navigator.userAgent);
|
563 |
+
if (isIOS || isAndroid) {
|
564 |
+
// 5MP
|
565 |
+
PDFJS.maxCanvasPixels = 5242880;
|
566 |
+
}
|
567 |
+
})();
|
568 |
+
|
569 |
+
// Disable fullscreen support for certain problematic configurations.
|
570 |
+
// Support: IE11+ (when embedded).
|
571 |
+
(function checkFullscreenSupport() {
|
572 |
+
var isEmbeddedIE = (navigator.userAgent.indexOf('Trident') >= 0 &&
|
573 |
+
window.parent !== window);
|
574 |
+
if (isEmbeddedIE) {
|
575 |
+
PDFJS.disableFullscreen = true;
|
576 |
+
}
|
577 |
+
})();
|
578 |
+
|
579 |
+
// Provides document.currentScript support
|
580 |
+
// Support: IE, Chrome<29.
|
581 |
+
(function checkCurrentScript() {
|
582 |
+
if ('currentScript' in document) {
|
583 |
+
return;
|
584 |
+
}
|
585 |
+
Object.defineProperty(document, 'currentScript', {
|
586 |
+
get: function () {
|
587 |
+
var scripts = document.getElementsByTagName('script');
|
588 |
+
return scripts[scripts.length - 1];
|
589 |
+
},
|
590 |
+
enumerable: true,
|
591 |
+
configurable: true
|
592 |
+
});
|
593 |
+
})();
|
assets/player/prototype.js
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
assets/player/string.js
CHANGED
@@ -1,3 +1,220 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var SC = SC || {},
|
2 |
+
CoreDocs = CoreDocs || {},
|
3 |
+
NO = false,
|
4 |
+
YES = true;
|
5 |
+
|
6 |
+
// ==========================================================================
|
7 |
+
// This is copied from CoreDocs to facilitate automatically generating Strings.js files.
|
8 |
+
// ==========================================================================
|
9 |
+
|
10 |
+
CoreDocs.loc = function(input, comment) {
|
11 |
+
if (comment === undefined)
|
12 |
+
{
|
13 |
+
CoreDocs.error("\"" + input + "\" needs a comment to be picked up for loc.");
|
14 |
+
}
|
15 |
+
|
16 |
+
// When we call SproutCore's loc(), it will replace all %@ parameters, and there is no way to escape them.
|
17 |
+
// In the future, we should get an escaping method into SC, and/or take advantage of their loc's string replacement.
|
18 |
+
// For now, we use @@ instead of %@ as a preliminary parameter marker.
|
19 |
+
input = input.loc();
|
20 |
+
input = input.replace(/@@/g, "%@");
|
21 |
+
return input;
|
22 |
+
}
|
23 |
+
|
24 |
+
// ==========================================================================
|
25 |
+
// This is the necessary subset of sproutcore strings for use in localization.
|
26 |
+
// ==========================================================================
|
27 |
+
|
28 |
+
// ==========================================================================
|
29 |
+
// SproutCore -- JavaScript Application Framework
|
30 |
+
// copyright 2006-2008, Sprout Systems, Inc. and contributors.
|
31 |
+
// ==========================================================================
|
32 |
+
|
33 |
+
// These are basic enhancements to the string class used throughout
|
34 |
+
// SproutCore.
|
35 |
+
|
36 |
+
/**
|
37 |
+
@namespace
|
38 |
+
|
39 |
+
SproutCore implements a variety of enhancements to the built-in String
|
40 |
+
object that make it easy to perform common substitutions and conversions.
|
41 |
+
|
42 |
+
Most of the utility methods defined here mirror those found in Prototype
|
43 |
+
1.6.
|
44 |
+
|
45 |
+
@since SproutCore 1.0
|
46 |
+
*/
|
47 |
+
SC.String = {
|
48 |
+
|
49 |
+
// Interpolate string. looks for %@ or %@1; to control the order of params.
|
50 |
+
/**
|
51 |
+
Apply formatting options to the string. This will look for occurrences
|
52 |
+
of %@ in your string and substitute them with the arguments you pass into
|
53 |
+
this method. If you want to control the specific order of replacement,
|
54 |
+
you can add a number after the key as well to indicate which argument
|
55 |
+
you want to insert.
|
56 |
+
|
57 |
+
Ordered insertions are most useful when building loc strings where values
|
58 |
+
you need to insert may appear in different orders.
|
59 |
+
|
60 |
+
h3. Examples
|
61 |
+
|
62 |
+
{{{
|
63 |
+
"Hello %@ %@".fmt('John', 'Doe') => "Hello John Doe"
|
64 |
+
"Hello %@2, %@1".fmt('John', 'Doe') => "Hello Doe, John"
|
65 |
+
}}}
|
66 |
+
|
67 |
+
@param args {Object...} optional arguments
|
68 |
+
@returns {String} formatted string
|
69 |
+
*/
|
70 |
+
fmt: function() {
|
71 |
+
// first, replace any ORDERED replacements.
|
72 |
+
var str = this.gsub(/%@([0-9]+)/, function(m) {
|
73 |
+
return (arguments[parseInt(m[1],0)-1] || '').toString();
|
74 |
+
}) ;
|
75 |
+
|
76 |
+
// now, replace any remaining %@ items. Use this indexOf() method b/c
|
77 |
+
// it is faster than split().
|
78 |
+
var ret = [] ;
|
79 |
+
var idx = -1 ;
|
80 |
+
var loc = 0 ;
|
81 |
+
var argIdx = 0;
|
82 |
+
while((idx = str.indexOf("%@",loc)) >= 0) {
|
83 |
+
// slice off initial part of string and push into ret. update loc.
|
84 |
+
ret.push(str.slice(loc,idx)) ;
|
85 |
+
loc = idx + 2 ; // 2 to skip '%@'.
|
86 |
+
|
87 |
+
// add in replacement.
|
88 |
+
var value = arguments[argIdx++] ;
|
89 |
+
if (value && value.toString) value = value.toString() ;
|
90 |
+
ret.push(value) ;
|
91 |
+
}
|
92 |
+
|
93 |
+
// include any remaining bits of the string.
|
94 |
+
if (loc < str.length) {
|
95 |
+
ret.push(str.slice(loc,str.length)) ;
|
96 |
+
}
|
97 |
+
|
98 |
+
// join return value.
|
99 |
+
return (ret.length > 1) ? ret.join('') : ret[0] ;
|
100 |
+
},
|
101 |
+
|
102 |
+
/**
|
103 |
+
Localizes the string. This will look up the reciever string as a key
|
104 |
+
in the current Strings hash. If the key matches, the loc'd value will be
|
105 |
+
used. The resulting string will also be passed through fmt() to insert
|
106 |
+
any variables.
|
107 |
+
|
108 |
+
@param args {Object...} optional arguments to interpolate also
|
109 |
+
@returns {String} the localized and formatted string.
|
110 |
+
*/
|
111 |
+
loc: function() {
|
112 |
+
// NB: This could be implemented as a wrapper to locWithDefault() but
|
113 |
+
// it would add some overhead to deal with the arguments and adds stack
|
114 |
+
// frames, so we are keeping the implementation separate.
|
115 |
+
|
116 |
+
var kit = String[String.currentLanguage()];
|
117 |
+
var str = kit[this] ;
|
118 |
+
if (!str) str = String.English[this] || this ;
|
119 |
+
return str.fmt.apply(str,arguments) ;
|
120 |
+
}
|
121 |
+
} ;
|
122 |
+
|
123 |
+
// Apply SC.String mixin to built-in String object
|
124 |
+
for (var key in SC.String) {
|
125 |
+
String.prototype[key] = SC.String[key];
|
126 |
+
}
|
127 |
+
|
128 |
+
// Add strings for various languages to this collection. String.loc()
|
129 |
+
// method will try to localize the string passed using the current language.
|
130 |
+
// if the language is not available, it will use English.
|
131 |
+
Object.extend(String,
|
132 |
+
/** @scope String @static */ {
|
133 |
+
|
134 |
+
/**
|
135 |
+
The current browser language as a two letter code.
|
136 |
+
*/
|
137 |
+
browserLanguage: ((navigator.language || navigator.browserLanguage).split('-', 1)[0]),
|
138 |
+
|
139 |
+
/**
|
140 |
+
If YES, localization will favor the detected language instead of the
|
141 |
+
preferred one.
|
142 |
+
*/
|
143 |
+
useAutodetectedLanguage: NO,
|
144 |
+
|
145 |
+
/**
|
146 |
+
This property is set by the build tools to the current build language.
|
147 |
+
*/
|
148 |
+
preferredLanguage: null,
|
149 |
+
|
150 |
+
/**
|
151 |
+
Returns the hash key to use for loc strings. The default implementation
|
152 |
+
will autodetect the browser language and look for a loc string to
|
153 |
+
match. If it can't find one then it will introspect to find loc strings
|
154 |
+
that are defined and use those instead.
|
155 |
+
*/
|
156 |
+
currentLanguage: function () {
|
157 |
+
var ret = (this.useAutodetectedLanguage) ? (this.browserLanguage || this.preferredLanguage || 'en') : (this.preferredLanguage || this.browserLanguage || 'en') ;
|
158 |
+
|
159 |
+
// then try a couple of normalized forms...
|
160 |
+
if (!this[ret]) ret = this.normalizedLanguage(ret);
|
161 |
+
return ret ;
|
162 |
+
},
|
163 |
+
|
164 |
+
/**
|
165 |
+
Returns a normalized language string for the two letter country code.
|
166 |
+
*/
|
167 |
+
normalizedLanguage: function(ret) {
|
168 |
+
switch(ret) {
|
169 |
+
case 'fr':
|
170 |
+
ret = 'French';
|
171 |
+
break ;
|
172 |
+
case 'de':
|
173 |
+
ret = 'German';
|
174 |
+
break ;
|
175 |
+
case 'ja':
|
176 |
+
case 'jp':
|
177 |
+
ret = 'Japanese';
|
178 |
+
break ;
|
179 |
+
case 'en':
|
180 |
+
ret = 'English' ;
|
181 |
+
break ;
|
182 |
+
|
183 |
+
case 'es':
|
184 |
+
ret = 'Spanish' ;
|
185 |
+
break;
|
186 |
+
|
187 |
+
default:
|
188 |
+
ret = "English";
|
189 |
+
break ;
|
190 |
+
}
|
191 |
+
return ret;
|
192 |
+
},
|
193 |
+
|
194 |
+
/**
|
195 |
+
Adds loc strings for the named language. This method takes care of
|
196 |
+
creating the localized string hash if it does not already exist.
|
197 |
+
The language can be one of the following or any two-letter country code.
|
198 |
+
|
199 |
+
English, French, German, Japanese, Spanish
|
200 |
+
|
201 |
+
@param language {String} the language code
|
202 |
+
@param strings {Hash} hash of loc strings.
|
203 |
+
@returns {this}
|
204 |
+
*/
|
205 |
+
addStringsFor: function(language, strings) {
|
206 |
+
// convert language to a normalized name...
|
207 |
+
language = String.normalizedLanguage(language) ;
|
208 |
+
if (!String[language]) String[language] = {} ;
|
209 |
+
Object.extend(String[language], strings || {});
|
210 |
+
return this;
|
211 |
+
}
|
212 |
+
|
213 |
+
});
|
214 |
+
|
215 |
+
String.English = String.English || {};
|
216 |
+
String.French = String.French || {};
|
217 |
+
String.German = String.German || {};
|
218 |
+
String.Japanese = String.Japanese || {};
|
219 |
+
String.Spanish = String.Spanish || {};
|
220 |
+
|