vendor: 5,340 bytes, lines 1-169
1/** 2 * @preserve 3 * Plugin Name: dflip 4 * Description: dflip - 3D & 2D FlipBook 5 * 6 * Author: Deepak Ghimire 7 * Author URI: http://codecanyon.net/user/dearhive?ref=dearhive 8 */ 9 10'use strict'; 11 12var DFLIP = DFLIP || {}; 13 14// old fallback 15// use DFLIP instead of PRESENTATION as of v 1.1 16var PRESENTATION = DFLIP; 17 18(function dFlip(DFLIP, $) { 19 20 DFLIP.version = "1.5.6"; 21 22 DFLIP.PAGE_MODE = {SINGLE: 1, DOUBLE: 2, AUTO: null}; 23 DFLIP.SINGLE_PAGE_MODE = {ZOOM: 1, BOOKLET: 2, AUTO: null}; 24 DFLIP.CONTROLSPOSITION = {HIDDEN: 'hide', TOP: 'top', BOTTOM: 'bottom'}; 25 DFLIP.DIRECTION = {LTR: 1, RTL: 2}; 26 DFLIP.LINK_TARGET = {NONE: 0, SELF: 1, BLANK: 2, PARENT: 3, TOP: 4}; 27 28 DFLIP.CORNERS = {TL: "tl", TR: "tr", BL: "bl", BR: "br", L: "l", R: "r", NONE: null}; 29 30 DFLIP.SOURCE_TYPE = {IMAGE: "image", PDF: "pdf", HTML: "html"}; 31 DFLIP.DISPLAY_TYPE = {WEBGL: "3D", HTML: "2D"}; 32 DFLIP.PAGE_SIZE = {AUTO: 0, SINGLE: 1, DOUBLEINTERNAL: 2}; 33 34 35 //defaults settings 36 var defaults = DFLIP.defaults = { 37 38 //sets if to use 3d or not (true|false) 39 webgl: true, 40 //if you want to turn of shadow in 3d set it to false 41 webglShadow: true, 42 43 // if enable sound at start (true|false) 44 soundEnable: true, 45 search: false, 46 47 // height of the container 48 // value(eg: 320) or percentage (eg: '50%') 49 // calculaton limit: minimum 320, max window height 50 height: 'auto', 51 52 // set to true to show outline on open (true|false) 53 autoEnableOutline: false, 54 55 // set to true to show thumbnail on open (true|false) 56 autoEnableThumbnail: false, 57 58 // set to true if PDF inbuilt outline is to be removed (true|false) 59 overwritePDFOutline: false, 60 61 // enableDownload of PDF files (true|false) 62 enableDownload: true, 63 64 // duration of page turn in milliseconds 65 duration: 800, 66 67 //direction of flipbook 68 //DFLIP.DIRECTION.LTR or 1 for left to right(default), 69 //DFLIP.DIRECTION.RTL or 2 for right to left, 70 direction: DFLIP.DIRECTION.LTR, 71 72 //set as 73 //DFLIP.PAGE_MODE.AUTO for auto-detect(default), 74 //DFLIP.PAGE_MODE.SINGLE or 1 for singleview, 75 //DFLIP.PAGE_MODE.DOUBLE or 2 for doubleview, 76 pageMode: DFLIP.PAGE_MODE.AUTO, 77 78 //set as 79 //DFLIP.SINGLE_PAGE_MODE.AUTO for auto-detect(default), 80 //DFLIP.SINGLE_PAGE_MODE.ZOOM or 1 for normal zoom single view, 81 //DFLIP.SINGLE_PAGE_MODE.BOOKLET or 2 for Booklet mode, 82 singlePageMode: DFLIP.SINGLE_PAGE_MODE.AUTO, 83 84 //color value in hexadecimal 85 backgroundColor: "#fff", 86 87 forceFit: true, //very rare usage leave it as true unless page are not fitting wrong... 88 transparent: false, //true or false 89 hard: "none", //possible values are "hard", "none", "cover" 90 openPage: 1, //the pagenumber where the book should open 91 92 annotationClass: "", 93 94 autoPlay: false, 95 autoPlayDuration: 5000, 96 autoPlayStart: false, 97 98 // texture settings 99 maxTextureSize: 1600, //max page size to be rendered. for pdf files only 100 minTextureSize: 256, //min page size to be rendered. for pdf files only 101 rangeChunkSize: 524288, 102 103 // icons for the buttons 104 icons: { 105 'altnext': 'ti-angle-right', 106 'altprev': 'ti-angle-left', 107 'next': 'ti-angle-right', 108 'prev': 'ti-angle-left', 109 'end': 'ti-angle-double-right', 110 'start': 'ti-angle-double-left', 111 'share': 'ti-sharethis', 112 'help': 'ti-help-alt', 113 'more': 'ti-more-alt', 114 'download': 'ti-download', 115 'zoomin': 'ti-zoom-in', 116 'zoomout': 'ti-zoom-out', 117 'fullscreen': 'ti-fullscreen', 118 'fitscreen': 'ti-arrows-corner', 119 'thumbnail': 'ti-layout-grid2', 120 'outline': 'ti-menu-alt', 121 'close': 'ti-close', 122 'search': 'ti-search', 123 'doublepage': 'ti-book', 124 'singlepage': 'ti-file', 125 'sound': 'ti-volume', 126 'facebook': 'ti-facebook', 127 'google': 'ti-google', 128 'twitter': 'ti-twitter-alt', 129 'mail': 'ti-email', 130 'play': 'ti-control-play', 131 'pause': 'ti-control-pause' 132 }, 133 134 // TRANSLATION text to be displayed 135 text: { 136 137 toggleSound: "Activer / Désactiver le son", 138 toggleThumbnails: "Basculer les vignettes", 139 toggleOutline: "Basculer le marque-page", 140 previousPage: "Page précédente", 141 nextPage: "Page suivante", 142 toggleFullscreen: "Basculer en plein écran", 143 zoomIn: "Zoomer", 144 zoomOut: "Dézoomer", 145 toggleHelp: "Basculer sur l'aide", 146 147 singlePageMode: "Mode page unique", 148 doublePageMode: "Mode double page", 149 downloadPDFFile: "Télécharger le fichier PDF", 150 gotoFirstPage: "Aller à la première page", 151 gotoLastPage: "Aller à la dernière page", 152 play: "Activer la lecture automatique", 153 pause: "Mettre en pause la lecture", 154 155 share: "Partager" 156 }, 157 158 //valid controlnames: 159 //altPrev,pageNumber,altNext,outline,thumbnail,zoomIn,zoomOut,fullScreen,share 160 //more,download,pageMode,startPage,endPage,sound 161 allControls: "altPrev,pageNumber,altNext,play,outline,thumbnail,zoomIn,zoomOut,fullScreen,share,download,search,more,pageMode,startPage,endPage,sound", 162 moreControls: "download,pageMode,startPage,endPage,sound", 163 hideControls: "", 164 165 controlsPosition: DFLIP.CONTROLSPOSITION.BOTTOM, 166 paddingTop: 30, 167 paddingLeft: 20, 168 paddingRight: 20, 169 paddingBottom: 30,
170 enableAnalytics: false, 171 172 //set if the zoom changes on mouse scroll (true|false) 173 scrollWheel: true, 174 175 // callbacks 176 onCreate: function (flipBook) { 177 // after flip book is created is fired 178 }, 179 onCreateUI: function (flipBook) { 180 // after ui created event is fired 181 }, 182 onFlip: function (flipBook) { 183 // after flip event is fired 184 }, 185 beforeFlip: function (flipBook) { 186 // before flip event is fired 187 }, 188 onReady: function (flipBook) { 189 // after flip book is completely loaded 190 }, 191 192 zoomRatio: 1.5, 193 pageSize: DFLIP.PAGE_SIZE.AUTO, 194 195 /** 196 * NON-OPTIONS AREA 197 * These options are not supposed to be sent from options variable 198 */ 199 /** 200 * dependency URLS (NON-OPTION): 201 * Do not set them as options, 202 * Refer to advance-examples 203 */ 204 //(NON-OPTION) source link for PDF.JS file 205 pdfjsSrc: "js/libs/pdf.min.js", 206 //(NON-OPTION) source link for PDFcompatibility.JS file 207 pdfjsCompatibilitySrc: "js/libs/compatibility.js", 208 //(NON-OPTION) source link for PDF.WORKER.JS file 209 pdfjsWorkerSrc: "js/libs/pdf.worker.min.js", 210 //(NON-OPTION) source link for THREE.JS file 211 threejsSrc: "js/libs/three.min.js", 212 //(NON-OPTION) source link for MOCKUP.JS file 213 mockupjsSrc: "js/libs/mockup.min.js", 214 //(NON-OPTION) File path to the trun sound 215 soundFile: "sound/turn2.mp3", 216 imagesLocation: "images", 217 imageResourcesPath: "images/pdfjs/", 218 cMapUrl: "cmaps/", //it's quite wierd how cmaps don't work properly with relative urls like others.. but is relative to pdf.min.js path 219 220 //(NON-OPTION) developer parameters 221 enableDebugLog: false, 222 canvasToBlob: false,//as of 1.2.9 canvas are better optimized and secure 223 enableAnnotation: true, 224 pdfRenderQuality: 0.90, 225 226 227 /** 228 * Let them be, change at your risk 229 */ 230 // if texture fallback override is required 231 // note: if set to anything other than "blank" the first page is changed 232 // recommended : "blank" 233 textureLoadFallback: "blank", //"images/textures/white.jpg", 234 // controls the flexibility of the paper more value for more flexiblilty 235 stiffness: 3, 236 // minTopOffset: 30, 237 // link to the images file that you want as background. 238 // supported files are jpgs,png. smaller files are preffered for performance 239 backgroundImage: "",//"images/textures/el.jpg", 240 // or any number like 5, 500. recommended: "auto" 241 242 pageRatio: null, //equals to width/height 243 244 pixelRatio: window.devicePixelRatio || 1, 245 thumbElement: 'div', 246 247 /*3D settings*/ 248 spotLightIntensity: 0.22, 249 ambientLightColor: "#fff", 250 ambientLightIntensity: 0.8, 251 shadowOpacity: 0.15, 252 253 linkTarget: DFLIP.LINK_TARGET.BLANK 254 }; 255 256 var has3d = 'WebKitCSSMatrix' in window 257 || (document.body && 'MozPerspective' in document.body.style), 258 hasMouse = 'onmousedown' in window, 259 hasTouch = 'ontouchstart' in window; 260 261 var userAgent = navigator.userAgent; 262 263 var utils = DFLIP.utils = { 264 265 drag: { 266 left: 0, 267 right: 1, 268 none: -1 269 }, 270 mouseEvents: (hasMouse) 271 ? {type: "mouse", start: "mousedown", move: "mousemove", end: "mouseup"} 272 : {type: "touch", start: "touchstart", move: "touchmove", end: "touchend"}, 273 274 html: { 275 div: "<div/>", 276 img: "<img/>", 277 a: "<a>", 278 input: "<input type='text'/>" 279 }, 280 //functions or so 281 toRad: function (deg) { 282 return deg * Math.PI / 180; 283 }, 284 isset: function (check, fallback) { 285 return check == null ? fallback : check; 286 }, 287 isnull: function (variable) { 288 return variable == null || variable == null; 289 }, 290 toDeg: function (rad) { 291 return rad * 180 / Math.PI; 292 }, 293 transition: function (hasTransition, duration) { 294 return hasTransition ? duration / 1000 + "s ease-out" : "0s none"; 295 }, 296 hasCompatibility: function () { 297 var compatible = false; 298 if (window.dFlipLocation != null) { 299 if (window.dFlipLocation.indexOf('lip-lit') > 0) 300 compatible = true; 301 } 302 return compatible; 303 }, 304 scrollIntoView: function (element, reference, align) { 305 reference = reference || element.parentNode; 306 reference.scrollTop = element.offsetTop - reference.offsetTop + 307 (align === false ? element.offsetHeight - reference.offsetHeight : 0); 308 reference.scrollLeft = element.offsetLeft - reference.offsetLeft; 309 }, 310 display: function (hasDisplay) { 311 return hasDisplay ? "block" : "none"; 312 }, 313 314 resetTranslate: function () { 315 return translateStr(0, 0); 316 }, 317 318 translateStr: function (x, y) { 319 return has3d ? ' translate3d(' + x + 'px,' + y + 'px, 0px) ' : ' translate(' + x + 'px, ' + y + 'px) '; 320 }, 321 httpsCorrection: function (url) { 322 var location = window.location; 323 if (location.href.indexOf("https://") > -1 && url.indexOf(location.hostname) > -1) { 324 url = url.replace("http://", "https://"); 325 } 326 if (location.href.indexOf("http://") > -1 && url.indexOf(location.hostname) > -1) { 327 url = url.replace("https://", "http://"); 328 } 329 return url; 330 }, 331 resetBoxShadow: function () { 332 return "rgba(0, 0, 0, 0) 0px 0px 20px"; 333 }, 334 335 rotateStr: function (deg) { 336 return ' rotateZ(' + deg + 'deg) '; 337 }, 338 339 bg: function (src) { 340 return '#fff' + bgImage(src); 341 }, 342 343 bgImage: function (src) { 344 return (src == null || src == "blank" ? '' : ' url(' + src + ')'); 345 }, 346 347 src: function (src) { 348 return (src != null ? '' + src + '' : ''); 349 }, 350 351 limitAt: function (x, min, max) { 352 return x < min ? min : x > max ? max : x; 353 }, 354 355 distOrigin: function (x, y) { 356 return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); 357 }, 358 359 distPoints: function (x1, y1, x2, y2) { 360 return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); 361 }, 362 calculateScale: function (startTouches, endTouches) { 363 var startDistance = distPoints(startTouches[0].x, startTouches[0].y, startTouches[1].x, startTouches[1].y), 364 endDistance = distPoints(endTouches[0].x, endTouches[0].y, endTouches[1].x, endTouches[1].y); 365 return endDistance / startDistance; 366 }, 367 /** 368 * Calculates the average of multiple vectors (x, y values) 369 */ 370 getVectorAvg: function (vectors) { 371 return { 372 x: vectors.map(function (v) { 373 return v.x; 374 }).reduce(utils.sum) / vectors.length, 375 y: vectors.map(function (v) { 376 return v.y; 377 }).reduce(utils.sum) / vectors.length 378 }; 379 }, 380 sum: function (a, b) { 381 return a + b; 382 }, 383 /** 384 * Returns the touches of an event relative to the container offset 385 * @param event 386 * @return array touches 387 */ 388 getTouches: function (event, position) { 389 position = position || {left: 0, top: 0}; 390 return Array.prototype.slice.call(event.touches).map(function (touch) { 391 return { 392 x: touch.pageX - position.left, 393 y: touch.pageY - position.top 394 }; 395 }); 396 }, 397 398 angleByDistance: function (distance, fullWidth) { 399 var h = fullWidth / 2; 400 var d = limitAt(distance, 0, fullWidth); 401 402 return d < h 403 ? toDeg(Math.asin(d / h)) 404 : 90 + toDeg(Math.asin((d - h) / h)); 405 406 }, 407 408 log: function (args) { 409 if (defaults.enableDebugLog == true && window.console) 410 console.log(args); 411 }, 412 lowerPowerOfTwo: function (value) { 413 return Math.pow(2, Math.floor(Math.log(value) / Math.LN2)); 414 }, 415 nearestPowerOfTwo: function (value, max) { 416 return Math.min(max || 2048, Math.pow(2, Math.ceil(Math.log(value) / Math.LN2))); 417 }, 418 zoomStops: function (value, zoomRatio, ceil, min, max) { 419 if (min == null) min = 256; 420 if (max == null) max = 2048; 421 //Math.pow(2, Math.ceil(Math.log(value) / Math.LN2)); 422 423 var factor = Math.log(value / min) / Math.log(zoomRatio); 424 425 return min * Math.pow(zoomRatio, ceil == null ? Math.round(factor) : (ceil == true ? Math.ceil(factor) 426 : Math.floor(factor))); 427 }, 428 429 extendOptions: function (defaults, options) { 430 return $.extend(true, {}, defaults, options); 431 }, 432 getFullscreenElement: function () { 433 return document.fullscreenElement 434 || document.mozFullScreenElement 435 || document.webkitFullscreenElement 436 || document.msFullscreenElement 437 }, 438 hasFullscreenEnabled: function () { 439 return document.fullscreenEnabled 440 || document.mozFullScreenEnabled 441 || document.webkitFullscreenEnabled 442 || document.msFullscreenEnabled 443 }, 444 getBasePage: function (pageNumber) { 445 return Math.floor(pageNumber / 2) * 2; 446 }, 447 448 loadResources: function loadResources(resourceTag, src, callback) { 449 var doc = document, 450 element = doc.createElement(resourceTag), 451 refElement = doc.getElementsByTagName(resourceTag)[0]; 452 453 element.async = true; 454 if (callback) { 455 element.addEventListener('load', function (e) { 456 callback(null, e); 457 }, false); 458 } 459 460 element.src = src; 461 462 refElement.parentNode.insertBefore(element, refElement); 463 }, 464 getScript: function (source, callback, errorCallback) { 465 var script = document.createElement('script'); 466 var prior = document.body.getElementsByTagName('script')[0]; 467 script.async = 1; 468 script.setAttribute("data-cfasync", false); 469 if (prior != null) { 470 prior.parentNode.insertBefore(script, prior); 471 prior = null; 472 } 473 else { //sometimes if script are loaded in head and no scripts are present in body 474 document.body.appendChild(script); 475 } 476 477 function load(_, isAbort) { 478 if (script != null) { //IE 10 doesn't regard 479 if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) { 480 //console.log("aborted loading :" + source); 481 script.onload = script.onreadystatechange = null; 482 script = null; 483 script = null; 484 if (!isAbort) { 485 if (callback) callback(); 486 callback = null; 487 errorCallback = null; 488 } 489 490 } 491 } 492 } 493 494 script.addEventListener("load", load, false); 495 script.addEventListener("readystatechange", load, false); 496 script.addEventListener("complete", load, false); 497 498 if (errorCallback) { 499 script.addEventListener("error", errorCallback, false); 500 } 501 //script.onload = script.onreadystatechange = load; 502 503 script.src = source + (prefix.dom == "MS" ? ("?" + Math.random(1)) : ""); 504 }, 505 isHardPage: function (config, pageNumber, pageCount, isBooklet) { 506 if (config != null) { 507 508 // var config = this.hardConfig; 509 510 if (config == "cover") { 511 return pageNumber == 0 || (isBooklet && pageNumber == 1) //front cover is 0
512 || pageNumber == (Math.floor(pageCount / (isBooklet ? 1 : 2)) - (isBooklet ? 0 : 1)); //start with 0 so 1 minus 513 } 514 else if (config == "all") { 515 return true; 516 } 517 else { 518 var baseTest = ("," + config + ",").indexOf("," + (pageNumber * 2 + 1) + ",") > -1; 519 var nextTest = ("," + config + ",").indexOf("," + (pageNumber * 2 + 2) + ",") > -1; 520 return baseTest || nextTest; 521 522 } 523 } 524 return false; 525 }, 526 fixMouseEvent: function (event) { 527 528 529 if (event) { 530 var originalEvent = event.originalEvent || event; 531 532 //noinspection JSUnresolvedVariable 533 if (originalEvent.changedTouches && originalEvent.changedTouches.length > 0) { 534 var _event = $.event.fix(event); 535 //noinspection JSUnresolvedVariable 536 var touch = originalEvent.changedTouches[0]; 537 _event.clientX = touch.clientX; 538 _event.clientY = touch.clientY; 539 _event.pageX = touch.pageX; 540 _event.touches = originalEvent.touches; 541 _event.pageY = touch.pageY; 542 _event.movementX = touch.movementX; 543 _event.movementY = touch.movementY; 544 return _event; 545 } 546 else { 547 return event; 548 } 549 } 550 else { 551 return event; 552 } 553 554 }, 555 556 //self Execution 557 hasWebgl: (function () { 558 try { 559 var canvas = document.createElement('canvas'); 560 //noinspection JSUnresolvedVariable 561 return !!(window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))); 562 } catch (e) { 563 return false; 564 } 565 })(), 566 isBookletMode: function (book) { 567 return book.pageMode == DFLIP.PAGE_MODE.SINGLE && book.singlePageMode == DFLIP.SINGLE_PAGE_MODE.BOOKLET 568 }, 569 isRTLMode: function (book) { 570 return book.direction == DFLIP.DIRECTION.RTL 571 }, 572 isMobile: (function () { 573 var check = false; 574 (function (a) { 575 if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true 576 })(userAgent || navigator.vendor || window.opera); 577 return check; 578 })(), 579 isIOS: /(iPad|iPhone|iPod)/g.test(userAgent), 580 isSafari: /constructor/i.test(window.HTMLElement) || (function (p) { 581 return p.toString() === "[object SafariRemoteNotification]"; 582 })(!window['safari'] || safari.pushNotification), 583 prefix: (function () { 584 var styles = window.getComputedStyle(document.documentElement, ''), 585 pre = (Array.prototype.slice 586 .call(styles) 587 .join('') 588 .match(/-(moz|webkit|ms)-/))[1], 589 dom = ('WebKit|Moz|MS').match(new RegExp('(' + pre + ')', 'i'))[1]; 590 return { 591 dom: dom, 592 lowercase: pre, 593 css: '-' + pre + '-', 594 js: pre[0].toUpperCase() + pre.substr(1) 595 }; 596 })(), 597 598 __extends: function (child, parent) { 599 for (var key in parent) 600 if (parent.hasOwnProperty(key)) child[key] = parent[key]; 601 602 function Ctor() { 603 this.constructor = child; 604 } 605 606 Ctor.prototype = parent.prototype; 607 child.prototype = new Ctor(); 608 child.__super = parent.prototype; 609 return child; 610 } 611 612 }; 613 614 //caching the utils 615 616 var SOURCE_TYPE = DFLIP.SOURCE_TYPE, 617 DISPLAY_TYPE = DFLIP.DISPLAY_TYPE, 618 619 drag = utils.drag, 620 mouseEvents = utils.mouseEvents, 621 html = utils.html, 622 isset = utils.isset, 623 isnull = utils.isnull, 624 625 toRad = utils.toRad, 626 toDeg = utils.toDeg, 627 transition = utils.transition, 628 translateStr = utils.translateStr, 629 resetBoxShadow = utils.resetBoxShadow, 630 rotateStr = utils.rotateStr, 631 632 bg = utils.bg, 633 bgImage = utils.bgImage, 634 src = utils.src, 635 636 limitAt = utils.limitAt, 637 distOrigin = utils.distOrigin, 638 distPoints = utils.distPoints, 639 angleByDistance = utils.angleByDistance, 640 log = utils.log, 641 nearestPowerOfTwo = utils.nearestPowerOfTwo, 642 extendOptions = utils.extendOptions, 643 getBasePage = utils.getBasePage, 644 getScript = utils.getScript, 645 fixMouseEvent = utils.fixMouseEvent, 646 prefix = utils.prefix, 647 isBookletMode = utils.isBookletMode, 648 isRTLMode = utils.isRTLMode, 649 isMobile = utils.isMobile, 650 hasWebgl = utils.hasWebgl, 651 isSafari = utils.isSafari, 652 isIOS = utils.isIOS, 653 __extends = utils.__extends; 654
655 // Support: IE<11, Chrome<21, Android<4.4, Safari<6 656 (function checkSetPresenceInImageData() { 657 // IE < 11 will use window.CanvasPixelArray which lacks set function. 658 if (window.CanvasPixelArray) { 659 if (typeof window.CanvasPixelArray.prototype.set !== 'function') { 660 window.CanvasPixelArray.prototype.set = function (arr) { 661 for (var i = 0, ii = this.length; i < ii; i++) { 662 this[i] = arr[i]; 663 } 664 }; 665 } 666 } 667 else { 668 // Old Chrome and Android use an inaccessible CanvasPixelArray prototype. 669 // Because we cannot feature detect it, we rely on user agent parsing. 670 var polyfill = false, versionMatch; 671 if (isSafari) { 672 versionMatch = userAgent.match(/Version\/([0-9]+)\.([0-9]+)\.([0-9]+) Safari\//); 673 // Safari < 6 lacks the set function. 674 polyfill = versionMatch && parseInt(versionMatch[1]) < 6; 675 } 676 677 if (polyfill) { 678 var contextPrototype = window.CanvasRenderingContext2D.prototype; 679 var createImageData = contextPrototype.createImageData; 680 contextPrototype.createImageData = function (w, h) { 681 var imageData = createImageData.call(this, w, h); 682 imageData.data.set = function (arr) { 683 for (var i = 0, ii = this.length; i < ii; i++) { 684 this[i] = arr[i]; 685 } 686 }; 687 return imageData; 688 }; 689 // this closure will be kept referenced, so clear its vars 690 contextPrototype = null; 691 } 692 } 693 })(); 694 695 // Support: IE<10, Android<4.0, iOS 696 (function checkRequestAnimationFrame() { 697 function fakeRequestAnimationFrame(callback) { 698 window.setTimeout(callback, 20); 699 } 700 701 if ('requestAnimationFrame' in window) { 702 return; 703 } 704 window.requestAnimationFrame = 705 window.mozRequestAnimationFrame || 706 window.webkitRequestAnimationFrame || 707 fakeRequestAnimationFrame; 708 })(); 709 710 // Checking if the typed arrays are supported 711 // Support: iOS<6.0 (subarray), IE<10, Android<4.0 712 (function checkTypedArrayCompatibility() { 713 if (typeof Uint8Array !== 'undefined') { 714 // Support: iOS<6.0 715 if (typeof Uint8Array.prototype.subarray === 'undefined') { 716 Uint8Array.prototype.subarray = function subarray(start, end) { 717 return new Uint8Array(this.slice(start, end)); 718 }; 719 Float32Array.prototype.subarray = function subarray(start, end) { 720 return new Float32Array(this.slice(start, end)); 721 }; 722 } 723 724 // Support: Android<4.1 725 if (typeof Float64Array === 'undefined') { 726 window.Float64Array = Float32Array; 727 } 728 return; 729 } 730 731 function subarray(start, end) { 732 return new TypedArray(this.slice(start, end)); 733 } 734 735 function setArrayOffset(array, offset) { 736 if (arguments.length < 2) { 737 offset = 0; 738 } 739 for (var i = 0, n = array.length; i < n; ++i, ++offset) { 740 this[offset] = array[i] & 0xFF; 741 } 742 } 743 744 function TypedArray(arg1) { 745 var result, i, n; 746 if (typeof arg1 === 'number') { 747 result = []; 748 for (i = 0; i < arg1; ++i) { 749 result[i] = 0; 750 } 751 } 752 else if ('slice' in arg1) { 753 result = arg1.slice(0); 754 } 755 else { 756 result = []; 757 for (i = 0, n = arg1.length; i < n; ++i) { 758 result[i] = arg1[i]; 759 } 760 } 761 762 result.subarray = subarray; 763 result.buffer = result; 764 result.byteLength = result.length; 765 result.set = setArrayOffset; 766 767 if (typeof arg1 === 'object' && arg1.buffer) { 768 result.buffer = arg1.buffer; 769 } 770 return result; 771 } 772 773 window.Uint8Array = TypedArray; 774 window.Int8Array = TypedArray; 775 776 // we don't need support for set, byteLength for 32-bit array 777 // so we can use the TypedArray as well 778 window.Uint32Array = TypedArray; 779 window.Int32Array = TypedArray; 780 window.Uint16Array = TypedArray; 781 window.Float32Array = TypedArray; 782 window.Float64Array = TypedArray; 783 })(); 784 785 var extendDFlipOptions = function (options) { 786 return $.extend(true, {}, defaults, options); 787 }; 788 789 //Creates ui for the flipbook 790 var createUI = function (container, object) { 791 792 var uiClass = "df-ui"; 793 var wrapperClass = "df-ui-wrapper"; 794 var buttonClass = uiClass + "-" + "btn"; 795 var isRTL = isRTLMode(object.target); 796 var ui = object.ui = $(html.div, {'class': uiClass}); 797 var options = object.options; 798 799 ui.dispose = function () { 800 container.find("." + buttonClass).each(function () { 801 $(this).off(); 802 }); 803 help.off(); 804 next.off(); 805 prev.off(); 806 play.off(); 807 zoom.off(); 808 zoomIn.off(); 809 zoomOut.off(); 810 page.off(); 811 sound.off(); 812 more.off(); 813 fullScreen.off(); 814 fit.off(); 815 share.off(); 816 start.off(); 817 end.off(); 818 pageModeButton.off(); 819 altPrev.off(); 820 altNext.off(); 821 thumbnail.off(); 822 outline.off(); 823 824 controls.remove(); 825 sizeControls.remove(); 826 prev.remove(); 827 next.remove(); 828 zoom.remove(); 829 if (ui.shareBox) { 830 if (ui.shareBox.dispose) 831 ui.shareBox.dispose(); 832 ui.shareBox = null; 833 } 834 document.removeEventListener('keyup', onKeyUp, false); 835 window.removeEventListener('click', closeMoreOptions, false); 836 ui.update = null; 837 object = null; 838 }; 839
840 var validPage = function (pageNumber) { 841 842 if (isNaN(pageNumber)) pageNumber = object.target._activePage; 843 else if (pageNumber < 1) pageNumber = 1; 844 else if (pageNumber > object.target.pageCount) pageNumber = object.target.pageCount; 845 return pageNumber; 846 847 }; 848 849 var next = ui.next = $(html.div, { 850 851 class: buttonClass + " " + uiClass + "-next " + options.icons['next'], 852 title: isRTL ? options.text.previousPage : options.text.nextPage, 853 html: "<span>" + options.text.nextPage + "</span>" 854 855 }).on("click", function () { 856 object.next(); 857 }); 858 859 var prev = ui.prev = $(html.div, { 860 861 class: buttonClass + " " + uiClass + "-prev " + options.icons['prev'], 862 title: isRTL ? options.text.nextPage : options.text.previousPage, 863 html: "<span>" + options.text.previousPage + "</span>" 864 865 }).on("click", function () { 866 867 object.prev(); 868 869 }); 870 var play = $(html.div, { 871 872 class: buttonClass + " " + uiClass + "-play " + options.icons['play'], 873 title: options.text.play, 874 html: "<span>" + options.text.play + "</span>" 875 876 }).on("click", function () { 877 var el = $(this); 878 object.setAutoPlay(!el.hasClass(options.icons['pause'])); 879 880 }); 881 if (options.autoPlay == true) { 882 ui.play = play; 883 object.setAutoPlay(options.autoPlayStart); 884 } 885 var zoom = $(html.div, { 886 class: wrapperClass + " " + uiClass + "-zoom" 887 }); 888 889 var zoomIn = ui.zoomIn = $(html.div, { 890 891 class: buttonClass + " " + uiClass + "-zoomin " + options.icons['zoomin'], 892 title: options.text.zoomIn, 893 html: "<span>" + options.text.zoomIn + "</span>" 894 895 }).on("click", function () { 896 897 object.zoom(1); 898 ui.update(); 899 if (object.target.startPoint && object.target.pan) 900 object.target.pan(object.target.startPoint); 901 902 }); 903 904 var zoomOut = ui.zoomOut = $(html.div, { 905 906 class: buttonClass + " " + uiClass + "-zoomout " + options.icons['zoomout'], 907 title: options.text.zoomOut, 908 html: "<span>" + options.text.zoomOut + "</span>" 909 910 }).on("click", function () { 911 object.zoom(-1); 912 ui.update(); 913 if (object.target.startPoint && object.target.pan) 914 object.target.pan(object.target.startPoint); 915 }); 916 zoom.append(zoomIn).append(zoomOut); 917 918 var page = ui.pageNumber = $(html.div, { 919 920 class: buttonClass + " " + uiClass + "-page", 921 922 }).on("change", function () { 923 924 var pageNumber = parseInt((ui.pageInput.val()), 10); 925 926 pageNumber = validPage(pageNumber); 927 object.gotoPage(pageNumber); 928 929 }).on("keyup", function (event) { 930 931 if (event.keyCode == 13) { 932 var pageNumber = parseInt((ui.pageInput.val()), 10); 933 934 pageNumber = validPage(pageNumber); 935 if (pageNumber !== validPage(object.target._activePage || object._activePage)) 936 object.gotoPage(pageNumber); 937 } 938 939 }); 940 941 ui.pageInput = $('<input id="df_book_page_number" type="text"/>').appendTo(page); 942 ui.pageLabel = $('<label for="df_book_page_number"/>').appendTo(page); 943 944 var sizeControls = $(html.div, { 945 class: wrapperClass + " " + uiClass + "-size" 946 }); 947 948 var help = $(html.div, { 949 class: buttonClass + " " + uiClass + "-help " + options.icons['help'], 950 title: options.text.toggleHelp, 951 html: "<span>" + options.text.toggleHelp + "</span>" 952 }).on("click", function () { 953 954 }); 955 956 957 //Sound Button 958 var sound = ui.sound = $(html.div, { 959 960 class: buttonClass + " " + uiClass + "-sound " + options.icons['sound'], 961 title: options.text.toggleSound, 962 html: "<span>" + options.text.toggleSound + "</span>" 963 964 }).on("click", function () { 965 966 options.soundEnable = !options.soundEnable; 967 ui.updateSound(); 968 969 }); 970 971 //Updates sound on click of sound button 972 ui.updateSound = function () { 973 974 if (options.soundEnable == false || options.soundEnable == 'false') 975 sound.addClass("disabled"); 976 else 977 sound.removeClass("disabled"); 978 979 }; 980 981 //immediate check 982 ui.updateSound(); 983 984 //Search button 985 //closes searchoptions container 986 function closeSearchOptions(event) { 987 ui.search.removeClass("df-active"); 988 } 989 990 if (typeof options.source == 'string' && options.search == true) { 991 var search = ui.search = $(html.div, { 992 993 class: buttonClass + " " + uiClass + "-search " + options.icons['search'] 994 995 }).on("click", function (event) { 996 if (!search.hasClass("df-active")) { 997 $(this).addClass("df-active"); 998 event.stopPropagation(); 999 } 1000 }); 1001 1002 1003 //register a click event on window to close the searchoptions 1004 window.addEventListener('click', closeSearchOptions, false); 1005 1006 //search container that holds the searchoptions 1007 var searchContainer = $(html.div, { 1008 class: "search-container" 1009 }); 1010 search.append(searchContainer); 1011 } 1012 1013 //More button 1014 var more = ui.more = $(html.div, { 1015 1016 class: buttonClass + " " + uiClass + "-more " + options.icons['more'] 1017 1018 }).on("click", function (event) { 1019 if (!more.hasClass("df-active")) { 1020 $(this).addClass("df-active"); 1021 event.stopPropagation(); 1022 } 1023 }); 1024 1025 //closes moreoptions container 1026 function closeMoreOptions(event) { 1027 more.removeClass("df-active"); 1028 } 1029 1030 //register a click event on window to close the moreoptions 1031 window.addEventListener('click', closeMoreOptions, false); 1032 1033 //more container that holds the moreoptions 1034 var moreContainer = $(html.div, { 1035 class: "more-container" 1036 }); 1037 more.append(moreContainer); 1038 1039 if (typeof options.source == 'string' && options.enableDownload == true) { 1040 var downloadClass = buttonClass + " " + uiClass + "-download " + options.icons['download']; 1041 var download = ui.download = $('<a download target="_blank" class="' + downloadClass + '"><span>' + options.text.downloadPDFFile + '</span></a>'); 1042 download.attr("href", options.source).attr("title", options.text.downloadPDFFile); 1043 //moreContainer.append(download); 1044 } 1045 1046 var fullscreenEnabled = utils.hasFullscreenEnabled(); 1047 1048 if (!fullscreenEnabled) { 1049 container.addClass("df-custom-fullscreen"); 1050 } 1051 1052 ui.switchFullscreen = function () { 1053 1054 var fullscreenElement = utils.getFullscreenElement(); 1055 1056 var container = object.container[0]; 1057 1058 if (ui.isFullscreen != true) { 1059 1060 object.container.addClass("df-fullscreen"); 1061 if (container.requestFullscreen) { 1062 container.requestFullscreen(); 1063 } 1064 else if (container.msRequestFullscreen) { 1065 container.msRequestFullscreen(); 1066 } 1067 else if (container.mozRequestFullScreen) { 1068 container.mozRequestFullScreen(); 1069 } 1070 else if (container.webkitRequestFullscreen) { 1071 container.webkitRequestFullscreen(); 1072 } 1073 1074 ui.isFullscreen = true 1075 1076 } 1077 else { 1078 1079 object.container.removeClass("df-fullscreen"); 1080 ui.isFullscreen = false;
1081 1082 if (document.exitFullscreen) { 1083 document.exitFullscreen(); 1084 } 1085 else if (document.msExitFullscreen) { 1086 document.msExitFullscreen(); 1087 } 1088 else if (document.mozCancelFullScreen) { 1089 document.mozCancelFullScreen(); 1090 } 1091 else if (document.webkitExitFullscreen) { 1092 document.webkitExitFullscreen(); 1093 } 1094 1095 } 1096 1097 if (!utils.hasFullscreenEnabled()) { 1098 setTimeout(function () { 1099 object.resize(); 1100 }, 50); 1101 } 1102 }; 1103 1104 var fullScreen = ui.fullScreen = $(html.div, { 1105 1106 class: buttonClass + " " + uiClass + "-fullscreen " + options.icons['fullscreen'], 1107 title: options.text.toggleFullscreen, 1108 html: "<span>" + options.text.toggleFullscreen + "</span>" 1109 1110 }).on("click", ui.switchFullscreen); 1111 1112 var fit = ui.fit = $(html.div, { 1113 1114 class: buttonClass + " " + uiClass + "-fit " + options.icons['fitscreen'] 1115 1116 }).on("click", function () { 1117 1118 $(this).toggleClass("df-button-fit-active"); 1119 1120 }); 1121 sizeControls.append(fullScreen); 1122 1123 var controls = $(html.div, { 1124 class: wrapperClass + " " + uiClass + "-controls" 1125 }); 1126 1127 var shareBox = ui.shareBox = new DFLIP.Share(container, options); 1128 1129 var share = ui.share = $(html.div, { 1130 1131 class: buttonClass + " " + uiClass + "-share " + options.icons['share'], 1132 title: options.text.share, 1133 html: "<span>" + options.text.share + "</span>" 1134 1135 }).on("click", function (event) { 1136 if (ui.shareBox.isOpen == true) 1137 ui.shareBox.close(); 1138 else { 1139 ui.shareBox.update(object.getURLHash()); 1140 ui.shareBox.show(); 1141 } 1142 }); 1143 1144 var start = ui.startPage = $(html.div, { 1145 1146 class: buttonClass + " " + uiClass + "-start " + (isRTL ? options.icons['end'] : options.icons['start']), 1147 title: options.text.gotoFirstPage, 1148 html: "<span>" + options.text.gotoFirstPage + "</span>" 1149 1150 }).on("click", function () { 1151 1152 object.start(); 1153 1154 }); 1155 1156 1157 var end = ui.endPage = $(html.div, { 1158 1159 class: buttonClass + " " + uiClass + "-end " + (isRTL ? options.icons['start'] : options.icons['end']), 1160 title: options.text.gotoLastPage, 1161 html: "<span>" + options.text.gotoLastPage + "</span>" 1162 1163 }).on("click", function () { 1164 1165 object.end(); 1166 1167 }); 1168 1169 var pageModeButton = ui.pageMode = $(html.div, { 1170 1171 class: buttonClass + " " + uiClass + "-pagemode " + options.icons['singlepage'], 1172 html: "<span>" + options.text.singlePageMode + "</span>" 1173 1174 }).on("click", function () { 1175 1176 var el = $(this); 1177 object.setPageMode(!el.hasClass(options.icons['doublepage'])); 1178 1179 }); 1180 1181 1182 object.setPageMode(object.target.pageMode == DFLIP.PAGE_MODE.SINGLE) 1183 //moreContainer.append(pageModeButton).append(start).append(end).append(sound); 1184 1185 var altPrev = ui.altPrev = $(html.div, { 1186 1187 class: buttonClass + " " + uiClass + "-prev" + " " + uiClass + "-alt " + options.icons['prev'], 1188 title: isRTL ? options.text.nextPage : options.text.previousPage, 1189 html: "<span>" + options.text.previousPage + "</span>" 1190 1191 }).on("click", function () { 1192 object.prev(); 1193 }); 1194 1195 var altNext = ui.altNext = $(html.div, { 1196 1197 class: buttonClass + " " + uiClass + "-next" + " " + uiClass + "-alt " + options.icons['next'], 1198 title: isRTL ? options.text.previousPage : options.text.nextPage, 1199 html: "<span>" + options.text.nextPage + "</span>" 1200 1201 }).on("click", function () { 1202 object.next(); 1203 }); 1204 1205 var thumbnail = ui.thumbnail = $(html.div, { 1206 1207 class: buttonClass + " " + uiClass + "-thumbnail " + options.icons['thumbnail'], 1208 title: options.text.toggleThumbnails, 1209 html: "<span>" + options.text.toggleThumbnails + "</span>" 1210 1211 }).on("click", function () { 1212 var $this = $(this); 1213 if (object.target.thumbContainer) { 1214 var thumbContainer = object.target.thumbContainer; 1215 thumbContainer.toggleClass("df-sidemenu-visible"); 1216 $this.toggleClass("df-active"); 1217 } 1218 else { 1219 object.contentProvider.initThumbs(); 1220 $this.toggleClass("df-active"); 1221 } 1222 if ($this.hasClass("df-active")) { 1223 $this.siblings(".df-active").trigger("click"); 1224 } 1225 ui.update(true); 1226 }); 1227 1228 var outline = ui.outline = $(html.div, { 1229 1230 class: buttonClass + " " + uiClass + "-outline " + options.icons['outline'], 1231 title: options.text.toggleOutline, 1232 html: "<span>" + options.text.toggleOutline + "</span>" 1233 1234 }).on("click", function () { 1235 var $this = $(this); 1236 if (object.target.outlineContainer) { 1237 var outlineContainer = object.target.outlineContainer; 1238 $this.toggleClass("df-active"); 1239 outlineContainer.toggleClass("df-sidemenu-visible"); 1240 if ($this.hasClass("df-active")) { 1241 $this.siblings(".df-active").trigger("click"); 1242 } 1243 ui.update(true); 1244 } 1245 }); 1246 1247 /** 1248 * Controls position and pplace ment is determined by options.moreControls and options.hideControls 1249 */ 1250 var allControls = options.allControls.replace(/ /g, '').split(','), 1251 moreControls = "," + options.moreControls.replace(/ /g, '') + ",", 1252 hideControls = "," + options.hideControls.replace(/ /g, '') + ","; 1253 1254 var moreControlsArray = moreControls.split(','); 1255 1256 for (var controlCount = 0; controlCount < allControls.length; controlCount++) { 1257 //if hidden skip 1258 var controlName = allControls[controlCount]; 1259 if (hideControls.indexOf("," + controlName + ",") < 0) { //not found in hide list 1260 var control = ui[controlName]; 1261 if (control != null) { 1262 if (moreControls.indexOf("," + controlName + ",") > -1 && controlName !== 'more' && controlName !== 'pageNumber') {//found in more controls 1263 moreContainer.append(control); 1264 } 1265 else { 1266 controls.append(control); 1267 } 1268 } 1269 } 1270 } 1271 1272 container.append(controls).append(prev).append(next).append(zoom); 1273 1274 var ctrlDown = false, shiftDown = false, altDown = false;
1275 var shiftKey = 16, ctrlKey = 17, altKey = 18, sKey = 83, vKey = 86, cKey = 67, eKey = 69, gKey = 71, nKey = 78, 1276 oKey = 79, deleteKey = 46, rightKey = 39, leftKey = 37, escKey = 27; 1277 1278 document.addEventListener('keyup', onKeyUp, false); 1279 1280 function onKeyUp(event) { 1281 switch (event.keyCode) { 1282 case escKey: 1283 if (ui.isFullscreen == true) ui.fullScreen.trigger("click"); 1284 break; 1285 case shiftKey: 1286 shiftDown = false; 1287 break; 1288 case ctrlKey: 1289 ctrlDown = false; 1290 break; 1291 case altKey: 1292 altDown = false; 1293 break; 1294 case leftKey: 1295 object.prev(); 1296 break; 1297 case rightKey: 1298 object.next(); 1299 break; 1300 default: 1301 break; 1302 } 1303 //log(event.keyCode); 1304 } 1305 1306 ui.update = function (resize) { 1307 log("ui update"); 1308 var target = object.target; 1309 1310 var pageNumber = validPage(target._activePage || object._activePage); 1311 var pageCount = target.pageCount || object.pageCount; 1312 1313 var isRTL = target.direction == DFLIP.DIRECTION.RTL, 1314 isStart = (pageNumber == 1 || pageNumber == 0), 1315 isEnd = pageNumber == pageCount; 1316 1317 ui.next.show(); 1318 ui.prev.show(); 1319 ui.altNext.removeClass("disabled"); 1320 ui.altPrev.removeClass("disabled"); 1321 1322 if ((isStart && !isRTL) || (isEnd && isRTL)) { 1323 ui.prev.hide(); 1324 ui.altPrev.addClass("disabled"); 1325 } 1326 if ((isEnd && !isRTL) || (isStart && isRTL)) { 1327 ui.next.hide(); 1328 ui.altNext.addClass("disabled"); 1329 } 1330 1331 ui.pageInput.val(pageNumber); 1332 ui.pageLabel.html((pageNumber) + "/" + pageCount); 1333 1334 1335 if (container.find(".df-sidemenu-visible").length > 0) { 1336 container.addClass("df-sidemenu-open"); 1337 } 1338 else { 1339 container.removeClass("df-sidemenu-open"); 1340 } 1341 if (resize == true) 1342 object.resize(); 1343 1344 if (target.contentProvider.zoomScale == target.contentProvider.maxZoom) { 1345 ui.zoomIn.addClass("disabled"); 1346 } 1347 else { 1348 ui.zoomIn.removeClass("disabled"); 1349 } 1350 1351 if (target.contentProvider.zoomScale == 1) { 1352 ui.zoomOut.addClass("disabled"); 1353 } 1354 else { 1355 ui.zoomOut.removeClass("disabled"); 1356 } 1357 1358 }; 1359 1360 if (object.target != null) { 1361 object.target.ui = ui; 1362 } 1363 1364 if (options.onCreateUI != null) 1365 options.onCreateUI(object); 1366 } 1367 ; 1368 1369 var PreviewStage = null; 1370 //later updated via RegisterMockupObjects in case 3d is requested 1371 1372 //Registers necessary mockup object when required 1373 function RegisterMockupObjects() { 1374 1375 PreviewStage = (function (_super) { 1376 __extends(PreviewStage, _super); 1377 1378 function PreviewStage(parameters) { 1379 parameters = parameters || {}; 1380 var _this = this; 1381 _super.call(this, parameters); 1382 _this.options = parameters; 1383 _this.canvas = $(_this.renderer.domElement).addClass("df-3dcanvas"); 1384 _this.container = parameters.container; 1385 _this.container.append(_this.canvas); 1386 //_this.container.height(parameters.height); 1387 _this.type = "PreviewStage"; 1388 _this.mouse = new THREE.Vector2(); 1389 _this.raycaster = new THREE.Raycaster(); 1390 1391 _this.camera.position.set(0, 20, 600); 1392 _this.camera.lookAt(new THREE.Vector3(0, 0, 0)); 1393 1394 //shadows are zigzap due to shadow camera position 1395 _this.spotLight.position.set(-220, 330, 550); 1396 1397 _this.spotLight.castShadow = isMobile ? false : parameters.webglShadow; 1398 //_this.spotLight.shadowDarkness = 0.6; 1399 if (_this.spotLight.shadow) { 1400 _this.spotLight.shadow.bias = -0.0008; 1401 } 1402 _this.spotLight.intensity = isset(parameters.spotLightIntensity, defaults.spotLightIntensity); 1403 _this.ambientLight.color = new THREE.Color(isset(parameters.ambientLightColor, defaults.ambientLightColor)); 1404 _this.ambientLight.intensity = isset(parameters.ambientLightIntensity, defaults.ambientLightIntensity); 1405 1406 var material = new THREE.ShadowMaterial(); 1407 material.opacity = isset(parameters.shadowOpacity, defaults.shadowOpacity); 1408 1409 _this.ground.material = material; 1410 _this.ground.position.z = -2; 1411 1412 //Restrict right left camera movement. 1413 _this.orbitControl.maxAzimuthAngle = 0; 1414 _this.orbitControl.minAzimuthAngle = 0; 1415 1416 _this.orbitControl.minPolarAngle = Math.PI / 2; 1417 _this.orbitControl.maxPolarAngle = 2.2; 1418 1419 //_this.orbitControl.maxPolarAngle = 10; 1420 _this.orbitControl.mouseButtons.ORBIT = THREE.MOUSE.RIGHT;
1421 _this.orbitControl.mouseButtons.PAN = -1; 1422 _this.orbitControl.maxDistance = 5000; 1423 _this.orbitControl.minDistance = 50; 1424 _this.orbitControl.noZoom = true; 1425 1426 _this.selectiveRendering = true; 1427 1428 _this.orbitControl.zoomSpeed = 5; 1429 1430 _this.orbitControl.keyPanSpeed = 0; 1431 _this.orbitControl.center.set(0, 0, 0); 1432 _this.orbitControl.update(); 1433 1434 _this.swipe_threshold = isMobile ? 15 : 20; 1435 1436 var cssRenderer = _this.cssRenderer = new THREE.CSS3DRenderer(); 1437 $(cssRenderer.domElement).css({ 1438 position: "absolute", 1439 top: 0, 1440 pointerEvents: "none" 1441 }).addClass("df-3dcanvas df-csscanvas"); 1442 _this.container[0].appendChild(cssRenderer.domElement); 1443 1444 var cssScene = _this.cssScene = new THREE.Scene(); 1445 1446 var divLeftDOM = document.createElement("div"); 1447 divLeftDOM.className = "df-page-content df-page-content-left"; 1448 1449 var divRightDOM = document.createElement("div"); 1450 divRightDOM.className = "df-page-content df-page-content-right"; 1451 1452 var divLeft = cssScene.divLeft = new THREE.CSS3DObject(divLeftDOM); 1453 var divRight = cssScene.divRight = new THREE.CSS3DObject(divRightDOM); 1454 cssScene.add(divLeft); 1455 cssScene.add(divRight); 1456 1457 _this.resizeCallback = function () { 1458 cssRenderer.setSize(_this.canvas.width(), _this.canvas.height()); 1459 }; 1460 1461 function requestRender() { 1462 _this.renderRequestPending = true; 1463 } 1464 1465 window.addEventListener(mouseEvents.move, requestRender, false); 1466 1467 window.addEventListener('keyup', requestRender, false); 1468 1469 1470 _this.dispose = function () { 1471 1472 _this.clearChild(); 1473 _this.render(); 1474 1475 window.removeEventListener(mouseEvents.move, requestRender, false); 1476 1477 if (_this.options.scrollWheel == true) { 1478 _this.container[0].removeEventListener('mousewheel', onMouseWheel, false); 1479 _this.container[0].removeEventListener('DOMMouseScroll', onMouseWheel, false); // firefox 1480 } 1481 1482 window.removeEventListener('keyup', requestRender, false); 1483 1484 _this.renderer.domElement.removeEventListener("mousemove", editor_mouseMove, false); 1485 _this.renderer.domElement.removeEventListener("touchmove", editor_mouseMove, false); 1486 1487 _this.renderer.domElement.removeEventListener("mousedown", editor_mouseDown, false); 1488 _this.renderer.domElement.removeEventListener("touchstart", editor_mouseDown, false); 1489 _this.renderer.domElement.removeEventListener("mouseup", editor_mouseUp, false); 1490 _this.renderer.domElement.removeEventListener("touchend", editor_mouseUp, false); 1491 1492 1493 _this.canvas.remove(); 1494 1495 cssRenderer.domElement.parentNode.removeChild(cssRenderer.domElement); 1496 1497 cssRenderer = null; 1498 1499 _this.renderCallback = null; 1500 _this.renderCallback = null; 1501 _this.orbitControl.dispose(); 1502 _this.orbitControl = null; 1503 1504 1505 _this.renderer.dispose(); 1506 1507 _this.cancelRAF(); 1508 }; 1509 1510 _this.renderCallback = function () { 1511 if (TWEEN.getAll().length > 0) 1512 _this.renderRequestPending = true; 1513 TWEEN.update(); 1514 cssRenderer.render(cssScene, _this.camera) 1515 }; 1516 1517 var onMouseWheel = function (event) { 1518 var delta = 0; 1519 1520 if (event.wheelDelta != null) { // WebKit / Opera / Explorer 9 1521 1522 delta = event.wheelDelta; 1523 1524 } 1525 else if (event.detail != null) { // Firefox 1526 1527 delta = -event.detail; 1528 1529 } 1530 if (delta) { 1531 var currentZoom = _this.previewObject.contentProvider.zoomScale; 1532 if ((delta > 0 && currentZoom == 1) 1533 || (delta < 0 && currentZoom > 1)) { 1534 event.preventDefault(); 1535 } 1536 _this.previewObject.zoom(delta > 0 ? 1 : -1); 1537 } 1538 1539 requestRender(); 1540 }; 1541 1542 var editor_mouseMove = function (event) { 1543 1544 _this.renderRequestPending = true; 1545 event = fixMouseEvent(event); 1546 if (_this.isMouseDown && event.movementX != 0 && event.movementY != 0) { 1547 _this.isMouseMoving = true; 1548 } 1549 if (event.touches != null && event.touches.length == 2 && _this.startTouches != null) { 1550 //return; 1551 // _this.startTouches = event.touches; 1552 _this.zoomDirty = true; 1553 var touchCenter = utils.getVectorAvg(utils.getTouches(event, _this.container.offset())), 1554 newScale = utils.calculateScale(_this.startTouches, utils.getTouches(event)), 1555 scale = newScale / _this.lastScale; 1556 1557 var zoom = _this.previewObject.contentProvider.zoomScale, 1558 x = touchCenter.x, 1559 y = touchCenter.y; 1560 1561 _this.camera.position.z = _this.originalZ / (newScale); 1562 _this.lastScale = newScale; 1563 1564 _this.lastZoomCenter = touchCenter; 1565 event.preventDefault(); 1566 return; 1567 } 1568 if (_this.isMouseDown == true && _this.previewObject.contentProvider.zoomScale == 1) { 1569 //check if swipe has happened 1570 1571 var swipe_dist = event.pageX - _this.lastPos, 1572 swipe_time = performance.now() - _this.lastTime; 1573 1574 //$("body > p").html(swipe_dist); 1575 1576 if (Math.abs(swipe_dist) > _this.swipe_threshold) { 1577 //swipe has triggered 1578 //_this.dragPage.pendingPoint = point; 1579 if (swipe_dist < 0) { 1580 _this.target.next(); 1581 } 1582 else { 1583 _this.target.prev(); 1584 } 1585 event.preventDefault(); 1586 _this.isMouseDown = false;
1587 } 1588 _this.lastPos = event.pageX; 1589 _this.lastTime = performance.now(); 1590 1591 } 1592 }; 1593 1594 var editor_mouseDown = function (event) { 1595 event = fixMouseEvent(event); 1596 if (event.touches != null && event.touches.length == 2 && _this.startTouches == null) { 1597 _this.startTouches = utils.getTouches(event); 1598 _this.lastScale = 1; 1599 _this.originalZ = _this.camera.position.z * 1; 1600 } 1601 document.activeElement.blur(); 1602 _this.mouseValue = event.pageX + "," + event.pageY; 1603 _this.isMouseMoving = false; 1604 _this.isMouseDown = true; 1605 _this.lastPos = event.pageX; 1606 _this.lastTime = performance.now(); 1607 }; 1608 1609 var editor_click = function (event) { 1610 _this.isMouseDown = false; 1611 //bail out if it's not left click 1612 if (event.button !== 0) return this; 1613 var mouseValue = event.pageX + "," + event.pageY; 1614 1615 if (_this.isMouseMoving) { 1616 1617 } 1618 else if (mouseValue == _this.mouseValue) { 1619 event = event || window.event; 1620 event = $.event.fix(event); 1621 1622 var mouse = _this.mouse, raycaster = _this.raycaster; 1623 mouse.x = ((event.offsetX) / _this.canvas.innerWidth()) * 2 - 1; 1624 mouse.y = 1 - ((event.offsetY) / _this.canvas.innerHeight()) * 2; 1625 1626 raycaster.setFromCamera(mouse, _this.camera); 1627 1628 var intersects = raycaster.intersectObjects(_this.target instanceof MOCKUP.Bundle 1629 ? _this.target.children : [_this.target], true); 1630 1631 if (intersects.length > 0) { 1632 1633 var object, objectCount = 0; 1634 do { 1635 object = intersects[objectCount] != null ? intersects[objectCount].object : null; 1636 //bookStage.clickFace = intersects[objectCount].face; 1637 objectCount++; 1638 } while ((object instanceof THREE.BoxHelper || !(object instanceof MOCKUP.Paper) || object.isFlipping == true) && objectCount < intersects.length); 1639 1640 //if (object.parent instanceof MOCKUP.Bundle) { 1641 // object = object.parent; 1642 //} 1643 1644 if (object.userData.object != null) { 1645 1646 // helper 1647 1648 //bookStage.selectObject(object.userData.object); 1649 1650 } 1651 else { 1652 1653 if (object.angles[1] > 90) { 1654 if (object.isEdge != true) _this.target.next(); 1655 } 1656 else { 1657 if (object.isEdge != true) _this.target.prev(); 1658 } 1659 1660 } 1661 1662 } 1663 else { 1664 1665 //bookStage.selectObject(null); 1666 1667 } 1668 } 1669 //bookStage.stage.render(); 1670 }; 1671 1672 var editor_mouseUp = function (event) { 1673 event = fixMouseEvent(event); 1674 if (event.touches != null && event.touches.length == 0) { 1675 var zoom = _this.previewObject.contentProvider.zoomScale; 1676 if (_this.zoomDirty == true) { 1677 _this.previewObject.contentProvider.zoomScale = 1678 utils.limitAt(_this.previewObject.contentProvider.zoomScale * _this.lastScale, 1679 1, _this.previewObject.contentProvider.maxZoom); 1680 _this.previewObject.zoomValue = _this.previewObject.contentProvider.zoomScale * 1; 1681 //_this.previewObject.zoom(_this.lastScale < 1 ? -1 : 1); 1682 //console.log(_this.previewObject.contentProvider.zoomScale * _this.lastScale,_this.previewObject.contentProvider.maxZoom) 1683 //_this.previewObject.pendingZoom = true; 1684 _this.previewObject.resize(); 1685 _this.zoomDirty = false; 1686 } 1687 1688 _this.lastScale = null; 1689 _this.startTouches = null; 1690 } 1691 if (event.touches != null && event.touches.length > 1) return; 1692 editor_click(event); 1693 }; 1694 //if (MOCKUP.mode !== MOCKUP.MODE.PLUGIN) { 1695 1696 //_this.renderer.domElement.addEventListener('click', editor_click, false); 1697 //bookStage.renderer.domElement.addEventListener('dblclick', editor_dblclick, false); 1698 _this.renderer.domElement.addEventListener("mousemove", editor_mouseMove, false); 1699 _this.renderer.domElement.addEventListener("touchmove", editor_mouseMove, false); 1700 1701 _this.renderer.domElement.addEventListener("mousedown", editor_mouseDown, false); 1702 _this.renderer.domElement.addEventListener("touchstart", editor_mouseDown, false); 1703 _this.renderer.domElement.addEventListener("mouseup", editor_mouseUp, false); 1704 _this.renderer.domElement.addEventListener("touchend", editor_mouseUp, false); 1705 if (_this.options.scrollWheel == true) { 1706 _this.container[0].addEventListener('mousewheel', onMouseWheel, false); 1707 _this.container[0].addEventListener('DOMMouseScroll', onMouseWheel, false); // firefox 1708 } 1709 1710 //} 1711 1712 $(_this.renderer.domElement).css({display: "block"}); 1713 1714 $(window).trigger("resize"); 1715 1716 return this; 1717 } 1718 1719 PreviewStage.prototype.width = function () { 1720 return this.container.width(); 1721 }; 1722 1723 PreviewStage.prototype.height = function () { 1724 return this.container.height(); 1725 }; 1726 1727 return PreviewStage; 1728 1729 })(MOCKUP.Stage); 1730 MOCKUP.PreviewStage = PreviewStage; 1731 1732 var BookPaper = (function (_super) { 1733 __extends(BookPaper, _super); 1734 1735 function BookPaper(parameters, stage) { 1736 parameters = parameters || {}; 1737 parameters.folds = 1; 1738 _super.call(this, parameters, stage); 1739 this.angle = 0; 1740 this.isFlipping = false;
1741 this.material.materials[5].transparent = true; 1742 this.material.materials[4].transparent = true; 1743 this.type = "BookPaper"; 1744 } 1745 1746 BookPaper.prototype.tween = function (oldAngle, newAngle) { 1747 var page = this; 1748 var epsilon = 0.00001; 1749 page.originalStiff = page.stiffness; 1750 var oldTarget = page.newStiffness; 1751 var isBooklet = isBookletMode(page.parent); 1752 //console.log(page.stiffness); 1753 var diff = newAngle - oldAngle;//170 -5 == 165 : 5-170 = -165 1754 1755 var isRight = oldAngle > 90; 1756 var isRTL = page.parent.direction == DFLIP.DIRECTION.RTL; 1757 page.init = { 1758 angle: oldAngle, 1759 angle2: (oldAngle < 90 ? 0 : 180), 1760 stiff: page.originalStiff, 1761 index: (isRight && !isRTL) || (!isRight && isRTL) ? 1 : 0 1762 }; 1763 page.first = { 1764 angle: oldAngle + diff / 4, 1765 angle2: (oldAngle < 90 ? 90 : 90), 1766 stiff: page.originalStiff, 1767 index: (isRight && !isRTL) || (!isRight && isRTL) ? 1 : 0.25 1768 }; 1769 page.mid = { 1770 angle: oldAngle + diff * 2 / 4, 1771 angle2: (oldAngle < 90 ? 135 : 45), 1772 stiff: page.newStiffness, 1773 index: (isRight && !isRTL) || (!isRight && isRTL) ? 0.5 : 0.5 1774 }; 1775 page.mid2 = { 1776 angle: oldAngle + diff * 3 / 4, 1777 angle2: (oldAngle < 90 ? 180 : 0), 1778 stiff: page.newStiffness, 1779 index: (isRight && !isRTL) || (!isRight && isRTL) ? 0.25 : 1 1780 }; 1781 page.end = { 1782 angle: newAngle, 1783 angle2: (oldAngle < 90 ? 180 : 0), 1784 stiff: page.newStiffness, 1785 index: (isRight && !isRTL) || (!isRight && isRTL) ? 0 : 1 1786 }; 1787 1788 //console.log(page.init, page.first, page.mid, page.end); 1789 page.isFlipping = true; 1790 1791 var update = function (tween, event) { 1792 1793 page.angles[1] = tween.angle; 1794 page.angles[4] = page.isHard ? tween.angle : tween.angle2; 1795 if (page.isHard == true) { 1796 page.stiffness = 0; 1797 } 1798 else { 1799 page.stiffness = tween.stiff / (oldTarget + epsilon) * (page.newStiffness + epsilon); 1800 page.stiffness = isNaN(page.stiffness) ? 0 : tween.stiff; 1801 } 1802 if (isBooklet) { 1803 page.material.materials[5].opacity = page.material.materials[4].opacity = tween.index; 1804 page.castShadow = (isRight && !isRTL) || (!isRight && isRTL) ? tween.index > 0.5 : tween.index > 0.5; 1805 } 1806 //check if any sibling is flipping and their stiff is more that this 1807 1808 page.updateAngle(true); 1809 1810 }; 1811 1812 if (isBooklet && ((!isRight && !isRTL) || (isRight && isRTL))) { 1813 page.material.materials[5].opacity = page.material.materials[4].opacity = 0; 1814 page.castShadow = false; 1815 } 1816 1817 page.currentTween = new TWEEN.Tween(page.init) 1818 .to({ 1819 angle: [page.first.angle, page.mid.angle, page.mid2.angle, page.end.angle], 1820 angle2: [page.first.angle2, page.mid.angle2, page.mid2.angle2, page.end.angle2], 1821 stiff: [page.first.stiff, page.mid.stiff, page.mid2.stiff, page.end.stiff], 1822 index: [page.first.index, page.mid.index, page.mid2.index, page.end.index] 1823 }, page.parent.duration) 1824 .onUpdate(function (event) { 1825 update(this, event); 1826 }).easing(TWEEN.Easing.Sinusoidal.Out) 1827 .onComplete(function (event) { 1828 page.stiffness = page.newStiffness; 1829 page.updateAngle(); 1830 page.material.materials[5].opacity = page.material.materials[4].opacity = 1; 1831 page.castShadow = true; 1832 page.isFlipping = false; 1833 if (page.parent && page.parent.refresh) 1834 page.parent.refresh(); 1835 //console.log(page.stiffness); 1836 }).start(); 1837 1838 }; 1839 1840 return BookPaper; 1841 })(MOCKUP.FlexBoxPaper); 1842 MOCKUP.BookPaper = BookPaper; 1843 1844 var Book = (function (_super) { 1845 __extends(Book, _super); 1846 1847 function Book(parameters, stage) { 1848 1849 parameters = parameters || {}; 1850 parameters.segments = parameters.segments || 50; 1851 this.pageCount = parameters.pageCount; 1852 1853 this.height = parameters.height; 1854 this.width = parameters.width; 1855 1856 //correcting page count as multiple of 2 1857 this.pageCount = (this.pageCount == 1 ? this.pageCount : Math.
1857ceil(this.pageCount / 2) * 2); 1858 1859 this.direction = parameters.direction || DFLIP.DIRECTION.LTR; 1860 1861 this.startPage = 1; 1862 this.endPage = this.pageCount; 1863 1864 this.stackCount = parameters.stackCount || 6;// = 15; 1865 this.materials = []; 1866 1867 _super.call(this, parameters, stage); 1868 this.angles = [0, 0, 0, 0, 0, 0]; 1869 this.stiffness = parameters.stiffness == null ? 1.5 : parameters.stiffness; //so that 0 can be set 1870 this.hardConfig = parameters.hard; //hard is not that good in 3d 1871 this._activePage = parameters.openPage || this.startPage; 1872 1873 this.createStack(parameters); 1874 this.pageMode = parameters.pageMode || ((isMobile || this.pageCount <= 2) ? DFLIP.PAGE_MODE.SINGLE 1875 : DFLIP.PAGE_MODE.DOUBLE); 1876 1877 this.singlePageMode = parameters.singlePageMode || (isMobile ? DFLIP.SINGLE_PAGE_MODE.BOOKLET 1878 : DFLIP.SINGLE_PAGE_MODE.ZOOM); 1879 1880 1881 this.type = "Book"; 1882 1883 } 1884 1885 Book.prototype.getPageByNumber = function (pageNumber) { 1886 var relativePageNumber = isBookletMode(this) ? (isRTLMode(this) ? pageNumber + 1 : pageNumber) 1887 : Math.floor((pageNumber - 1) / 2); 1888 return this.getObjectByName(relativePageNumber.toString()); 1889 }; 1890 1891 Book.prototype.isPageHard = function (pageNumber) { 1892 1893 return utils.isHardPage(this.hardConfig, pageNumber, this.pageCount); 1894 1895 }; 1896 1897 Book.prototype.activePage = function (pageNumber) { 1898 if (pageNumber == null) return this._activePage; 1899 this.gotoPage(pageNumber); 1900 }; 1901 1902 Book.prototype.gotoPage = function (pageNumber) { 1903 pageNumber = parseInt(pageNumber, 10); 1904 this._activePage = pageNumber; 1905 if (this.autoPlay == true) { 1906 this.previewObject.setAutoPlay(this.autoPlay); 1907 } 1908 this.updatePage(pageNumber); 1909 if (this && this.thumblist && this.thumblist.review) 1910 this.thumblist.review(); 1911 }; 1912 1913 1914 Book.prototype.moveBy = function (step) { 1915 var nextPage = this._activePage + step; 1916 nextPage = limitAt(nextPage, this.startPage, this.endPage); 1917 if (this.firstFlipped != true) { 1918 this.previewObject.analytics({ 1919 eventAction: "First Page Flip", 1920 options: this.previewObject.options 1921 }); 1922 this.firstFlipped = true; 1923 } 1924 this.gotoPage(nextPage); 1925 }; 1926 1927 Book.prototype.next = function (step) { 1928 if (step == null) 1929 step = 1930 (this.direction == DFLIP.DIRECTION.RTL) 1931 ? -this.pageMode : this.pageMode; 1932 1933 this.moveBy(step); 1934 }; 1935 1936 Book.prototype.prev = function (step) { 1937 if (step == null) 1938 step = 1939 (this.direction == DFLIP.DIRECTION.RTL) 1940 ? this.pageMode : -this.pageMode; 1941 1942 this.moveBy(step); 1943 }; 1944 1945 Book.prototype.updateAngle = function () { 1946 1947 var startAngle = this.angles[1]; 1948 var endAngle = this.angles[4]; 1949 1950 var spreadAngle = endAngle - startAngle; 1951 var stacks = this.stackCount; 1952 1953 for (var _stackCount = 0; _stackCount < stacks; _stackCount++) { 1954 var clone = this.children[_stackCount]; 1955 //start from angle[1] and end at angles[4] 1956 clone.angles[1] = startAngle + _stackCount * spreadAngle / (stacks * 100); 1957 clone.stiffness = this.stiffness;//_stackCount/stacks; 1958 clone.updateAngle(); 1959 } 1960 1961 }; 1962 1963 Book.prototype.refresh = function () { 1964 this.updatePage(this._activePage); 1965 if (this.flipCallback != null) this.flipCallback(); 1966 }; 1967 1968 1969 Book.prototype.updatePage = function (pageNumber) { 1970 // this.contentProvider.setLoading(pageNumber, true); 1971 var isRTL = (this.direction == DFLIP.DIRECTION.RTL), 1972 isBooklet = isBookletMode(this), 1973 newBaseNumber = getBasePage(pageNumber); 1974 1975 var pageDivisor = isBooklet ? 1 : 2; 1976 1977 pageNumber = Math.floor((pageNumber / pageDivisor)); 1978 1979 if (isRTL) pageNumber = this.pageCount / pageDivisor - pageNumber; 1980 1981 var oldBaseNumber = this.oldBaseNumber || 0; 1982 var pageCount = this.pageCount / pageDivisor; 1983 var stackCount = this.stackCount; 1984 var angleShift = 0.02; 1985 var depth = 0.4; 1986 var stiffFactor = isBooklet ? 0 1987 : (0.5 - Math.abs(pageCount / 2 - pageNumber) / pageCount) / this.stiffness; 1988 var positionFactor = 1;//(stiffFactor +width); 1989 // var centre = Math.floor(stackCount / 2); 1990 var midPoint = Math.floor(stackCount / 2);//pageNumber < centre ? pageNumber //starting center pages 1991 // : ((pageCount - pageNumber > centre) ? centre //other pages 1992 //: (pageNumber + centre - pageCount)) ;//remainig center page 1993 //console.log(midPoint); 1994 1995 //var targetIndex = midPoint; 1996 //if(midPoint == centre) { 1997 /*This sitaution is good when there is icrement or decrement by 1*/ 1998 var isLeft = false;
1999 if (oldBaseNumber > pageNumber) { 2000 isLeft = true; 2001 this.children[stackCount - 1].skipFlip = true; 2002 this.children.unshift(this.children.pop()); 2003 2004 // this.contentProvider.setLoading(pageNumber, true); 2005 } 2006 else if (oldBaseNumber < pageNumber) { 2007 this.children[0].skipFlip = true; 2008 this.children.push(this.children.shift()); 2009 2010 // this.contentProvider.setLoading(pageNumber, true); 2011 } 2012 2013 var remainingPages = (pageCount - pageNumber); 2014 var stackDepth = (5) / pageCount; 2015 var leftDepth = stackDepth * pageNumber / 2; 2016 var rightDepth = stackDepth * remainingPages / 2; 2017 var maxDepth = (leftDepth < rightDepth ? rightDepth : leftDepth); 2018 //maxDepth = maxDepth > 5 ? 5: maxDepth; 2019 for (var _pageCount = 0; _pageCount < stackCount; _pageCount++) { 2020 var page = this.children[_pageCount];//this.getObjectByName("page"+_pageCount);//this.children[_pageCount]; 2021 2022 var color = page.color; 2023 var oldAngle = page.angles[1]; 2024 var newAngle; 2025 var relativePageNumber = pageNumber - midPoint + _pageCount; 2026 if (isRTL) relativePageNumber = isBooklet ? this.pageCount - relativePageNumber 2027 : Math.floor(this.pageCount / 2) - relativePageNumber - 1; 2028 2029 var isHard = page.isHard = this.isPageHard(relativePageNumber); 2030 var oldName = page.name; 2031 2032 2033 //Sizing 2034 page.isEdge = false; //true; 2035 if (_pageCount == 0) { 2036 page.depth = leftDepth < depth ? depth : leftDepth; 2037 } 2038 else if (_pageCount == stackCount - 1) { 2039 page.depth = rightDepth < depth ? depth : rightDepth; 2040 } 2041 else { 2042 page.depth = depth; 2043 page.isEdge = false; 2044 } 2045 if (page.isFlipping == true) { 2046 page.depth = depth; 2047 } 2048 page.position.x = 0; 2049 2050 var leftAngle = angleShift * _pageCount, 2051 rightAngle = 180 - angleShift * (_pageCount - midPoint) + angleShift * _pageCount; 2052 2053 if (_pageCount < midPoint) { 2054 page.newStiffness = isHard || this.stiffness == 0 ? 0 : stiffFactor / (pageNumber / pageCount) / 4; 2055 newAngle = leftAngle; 2056 page.position.z = maxDepth - (-_pageCount + midPoint) * depth;//(pageNumber < pageCount / 2) 2057 if (isLeft == true) page.position.z -= depth; 2058 2059 } 2060 else { 2061 newAngle = rightAngle; 2062 page.newStiffness = isHard || this.stiffness == 0 ? 0 2063 : stiffFactor / (Math.abs(pageCount - pageNumber) / pageCount) / 4; 2064 page.position.z = (maxDepth - (-stackCount + _pageCount + midPoint + 1) * depth) - page.depth;//(pageNumber < pageCount / 2) 2065 2066 } 2067 2068 if (page.isFlipping == false) { 2069 2070 if (Math.abs(oldAngle - newAngle) > 20 && page.skipFlip == false) { 2071 page.depth = depth; 2072 //we need predicted stiffness so that there is no overlap issues 2073 var predicted = page.stiffness; 2074 2075 if (oldAngle > newAngle) {//left 2076 predicted = stiffFactor / (Math.abs(pageCount - pageNumber) / pageCount) / 4; 2077 } 2078 else {//right 2079 predicted = stiffFactor / (pageNumber / pageCount) / 4; 2080 } 2081 page.position.z += depth;//((_pageCount < midPoint) ? 0 : depth) * 2;/// 2; 2082 2083 page.stiffness = isNaN(predicted) ? page.stiffness : predicted; 2084 page.updateAngle(true); 2085 page.targetStiffness = isHard ? 0 : (_pageCount < pageNumber) 2086 ? stiffFactor / (Math.abs(pageCount - pageNumber) / pageCount) / 4 2087 : stiffFactor / (pageNumber / pageCount) / 4; 2088 2089 page.targetStiffness = isHard ? 0 : (isNaN(page.targetStiffness) ? page.stiffness : page.targetStiffness); 2090 2091 page.isFlipping = true; 2092
2093 page.tween(oldAngle, newAngle); 2094 2095 if (this.preFlipCallback != null) 2096 this.preFlipCallback(); 2097 } 2098 else { 2099 page.skipFlip = false; 2100 page.newStiffness = isNaN(page.newStiffness) ? 0 : page.newStiffness; 2101 if (page.angles[1] != newAngle || page.stiffness != page.newStiffness || page.depth != page.oldDepth) { 2102 page.angles[1] = page.angles[4] = newAngle; 2103 page.stiffness = page.newStiffness; 2104 page.updateAngle(true); 2105 } 2106 else { 2107 //console.log("skipped"); 2108 } 2109 } 2110 } 2111 2112 page.visible = isBooklet 2113 ? (isRTL 2114 2115 ? (_pageCount < midPoint || page.isFlipping) 2116 : (_pageCount >= midPoint || page.isFlipping)) 2117 2118 : ((relativePageNumber >= 0 && relativePageNumber < pageCount) || (isBooklet && relativePageNumber == pageCount)); 2119 2120 2121 if (this.requestPage != null) { 2122 page.name = relativePageNumber.toString(); 2123 if (page.name != oldName) { 2124 2125 page.textureLoaded = false; 2126 page.frontImage(defaults.textureLoadFallback); 2127 page.frontPageStamp = "-1"; 2128 page.frontTextureLoaded = false; 2129 page.thumbLoaded = false; 2130 2131 // if (!isBooklet) { 2132 page.backImage(defaults.textureLoadFallback); 2133 page.backPageStamp = "-1"; 2134 page.backTextureLoaded = false; 2135 // } 2136 this.requestPage(); 2137 } 2138 } 2139 2140 //if (isBooklet && _pageCount < midPoint && page.isFlipping == false) 2141 // page.visible = false; 2142 2143 page.oldDepth = page.depth; 2144 var xPos = Math.abs(page.geometry.boundingBox.max.x) < Math.abs(page.geometry.boundingBox.min.x) 2145 ? page.geometry.boundingBox.max.x : page.geometry.boundingBox.min.x; 2146 page.position.x = (page.isEdge == true && page.isFlipping == false) ? ((_pageCount < midPoint) 2147 ? xPos : -xPos) : 0; 2148 } 2149 //$(".quick-hint").html(pageNumber); 2150 //console.log("leftDepth:" + leftDepth, "rightDepth:" + rightDepth, "midPoint:" + midPoint, "oldBaseNumber:" + oldBaseNumber, "pageNumber:" + pageNumber); 2151 this.oldBaseNumber = pageNumber; 2152 2153 if (this.updatePageCallback != null) 2154 this.updatePageCallback(); 2155 2156 }; 2157 //if (window.flipBook != null)flipBook.book.refresh(); 2158 //book.activePage(book.activePage()); 2159 Book.prototype.createCover = function (parameters) { 2160 parameters.width = parameters.width * 2; 2161 this.cover = new MOCKUP.BiFold(parameters); 2162 this.add(this.cover); 2163 }; 2164 2165 Book.prototype.createStack = function (parameters) { 2166 2167 var colors = "red,green,blue,yellow,orange,black".split(","); 2168 2169 for (var _stackCount = 0; _stackCount < this.stackCount; _stackCount++) { 2170 parameters.angles = [, this.stackCount - _stackCount];//[1] = (this.stackCount - _stackCount); 2171 parameters.stiffness = (this.stackCount - _stackCount) / 100; 2172 2173 var clone = new MOCKUP.BookPaper(parameters); 2174 clone.angles[1] = 180; 2175 //clone.name = "page" + _stackCount; 2176 clone.index = _stackCount; 2177 clone.updateAngle(); 2178 clone.textureReady = false; 2179 clone.textureRequested = false; 2180 this.add(clone); 2181 clone.color = colors[_stackCount]; 2182 //for (var _count = 0; _count < 4; _count++) { 2183 // clone.material.materials[_count].color = new THREE.Color(THREE.ColorKeywords[colors[_stackCount]]); 2184 //} 2185 clone.position.z = -1 * _stackCount;// * (this.mainObject.depth * 1.05); 2186 } 2187 }; 2188 2189 2190 Book.prototype.shininess = function (shininess) { 2191 if (shininess == null) { 2192 return this.mainObject.shininess(); 2193 } 2194 else {
2195 this.mainObject.shininess(shininess); 2196 } 2197 }; 2198 2199 Book.prototype.bumpScale = function (bumpScale) { 2200 if (bumpScale == null) { 2201 return this.mainObject.bumpScale(); 2202 } 2203 else { 2204 this.mainObject.bumpScale(bumpScale); 2205 } 2206 }; 2207 2208 2209 Book.prototype.frontImage = function (frontImage) { 2210 if (frontImage == null) { 2211 return this.mainObject.frontImage(); 2212 } 2213 else { 2214 this.mainObject.frontImage(frontImage); 2215 } 2216 }; 2217 2218 2219 Book.prototype.backImage = function (backImage) { 2220 if (backImage == null) { 2221 return this.mainObject.backImage(); 2222 } 2223 else { 2224 this.mainObject.backImage(backImage); 2225 } 2226 }; 2227 2228 return Book; 2229 })(MOCKUP.Bundle); 2230 MOCKUP.Book = Book; 2231 2232 } 2233 2234 //base object of flipbook or other trifold objects 2235 var PreviewObject = (function (_super) { 2236 2237 function PreviewObject(parameters) { 2238 parameters = parameters || {}; 2239 //_super.call(this, parameters); 2240 this.type = "PreviewObject"; 2241 var _this = this; 2242 2243 _this.zoomValue = 1; 2244 2245 function resizeDelay() { 2246 setTimeout(function () { 2247 _this.resize() 2248 }, 50); 2249 } 2250 2251 window.addEventListener("resize", resizeDelay, false); 2252 2253 this.sound = document.createElement("audio"); 2254 this.sound.setAttribute("src", parameters.soundFile + "?ver=" + DFLIP.version); 2255 this.sound.setAttribute("type", "audio/mpeg"); 2256 2257 this.autoPlayFunction = function () { 2258 if (_this && _this.target.autoPlay) { 2259 if (_this.target.direction == DFLIP.DIRECTION.RTL) 2260 _this.target.prev(); 2261 else 2262 _this.target.next(); 2263 } 2264 }; 2265 //this.pageMode = DFLIP.PAGE_MODE.DOUBLE; 2266 this.dispose = function () { 2267 2268 clearInterval(this.autoPlayTimer); 2269 this.autoPlayTimer = null; 2270 this.autoPlayFunction = null; 2271 2272 //complete any tweens left. 2273 if (this.target && this.target.children) { 2274 for (var count = 0; count < this.target.children.length; count++) { 2275 var page = this.target.children[count]; 2276 if (page && page.currentTween) page.currentTween.stop(); 2277 } 2278 } 2279 //first dispose internal objects 2280 if (this.zoomTween) { 2281 if (this.zoomTween.stop) this.zoomTween.stop(); 2282 this.zoomTween = null; 2283 } 2284 if (this.container && this.container.info && this.container.info.remove) 2285 this.container.info.remove(); 2286 2287 if (this.target && this.target.dispose) 2288 this.target.dispose(); 2289 this.target = null; 2290 2291 if (this.stage && this.stage.dispose) 2292 this.stage.dispose(); 2293 this.stage = null; 2294 2295 //if (this.target && this.target.outlineContainer) this.target.outlineContainer.remove(); 2296 2297 if (this.ui && this.ui.dispose) 2298 this.ui.dispose(); 2299 this.ui = null; 2300 2301 if (this.contentProvider && this.contentProvider.dispose) 2302 this.contentProvider.dispose(); 2303 this.contentProvider = null; 2304 2305 window.removeEventListener("resize", resizeDelay); 2306 2307 }; 2308 } 2309 2310 PreviewObject.prototype = { 2311 2312 start: function () { 2313 2314 this.target.gotoPage(this.target.startPage); 2315 2316 }, 2317 2318 end: function () { 2319 this.target.gotoPage(this.target.endPage); 2320 }, 2321 2322 next: function () { 2323 2324 }, 2325 2326 prev: function () { 2327 2328 }, 2329 getPageTextContent: function (pageIndex) { 2330 return this.contentProvider.pdfDocument.getPage(pageIndex + 1).then(function (page) { 2331 return page.getTextContent({normalizeWhitespace: true}); 2332 }); 2333 }, 2334 calculateSize: function (containerHeight, stageWidth, maxHeight, paddingHeight, paddingWidth, isAutoHeight, pageRatio, isSingle) { 2335 var stageHeight = containerHeight; 2336 var stageInnerWidth = stageWidth - paddingWidth; 2337 var stageInnerHeight = stageHeight - paddingHeight; 2338 2339 var autoWidth = Math.ceil(isSingle ? stageInnerWidth : stageInnerWidth / (2)); 2340 2341 var autoHeight = autoWidth / pageRatio; // Height when page auto fits 2342 var refHeight = null; 2343 2344 if (isAutoHeight) { 2345 //Incase the value is auto height find the autoheight for flipbook 2346 refHeight = Math.min(autoHeight, maxHeight - paddingHeight); 2347 stageHeight = refHeight; 2348 } 2349 else { 2350 refHeight = Math.min(stageInnerHeight, maxHeight - paddingHeight); 2351 } 2352 2353 //check if book fits by width 2354 var isWide = autoHeight > refHeight; 2355 var width, height; 2356 if (isWide) { 2357 height = refHeight; 2358 width = Math.floor(height * pageRatio); 2359 } 2360 else { 2361 width = autoWidth;
2362 height = Math.ceil(autoWidth / pageRatio); 2363 } 2364 if (isAutoHeight) { 2365 stageHeight = Math.max(height + paddingHeight, 320); 2366 } 2367 return { 2368 stageHeight: stageHeight, 2369 isWide: isWide, 2370 height: height, 2371 width: width 2372 }; 2373 }, 2374 zoom: function (delta) { 2375 2376 this.pendingZoom = true; 2377 this.zoomDelta = delta; 2378 2379 this.resize(); 2380 this.ui.update(); 2381 }, 2382 2383 resize: function () { 2384 2385 var _this = this; 2386 2387 if (_this.target == null || 2388 _this.target.ui == null || 2389 _this.target.contentProvider == null || 2390 _this.target.contentProvider.viewport == null || 2391 _this.target.stage == null) 2392 return; 2393 2394 if (this.ui && this.ui.isFullscreen == true && utils.hasFullscreenEnabled() == true && utils.getFullscreenElement() == null) { 2395 this.ui.switchFullscreen(); 2396 } 2397 2398 //Variable Caches 2399 var target = _this.target, 2400 container = _this.container, 2401 options = _this.options, 2402 stage = target.stage, 2403 contentProvider = target.contentProvider, 2404 pageRatio = contentProvider.pageRatio, 2405 zoomViewport = contentProvider.zoomViewport, 2406 isRTL = isRTLMode(target), 2407 is3d = target.mode !== "css", 2408 isLandScape = contentProvider.pageRatio > 1, 2409 isAutoHeight = this.ui.isFullscreen == true ? false : options.height === "auto", 2410 isWide, height, width, cameraZ, fov, zoom, maxZoom, 2411 sideShift = container.hasClass("df-sidemenu-open") ? 220 : 0, 2412 isSingle = this.target.pageMode == DFLIP.PAGE_MODE.SINGLE; 2413 2414 2415 //checking if the responsive width according to container 2416 var containerWidth = container.width(); 2417 if (containerWidth < 400) {//rather than responsive lets use 2418 _this.container.addClass("df-xs"); 2419 } 2420 else { 2421 _this.container.removeClass("df-xs"); 2422 } 2423 2424 var controlsHeight = container.find(".df-ui-controls").height(); 2425 var paddingTop = options.paddingTop + (options.controlsPosition == DFLIP.CONTROLSPOSITION.TOP 2426 ? controlsHeight : 0), 2427 paddingRight = options.paddingRight, 2428 paddingBottom = options.paddingBottom + (options.controlsPosition == DFLIP.CONTROLSPOSITION.BOTTOM 2429 ? controlsHeight : 0), 2430 paddingLeft = options.paddingLeft; 2431 2432 paddingTop = isNaN(paddingTop) ? 0 : limitAt(paddingTop, 0, paddingTop), 2433 paddingBottom = isNaN(paddingBottom) ? 0 : limitAt(paddingBottom, 0, paddingBottom), 2434 paddingLeft = isNaN(paddingLeft) ? 0 : limitAt(paddingLeft, 0, paddingLeft), 2435 paddingRight = isNaN(paddingRight) ? 0 : limitAt(paddingRight, 0, paddingRight); 2436 2437 var paddingHeight = paddingTop + paddingBottom, 2438 paddingWidth = paddingLeft + paddingRight; 2439 2440 //containerHeight, containerWidth, controlsHeight above 2441 var stageWidth = containerWidth - sideShift; //if sideMenu for thumbnails is open? 2442 2443 /*SIZE CALCULATION*/ 2444 //checking if the container height is more than the window height 2445 container.height(options.height); 2446 var maxHeight = $(window).height(); 2447 2448 var containerHeight = Math.min(container.height(), maxHeight); 2449 2450 var sizes = _this.calculateSize(containerHeight, stageWidth, maxHeight, paddingHeight, paddingWidth, isAutoHeight, pageRatio, isSingle); 2451 2452 if (isAutoHeight) { 2453 containerHeight = stageHeight = _this.calculateSize(containerHeight, stageWidth + sideShift, maxHeight, paddingHeight, paddingWidth, isAutoHeight, pageRatio, isSingle).stageHeight; 2454 } 2455 else { 2456 containerHeight = stageHeight = sizes.stageHeight; 2457 } 2458 2459 container.height(containerHeight);//setting twice for failsafe 2460 2461 2462 var stageHeight = containerHeight; 2463 2464 2465 var stageInnerWidth = stageWidth - paddingWidth, 2466 stageInnerHeight = stageHeight - paddingHeight; 2467 2468 width = Math.floor(isSingle ? stageInnerWidth : stageInnerWidth / 2); 2469 height = Math.floor(width / pageRatio); 2470 2471 //check if book fits by width
vendor: 4,412 bytes, lines 2472-2575
2472 isWide = height > stageInnerHeight; 2473 if (isWide) { 2474 height = stageInnerHeight; 2475 width = height * pageRatio; 2476 } 2477 2478 /*ZOOM CALCULATION*/ 2479 //update maxZoom for current Stage Dimension 2480 maxZoom = contentProvider.maxZoom = contentProvider.zoomViewport.height / height; 2481 2482 //set to 1 if unset initally 2483 if (_this.zoomValue == null) _this.zoomValue = 1; 2484 if (contentProvider.zoomScale == null) contentProvider.zoomScale = 1; 2485 2486 if (_this.pendingZoom == true && _this.zoomDelta != null) { 2487 2488 var delta = _this.zoomDelta, predictedIndex, currentMaxDimension = Math.max(height, width); 2489 2490 _this.zoomValue = _this.zoomDelta > 0 ? _this.zoomValue * _this.options.zoomRatio 2491 : _this.zoomValue / _this.options.zoomRatio; 2492 _this.zoomValue = limitAt(_this.zoomValue, 1, maxZoom); 2493 2494 if (_this.zoomValue == 1) { 2495 contentProvider.zoomScale = 1; 2496 } 2497 else { 2498 /* 2499 predictedIndex = height * _this.zoomValue; 2500 //zoomStops matches the contentProvider internal calcuation and prediction stops so that the texture size won't differ 2501 predictedIndex = utils.zoomStops(predictedIndex, _this.options.zoomRatio, _this.zoomDelta > 0, Math.max(width, height)); 2502 contentProvider.zoomScale = limitAt(predictedIndex / currentMaxDimension, 1, maxZoom); 2503 */ 2504 contentProvider.zoomScale = limitAt(_this.zoomValue, 1, maxZoom); 2505 } 2506 2507 } 2508 2509 zoom = contentProvider.zoomScale; 2510 2511 //Update Image CacheSize Index 2512 contentProvider.checkViewportSize(width, height, zoom); 2513 2514 if (contentProvider.contentSourceType == SOURCE_TYPE.PDF) { 2515 //recalculation is required for pixel shift issue only if the source is PDF 2516 width = contentProvider.imageViewport.width / zoom; 2517 height = contentProvider.imageViewport.height / zoom; 2518 } 2519 2520 if (contentProvider.zoomScale != 1) { 2521 this.target.container.addClass("df-zoom-enabled"); 2522 } 2523 2524 var zoomWidth = target.zoomWidth = Math.floor(width * zoom), 2525 zoomHeight = target.zoomHeight = Math.floor(height * zoom); 2526 var zoomFullWidth = zoomWidth * 2; 2527 2528 if (is3d) { 2529 2530 //zoomHeight is equal to target.height (normally 300) so relative calculation is required 2531 var proportion = zoomHeight / target.height, 2532 aspect = stageWidth / stageHeight; 2533 var relativeHeight = zoom * (height + paddingHeight) / proportion, 2534 relativeWidth = zoom * (width * (isSingle ? 1 : 2) + paddingWidth) / proportion; 2535 2536 var focusSize = isWide ? relativeHeight : relativeWidth / aspect; 2537 stage.resizeCanvas(stageWidth, stageHeight); 2538 2539 cameraZ = 1 / (2 * Math.tan(Math.PI * stage.camera.fov * 0.5 / 180) / (focusSize / zoom)) + 2.2; 2540 2541 stage.camera.updateProjectionMatrix(); 2542 2543 stage.renderRequestPending = true; 2544 2545 //pixel value to stage position value 2546 2547 var shift = (paddingTop - paddingBottom) * (target.height / height) / zoom / 2; 2548 2549 //put a check if the existing gap is enough 2550 // _this.target.position.y = shift; 2551 // stage.cssScene.position.y = _this.target.position.y; 2552 2553 var _reset = contentProvider.zoomScale == 1; 2554 if (stage.camera.position.z !== cameraZ && _this.pendingZoom == true) { //avoid recreating the tween if the target is same as before 2555 if (_this.zoomTween != null) 2556 _this.zoomTween.stop(); 2557 _this.zoomTween = new TWEEN.Tween({ 2558 campos: stage.camera.position.z, 2559 otx: stage.orbitControl.target.x, 2560 oty: stage.orbitControl.target.y, 2561 otz: stage.orbitControl.target.z 2562 }).delay(0) 2563 .to({ 2564 campos: cameraZ, 2565 otx: 0, 2566 oty: shift, 2567 otz: 0 2568 }, 2569 100) 2570 .onUpdate(function () { 2571 stage.camera.position.z = this.campos; 2572 if (_reset) { 2573 stage.camera.position.y = this.oty; 2574 stage.orbitControl.target = new THREE.Vector3(this.otx, this.oty, this.otz); 2575 }
2576 stage.orbitControl.update(); 2577 }).easing(TWEEN.Easing.Linear.None) 2578 .onComplete(function () { 2579 stage.camera.position.z = cameraZ; 2580 if (contentProvider.zoomScale == 1) { 2581 stage.camera.position.set(0, shift, cameraZ); 2582 stage.orbitControl.target = new THREE.Vector3(0, shift, 0); 2583 } 2584 stage.orbitControl.update(); 2585 }) 2586 .start(); 2587 } 2588 else { 2589 if (contentProvider.zoomScale == 1) { 2590 stage.camera.position.set(0, shift, cameraZ); 2591 stage.orbitControl.target = new THREE.Vector3(0, shift, 0); 2592 } 2593 /*else { 2594 stage.camera.position.z = cameraZ; 2595 }*/ 2596 stage.orbitControl.update(); 2597 } 2598 2599 stage.orbitControl.update(); 2600 stage.orbitControl.mouseButtons.ORBIT = zoom != 1 ? -1 : THREE.MOUSE.RIGHT; 2601 stage.orbitControl.mouseButtons.PAN = zoom != 1 ? THREE.MOUSE.LEFT : -1; 2602 2603 } 2604 else { 2605 2606 target.pageWidth = Math.round(width); 2607 target.fullWidth = target.pageWidth * 2; 2608 target.height = Math.round(height); 2609 2610 var shiftHeight = target.shiftHeight = Math.round(limitAt((zoomHeight - stageHeight + paddingHeight) / 2, 0, zoomHeight)), 2611 shiftWidth = target.shiftWidth = Math.round(limitAt((zoomFullWidth - stageWidth + paddingWidth) / 2, 0, zoomFullWidth)); 2612 2613 if (zoom == 1) { 2614 target.left = 0; 2615 target.top = 0; 2616 } 2617 target.stage.css({ 2618 top: -shiftHeight, 2619 bottom: -shiftHeight, 2620 right: -shiftWidth + (isRTL ? sideShift : 0), 2621 left: -shiftWidth + (isRTL ? 0 : sideShift), 2622 paddingTop: paddingTop, 2623 paddingRight: paddingRight, 2624 paddingBottom: paddingBottom, 2625 paddingLeft: paddingLeft, 2626 transform: "translate3d(" + target.left + "px," + target.top + "px,0)" 2627 }); 2628 target.stageHeight = stage.height(); 2629 2630 target.wrapper.css({ 2631 width: zoomFullWidth, 2632 height: zoomHeight, 2633 marginTop: (containerHeight - zoomHeight - paddingHeight) > 0 2634 ? (containerHeight - paddingHeight - zoomHeight) / 2 2635 : 0 2636 }); 2637 2638 var wrapperSize = Math.floor((distOrigin(width, height)) * zoom); 2639 2640 target.stage.find(".df-page-wrapper").width(wrapperSize).height(wrapperSize); 2641 2642 target.stage.find(".df-book-page, .df-page-front , .df-page-back, .df-page-fold-inner-shadow").height(zoomHeight).width(zoomWidth); 2643 2644 } 2645 2646 _this.checkCenter({type: "resize"}); 2647 2648 if (contentProvider.zoomScale == 1) { 2649 this.target.container.removeClass("df-zoom-enabled"); 2650 } 2651 2652 if (target.thumblist) { 2653 target.thumblist.reset($(target.thumblist.container).height()); 2654 } 2655 2656 _this.pendingZoom = false;
2657 2658 }, 2659 2660 playSound: function () { 2661 try { 2662 if (this.options && this.options.soundEnable == true) { 2663 this.sound.currentTime = 0; 2664 this.sound.play(); 2665 } 2666 } catch (error) { 2667 2668 } 2669 }, 2670 2671 setPageMode: function (isSingle) { 2672 if (isSingle == true) { 2673 this.ui.pageMode.addClass(this.options.icons['doublepage']); 2674 this.ui.pageMode.html("<span>" + this.options.text.doublePageMode + "</span>"); 2675 this.ui.pageMode.attr("title", this.options.text.doublePageMode); 2676 this.target.pageMode = DFLIP.PAGE_MODE.SINGLE; 2677 } 2678 else { 2679 this.ui.pageMode.removeClass(this.options.icons['doublepage']); 2680 this.ui.pageMode.html("<span>" + this.options.text.singlePageMode + "</span>"); 2681 this.ui.pageMode.attr("title", this.options.text.singlePageMode); 2682 this.target.pageMode = DFLIP.PAGE_MODE.DOUBLE; 2683 } 2684 2685 if (this.target && this.target.singlePageMode == DFLIP.SINGLE_PAGE_MODE.BOOKLET) { 2686 this.target.reset(); 2687 } 2688 2689 this.resize(); 2690 }, 2691 setAutoPlay: function (isPlay) { 2692 if (this.options.autoPlay) { 2693 isPlay = isPlay == true; 2694 var text = isPlay ? this.options.text.pause : this.options.text.play; 2695 this.ui.play.toggleClass(this.options.icons['pause'], isPlay); 2696 this.ui.play.html("<span>" + text + "</span>"); 2697 this.ui.play.attr("title", text); 2698 2699 clearInterval(this.autoPlayTimer); 2700 if (isPlay) { 2701 this.autoPlayTimer = setInterval(this.autoPlayFunction, this.options.autoPlayDuration); 2702 } 2703 2704 this.target.autoPlay = isPlay; 2705 } 2706 }, 2707 height: function (height) { 2708 if (height == null) { 2709 return this.container.height(); 2710 } 2711 else { 2712 this.options.height = height; 2713 this.container.height(height); 2714 this.resize(); 2715 } 2716 }, 2717 /** 2718 *checks whether the book is closed and needs to be centered 2719 */ 2720 checkCenter: function (options) { 2721 2722 options = options == null ? {} : options; 2723 this.centerType = this.centerType || "start"; 2724 var target = this.target; 2725 var singleShift = 0, left = 0, right = 0; 2726 var basePage = utils.getBasePage(target._activePage); 2727 var isEven = target._activePage % 2 == 0; 2728 var isRTL = target.direction == DFLIP.DIRECTION.RTL; 2729 var isSingle = target.pageMode == DFLIP.PAGE_MODE.SINGLE, 2730 isBooklet = isSingle && target.singlePageMode == DFLIP.SINGLE_PAGE_MODE.BOOKLET; 2731 var stageWidth = target.stage.width(), 2732 width; 2733 2734 if (target.mode == 'css') { 2735 width = target.wrapper.width(); 2736 //calculate the excess shift required for correction in case width is too small 2737 singleShift = Math.max((width - stageWidth) / 2, 0); 2738 2739 left = -width / 4; 2740 right = width / 4; 2741 2742 if (basePage == 0 || isBooklet) { 2743 target.wrapper.css({ 2744 left: isSingle 2745 ? isRTL ? right - singleShift : left - singleShift 2746 : isRTL ? right : left 2747 }); 2748 target.shadow.css({width: '50%', left: isRTL ? 0 : '50%', transitionDelay: ''}); 2749 } 2750 else if (basePage == target.pageCount) { 2751 target.wrapper.css({ 2752 left: isSingle 2753 ? isRTL ? left - singleShift : right - singleShift 2754 : isRTL ? left : right 2755 }); 2756 target.shadow.css({width: '50%', left: isRTL ? '50%' : 0, transitionDelay: ''}); 2757 } 2758 else { 2759 target.wrapper.css({ 2760 left: isSingle 2761 ? isRTL 2762 ? (isEven ? left - singleShift : right - singleShift) 2763 : (isEven ? right - singleShift : left - singleShift) 2764 : 0 2765 }); 2766 target.shadow.css({ 2767 width: '100%', 2768 left: 0, 2769 transitionDelay: (parseInt(target.duration, 10) + 50) + 'ms' 2770 }); 2771 } 2772 2773 target.wrapper.css({transition: options.type == "resize" ? "none" : ""}); 2774 2775 } 2776 else if (target.stage != null) { 2777 var init = target.position.x, end; 2778 singleShift = target.width / 4; 2779 width = target.width; 2780 left = -width / 2; 2781 right = width / 2; 2782 2783 if (basePage == 0 || isBooklet) { 2784 end = isRTL ? right : left; 2785 }
2786 else if (basePage == target.pageCount) { 2787 end = isRTL ? left : right; 2788 } 2789 else { 2790 end = isSingle 2791 ? isRTL 2792 ? (isEven ? left : right) 2793 : (isEven ? right : left) 2794 : 0; 2795 } 2796 //create a centertween 2797 if (end !== this.centerEnd) { //avoid recreating the tween if the target is same as before 2798 this.centerTween = new TWEEN.Tween({x: init}).delay(0) 2799 .to({x: end}, target.duration) 2800 .onUpdate(function () { 2801 target.position.x = this.x; 2802 target.stage.cssScene.position.x = this.x; 2803 }).easing(target.ease) 2804 .start(); 2805 this.centerEnd = end; 2806 2807 } 2808 } 2809 // log("checkcenter at : " + left); 2810 }, 2811 2812 width: function (width) { 2813 if (width == null) { 2814 return this.container.width(); 2815 } 2816 else { 2817 this.options.width = width; 2818 this.container.width(width); 2819 this.resize(); 2820 } 2821 } 2822 2823 }; 2824 2825 return PreviewObject; 2826 2827 })({}); 2828 2829 DFLIP.PreviewObject = PreviewObject; 2830 2831 //contentprovider that handles the source of book 2832 var ContentProvider = (function (_super) { 2833 __extends(ContentProvider, _super); 2834 2835 2836 function ContentProvider(contentSource, callback, parameters, flipbook) { 2837 2838 parameters = parameters || {}; 2839 2840 var _this = this; 2841 2842 _this.contentRawSource = contentSource || [defaults.textureLoadFallback]; 2843 _this.contentSource = _this.contentRawSource; 2844 _this.contentSourceType = null; 2845 _this.minDimension = parameters.minTextureSize || 256; 2846 _this.maxDimension = parameters.maxTextureSize || 2048; 2847 _this.pdfRenderQuality = parameters.pdfRenderQuality || DFLIP.defaults.pdfRenderQuality; 2848 _this.flipbook = flipbook; 2849 _this.waitPeriod = 50; 2850 _this.maxLength = 297; 2851 _this.enableDebug = false; 2852 _this.zoomScale = 1; 2853 _this.maxZoom = 2; 2854 _this.options = parameters; 2855 _this.outline = parameters.outline; 2856 _this.links = parameters.links; 2857 _this.html = parameters.html; 2858 _this.isCrossOrigin = parameters.isCrossOrigin; 2859 2860 _this.normalViewport = { 2861 height: 297, 2862 width: 210, 2863 scale: 1 2864 }; 2865 _this.viewport = { 2866 height: 297, 2867 width: 210, 2868 scale: 1 2869 }; 2870 _this.imageViewport = { 2871 height: 297, 2872 width: 210, 2873 scale: 1 2874 }; 2875 _this.bookSize = { 2876 height: 297, 2877 width: 210 2878 } 2879 _this.zoomViewport = { 2880 height: 297, 2881 width: 210 2882 }; 2883 2884 _this.thumbsize = 128; 2885 _this.cacheIndex = 256; //index of bigger dimension height or width 2886 _this.cache = []; 2887 2888 _this.pageRatio = parameters.pageRatio || _this.viewport.width / _this.viewport.height; 2889 2890 //texture load control so that it wont delay the transition 2891 _this.textureLoadTimeOut = null; 2892 2893 _this.type = "TextureLibrary"; 2894 2895 if (Array === _this.contentSource.constructor || Array.isArray(_this.contentSource) || _this.contentSource instanceof Array) { 2896 2897 //case of images and html content 2898 _this.contentSourceType = SOURCE_TYPE.IMAGE; 2899 _this.pageCount = _this.contentSource.length; 2900 2901 //_this.setLoading(1, true); 2902 2903 // Make in memory copy of image to avoid css issues 2904 $("<img/>") 2905 .attr("src", _this.contentSource[0]) 2906 .on('load', (function () { 2907 _this.viewport.height = this.height; 2908 _this.viewport.width = this.width; 2909 2910 _this.pageRatio = _this.viewport.width / _this.viewport.height; 2911 _this.bookSize = { 2912 width: (_this.pageRatio > 1 ? 1 : _this.pageRatio) * _this.maxLength, 2913 height: _this.maxLength / (_this.pageRatio < 1 ? 1 : _this.pageRatio) 2914 }; 2915 _this.zoomViewport = { 2916 width: (_this.pageRatio > 1 ? 1 : _this.pageRatio) * _this.maxDimension, 2917 height: _this.maxDimension / (_this.pageRatio < 1 ? 1 : _this.pageRatio) 2918 }; 2919 2920 _this.linkService = new PDFLinkService(); 2921 2922 $(this).off(); 2923 2924 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL) { 2925 _this.pageCount = _this.contentSource.length * 2 - 2; 2926 if (_this.options.webgl == true) 2927 _this.requiresImageTextureScaling = true; 2928 } 2929 2930 if (callback != null) { 2931 callback(_this); 2932 callback = null; 2933 } 2934 //_this.setLoading(1); 2935 2936 //console.log(_this.zoomViewport); 2937 log(this.height + ":" + this.width); 2938 //pic_real_width = this.width; // Note: $(this).width() will not 2939 //pic_real_height = this.height; // work for in memory images. 2940 //moved to set target function 2941 //_this. 2942 // (); 2943 2944 2945 })); 2946 2947 } 2948 else if (typeof _this.contentSource == 'string' || _this.contentSource instanceof String) { //case of link to pdf file 2949 2950 //region Check if file isbase64 or normal 2951 var checkSource = function () { 2952 if (_this.contentSource.indexOf(".base64") > 1) { 2953 $.ajax({ 2954 url: _this.contentSource, 2955 xhrFields: { 2956 onprogress: function (e) { 2957 if (e.lengthComputable) { 2958 var percentage = 100 * e.loaded / e.total;
2959 _this.updateInfo("Loading PDF " + percentage.toString().split(".")[0] + "% ..."); 2960 } 2961 } 2962 }, 2963 success: function (response) { 2964 _this.options.docParameters = {data: atob(response)}; 2965 processSource(); 2966 } 2967 }); 2968 } 2969 else { 2970 processSource(); 2971 } 2972 } 2973 //endregion 2974 2975 var processSource = function () { 2976 if (_this) { 2977 //configurePDFJS(PDFJS); 2978 PDFJS.workerSrc = defaults.pdfjsWorkerSrc; 2979 2980 _this.contentSourceType = SOURCE_TYPE.PDF; 2981 //PDFJS.disableWorker = true; 2982 PDFJS.disableAutoFetch = true; 2983 PDFJS.disableStream = true; 2984 if (isSafari || isIOS || _this.options.disableFontFace == true) { 2985 PDFJS.disableFontFace = isSafari || isIOS || _this.options.disableFontFace == true; 2986 } 2987 PDFJS.imageResourcesPath = defaults.imageResourcesPath; 2988 PDFJS.cMapUrl = defaults.cMapUrl; 2989 PDFJS.cMapPacked = !0; 2990 PDFJS.externalLinkTarget = _this.options.linkTarget; 2991 2992 var loading = _this.loading = PDFJS.getDocument(_this.options.docParameters ? _this.options.docParameters 2993 : { 2994 url: utils.httpsCorrection(contentSource), 2995 rangeChunkSize: isNaN(_this.options.rangeChunkSize) ? 524288 : _this.options.rangeChunkSize 2996 }); 2997 2998 loading.then(function sourceLoaded(pdf) { 2999 3000 _this.pdfDocument = pdf; 3001 pdf.getPage(1).then(function (page) { 3002 _this.normalViewport = page.getViewport(1); 3003 _this.viewport = page.getViewport(1); 3004 _this.viewport.height = _this.viewport.height / 10; 3005 _this.viewport.width = _this.viewport.width / 10; 3006 3007 _this.pageRatio = _this.viewport.width / _this.viewport.height; 3008 3009 _this.bookSize = { 3010 width: (_this.pageRatio > 1 ? 1 : _this.pageRatio) * _this.maxLength, 3011 height: _this.maxLength / (_this.pageRatio < 1 ? 1 : _this.pageRatio) 3012 }; 3013 3014 _this.zoomViewport = { 3015 width: (_this.pageRatio > 1 ? 1 : _this.pageRatio) * _this.maxDimension, 3016 height: _this.maxDimension / (_this.pageRatio < 1 ? 1 : _this.pageRatio) 3017 }; 3018 3019 _this.refPage = page; 3020 3021 //console.log(_this.zoomViewport); 3022 3023 //check if intenal pages are of double sizes. 3024 if (pdf.numPages > 1) { 3025 pdf.getPage(2).then(function (page) { 3026 if (_this.options.pageSize == DFLIP.PAGE_SIZE.AUTO) { 3027 var _viewport = page.getViewport(1); 3028 //Update: doing width check gives false alarm if the internal pages are of different sizes yet follow same aspect ratio 3029 //if (_viewport.width > _this.normalViewport.width * 1.5) { 3030 var _pageRatio = _viewport.width / _viewport.height; 3031 if (_pageRatio > _this.pageRatio * 1.5) { 3032 _this.options.pageSize = DFLIP.PAGE_SIZE.DOUBLEINTERNAL; 3033 _this.pageCount = pdf.numPages * 2 - 2; 3034 } 3035 else { 3036 _this.options.pageSize = DFLIP.PAGE_SIZE.SINGLE; 3037 } 3038 } 3039 if (callback != null) { 3040 callback(_this); 3041 callback = null; 3042 } 3043 }); 3044 } 3045 else { 3046 if (callback != null) { 3047 callback(_this); 3048 callback = null; 3049 } 3050 } 3051 3052 }); 3053 _this.linkService = new PDFLinkService(); 3054 _this.linkService.setDocument(pdf, null); 3055 3056 //moved to set target function 3057 //_this.initThumbs(); 3058 _this.pageCount = pdf.numPages; 3059 _this.contentSource = pdf; 3060 3061 }, 3062 function loadingError(error) { 3063 if (_this) { 3064 var cors = "", tmp = document.createElement('a'); 3065 tmp.href = _this.contentSource; 3066 3067 if (tmp.hostname !== window.location.hostname) 3068 cors = "CROSS ORIGIN!! "; 3069 3070 _this.updateInfo(cors + "Cannot access file! " + _this.contentSource); 3071 } 3072 }); 3073 3074 loading.onProgress = function getDocumentProgress(progressData) { 3075 if (_this) { 3076 var percentage = 100 * progressData.loaded / progressData.total; 3077 if (isNaN(percentage)) { 3078 if (progressData && progressData.loaded) {
3079 _this.updateInfo("Loading PDF " + (Math.ceil(progressData.loaded / 10000) / 100).toString() + "MB ..."); 3080 } 3081 else { 3082 _this.updateInfo("Loading PDF ..."); 3083 } 3084 } 3085 else { 3086 _this.updateInfo("Loading PDF " + percentage.toString().split(".")[0] + "% ..."); 3087 } 3088 } 3089 }; 3090 } 3091 }; 3092 var checkCORS = function () { 3093 if (_this) { 3094 defaults.pdfjsWorkerSrc += "?ver=" + DFLIP.version; 3095 3096 _this.updateInfo("Loading PDF Worker ..."); 3097 var tmp = document.createElement('a'); 3098 tmp.href = defaults.pdfjsWorkerSrc; 3099 3100 if (tmp.hostname !== window.location.hostname) { 3101 _this.updateInfo("Loading PDF Worker CORS ..."); 3102 $.ajax({ 3103 url: defaults.pdfjsWorkerSrc, 3104 cache: true, 3105 success: function (data) { 3106 defaults.pdfjsWorkerSrc = DFLIP.createObjectURL(data, "text/javascript"); 3107 checkSource(); 3108 } 3109 }); 3110 } 3111 else { 3112 checkSource(); 3113 } 3114 } 3115 }; 3116 if (window.PDFJS == null) { 3117 if (_this) { 3118 _this.updateInfo("Loading PDF Service ..."); 3119 3120 getScript(defaults.pdfjsSrc + "?ver=" + DFLIP.version, function () { 3121 3122 if (typeof define === 'function' && define.amd && window.requirejs) { 3123 _this.updateInfo("Loading PDF Service (require) ..."); 3124 require.config({paths: {'pdfjs-dist/build/pdf.worker': defaults.pdfjsWorkerSrc.replace(".js", "")}}); 3125 require(['pdfjs-dist/build/pdf'], function (pdf) { 3126 checkCORS(); 3127 }); 3128 } 3129 else { 3130 checkCORS(); 3131 } 3132 }, function () { 3133 _this.updateInfo("Unable to load PDF service.."); 3134 }); 3135 3136 } 3137 } 3138 else { 3139 3140 checkSource(); 3141 } 3142 3143 } 3144 else { 3145 console.error("Unknown source type. Please check documentation for help"); 3146 } 3147 3148 this.dispose = function () { 3149 if (_this.loading && _this.loading.destroy) { 3150 _this.loading.destroy(); 3151 } 3152 _this.loading = null; 3153 if (_this.textureLoadTimeOut) { 3154 clearTimeout(_this.textureLoadTimeOut); 3155 _this.textureLoadTimeOut = null; 3156 } 3157 if (this.targetObject) { 3158 if (this.targetObject.thumbContainer && this.targetObject.thumbContainer.remove) 3159 this.targetObject.thumbContainer.remove(); 3160 if (this.targetObject.outlineContainer && this.targetObject.outlineContainer.remove) 3161 this.targetObject.outlineContainer.remove(); 3162 if (this.targetObject.dispose) this.targetObject.dispose(); 3163 this.targetObject.processPage = null; 3164 this.targetObject.requestPage = null; 3165 if (this.targetObject.container && this.targetObject.container.off) 3166 this.targetObject.container.off(); 3167 3168 } 3169 if (this.pdfDocument && this.pdfDocument.destroy) this.pdfDocument.destroy(); 3170 if (this.linkService && this.linkService.dispose) this.linkService.dispose(); 3171 if (this.outlineViewer && this.outlineViewer.dispose) this.outlineViewer.dispose(); 3172 if (this.thumblist && this.thumblist.dispose) { 3173 this.thumblist.review = null; 3174 this.thumblist.dispose(); 3175 } 3176 3177 this.activeThumb = null; 3178 this.targetObject = null; 3179 this.pdfDocument = null; 3180 this.linkService = null; 3181 this.outlineViewer = null; 3182 this.thumblist = null; 3183 _this = null; 3184 }; 3185 return this; 3186 } 3187 3188 ContentProvider.prototype.updateInfo = function (info) { 3189 if (this.flipbook && this.flipbook.updateInfo) { 3190 this.flipbook.updateInfo(info); 3191 } 3192 }; 3193 3194 ContentProvider.prototype.initThumbs = function () { 3195 3196 var _this = this;
3197 if (_this.cache[_this.thumbsize] == null) _this.cache[_this.thumbsize] = []; 3198 var thumbLoadTimeOut; 3199 var review = function () { 3200 clearTimeout(thumbLoadTimeOut); 3201 thumbLoadTimeOut = setTimeout(function () { 3202 3203 thumbLoadTimeOut = setTimeout(reviewThumbs, _this.waitPeriod / 2); 3204 3205 }, _this.waitPeriod); 3206 }; 3207 3208 var reviewThumbs = function () { 3209 var requestCount = 0; 3210 if (Date.now() - _this.thumblist.lastScrolled < 100) { 3211 requestCount = 1; 3212 } 3213 else { 3214 _this.targetObject.container.find(".df-thumb-container .df-vrow").each(function () { 3215 var thumb = $(this); 3216 if (!thumb.hasClass("df-thumb-loaded")) { 3217 requestCount++; 3218 var id = $(this).attr("id").replace("df-thumb", ""); 3219 _this.getPage(id, review, true); 3220 thumb.addClass("df-thumb-loaded"); 3221 return false; 3222 } 3223 }); 3224 if (requestCount == 0) { 3225 clearTimeout(thumbLoadTimeOut); 3226 } 3227 } 3228 3229 if (requestCount > 0) { 3230 review(); 3231 } 3232 //move to thumb if thumb is on 3233 if (_this.activeThumb != _this.targetObject._activePage) { 3234 var thumbVisible = _this.targetObject.thumbContainer != null && _this.targetObject.thumbContainer.hasClass("df-sidemenu-visible"); 3235 3236 if (thumbVisible) { 3237 var wrapper = _this.thumblist.container; 3238 var cScroll = wrapper.scrollTop, 3239 cHeight = wrapper.getBoundingClientRect().height; 3240 3241 var thumb = _this.targetObject.thumbContainer.find("#df-thumb" + _this.targetObject._activePage); 3242 if (thumb.length > 0) {//TODO direct jumps won't work.. 3243 _this.targetObject.thumbContainer.find(".df-selected").removeClass("df-selected"); 3244 thumb.addClass("df-selected"); 3245 //js calculation 3246 thumb = thumb[0]; 3247 3248 //updated with custmscrollinto view since inbuilt causes page movement 3249 if (cScroll + cHeight < thumb.offsetTop + thumb.scrollHeight) 3250 utils.scrollIntoView(thumb, null, false); 3251 else if (cScroll > thumb.offsetTop) 3252 utils.scrollIntoView(thumb); 3253 3254 _this.activeThumb = _this.targetObject._activePage; 3255 } 3256 else { 3257 $(wrapper).scrollTop(_this.targetObject._activePage * 124); 3258 review(); 3259 } 3260 } 3261 } 3262 }; 3263 3264 _this.thumblist = _this.targetObject.thumblist = new ThumbList({ 3265 //w: 128 * _this.viewport.width/_this.viewport.height, 3266 h: 500, 3267 addFn: function (row) { 3268 3269 }, 3270 scrollFn: review, 3271 itemHeight: 128, 3272 totalRows: _this.pageCount, 3273 generatorFn: function (row) { 3274 var el = document.createElement("div"); 3275 var pageNumber = row + 1; 3276 el.id = "df-thumb" + pageNumber; 3277 var elText = document.createElement("div"); 3278 elText.innerHTML = pageNumber; 3279 el.appendChild(elText); 3280 //el.style.position = "absolute"; 3281 //el.callback = function_this.getPage(pageNumber,null,true); 3282 return el; 3283 } 3284 }); 3285 3286 _this.thumblist.lastScrolled = Date.now(); 3287 _this.thumblist.review = review; 3288 review(); 3289 3290 //_this.thumblist.container.classList.add('thumb-container');
3291 var thumbContainer = $('<div>').addClass("df-thumb-container df-sidemenu-visible df-sidemenu"); 3292 thumbContainer.append($(_this.thumblist.container).addClass("df-thumb-wrapper")); 3293 _this.targetObject.thumbContainer = thumbContainer; 3294 _this.targetObject.container.append(thumbContainer); 3295 3296 var sideMenuClose = $(html.div, { 3297 class: "df-ui-btn df-ui-sidemenu-close ti-close" 3298 }); 3299 thumbContainer.append(sideMenuClose); 3300 _this.thumblist.reset($(_this.thumblist.container).height()); 3301 _this.targetObject.container.on('click', '.df-thumb-container .df-vrow', function (e) { 3302 e.stopPropagation(); 3303 var id = $(this).attr("id").replace("df-thumb", ""); 3304 _this.targetObject.gotoPage(parseInt(id, 10)); 3305 }); 3306 }; 3307 3308 ContentProvider.prototype.initOutline = function () { 3309 var _this = this; 3310 var outlineContainer = $('<div>').addClass("df-outline-container df-sidemenu"); 3311 var outlineWrapper = $('<div>').addClass("df-outline-wrapper"); 3312 3313 var sideMenuClose = $(html.div, { 3314 class: "df-ui-btn df-ui-sidemenu-close ti-close" 3315 }); 3316 3317 outlineContainer.append(sideMenuClose).append(outlineWrapper); 3318 _this.targetObject.container.append(outlineContainer); 3319 _this.targetObject.outlineContainer = outlineContainer; 3320 3321 _this.outlineViewer = new BookMarkViewer({ 3322 container: outlineWrapper[0], 3323 linkService: _this.linkService, 3324 outlineItemClass: "df-outline-item", 3325 outlineToggleClass: "df-outline-toggle", 3326 outlineToggleHiddenClass: "df-outlines-hidden" 3327 }); 3328 3329 function processOutline(outline) { 3330 3331 if (_this.options.overwritePDFOutline == true) { 3332 outline = []; 3333 } 3334 outline = outline || []; 3335 3336 if (_this.outline) { 3337 for (var count = 0; count < _this.outline.length; count++) { 3338 _this.outline[count].custom = true; 3339 if (outline) outline.push(_this.outline[count]); 3340 } 3341 /* _this.outline.forEach(function(v) { 3342 //v.custom = true; 3343 this.push(v); 3344 }, this); 3345 outline.push(_this.outline)*/ 3346 } 3347 if (outline.length === 0 && _this.targetObject.ui.outline != null) { 3348 _this.targetObject.ui.outline.hide(); 3349 } 3350 3351 _this.outlineViewer.render({outline: outline}); 3352 } 3353 3354 if (_this.pdfDocument) { 3355 _this.pdfDocument.getOutline().then(function (outline) { 3356 processOutline(outline); 3357 }); 3358 } 3359 else { 3360 processOutline([]); 3361 } 3362 3363 if (_this.options.autoEnableOutline == true) { 3364 _this.targetObject.ui.outline.trigger("click"); 3365 } 3366 3367 if (_this.options.autoEnableThumbnail == true) { 3368 _this.targetObject.ui.thumbnail.trigger("click"); 3369 } 3370 3371 }; 3372 3373 ContentProvider.prototype.checkViewportSize = function (width, height, zoom) { 3374 var _this = this; 3375 var target = _this.targetObject; 3376 var zoomWidth = width * zoom, 3377 zoomHeight = height * zoom; 3378 3379 var oldCacheSize = _this.cacheIndex; 3380 3381 /* var height = target.mode == "css" 3382 ? (target.container.height() - (target.stage.innerWidth() - target.stage.width()) ) 3383 : target.stage.height(); 3384 3385 var width = height * _this.normalViewport.width / _this.normalViewport.height;*/ 3386 3387 //var zoom = _this.zoomScale != 1; 3388 3389 if (_this.contentSourceType == SOURCE_TYPE.PDF) { 3390 3391 3392 /* _this.viewport.height = height; 3393 _this.viewport.width = width;*/ 3394 _this.cacheIndex = Math.ceil(Math.max(zoomWidth, zoomHeight)); 3395 3396 // if (zoom !== 1) { 3397 3398 _this.cacheIndex = Math.floor(Math.max(zoomWidth, zoomHeight));// * _this.zoomScale;//nearestPowerOfTwo(Math.max(_this.viewport.width,_this.viewport.height)); 3399 // _this.cacheIndex = Math.floor(utils.zoomStops(Math.max(zoomWidth, zoomHeight), _this.options.zoomRatio, oldCacheSize < _this.cacheIndex, Math.max(width, height))); 3400 3401 // } 3402 3403 _this.cacheIndex = limitAt(_this.cacheIndex * defaults.pixelRatio, _this.minDimension, _this.maxDimension); 3404 //removed to force internal page size fit incase the internal pages are of different sizes. 3405 // _this.cacheScale = _this.cacheIndex / Math.max(_this.normalViewport.width, _this.normalViewport.height); 3406 3407 if (_this.cache[_this.cacheIndex] == null) _this.cache[_this.cacheIndex] = []; 3408 3409 if (oldCacheSize !== _this.cacheIndex) { 3410 for (var pageCount = 0; pageCount < target.children.length; pageCount++) { 3411 var page = target.children[pageCount]; 3412 //page.name = '-2'; 3413 } 3414 target.refresh(); 3415 } 3416 3417 //if(zoom !==1){ 3418 // zoomHeight = height> width ? _this.cacheIndex : _this.cacheIndex * _this.pageRatio; 3419 //} 3420 _this.imageViewport = _this.refPage.getViewport(zoomHeight / _this.normalViewport.height); 3421 _this.viewport = (target.mode == "css") ? _this.imageViewport 3422 : _this.refPage.getViewport(_this.bookSize.height / _this.normalViewport.height); 3423 3424 log(_this.cacheIndex); 3425 3426 _this.annotedPage = undefined; 3427 _this.review(); 3428 //_this.zoomScale = (zoom == true) ? _this.normalViewport.height * _this.viewport.scale / _this.viewport.height : 1; 3429 3430 } 3431 else { 3432 if (_this.cache[_this.cacheIndex] == null) _this.cache[_this.cacheIndex] = []; 3433 /* _this.cacheIndex = _this.zoomScale == 1 ? limitAt(_this.cacheIndex, _this.minDimension, _this.maxDimension) : _this.maxDimension;*/ 3434 3435 //_this.zoomScale = (zoom == true) ? _this.zoomViewport.height / height : 1; 3436 } 3437 3438 //_this.zoomScale = (zoom == true) ? _this.zoomViewport.height / height : 1; 3439 }; 3440 3441 ContentProvider.prototype.getCache = function (index, isThumb) { 3442 return (isThumb == true)
3443 ? this.cache[this.thumbsize] == null ? null : this.cache[this.thumbsize][index] 3444 : this.cache[this.cacheIndex] == null ? null : this.cache[this.cacheIndex][index]; 3445 }; 3446 3447 ContentProvider.prototype.setCache = function (index, src, isThumb, cacheIndexSize) { 3448 if (isThumb == true) { 3449 if (this.cache[this.thumbsize] != null) this.cache[this.thumbsize][index] = src; 3450 } 3451 else { 3452 var cacheIndex = cacheIndexSize == null ? this.cacheIndex : cacheIndexSize; 3453 if (this.cache[cacheIndex] != null) 3454 this.cache[cacheIndex][index] = src; 3455 } 3456 3457 }; 3458 3459 ContentProvider.prototype.setTarget = function (targetObject) { 3460 var _this = this; 3461 if (targetObject == null) { 3462 return this.targetObject; 3463 } 3464 else { 3465 this.targetObject = targetObject; 3466 targetObject.contentProvider = this; 3467 3468 targetObject.container.removeClass("df-loading df-init"); 3469 3470 //_this.initThumbs(); 3471 3472 if (_this.linkService != null) { 3473 _this.linkService.setViewer(targetObject); 3474 3475 _this.initOutline(); 3476 } 3477 3478 targetObject.processPage = function (pageNumber, callback) { 3479 if (pageNumber > 0 && pageNumber <= _this.pageCount) { 3480 //log("Loading page :" + pageNumber); 3481 _this.getPage(pageNumber, callback); 3482 } 3483 else { 3484 _this.setPage(pageNumber, defaults.textureLoadFallback, callback); 3485 //log("Invalid PageNumber :" + pageNumber); 3486 } 3487 }; 3488 3489 targetObject.requestPage = function () { 3490 3491 _this.review("Request"); 3492 3493 }; 3494 3495 if (targetObject.resize != null) 3496 targetObject.resize(); 3497 3498 } 3499 }; 3500 3501 ContentProvider.prototype.review = function (message) { 3502 var _this = this; 3503 message = message || "timer review"; 3504 clearTimeout(_this.textureLoadTimeOut); 3505 _this.textureLoadTimeOut = setTimeout(function () { 3506 3507 _this.textureLoadTimeOut = setTimeout(_this.reviewPages, _this.waitPeriod / 2, _this, message); 3508 3509 }, _this.waitPeriod); 3510 }; 3511 3512 ContentProvider.prototype.reviewPages = function (_this, message) { 3513 _this = _this || this; 3514 var target = _this.targetObject; 3515 3516 if (target == null) return; 3517 3518 var isBooklet = isBookletMode(target); 3519 if (message != null) log(message); 3520 var requiresRevisit = false; 3521 var pageCount, page; 3522 3523 for (pageCount = 0; pageCount < _this.targetObject.children.length; pageCount++) { 3524 page = target.children[pageCount]; 3525 if (page.isFlipping == true) { //requires revisit 3526 requiresRevisit = true; 3527 break; 3528 } 3529 } 3530 if (requiresRevisit == false) { 3531 3532 var pageLength = target.children.length > 3 ? 3 : target.children.length; 3533 var midPoint = pageLength / 2; 3534 3535 var basePage = isBooklet ? target._activePage : getBasePage(target._activePage); 3536 _this.baseNumber = basePage; 3537 3538 if (_this.zoomScale > 1) { 3539 pageLength = 1; 3540 } 3541 3542 for (pageCount = 0; pageCount < pageLength; pageCount++) { 3543 3544 var dividend = Math.floor(pageCount / 2); 3545 var diff = pageCount % 2 == 0 3546 ? -dividend * (isBooklet ? 1 : 2) 3547 : (dividend == 0 ? 1 : dividend) * (isBooklet ? 1 : 2); 3548 3549 var frontPageNumber = basePage + diff, 3550 backPageNumber = basePage + diff + 1; 3551 3552 var page1 = target.getPageByNumber(frontPageNumber), 3553 page2 = target.getPageByNumber(backPageNumber), 3554 reqFrontPageStamp = frontPageNumber + "|" + _this.cacheIndex, 3555 reqBackPageStamp = backPageNumber + "|" + _this.cacheIndex; 3556 3557 3558 var requestCount = 0; 3559 if (page1 != null && page1.frontPageStamp != reqFrontPageStamp && page1.visible == true) { 3560 page1.frontTextureLoaded = false; 3561 target.processPage(frontPageNumber, function () { 3562 _this.review("Batch Call"); 3563 }); 3564 page1.frontPageStamp = reqFrontPageStamp; 3565 requestCount++; 3566 } 3567 if (page2 != null && page2.backPageStamp != reqBackPageStamp && page2.visible == true && !isBooklet) { 3568 page2.backTextureLoaded = false;
3569 target.processPage(backPageNumber, function () { 3570 _this.review("Batch Call"); 3571 }); 3572 page2.backPageStamp = reqBackPageStamp; 3573 requestCount++; 3574 } 3575 3576 //diff is 0 only at the open pages 3577 if (diff == 0 && _this.annotedPage !== basePage) {// && target.mode !== "css") { 3578 _this.getAnnotations(frontPageNumber); 3579 if (!isBooklet) _this.getAnnotations(backPageNumber); 3580 _this.annotedPage = basePage; 3581 } 3582 3583 if (requestCount > 0) { 3584 break; 3585 } 3586 } 3587 if (requestCount == 0) { 3588 if (target.mode !== "css") { 3589 _this.setLoading(basePage); 3590 } 3591 else { 3592 // _this.setLoading(basePage); 3593 // _this.setLoading(basePage + 1); 3594 } 3595 } 3596 } 3597 else { 3598 _this.review("Revisit request"); 3599 if (_this.annotedPage != null && target.mode !== "css") { 3600 var baseActive = getBasePage(target._activePage); 3601 $(target.getContentLayer(baseActive)).html(""); 3602 $(target.getContentLayer(baseActive + 1)).html(""); 3603 _this.annotedPage = null; 3604 } 3605 } 3606 3607 }; 3608 3609 ContentProvider.prototype.getPage = function (pageNumber, callbackFunction, isThumb) { 3610 var _this = this; 3611 3612 pageNumber = parseInt(pageNumber, 10); 3613 var _pageNumber = pageNumber; 3614 var source = _this.contentSource; 3615 if (pageNumber <= 0 && pageNumber >= _this.pageCount) { 3616 _this.setPage(pageNumber, defaults.textureLoadFallback, callbackFunction, isThumb); 3617 } 3618 else { 3619 if (_this.contentSourceType == SOURCE_TYPE.PDF) { 3620 if (_this.getCache(pageNumber, isThumb) != null) { 3621 _this.setPage(pageNumber, _this.getCache(pageNumber, isThumb), callbackFunction, isThumb); 3622 log("Page " + pageNumber + " loaded from cache"); 3623 } 3624 else { 3625 if (isThumb !== true) _this.setLoading(pageNumber, true); 3626 3627 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 2) { 3628 _pageNumber = Math.ceil((pageNumber - 1) / 2) + 1; 3629 } 3630 source.getPage(_pageNumber, isThumb).then(function (page) { 3631 renderPage(page, pageNumber, callbackFunction, isThumb); 3632 }); 3633 } 3634 } 3635 else if (_this.contentSourceType == SOURCE_TYPE.IMAGE || _this.contentSourceType == SOURCE_TYPE.HTML) { 3636 if (_this.getCache(pageNumber, isThumb) != null) { 3637 _this.setPage(pageNumber, _this.getCache(pageNumber, isThumb), callbackFunction, isThumb); 3638 log("Page " + pageNumber + " loaded from cache"); 3639 } 3640 else { 3641 if (isThumb !== true) _this.setLoading(pageNumber, true); 3642 3643 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 2) { 3644 _pageNumber = Math.ceil((pageNumber - 1) / 2) + 1; 3645 } 3646 3647 //if (_this.isCrossOrigin == null) { 3648 // 3649 // _this.setCache(pageNumber, source[_pageNumber - 1], isThumb, _this.cacheIndex); 3650 // _this.setPage(pageNumber, source[_pageNumber - 1], callbackFunction, isThumb); 3651 // 3652 // if (callbackFunction != null) callbackFunction(); 3653 // 3654 //} else { 3655 loadImagejQuery(source[_pageNumber - 1], function (src) { 3656 3657 _this.setCache(pageNumber, src, isThumb, _this.cacheIndex); 3658 _this.setPage(pageNumber, src, callbackFunction, isThumb); 3659 3660 if (callbackFunction != null) callbackFunction(); 3661 3662 }, _this.isCrossOrigin); 3663 //} 3664 } 3665 3666 //_this.setPage(pageNumber, source[pageNumber - 1], callbackFunction, isThumb); 3667 } 3668 } 3669 3670 function loadImage(src, callback, isCrossOrigin) { 3671 3672 var img = new Image; 3673 3674 img.crossOrigin = "Anonymous"; 3675 3676 img.onload = function () { 3677 3678 if (isCrossOrigin == true) { 3679 var canvas = document.createElement("canvas"), 3680 ctx = canvas.getContext("2d"); 3681 canvas.width = img.width;
3682 canvas.height = img.height; 3683 ctx.drawImage(img, 0, 0); 3684 //localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") ); 3685 3686 if (defaults.canvasToBlob == true) { 3687 canvas.toBlob(function (blob) { 3688 var src = DFLIP.createObjectURL(blob, "image/jpeg"); 3689 3690 if (callback != null) callback(src); 3691 3692 }, "image/jpeg", 0.85) 3693 3694 3695 } 3696 else { 3697 if (callback != null) callback(canvas); 3698 } 3699 } 3700 else { 3701 if (callback != null) callback(src); 3702 } 3703 //$(this).off(); 3704 img.onload = null; 3705 img = null; 3706 3707 }; 3708 3709 img.src = src; 3710 3711 // make sure the load event fires for cached images too 3712 if (img.complete || img.complete === undefined) { 3713 img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; 3714 img.src = src; 3715 } 3716 3717 } 3718 3719 function loadImagejQuery(src, callback, isCrossOrigin) { 3720 $("<img/>") 3721 .attr("src", _this.contentSource[0]) 3722 .on('load', (function () { 3723 3724 3725 $(this).off(); 3726 3727 if (callback != null) { 3728 callback(src); 3729 // callback = null; 3730 } 3731 //_this.setLoading(1); 3732 3733 //console.log(_this.zoomViewport); 3734 log(this.height + ":" + this.width); 3735 //pic_real_width = this.width; // Note: $(this).width() will not 3736 //pic_real_height = this.height; // work for in memory images. 3737 //moved to set target function 3738 //_this. 3739 // (); 3740 3741 3742 })); 3743 } 3744 3745 function renderPage(page, pageNumber, callbackFunction, isThumb) { 3746 3747 3748 var forceFit = _this.options.forceFit; 3749 var isDoublePage = _this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 1 && pageNumber < _this.pageCount; 3750 var widthFix = isDoublePage && forceFit ? 2 : 1; 3751 3752 /* var heightScale = _this.pageRatio < 1 3753 ? _this.cacheScale 3754 : _this.cacheScale / _this.pageRatio;*/ 3755 //_this.cacheScale = _this.cacheIndex / Math.max(_this.normalViewport.width, _this.normalViewport.height); 3756 //scales are calculated based on perpage in case per page fitting is required. 3757 var viewport = forceFit ? page.getViewport(1) : _this.normalViewport; 3758 3759 var scale = _this.cacheIndex / Math.max(viewport.width / widthFix, viewport.height);//heightScale /_this.normalViewport.height; 3760 if (_this.webgl == true) { 3761 scale = nearestPowerOfTwo(_this.cacheIndex) / (_this.pageRatio > 1 3762 ? viewport.width / widthFix : viewport.height); 3763 } 3764 3765 var canvas = document.createElement('canvas'); 3766 var start = performance.now(); 3767 3768 var requestedCacheSize = _this.cacheIndex; 3769 3770 var context = canvas.getContext('2d'); 3771 3772 // scale = scale * defaults.pixelRatio; 3773 3774 if (isThumb == true) { 3775 scale = _this.thumbsize / _this.normalViewport.height; 3776 } 3777 3778 canvas.height = Math.round(viewport.height * scale); //causes fluctuation in value like 22.99999 as 22 3779 canvas.width = Math.round(viewport.width / widthFix * scale); 3780 3781 if (_this.targetObject.mode == 'css' && Math.abs(_this.targetObject.zoomHeight - canvas.height) < 2) { 3782 canvas.height = _this.targetObject.zoomHeight + 0; //causes fluctuation in value like 22.99999 as 22 3783 canvas.width = _this.targetObject.zoomWidth + 0; 3784 } 3785 3786 viewport = page.getViewport(scale); 3787 log("rendering " + pageNumber + " at " + canvas.width + "x" + canvas.height); 3788 3789 if (isDoublePage) { 3790 if (isRTLMode(_this.targetObject)) { 3791 if (pageNumber % 2 == 0) { 3792 viewport.transform[4] = -canvas.width; 3793 } 3794 } 3795 else { 3796 if (pageNumber % 2 == 1) { 3797 viewport.transform[4] = -canvas.width; 3798 } 3799 } 3800 } 3801 var renderContext = { 3802 canvasContext: context, 3803 viewport: viewport 3804 }; 3805 3806 page.cleanupAfterRender = true; 3807 var pageRendering = page.render(renderContext); 3808 3809 pageRendering.promise.then( 3810 function () { 3811 3812 log(performance.now() - start); 3813 start = performance.now(); 3814 if (isThumb == true || (_this.options.canvasToBlob == true && _this.webgl !== true)) { 3815 canvas.toBlob(function (blob) { 3816 var src = DFLIP.createObjectURL(blob, "image/jpeg"); 3817 log(performance.now() - start); 3818 _this.setCache(pageNumber, src, isThumb, requestedCacheSize); 3819 _this.setPage(pageNumber, src, callbackFunction, isThumb); 3820 3821 //canvas.width = canvas.height = 1; 3822 //context.clearRect( 0, 0, canvas.width, canvas.height ); 3823 3824 //page.cleanup(); 3825 }, "image/jpeg", _this.pdfRenderQuality) 3826 } 3827 else { 3828 log("Setting Page " + pageNumber);
3829 _this.setPage(pageNumber, canvas, callbackFunction, isThumb); 3830 } 3831 renderContext = null; 3832 }); 3833 3834 } 3835 3836 }; 3837 3838 ContentProvider.prototype.getTargetPage = function (pageNumber) { 3839 3840 }; 3841 3842 ContentProvider.prototype.setLoading = function (pageNumber, show) { 3843 if (this.targetObject != null) { 3844 if (this.webgl == true) { 3845 var container = this.targetObject.container; 3846 if (show == true) { 3847 if (container.isLoading !== true) { 3848 container.addClass("df-loading"); 3849 container.isLoading = true; 3850 log("Loading icon at " + pageNumber + " as " + show); 3851 } 3852 } 3853 else { 3854 if (container.isLoading != null) { 3855 container.removeClass("df-loading"); 3856 container.isLoading = null; 3857 log("Loading icon at " + pageNumber + " as " + show); 3858 } 3859 } 3860 } 3861 else { 3862 var contentLayer = $(this.targetObject.getContentLayer(pageNumber)); 3863 if (contentLayer != null) { 3864 if (show == true) contentLayer.addClass("df-page-loading"); 3865 else contentLayer.removeClass("df-page-loading"); 3866 log("Loading icon at " + pageNumber + " as " + show); 3867 } 3868 } 3869 } 3870 }; 3871 3872 ContentProvider.prototype.getAnnotations = function (pageNumber) { 3873 var _this = this; 3874 3875 if (_this.options.enableAnnotation == false || utils.hasCompatibility() === true) return; 3876 3877 var target = _this.targetObject; 3878 3879 pageNumber = parseInt(pageNumber, 10); 3880 var source = _this.contentSource; 3881 var contentLayer = $(target.getContentLayer(pageNumber)); 3882 contentLayer.empty(); 3883 if (pageNumber > 0 && pageNumber <= _this.pageCount) { 3884 3885 3886 if (_this.contentSourceType == SOURCE_TYPE.PDF) { 3887 var basePage = getBasePage(pageNumber); 3888 3889 var _pageNumber = pageNumber; 3890 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 2) { 3891 _pageNumber = Math.ceil((pageNumber - 1) / 2) + 1; 3892 } 3893 3894 source.getPage(_pageNumber).then(function (page) { 3895 3896 if (contentLayer != null && contentLayer.length > 0) { 3897 var viewport = page.getViewport(1); 3898 viewport = page.getViewport(_this.viewport.height / viewport.height); 3899 // _this.viewport 3900 _this.setupAnnotations(page, viewport, contentLayer, pageNumber); 3901 3902 /* //it's just resizing nothing to do with annotation fetch 3903 if (target.mode != "css") { 3904 3905 var page3d = target.getPageByNumber(pageNumber); 3906 if (page3d != null) { 3907 var isLeft = (pageNumber % 2 == 0); 3908 var width = Math.abs(page3d.geometry.boundingBox.max.x - page3d.geometry.boundingBox.min.x); 3909 var height = Math.abs(page3d.geometry.boundingBox.max.z - page3d.geometry.boundingBox.min.z); 3910 3911 var div3d = isLeft ? target.parent.cssScene.divLeft : target.parent.cssScene.divRight; 3912 if (div3d != null) { 3913 div3d.rotation.y = (isLeft ? -1 : 1 ) * Math.atan2(height, width) * 0.9; 3914 div3d.position.z = height * 0.8; 3915 div3d.position.x = (isLeft ? 1 : -1 ) * height / 2.5; 3916 $(div3d.element).css({ 3917 width: width, 3918 left: isLeft ? -width / 2 : width / 2 3919 }); 3920 3921 } 3922 } 3923 }*/ 3924 } 3925 }); 3926 } 3927 3928 //render any custom liks available for page. 3929 3930 if (_this.links != null && _this.links[pageNumber] != null) { 3931 var pageLinks = _this.links[pageNumber]; 3932 for (var index = 0; index < pageLinks.length; index++) { 3933 var pageLink = pageLinks[index]; 3934 3935 var annotation; 3936 if (pageLink.dest && pageLink.dest.indexOf && pageLink.dest.indexOf('[html]') == 0) { 3937 annotation = document.createElement('div'); 3938 annotation.innerHTML = pageLink.dest.substr(6); 3939 annotation.className = "customHtmlAnnotation"; 3940 } 3941 else { 3942 annotation = document.createElement('a'); 3943 annotation.setAttribute("dest", pageLink.dest); 3944 annotation.className = "customLinkAnnotation"; 3945 annotation.href = "#" + pageLink.dest; 3946 annotation.onclick = function () { 3947 var dest = this.getAttribute("dest"); 3948 if (dest) { 3949 _this.linkService.customNavigateTo(dest); 3950 } 3951 return false;
3952 }; 3953 3954 } 3955 annotation.style.left = pageLink.x + "%"; 3956 annotation.style.top = pageLink.y + "%"; 3957 3958 annotation.style.width = pageLink.w + "%"; 3959 annotation.style.height = pageLink.h + "%"; 3960 contentLayer[0].appendChild(annotation); 3961 } 3962 } 3963 3964 //render any html available for page. 3965 3966 if (_this.html != null && _this.html[pageNumber] != null) { 3967 var pageHTML = _this.html[pageNumber]; 3968 contentLayer.append($("<div class='customHTMLAnnotation'>").html(pageHTML)); 3969 } 3970 } 3971 }; 3972 3973 ContentProvider.prototype.setPage = function (pageNumber, textureSrc, callbackFunction, isThumb) { 3974 var _this = this; 3975 var target = _this.targetObject; 3976 var isRTL = isRTLMode(target); 3977 var isBooklet = isBookletMode(target); 3978 if (isThumb == true) { 3979 var page = _this.targetObject.container.find("#df-thumb" + pageNumber); 3980 //log("setting:" + pageNumber + " " + bgImage(textureSrc)); 3981 page.css({ 3982 backgroundImage: bgImage(textureSrc) 3983 }); 3984 } 3985 else { 3986 3987 if (textureSrc == defaults.textureLoadFallback) { 3988 log("Fallback on " + pageNumber); 3989 } 3990 3991 var bookPage = target.getPageByNumber(pageNumber); 3992 if (bookPage != null) { 3993 if ( 3994 (pageNumber % 2 != 0 && !isRTL) || 3995 (pageNumber % 2 != 1 && isRTL && !isBooklet) || (isBooklet && !isRTL) 3996 ) { 3997 log(pageNumber + "rendered to back of " + bookPage.color); 3998 bookPage.backImage(textureSrc, function (object, texture) { 3999 bookPage.backTextureLoaded = true; 4000 _this.setLoading(pageNumber); 4001 if (_this.requiresImageTextureScaling && texture && pageNumber != 1 && pageNumber != _this.pageCount) { 4002 texture.repeat.x = 0.5; 4003 texture.offset.x = 0.5; 4004 } 4005 if (callbackFunction != null) callbackFunction(); 4006 }); 4007 4008 } 4009 else { 4010 log(pageNumber + "rendered to front of " + bookPage.color); 4011 bookPage.frontImage(textureSrc, function (object, texture) { 4012 bookPage.frontTextureLoaded = true; 4013 _this.setLoading(pageNumber); 4014 if (_this.requiresImageTextureScaling && texture && pageNumber != 1 && pageNumber != _this.pageCount) { 4015 texture.repeat.x = 0.5; 4016 } 4017 if (callbackFunction != null) callbackFunction(); 4018 }); 4019 //} 4020 } 4021 } 4022 else { 4023 log("Invalid set request on Page " + pageNumber); 4024 } 4025 } 4026 }; 4027 4028 ContentProvider.prototype.setupAnnotations = function (page, viewport, pageDiv, pageNumber) { 4029 if (pageDiv == null || $(pageDiv).length == 0) return; 4030 var _this = this; 4031 return page.getAnnotations().then(function (annotationsData) { 4032 viewport = viewport.clone({ 4033 dontFlip: true 4034 }); 4035 4036 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 2 && pageNumber % 2 == 1) { 4037 //viewport.transform[4]= -viewport.scale * page.view[2]/2; 4038 4039 } 4040 else if (pageNumber == 1) { 4041 4042 } 4043 if (pageDiv == null) { 4044 return; 4045 } 4046 pageDiv = $(pageDiv); 4047 if (pageDiv.find(".annotationDiv").length == 0) { 4048 pageDiv.append($("<div class='annotationDiv'>")); 4049 } 4050 var div = pageDiv.find(".annotationDiv"); 4051 div.empty(); 4052 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 2 && pageNumber % 2 == 1) { 4053 //viewport.transform[4]= -viewport.scale * page.view[2]/2; 4054 div.css({left: '-100%'}); 4055 } 4056 else if (pageNumber == 1) { 4057 div.css({left: ''}); 4058 } 4059 /* div.css({ 4060 transform:'matrix(' + _this.viewport.transform.join(',') + ')' 4061 });*/ 4062 4063 PDFJS.AnnotationLayer.render({ 4064 annotations: annotationsData, 4065 div: div[0], 4066 page: page, 4067 viewport: viewport, 4068 linkService: _this.linkService 4069 }); 4070 4071 if (_this.options.annotationClass && _this.options.annotationClass !== "") { 4072 div.find(" > section").addClass(_this.options.annotationClass); 4073 } 4074 if (_this.options.search == true) { 4075 // div.find(" > section").addClass("someclass"); 4076 if (pageDiv.find(".textLayerDiv").length == 0) { 4077 pageDiv.append($("<div class='textLayerDiv'>")); 4078 } 4079 var div2 = pageDiv.find(".textLayerDiv"); 4080 4081 page.getTextContent().then(function (textContent) { 4082 // console.log(textContent); 4083 var textLayer = new DFLIP.TextLayerBuilder({
4084 textLayerDiv: div2[0], 4085 pageIndex: null, 4086 viewport: viewport.clone({ 4087 dontFlip: false 4088 }) 4089 }); 4090 4091 textLayer.setTextContent(textContent); 4092 textLayer.render(); 4093 }); 4094 } 4095 }); 4096 4097 }; 4098 4099 return ContentProvider; 4100 })({}); 4101 4102 var PageCSS = (function () { 4103 function PageCSS(parameters) { 4104 this.angles = parameters.angles || [0, 0, 0, 0, 0, 0]; 4105 this.stiffness = parameters.angles || 0.1; 4106 this.segments = parameters.segments || 1; 4107 this.canvasMode = parameters.contentSourceType !== SOURCE_TYPE.IMAGE && parameters.canvasToBlob == false; 4108 this.initDOM(); 4109 } 4110 4111 function createInternals(pageSide) { 4112 var contentLayer = pageSide.contentLayer = $(html.div, { 4113 class: "df-page-content" 4114 }); 4115 pageSide.append(contentLayer); 4116 } 4117 4118 PageCSS.prototype = { 4119 initDOM: function () { 4120 var element = this.element = $(html.div, { 4121 class: "df-book-page" 4122 }); 4123 var wrapper = this.wrapper = $(html.div, { 4124 class: "df-page-wrapper" 4125 }); 4126 var front = this.front = $(html.div, { 4127 class: "df-page-front" 4128 }); 4129 var back = this.back = $(html.div, { 4130 class: "df-page-back" 4131 }); 4132 var foldInnerShadow = this.foldInnerShadow = $(html.div, { 4133 class: "df-page-fold-inner-shadow" 4134 }); 4135 var foldOuterShadow = this.foldOuterShadow = $(html.div, { 4136 class: "df-page-fold-outer-shadow" 4137 }); 4138 this.frontIMG = new Image(); 4139 this.backIMG = new Image(); 4140 4141 createInternals(front, this.segments, true); 4142 createInternals(back, this.segments, false); 4143 element.append(wrapper).append(foldOuterShadow); 4144 wrapper.append(front).append(back).append(foldInnerShadow); 4145 4146 }, 4147 4148 updatePoint: function (point) { 4149 4150 if (point == null) return; 4151 4152 //detect the current page 4153 var page = this.parent.dragPage != null ? this.parent.dragPage 4154 : point.page != null ? point.page : this; 4155 4156 //get the pageWidth and pageHeight 4157 var pageWidth = page.element.width(), 4158 pageHeight = page.element.height(); 4159 4160 //the corner where the drag started 4161 var corner = this.parent.corner != null ? this.parent.corner : point.corner, 4162 corners = DFLIP.CORNERS; 4163 4164 var 4165 isRight = page.side == drag.right, 4166 isBottom = (corner == corners.BL) || (corner == corners.BR); 4167 4168 point.rx = (isRight == true) 4169 ? pageWidth * 2 - point.x 4170 : point.x; 4171 4172 point.ry = (isBottom == true) 4173 ? pageHeight - point.y 4174 : point.y; 4175 4176 var radAngle = Math.atan2(point.ry, point.rx); 4177 4178 radAngle = Math.PI / 2 - limitAt(radAngle, 0, toRad(90)); 4179 4180 var correctionX = isRight 4181 ? point.x / 2 4182 : pageWidth - point.x / 2, 4183 4184 correctionY = point.ry / 2, 4185 4186 refLength = Math.max(0, 4187 Math.sin(radAngle - Math.atan2(correctionY, correctionX)) * distOrigin(correctionX, 4188 correctionY)), 4189 4190 foldLength = 0.5 * distOrigin(point.rx, point.ry); 4191 4192 var x = Math.round(pageWidth - refLength * Math.sin(radAngle)), 4193 y = Math.round(refLength * Math.cos(radAngle)), 4194 4195 angle = toDeg(radAngle); 4196 4197 var angle1 = isBottom 4198 ? isRight ? 180 + (90 - angle) : 180 + angle 4199 : isRight ? angle : 90 - angle; 4200 4201 var angle2 = isBottom 4202 ? isRight ? 180 + (90 - angle) : angle 4203 : isRight ? angle + 180 : angle1, 4204 angleS = isBottom 4205 ? isRight ? 90 - angle : angle + 90 4206 : isRight ? angle1 - 90 : angle1 + 180, 4207 x1 = isRight ? pageWidth - x : x, 4208 y1 = isBottom ? pageHeight + y : -y, 4209 x2 = isRight ? -x : x - pageWidth, 4210 y2 = isBottom ? -pageHeight - y : y; 4211 4212 var opacity = limitAt(point.distance * 0.5 / pageWidth, 0, 0.5); 4213 var foldOpacity = limitAt((pageWidth * 2 - point.rx) * 0.5 / pageWidth, 0.05, 0.3); 4214 4215 page.element.addClass("df-folding"); 4216 4217 var front = isRight ? page.back : page.front; 4218 var back = isRight ? page.front : page.back; 4219 var outerShadow = page.foldOuterShadow; 4220 var innerShadow = page.foldInnerShadow; 4221 page.wrapper.css({ 4222 transform: translateStr(x1, y1) + rotateStr(angle1) 4223 }); 4224 4225 front.css({ 4226 transform: rotateStr(-angle1) + translateStr(-x1, -y1) 4227 }); 4228 4229 back.css({ 4230 transform: rotateStr(angle2) + translateStr(x2, y2), 4231 boxShadow: "rgba(0, 0, 0, " + opacity + ") 0px 0px 20px" 4232 }); 4233 4234 innerShadow.css({ 4235 transform: rotateStr(angle2) + translateStr(x2, y2), 4236 opacity: foldOpacity / 2, 4237 backgroundImage: prefix.css + "linear-gradient( " + angleS + "deg, rgba(0, 0, 0, 0.25) , rgb(0, 0, 0) " + foldLength * 0.7 + "px, rgb(255, 255, 255) " + foldLength + "px)" 4238 }); 4239 4240 outerShadow.css({ 4241 //transform: rotateStr(angle - (isRight ? -180 : 0)) + translateStr(isRight ? -x : x - pageWidth, y), 4242 opacity: foldOpacity / 2, 4243 left: isRight ? "auto" : 0, 4244 right: isRight ? 0 : "auto", 4245 backgroundImage: prefix.css + "linear-gradient( " + (-angleS + 180) + "deg, rgba(0, 0, 0,0) " + foldLength / 3 + "px, rgb(0, 0, 0) " + foldLength + "px)" 4246 }); 4247 4248 //$("body > p").html(JSON.stringify({ 4249 // x: Math.round(point.rx), 4250 // y: Math.round(point.ry), 4251 // a: Math.round(angle), 4252 // a1: Math.round(angle1), 4253 // cx: Math.round(correctionX), 4254 // cy: Math.round(correctionY), 4255 // dx: Math.round(x), 4256 // dy: Math.round(y), 4257 // ref: Math.round(refLength), 4258 // dis: Math.round(distOrigin(point.x, point.y)) 4259 //})); 4260 }, 4261 4262 updateAngle: function (angle, isRight) { 4263 4264 var width = this.element.width() * 5; 4265 4266 //if(prefix.dom!=='MS') { 4267 this.wrapper.css({ 4268 perspective: width, 4269 perspectiveOrigin: isRight == true ? "0% 50%" : "100% 50%" 4270 }); 4271 //} 4272 4273 this.front.css({ 4274 display: (isRight == true ? (angle <= -90 ? 'block' : 'none') : (angle < 90 ? 'block' : 'none')), 4275 transform: (prefix.dom !== 'MfS' ? "" : "perspective(" + width + "px) ") 4276 + (isRight == true ? "translateX(-100%) " : "") 4277 + "rotateY(" + ((isRight == true ? 180 : 0) + angle) + "deg)" 4278 }); 4279 this.back.css({ 4280 display: (isRight == true ? (angle > -90 ? 'block' : 'none') : (angle >= 90 ? 'block' : 'none')), 4281 transform: (prefix.dom !== 'MSd' ? "" : "perspective(" + width + "px) ") 4282 + (isRight == false ? "translateX(100%) " : "") 4283 + "rotateY(" + ((isRight == false ? -180 : 0) + angle) + "deg)" 4284 }); 4285 //$("body > p").html(JSON.stringify({ 4286 // a: Math.round(angle) 4287 //})); 4288 return; 4289 /*if(this.angles[1] != null) { 4290 var segsb = this.back.segments; 4291 var segsf = this.front.segments; 4292 var width = this.element.width(); 4293 var angle1 = this.angles[1]; 4294 var angle2 = this.angles[4]/segsb.length; 4295 var step = Math.floor(width/segsb.length); 4296 4297 for (var count = 0; count < segsb.length; count++) { 4298 var segb = segsb[count]; 4299 var segf = segsf[count]; 4300 segb.css({ 4301 transform: "rotate3d(0,1,0," + (count == 0 ? angle1 : angle2) + "deg)", 4302 //backgroundPositionX: -step * count, 4303 //backgroundSize: width + "px 100%" 4304 }); 4305 4306 segf.css({ 4307 transform: "rotate3d(0,1,0," + (count == 0 ? 180 + angle1 : angle2) + "deg)", 4308 //backgroundPositionX: step * (count + 1), 4309 //backgroundSize: width + "px 100%" 4310 }); 4311 } 4312 } 4313 else{ 4314 this.element.find(".bg-segment").css({ 4315 transform: "translate3d(0px,0,0) rotate3d(0,1,0,0deg)" 4316 }); 4317 }*/ 4318 4319 }, 4320 4321 tween: function (point) { 4322 var page = this; 4323 if (page == null || page.parent == null) return; 4324 var isBooklet = isBookletMode(page.parent); 4325 var isRight = page.side == drag.right; 4326 var isRTL = page.parent.direction == DFLIP.DIRECTION.RTL; 4327 var isBottom = page.parent.corner == DFLIP.CORNERS.BL || page.parent.corner == DFLIP.CORNERS.BR; 4328 var isMagnetic = page.magnetic == true; 4329 var travelY = isBottom ? page.parent.height : 0; 4330 4331 var init, first, mid, angle = 0; 4332 4333 var end = page.end = (page && page.animateToReset == true) 4334 ? {x: isRight ? page.parent.fullWidth : 0, y: travelY} 4335 : {x: isRight ? 0 : page.parent.fullWidth, y: travelY}; 4336 4337 page.ease = page.isHard ? TWEEN.Easing.Quadratic.InOut : TWEEN.Easing.Linear.None; 4338 4339 var tempDuration = page.parent.duration; 4340 4341 if (page.isHard == true) { 4342 4343 if (point != null) { 4344 angle = angleByDistance(point.distance, point.fullWidth); 4345 } 4346 4347 init = page.init = {angle: angle * (isRight ? -1 : 1)}; 4348 end = page.end = (page && page.animateToReset == true) 4349 ? {angle: isRight ? 0 : -0} 4350 : {angle: isRight ? -180 : 180}; 4351 4352 } 4353 else { 4354 4355 if (point == null) { 4356 4357 init = page.init = (page && page.animateToReset == true) 4358 ? {x: isRight ? 0 : page.parent.fullWidth, y: 0} 4359 : {x: isRight ? page.parent.fullWidth : 0, y: 0}; 4360 4361 first = page.first = { 4362 x: (isRight ? 3 : 1) * page.parent.fullWidth / 4, 4363 y: 0 4364 }; 4365 4366 mid = page.mid = {x: (isRight ? 1 : 3) * page.parent.fullWidth / 4, y: 0}; 4367 4368 } 4369 else { 4370 4371 init = page.init = {x: point.x, y: point.y, opacity: 1}; 4372 first = page.first = {x: point.x * 3 / 4, y: point.y * 3 / 4, opacity: 1}; 4373 mid = page.mid = {x: point.x / 4, y: point.y / 4, opacity: 1}; 4374 4375 tempDuration = page.parent.duration * distPoints(init.x, init.y, end.x, end.y) / page.parent.fullWidth; 4376 4377 tempDuration = limitAt(tempDuration, page.parent.duration / 3, page.parent.duration); 4378 4379 } 4380 } 4381 init.index = 0; 4382 // first.index = 0; 4383 // mid.index = 0; 4384 end.index = 1; 4385 page.isFlipping = true; 4386 4387 var update = function (tween) { 4388 4389 if (page.isHard == true) { 4390 page.updateAngle(tween.angle, isRight); 4391 page.angle = tween.angle; 4392 } 4393 else { 4394 page.updatePoint({ 4395 x: tween.x, 4396 y: tween.y 4397 }); 4398 page.x = tween.x; 4399 page.y = tween.y; 4400 } 4401 if (isBooklet && !isMagnetic) 4402 page.element[0].style.opacity = (isRight && !isRTL) || (!isRight && isRTL) 4403 ? tween.index > 0.5 ? 2 * (1 - tween.index) : 1 4404 : tween.index < 0.5 ? 2 * tween.index : 1; 4405 4406 }; 4407 4408 if (isBooklet && ((!isRight && !isRTL) || (isRight && isRTL))) 4409 page.element[0].style.opacity = 0; 4410 4411 var completeTween = page.completeTween = page.completeTween || function (skipRefresh) { 4412 page.isFlipping = false;
4413 4414 if (page.isHard == true) { 4415 4416 page.updateAngle(page.end.angle); 4417 page.back.css({display: "block"}); 4418 page.front.css({display: "block"}); 4419 4420 } 4421 else { 4422 4423 page.updatePoint({ 4424 x: page.end.x, 4425 y: page.end.y 4426 }); 4427 4428 } 4429 4430 page.element[0].style.opacity = 1; 4431 4432 if (page.animateToReset !== true) { 4433 page.side = page.side == drag.right ? drag.left : drag.right; 4434 } 4435 else 4436 page.animateToReset = null; 4437 4438 page.currentTween = null; 4439 page.pendingPoint = null; 4440 page.magnetic = false; 4441 page.parent.dragPage = null; 4442 page.parent.corner = DFLIP.CORNERS.NONE; 4443 4444 if (skipRefresh != true) 4445 page.parent.refresh(); 4446 4447 4448 //log("Tween Completed"); 4449 }; 4450 if (page.isHard == true) { 4451 page.currentTween = new TWEEN.Tween(init).delay(0) 4452 .to(end, page.parent.duration) 4453 .onUpdate(function () { 4454 update(this); 4455 }).easing(page.ease) 4456 .onComplete(page.completeTween) 4457 .start(); 4458 } 4459 else { 4460 if (point == null) { 4461 page.currentTween = new TWEEN.Tween(init).delay(0) 4462 .to(end, page.parent.duration) 4463 .onUpdate(function () { 4464 update(this); 4465 }).easing(TWEEN.Easing.Sinusoidal.Out) 4466 .onComplete(page.completeTween) 4467 .start(); 4468 } 4469 else { 4470 page.currentTween = new TWEEN.Tween(init).delay(0) 4471 .to(end, tempDuration) 4472 .onUpdate(function () { 4473 update(this); 4474 }).easing(TWEEN.Easing.Sinusoidal.Out) 4475 .onComplete(page.completeTween); 4476 page.currentTween.start(); 4477 } 4478 } 4479 //page.currentTween.parent= page; 4480 4481 }, 4482 frontImage: function (texture, callback) { 4483 var _this = this; 4484 4485 function completed() { 4486 _this.front.css({ 4487 backgroundImage: bgImage(texture) 4488 }); 4489 if (callback != null) callback(); 4490 } 4491 4492 if (_this.canvasMode == true) { 4493 _this.front.find(">canvas").remove(); 4494 if (texture !== defaults.textureLoadFallback) { 4495 _this.front.append($(texture)); 4496 } 4497 if (callback != null) callback(); 4498 } 4499 else { 4500 if (texture == defaults.textureLoadFallback) { 4501 completed(); 4502 } 4503 else { 4504 _this.frontIMG.onload = completed; 4505 _this.frontIMG.src = texture; 4506 } 4507 } 4508 }, 4509 backImage: function (texture, callback) { 4510 var _this = this; 4511 4512 function completed() { 4513 _this.back.css({ 4514 backgroundImage: bgImage(texture) 4515 }); 4516 if (callback != null) callback(); 4517 } 4518 4519 if (_this.canvasMode == true) { 4520 _this.back.find(">canvas").remove(); 4521 if (texture !== defaults.textureLoadFallback) { 4522 _this.back.append($(texture)); 4523 } 4524 if (callback != null) callback(); 4525 } 4526 else { 4527 if (texture == defaults.textureLoadFallback) { 4528 completed(); 4529 } 4530 else { 4531 _this.backIMG.onload = completed; 4532 _this.backIMG.src = texture; 4533 } 4534 } 4535 4536 }, 4537 updateCSS: function (css) { 4538 this.element.css(css); 4539 }, 4540 resetCSS: function () { 4541 this.wrapper.css({ 4542 transform: '' 4543 }); 4544 4545 this.front.css({ 4546 transform: '', 4547 boxShadow: '' 4548 }); 4549 4550 this.back.css({ 4551 transform: '', 4552 boxShadow: '' 4553 }); 4554 }, 4555 clearTween: function (skipRefresh) { 4556 this.currentTween.stop(); 4557 this.completeTween(skipRefresh == true); 4558 this.resetCSS(); 4559 } 4560 4561 }; 4562 4563 return PageCSS; 4564 })(); 4565 4566 var BookCSS = (function (_super) { 4567 __extends(BookCSS, _super); 4568 4569 function updateFolding(dragPage) { 4570 dragPage.parent.container.find(".df-folding").removeClass("df-folding"); 4571 dragPage.element.addClass("df-folding"); 4572 } 4573 4574 function hasFlipping(book) { 4575 var hasFlipping = false;
4576 for (var pageCount = 0; pageCount < book.pages.length; pageCount++) { 4577 var page = book.pages[pageCount]; 4578 if (page.isFlipping == true) { 4579 hasFlipping = true; 4580 break; 4581 } 4582 } 4583 return hasFlipping; 4584 } 4585 4586 function BookCSS(parameters, container) { 4587 //parameters = extendOptions(parameters); 4588 4589 //_super.call(this, parameters, stage); 4590 var _this = this; 4591 _this.type = "BookCSS"; 4592 _this.images = parameters.images || []; 4593 _this.pageCount = parameters.pageCount || 2; 4594 //_this.segments = parameters.segments = 5; 4595 4596 _this.foldSense = 50; 4597 4598 _this.stackCount = 4; 4599 _this.mode = "css"; 4600 _this.pages = []; 4601 _this.duration = parameters.duration; 4602 4603 _this.container = $(container); 4604 _this.options = parameters; 4605 _this.drag = drag.none; 4606 _this.pageCount = (_this.pageCount == 1 ? _this.pageCount : Math.ceil(_this.pageCount / 2) * 2); 4607 _this.pageMode = parameters.pageMode || ((isMobile || _this.pageCount <= 2) ? DFLIP.PAGE_MODE.SINGLE 4608 : DFLIP.PAGE_MODE.DOUBLE); 4609 4610 _this.singlePageMode = parameters.singlePageMode || (isMobile ? DFLIP.SINGLE_PAGE_MODE.BOOKLET 4611 : DFLIP.SINGLE_PAGE_MODE.ZOOM); 4612 4613 _this.swipe_threshold = isMobile ? 15 : 50; 4614 4615 _this.direction = parameters.direction || DFLIP.DIRECTION.LTR; 4616 4617 _this.startPage = 1; 4618 _this.endPage = _this.pageCount; 4619 4620 _this._activePage = parameters.openPage || _this.startPage; 4621 4622 _this.hardConfig = parameters.hard; 4623 //var foldTime = null; 4624 has3d = 'WebKitCSSMatrix' in window || (document.body && 'MozPerspective' in document.body.style); 4625 4626 _this.animateF = function () { 4627 if (TWEEN.getAll().length > 0) 4628 TWEEN.update(); 4629 else 4630 clearInterval(_this.animate); 4631 }; 4632 4633 _this.init(parameters); 4634 4635 _this.skipDrag = false; 4636 4637 function checkPage(point) { 4638 if (_this.dragPage != point.page && point.page.visible == true) { 4639 _this.dragPage.clearTween(true); 4640 _this.dragPage = point.page; 4641 _this.corner = point.corner; 4642 _this.dragPage.pendingPoint = point; 4643 } 4644 } 4645 4646 var mouseMove = function (event) { 4647 //event.preventDefault(); 4648 var point = _this.eventToPoint(event); 4649 if (event.touches != null && event.touches.length == 2 && _this.startTouches != null) { 4650 //return; 4651 // _this.startTouches = event.touches; 4652 _this.zoomDirty = true; 4653 var touchCenter = utils.getVectorAvg(utils.getTouches(event, _this.container.offset())), 4654 newScale = utils.calculateScale(_this.startTouches, utils.getTouches(event)), 4655 scale = newScale / _this.lastScale; 4656 4657 var zoom = _this.contentProvider.zoomScale, 4658 x = touchCenter.x, 4659 y = touchCenter.y; 4660 4661 _this.stage.css({ 4662 transform: "translate3d(" + _this.left + "px," + _this.top + "px,0) scale3d(" + newScale + "," + newScale + ",1)" 4663 }); 4664 4665 _this.lastScale = newScale; 4666 4667 _this.lastZoomCenter = touchCenter; 4668 event.preventDefault(); 4669 } 4670 4671 if ((event.touches != null && event.touches.length > 1) || _this.startPoint == null || _this.startTouches != null) return; 4672 4673 var targetPage = _this.dragPage || point.page; 4674 4675 if (_this.contentProvider.zoomScale !== 1) { 4676 if ((event.touches != null || _this.isPanning == true)) { 4677 _this.pan(point); 4678 event.preventDefault(); 4679 } 4680 } 4681 else { 4682 if (_this.skipDrag !== true) { 4683 //if (_this.cancelMouse != true) { 4684 4685 var distance = point.distance;//_this.getDistance(event);//point.x < _this.pageWidth ? point.x : _this.fullWidth - point.x; 4686 4687 if (!hasFlipping(_this)) { 4688 4689 4690 if ((_this.dragPage != null) || (point.isInside == true)) { 4691 //$(".quick-hint").html(distance); 4692 if (_this.dragPage != null) { 4693 log("set mouse down move"); 4694 } 4695 else { 4696 point.y = limitAt(point.y, 1, _this.height - 1); 4697 point.x = limitAt(point.x, 1, point.fullWidth - 1); 4698 } 4699 4700 var corner = _this.corner || point.corner; 4701 if (targetPage.isHard) { 4702 var isRight = corner == DFLIP.CORNERS.BR || corner == DFLIP.CORNERS.TR; 4703 4704 var angle = angleByDistance(point.distance, point.fullWidth); 4705 4706 targetPage.updateAngle(angle * (isRight ? -1 : 1), isRight); 4707 4708 } 4709 else { 4710 targetPage.updatePoint(point, _this); 4711 } 4712 4713 targetPage.magnetic = true; 4714 targetPage.magneticCorner = point.corner; 4715 event.preventDefault(); 4716 //point.page.updatePoint(point); 4717 } 4718 4719 if (_this.dragPage == null && targetPage != null && point.isInside == false && targetPage.magnetic == true) { 4720 targetPage.pendingPoint = point; 4721 targetPage.animateToReset = true; 4722 _this.corner = targetPage.magneticCorner; 4723 _this.animatePage(targetPage); 4724 targetPage.pendingPoint = null; 4725 targetPage.magnetic = false;
4726 targetPage.magneticCorner = null; 4727 } 4728 4729 if (_this.isPanning == true && _this.dragPage == null && _this.contentProvider.zoomScale == 1) { 4730 //check if swipe has happened 4731 //console.log(_this.lastPos - point.x,performance.now()-_this.lastTime); 4732 var swipe_dist = point.x - _this.lastPos, 4733 swipe_time = performance.now() - _this.lastTime; 4734 if (Math.abs(swipe_dist) > _this.swipe_threshold) { 4735 //swipe has triggered 4736 //_this.dragPage.pendingPoint = point; 4737 if (swipe_dist < 0) { 4738 _this.next(); 4739 } 4740 else { 4741 _this.prev(); 4742 } 4743 _this.drag = drag.none; 4744 _this.isPanning = false; 4745 event.preventDefault(); 4746 } 4747 _this.lastPos = point.x; 4748 _this.lastTime = performance.now(); 4749 4750 } 4751 } 4752 } 4753 } 4754 4755 }, 4756 mouseUp = function (event) { 4757 if (event.touches != null && event.touches.length == 0) { 4758 var zoom = _this.contentProvider.zoomScale; 4759 if (_this.zoomDirty == true) { 4760 _this.previewObject.contentProvider.zoomScale = 4761 utils.limitAt(_this.previewObject.contentProvider.zoomScale * _this.lastScale, 4762 1, _this.previewObject.contentProvider.maxZoom); 4763 _this.previewObject.zoomValue = _this.previewObject.contentProvider.zoomScale * 1; 4764 //_this.previewObject.zoom(_this.lastScale < 1 ? -1 : 1); 4765 //console.log(_this.previewObject.contentProvider.zoomScale * _this.lastScale,_this.previewObject.contentProvider.maxZoom) 4766 //_this.previewObject.pendingZoom = true; 4767 _this.previewObject.resize(); 4768 _this.zoomDirty = false; 4769 } 4770 _this.wrapper.css({ 4771 transform: "" 4772 }); 4773 _this.lastScale = null; 4774 _this.startTouches = null; 4775 } 4776 _this.isPanning = false; 4777 if (event.touches != null && event.touches.length > 1) return; 4778 if (_this.skipDrag !== true) { 4779 //completeFold(); 4780 var point = _this.eventToPoint(event); 4781 if (_this.dragPage) { 4782 event.preventDefault(); 4783 4784 /* if (_this.animate != null) { 4785 clearInterval(_this.animate); 4786 } 4787 4788 _this.animate = setInterval(_this.animateF, 30); 4789 4790 _this.dragPage.tween(point);*/ 4791 4792 //use something like pending point 4793 // detect the next page anbd call the updatepage 4794 //will be better 4795 4796 _this.dragPage.pendingPoint = point; 4797 if (point.x == _this.startPoint.x && point.y == _this.startPoint.y && point.isInside == true) { 4798 4799 if (_this.corner == DFLIP.CORNERS.BR || _this.corner == DFLIP.CORNERS.TR) { 4800 checkPage(point); 4801 if (_this.dragPage.isFlipping !== true) 4802 _this.next(); 4803 } 4804 else if (_this.corner == DFLIP.CORNERS.BL || _this.corner == DFLIP.CORNERS.TL) { 4805 checkPage(point); 4806 if (_this.dragPage.isFlipping !== true) 4807 _this.prev(); 4808 } 4809 } 4810 else if (_this.dragPage.isFlipping !== true) { 4811 if (point.distance > point.fullWidth / 2) { 4812 if (point.x > point.fullWidth / 2) 4813 _this.prev(); 4814 else 4815 _this.next(); 4816 } 4817 else { 4818 _this.dragPage.animateToReset = true; 4819 _this.animatePage(_this.dragPage); 4820 } 4821 } 4822 //_this.dragPage.animateToReset = true; 4823 if (_this.dragPage) { 4824 _this.dragPage.pendingPoint = null; 4825 _this.dragPage.magnetic = false;
4826 } 4827 } 4828 else { 4829 //detect click 4830 /*if(_this.wrapper[0].contains(event.target) && _this.contentProvider.zoomScale == 1 && point.x == _this.startPoint.x && point.y == _this.startPoint.y && point.isInsidePage && _this.startPoint.page == point.page && !point.page.isFlipping && event.srcElement.nodeName!=="A"){ 4831 if(_this.startPoint.page.side ==0){ 4832 _this.prev(); 4833 _this.startPoint.page = null; 4834 } 4835 else{ 4836 _this.next(); 4837 _this.startPoint.page = null; 4838 } 4839 }*/ 4840 } 4841 4842 _this.drag = drag.none; 4843 4844 //_this.dragPage = null; 4845 //_this.corner = DFLIP.CORNERS.NONE; 4846 //log("set mouse up"); 4847 } 4848 4849 }, 4850 mouseClick = function (event) { 4851 4852 var point = _this.eventToPoint(event); 4853 4854 var element = event.srcElement || event.originalTarget; 4855 4856 if (_this.dragPage && _this.dragPage.magnetic) return; 4857 4858 if (_this.wrapper[0].contains(event.target) && _this.contentProvider.zoomScale == 1 && point.x == _this.startPoint.x && point.y == _this.startPoint.y && point.isInsidePage && _this.startPoint.page == point.page && !point.page.isFlipping && element.nodeName !== "A") { 4859 4860 if (_this.startPoint.page.side == 0) { 4861 _this.corner = DFLIP.CORNERS.TL; 4862 _this.prev(); 4863 _this.startPoint.page = null; 4864 } 4865 else { 4866 _this.corner = DFLIP.CORNERS.TR; 4867 _this.next(); 4868 _this.startPoint.page = null; 4869 } 4870 _this.isPanning = false; 4871 } 4872 4873 }, 4874 mouseDown = function (event) { 4875 if (event.touches != null && event.touches.length == 2 && _this.startTouches == null) { 4876 _this.startTouches = utils.getTouches(event); 4877 _this.lastScale = 1; 4878 } 4879 if ((event.touches != null && event.touches.length > 1) || (event.touches == null && event.button !== 0)) return; 4880 var point = _this.eventToPoint(event); 4881 _this.startPoint = point; 4882 _this.left = _this.left || 0; 4883 _this.top = _this.top || 0; 4884 _this.isPanning = true; 4885 _this.lastPos = point.x; 4886 _this.lastTime = performance.now(); 4887 4888 if (_this.skipDrag !== true) { 4889 4890 if (point.isInside == true && !hasFlipping(_this)) { 4891 _this.startPoint = point; 4892 _this.drag = point.drag; 4893 _this.dragPage = point.page; 4894 4895 _this.corner = point.corner; 4896 4897 log(_this.corner); 4898 4899 updateFolding(_this.dragPage); 4900 //log("set mouse down"); 4901 if (point.page.isHard) { 4902 4903 } 4904 else { 4905 point.page.updatePoint(point, _this); 4906 } 4907 if (point.page.name == "0") { 4908 _this.shadow.css({ 4909 width: '50%', 4910 left: _this.direction == DFLIP.DIRECTION.RTL ? 0 : '50%', 4911 transitionDelay: '' 4912 }); 4913 } 4914 else if (point.page.name == Math.ceil(_this.pageCount / 2) - 1) { 4915 _this.shadow.css({ 4916 width: '50%', 4917 left: _this.direction == DFLIP.DIRECTION.RTL ? '50%' : 0, 4918 transitionDelay: '' 4919 }); 4920 } 4921 } 4922 } 4923 }, 4924 onMouseWheel = function (event) { 4925 var delta = 0; 4926 4927 //var zoom = _this.contentProvider.zoomScale > 1; 4928 if (event.wheelDelta != null) { // WebKit / Opera / Explorer 9 4929 4930 delta = event.wheelDelta / 120; 4931 4932 } 4933 else if (event.detail != null) { // Firefox 4934 4935 delta = -event.detail / 3; 4936 4937 } 4938 4939 var zoom1 = _this.contentProvider.zoomScale, 4940 maxZoom = _this.contentProvider.maxZoom; 4941 4942 if (delta) { 4943 4944 if ((delta > 0 && zoom1 < maxZoom) || (delta < 0 && zoom1 > 1)) { 4945 4946 event.stopPropagation(); 4947 event.preventDefault(); 4948 4949 var pointOld = _this.eventToPoint(event); 4950 var pointNew = _this.eventToPoint(event); 4951 4952 var origin = {x: _this.container.width() / 2, y: -23 + _this.container.height() / 2}; 4953 4954 _this.previewObject.zoom(delta); 4955 4956 var zoom2 = _this.contentProvider.zoomScale; 4957 if (zoom1 !== zoom2) { 4958 var dz = (zoom2 / zoom1); 4959 4960 //fix zoom to previous center 4961 if (zoom2 == 1) { 4962 _this.left = 0; 4963 _this.top = 0; 4964 } 4965 else { 4966 _this.left *= dz; 4967 _this.top *= dz; 4968 } 4969 4970 //fix zoom to previous pointer 4971 var dx = (pointOld.raw.x - origin.x) * dz, 4972 dy = (pointOld.raw.y - origin.y) * dz; 4973 4974 pointNew.raw.x = origin.x + dx;// origin.x + dz * (point.x-origin.x); 4975 pointNew.raw.y = origin.y + dy;// origin.y + dz * (point.y-origin.y); 4976 4977 _this.startPoint = pointNew; 4978 //console.log(pointOld.raw.x - origin.x,dx,pointOld.raw.y - origin.y,dy,pointNew.raw,_this.startPoint.raw); 4979 _this.pan(pointOld); 4980 4981 var targetPage = _this.dragPage || pointOld.page; 4982 if (_this.dragPage == null && targetPage != null && pointOld.isInside == true && targetPage.magnetic == true) { 4983 targetPage.pendingPoint = pointOld; 4984 targetPage.animateToReset = true; 4985 _this.corner = targetPage.magneticCorner; 4986 _this.animatePage(targetPage); 4987 targetPage.pendingPoint = null; 4988 targetPage.magnetic = false;
4989 targetPage.magneticCorner = null; 4990 } 4991 } 4992 4993 } 4994 } 4995 4996 }; 4997 4998 var containerDom = _this.container[0]; 4999 var stageDom = _this.stage[0]; 5000 if (containerDom) { 5001 stageDom.addEventListener("mousemove", mouseMove, false); 5002 stageDom.addEventListener("touchmove", mouseMove, false); 5003 5004 stageDom.addEventListener("mousedown", mouseDown, false); 5005 stageDom.addEventListener("click", mouseClick, false); 5006 stageDom.addEventListener("mouseup", mouseUp, false); 5007 stageDom.addEventListener("touchend", mouseUp, false); 5008 stageDom.addEventListener("touchstart", mouseDown, false); 5009 5010 if (_this.options.scrollWheel == true) { 5011 //lets not trigger scroll when in outline or another 5012 stageDom.addEventListener('mousewheel', onMouseWheel, false); 5013 stageDom.addEventListener('DOMMouseScroll', onMouseWheel, false); // firefox 5014 } 5015 } 5016 5017 this.dispose = function () { 5018 stageDom.removeEventListener("mousemove", mouseMove, false); 5019 stageDom.removeEventListener("touchmove", mouseMove, false); 5020 5021 stageDom.removeEventListener("mousedown", mouseDown, false); 5022 stageDom.removeEventListener("click", mouseClick, false); 5023 stageDom.removeEventListener("mouseup", mouseUp, false); 5024 stageDom.removeEventListener("touchend", mouseUp, false); 5025 stageDom.removeEventListener("touchstart", mouseDown, false); 5026 5027 if (_this.options.scrollWheel == true) { 5028 stageDom.removeEventListener('mousewheel', onMouseWheel, false); 5029 stageDom.removeEventListener('DOMMouseScroll', onMouseWheel, false); // firefox 5030 } 5031 _this.updatePageCallback = null; 5032 _this.flipCallback = null; 5033 _this.animateF = null; 5034 _this.stage.remove(); 5035 5036 }; 5037 } 5038 5039 BookCSS.prototype = { 5040 add: function (object) { 5041 if (object instanceof PageCSS) 5042 this.container.append($(object.element)); 5043 else 5044 this.container.append($(object)); 5045 }, 5046 pan: function (point) { 5047 var origin = this.startPoint; 5048 var scale = this.contentProvider.zoomScale; 5049 5050 var left = (this.left + (point.raw.x - origin.raw.x)), 5051 top = (this.top + (point.raw.y - origin.raw.y)); 5052 5053 //round removes blur due to decimal value in transform. 5054 this.left = Math.round(limitAt(left, -this.shiftWidth, this.shiftWidth)); 5055 this.top = Math.round(limitAt(top, -this.shiftHeight, this.shiftHeight)); 5056 5057 if (scale == 1) { 5058 this.left = 0; 5059 this.top = 0; 5060 } 5061 5062 this.startPoint = point; 5063 5064 //console.log(point, origin); 5065 this.stage.css({ 5066 transform: "translate3d(" + this.left + "px," + this.top + "px,0)" 5067 }); 5068 5069 //var a = book.wrapper.height(); 5070 }, 5071 getPageByNumber: function (pageNumber) { 5072 var relativePageNumber = isBookletMode(this) ? (isRTLMode(this) ? pageNumber + 1 : pageNumber) 5073 : Math.floor((pageNumber - 1) / 2); 5074 var page; 5075 for (var count = 0; count < this.pages.length; count++) { 5076 if (relativePageNumber == parseInt(this.pages[count].name, 10)) 5077 page = this.pages[count]; 5078 } 5079 return page; 5080 }, 5081 getPageSide: function (pageNumber) { 5082 5083 var isRTL = this.direction == DFLIP.DIRECTION.RTL; 5084 5085 var page = this.getPageByNumber(pageNumber); 5086 if (page == null) return; 5087 if (isBookletMode(this)) return isRTL ? page.front : page.back; 5088 if (pageNumber % 2 == 0) 5089 return isRTL ? page.back : page.front; 5090 else 5091 return isRTL ? page.front : page.back; 5092 }, 5093 getContentLayer: function (pageNumber) { 5094 var pageSide = this.getPageSide(pageNumber); 5095 return pageSide == null ? null : pageSide.contentLayer; 5096 } 5097 }; 5098 5099 BookCSS.prototype.init = function (parameters) { 5100 var _this = this; 5101 _this.stage = $(html.div, { 5102 class: "df-book-stage" 5103 }); 5104 _this.wrapper = $(html.div, { 5105 class: "df-book-wrapper" 5106 }); 5107 _this.shadow = $(html.div, { 5108 class: "df-book-shadow" 5109 }); 5110 //_this.resize(); 5111 _this.container.append(_this.stage); 5112 _this.stage.append(_this.wrapper); 5113 _this.wrapper.append(_this.shadow); 5114 /* _this.nextButton = $(html.div, { 5115 class: "df-book-next-button df-book-side-buttons " + parameters.icons['altnext'] 5116 }).appendTo(_this.wrapper).on("click", function () { 5117 _this.next(); 5118 }); 5119 _this.prevButton = $(html.div, { 5120 class: "df-book-prev-button df-book-side-buttons " + parameters.icons['altprev'] 5121 }).appendTo(_this.wrapper).on("click", function () { 5122 _this.prev(); 5123 });*/ 5124 5125 5126 //_this.container.height(parameters.height); 5127 5128 _this.createStack(parameters); 5129 }; 5130 5131 BookCSS.prototype.createStack = function (parameters) { 5132 5133 var colors = "red,green,blue,yellow,orange,black".split(","); 5134 5135 for (var _stackCount = 0; _stackCount < this.stackCount; _stackCount++) { 5136 parameters.angles = [, this.stackCount - _stackCount];//[1] = (this.stackCount - _stackCount); 5137 parameters.stiffness = (this.stackCount - _stackCount) / 100; 5138 5139 var clone = new PageCSS(parameters); 5140 clone.angles[1] = 180; 5141 clone.index = _stackCount; 5142 clone.parent = this; 5143 clone.textureReady = false;
5144 clone.textureRequested = false; 5145 this.wrapper.append(clone.element); 5146 clone.isFlipping = false; 5147 this.pages.push(clone); 5148 clone.color = colors[_stackCount]; 5149 //for (var _count = 0; _count < 4; _count++) { 5150 // clone.element.css({ 5151 // backgroundColor : colors[_stackCount] 5152 // }); 5153 //} 5154 } 5155 5156 this.children = this.pages; 5157 }; 5158 5159 BookCSS.prototype.isPageHard = function (pageNumber) { 5160 5161 return utils.isHardPage(this.hardConfig, pageNumber, this.pageCount, isBookletMode(this)); 5162 5163 }; 5164 5165 BookCSS.prototype.setDuration = function (_duration) { 5166 this.duration = _duration; 5167 }; 5168 5169 BookCSS.prototype.moveBy = function (step) { 5170 var nextPage = this._activePage + step; 5171 5172 nextPage = limitAt(nextPage, this.startPage, this.endPage); 5173 if (this.firstFlipped != true) { 5174 this.previewObject.analytics({ 5175 eventAction: "First Page Flip", 5176 options: this.previewObject.options 5177 }); 5178 this.firstFlipped = true; 5179 } 5180 this.gotoPage(nextPage); 5181 }; 5182 5183 BookCSS.prototype.next = function (step) { 5184 if (step == null) 5185 step = 5186 (this.direction == DFLIP.DIRECTION.RTL) 5187 ? -this.pageMode : this.pageMode; 5188 5189 this.moveBy(step); 5190 }; 5191 5192 BookCSS.prototype.prev = function (step) { 5193 if (step == null) 5194 step = 5195 (this.direction == DFLIP.DIRECTION.RTL) 5196 ? this.pageMode : -this.pageMode; 5197 5198 this.moveBy(step); 5199 }; 5200 BookCSS.prototype.eventToPoint = function (event) { 5201 5202 event = fixMouseEvent(event); 5203 5204 var wrapper = this.wrapper, 5205 pages = this.pages, 5206 pageWidth = this.pageWidth, 5207 fullWidth = this.fullWidth, 5208 height = this.height, 5209 win = $(window), 5210 point = {x: event.clientX, y: event.clientY}; 5211 5212 var left = point.x - wrapper[0].getBoundingClientRect().left;// + win['scrollLeft'](); 5213 5214 var top = point.y - wrapper[0].getBoundingClientRect().top;// + win['scrollTop'](); 5215 5216 point.x = point.x - this.container[0].getBoundingClientRect().left; 5217 point.y = point.y - this.container[0].getBoundingClientRect().top; 5218 5219 var distance = (this.drag == drag.none) 5220 ? left < pageWidth ? left : fullWidth - left 5221 : this.drag == drag.left ? left : fullWidth - left; 5222 5223 var page = //((left >= 0 && left <= fullWidth)? 5224 (left < pageWidth ? pages[this.stackCount / 2 - 1] : pages[this.stackCount / 2]); 5225 5226 var pageDrag = left < this.foldSense ? drag.left 5227 : (left > fullWidth - this.foldSense) ? drag.right : drag.none; 5228 5229 //determine the corner 5230 var x = left, 5231 y = top, 5232 h = height, 5233 w = fullWidth, 5234 delta = this.foldSense, 5235 corners = DFLIP.CORNERS, 5236 corner; 5237 5238 if (x >= 0 && x < delta) { 5239 if (y >= 0 && y <= delta) 5240 corner = corners.TL; 5241 else if (y >= h - delta && y <= h) 5242 corner = corners.BL; 5243 else if (y > delta && y < h - delta) 5244 corner = corners.L; 5245 else 5246 corner = corners.NONE; 5247 } 5248 else if (x >= w - delta && x <= w) { 5249 if (y >= 0 && y <= delta) 5250 corner = corners.TR; 5251 else if (y >= h - delta && y <= h) 5252 corner = corners.BR; 5253 else if (y > delta && y < h - delta) 5254 corner = corners.R; 5255 else 5256 corner = corners.NONE; 5257 } 5258 else 5259 corner = corners.NONE; 5260 5261 return { 5262 isInsidePage: x >= 0 && x <= w && y >= 0 && y <= h, 5263 isInside: corner !== corners.NONE && corner !== corners.L && corner !== corners.R, 5264 x: left, 5265 y: top, 5266 fullWidth: fullWidth, 5267 rawDistance: fullWidth - left, 5268 distance: distance, 5269 page: page, 5270 drag: pageDrag, 5271 foldSense: this.foldSense, 5272 event: event, 5273 raw: point, 5274 corner: corner 5275 }; 5276 }; 5277 5278 BookCSS.prototype.gotoPage = function (pageNumber) { 5279 pageNumber = parseInt(pageNumber, 10); 5280 this._activePage = pageNumber; 5281 5282 if (this.autoPlay == true) { 5283 this.previewObject.setAutoPlay(this.autoPlay); 5284 } 5285 this.updatePage(pageNumber); 5286 if (this && this.thumblist && this.thumblist.review) 5287 this.thumblist.review(); 5288 }; 5289 5290 BookCSS.prototype.refresh = function () { 5291 this.updatePage(this._activePage); 5292 if (this.flipCallback != null) this.flipCallback(); 5293 }; 5294 5295 BookCSS.prototype.updatePage = function (pageNumber) { 5296 5297 var isRTL = (this.direction == DFLIP.DIRECTION.RTL), 5298 isBooklet = isBookletMode(this), 5299 newBaseNumber = getBasePage(pageNumber); 5300 5301 var pageDivisor = isBooklet ? 1 : 2; 5302 5303 pageNumber = Math.floor((pageNumber / pageDivisor)); 5304 5305 if (isRTL) pageNumber = this.pageCount / pageDivisor - pageNumber; 5306 5307 var oldBaseNumber = this.oldBaseNumber || 0; 5308 var pageCount = this.pageCount / pageDivisor; 5309 var stackCount = this.stackCount; 5310 5311 var midPoint = Math.floor(stackCount / 2); 5312 5313 if (oldBaseNumber > pageNumber) { 5314 this.children[stackCount - 1].skipFlip = true; 5315 this.children.unshift(this.children.pop()); 5316 } 5317 else if (oldBaseNumber < pageNumber) { 5318 this.children[0].skipFlip = true; 5319 this.children.push(this.children.shift()); 5320 } 5321 5322 for (var _pageCount = 0; _pageCount < stackCount; _pageCount++) { 5323 var page = this.children[_pageCount]; 5324 5325 if (oldBaseNumber !== pageNumber) { 5326 if (page.currentTween != null) { 5327 page.clearTween(true); 5328 //page.currentTween.stop(); 5329 //page.completeTween(true); 5330 //page.resetCSS(); 5331 //page.currentTween = null; 5332 } 5333 } 5334 5335 var oldSide = page.side; 5336 var newSide; 5337 var relativePageNumber = pageNumber - midPoint + _pageCount; 5338 if (isRTL) relativePageNumber = isBooklet ? this.pageCount - relativePageNumber 5339 : Math.floor(this.pageCount / 2) - relativePageNumber - 1; 5340 5341 var oldName = page.name; 5342 5343 page.isHard = this.isPageHard(relativePageNumber); 5344 if (page.isHard) { 5345 page.element.addClass("df-hard-page"); 5346 } 5347 else { 5348 page.element.removeClass("df-hard-page"); 5349 page.front.css({display: "block"}); 5350 page.back.css({display: "block"}); 5351 } 5352 if (relativePageNumber == 0 || relativePageNumber == pageCount) { 5353 page.element.addClass("df-cover-page"); 5354 } 5355 else { 5356 page.element.removeClass("df-cover-page"); 5357 } 5358 5359 var oldPageNumber = $(page.element).attr("pageNumber"); 5360 if (oldPageNumber != relativePageNumber) { 5361 page.front.contentLayer.empty(); 5362 page.back.contentLayer.empty(); 5363 } 5364 $(page.element).attr("pageNumber", relativePageNumber); 5365 5366 5367 //Sizing 5368 page.isEdge = false; //true;
5369 if (_pageCount == 0) { 5370 5371 } 5372 else if (_pageCount == stackCount - 1) { 5373 5374 } 5375 else { 5376 5377 page.isEdge = false; 5378 } 5379 5380 5381 if (_pageCount < midPoint) { 5382 newSide = drag.left; 5383 } 5384 else { 5385 newSide = drag.right; 5386 } 5387 5388 5389 if (page.isFlipping == false) { 5390 5391 if (newSide !== oldSide && page.skipFlip == false) { 5392 5393 this.animatePage(page); 5394 5395 if (this.preFlipCallback != null) 5396 this.preFlipCallback(); 5397 5398 } 5399 else { 5400 page.skipFlip = false; 5401 page.element.removeClass("df-flipping df-quick-turn df-folding df-left-side df-right-side"); 5402 page.element.addClass((_pageCount < midPoint) ? "df-left-side" : "df-right-side"); 5403 page.side = newSide; 5404 } 5405 } 5406 5407 page.visible = isBooklet 5408 ? (isRTL 5409 5410 ? (_pageCount < midPoint || page.isFlipping) 5411 : (_pageCount >= midPoint || page.isFlipping)) 5412 5413 : ((relativePageNumber >= 0 && relativePageNumber < pageCount) || (isBooklet && relativePageNumber == pageCount)); 5414 5415 if (this.requestPage != null && page.visible == true) { 5416 5417 page.name = relativePageNumber.toString(); 5418 if (page.name != oldName) { 5419 5420 page.backTextureLoaded = false; 5421 page.frontTextureLoaded = false; 5422 page.backPageStamp = "-1"; 5423 page.frontPageStamp = "-1"; 5424 page.thumbLoaded = false; 5425 page.front.contentLayer.html(""); 5426 page.back.contentLayer.html(""); 5427 //if (oldName !== '-2') { 5428 //canvas clearing 5429 page.frontImage(defaults.textureLoadFallback); 5430 page.backImage(defaults.textureLoadFallback); 5431 //} 5432 this.requestPage(); 5433 5434 } 5435 } 5436 5437 page.oldDepth = page.depth; 5438 page.updateCSS({ 5439 display: page.visible == true ? "block" : "none",
5440 zIndex: 6 + (_pageCount < midPoint ? (_pageCount - midPoint) : (midPoint - _pageCount)), 5441 transform: '' 5442 }); 5443 5444 if (page.pendingPoint == null && page.isFlipping == false) { 5445 page.resetCSS(); 5446 } 5447 } 5448 5449 if (TWEEN.getAll().length == 0) { 5450 clearInterval(this.animate); 5451 } 5452 $(".quick-hint").html(pageNumber); 5453 5454 this.oldBaseNumber = pageNumber; 5455 5456 if (this.updatePageCallback) 5457 this.updatePageCallback(); 5458 5459 }; 5460 5461 BookCSS.prototype.animatePage = function (page) { 5462 page.element.addClass("df-flipping"); 5463 page.isFlipping = true; 5464 5465 if (this.animate != null) { 5466 clearInterval(this.animate); 5467 } 5468 5469 this.animate = setInterval(this.animateF, 30); 5470 5471 page.tween(page.pendingPoint); 5472 }; 5473 5474 return BookCSS; 5475 }) 5476 ({}); 5477 5478 var FlipBook = (function (_super) { 5479 5480 __extends(FlipBook, _super); 5481 5482 function FlipBook(container, source, parameters) { 5483 _super.call(this, parameters); 5484 var _this = this; 5485 5486 _this.type = "FlipBook"; 5487 _this.container = container; 5488 _this.options = parameters; 5489 _this.options.source = source; 5490 _this.contentSource = source; 5491 5492 if (parameters.height != null && parameters.height.toString().indexOf('%') < 0) { 5493 _this.container.height(Math.min(parameters.height, $(window).height())); 5494 } 5495 else { 5496 _this.container.height(parameters.height); 5497 } 5498 5499 if (_this.options.isLightBox) { 5500 window.dfLightBox.closeButton.addClass(_this.options.icons['close']); 5501 } 5502 if (_this.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL) { 5503 //currently booklet version cannot handle double sized image pages 5504 if (Array === _this.contentSource.constructor || Array.isArray(_this.contentSource) || _this.contentSource instanceof Array) { 5505 _this.options.singlePageMode = DFLIP.SINGLE_PAGE_MODE.ZOOM; 5506 } 5507 _this.container.addClass("df-double-internal"); 5508 } 5509 if (!_this.options.isLightBox && _this.container.attr("id") != null) { 5510 _this.options.id = _this.container.attr("id"); 5511 } 5512 5513 if (_this.options.parsed !== true && _this.options.links != null) { 5514 DFLIP.parseLinks(_this.options.links); 5515 } 5516 var webgl = _this.webgl = parameters.webgl == true && hasWebgl == true; 5517 5518 container.addClass("df-container df-loading df-init df-floating" + " df-controls-" + _this.options.controlsPosition); 5519 5520 if (_this.options.transparent == true) { 5521 container.addClass("df-transparent"); 5522 } 5523 if (_this.options.direction == DFLIP.DIRECTION.RTL) { 5524 container.addClass("df-rtl"); 5525 } 5526 _this.container.info = $(html.div, { 5527 class: "loading-info" 5528 }).appendTo(_this.container).html("Loading..."); 5529 5530 if (userAgent.indexOf('MSIE') !== -1 5531 || navigator.appVersion.indexOf('Trident/') > 0 || (isSafari && !isIOS)) { 5532 _this.options.webgl = false; //IE 11 5533 } 5534 5535 if (!!userAgent.match(/msie\s[5-9]/i)) { 5536 _this.container.info.html("Your browser (Internet Explorer) is out of date to run DFlip Flipbook Plugin. <br><a href='http://browsehappy.com/'>Upgrade to a new one</a>").addClass("df-old-browser"); 5537 container.removeClass("df-loading"); 5538 return _this; 5539 } 5540 5541 var backgroundImage = parameters.backgroundImage == null || parameters.backgroundImage == '' ? '' 5542 : "url('" + parameters.backgroundImage + "')"; 5543 5544 _this.container.css({ 5545 position: "relative", 5546 overflow: "hidden", 5547 backgroundColor: parameters.backgroundColor, 5548 backgroundImage: backgroundImage 5549 }); 5550 5551 if (_this.options.isLightBox == true) { 5552 _this.analytics({ 5553 eventAction: "Open Book", 5554 options: _this.options 5555 }); 5556 } 5557 _this.init(webgl, source); 5558 5559 if (_this.options.onCreate != null) 5560 _this.options.onCreate(_this); 5561 5562 return _this; 5563 5564 } 5565 5566 FlipBook.prototype.init = function (webgl) { 5567 var _this = this; 5568 var book = _this.target; 5569 5570 var options = _this.options; 5571 5572 if (webgl == true) { 5573 5574 var updateMockupJs = function (callback) { 5575 5576 var process3d = function () { 5577 MOCKUP.defaults.anisotropy = 0; 5578 MOCKUP.defaults.groundTexture = "blank"; 5579 THREE.skipPowerOfTwo = true; 5580 5581 RegisterMockupObjects(); 5582 5583 if (callback != null) callback(); 5584 }; 5585 5586 if (window.MOCKUP == null) {
5587 _this.updateInfo("Loading WEBGL 3D ..."); 5588 5589 if (typeof define === 'function' && define.amd && window.requirejs) { 5590 requirejs.config({ 5591 "paths": { 5592 "three": defaults.threejsSrc.replace(".js", "") 5593 }, 5594 shim: { 5595 'three': { 5596 exports: 'THREE' 5597 } 5598 } 5599 }); 5600 require(['three'], function (THREE) { 5601 window.THREE = THREE; 5602 getScript(defaults.mockupjsSrc + "?ver=" + DFLIP.version, function () { 5603 process3d(); 5604 }); 5605 return THREE; 5606 }); 5607 } 5608 else if (typeof define === 'function' && define.amd) { 5609 require(["three", defaults.threejsSrc.replace(".js", "")], function (ready, fx) { 5610 ready(function () { 5611 5612 }); 5613 }); 5614 } 5615 else { 5616 getScript(defaults.threejsSrc + "?ver=" + DFLIP.version, function () { 5617 //_this.updateInfo("Loading 3D Pages ..."); this was retainnng _this and not releasing memory 5618 getScript(defaults.mockupjsSrc + "?ver=" + DFLIP.version, function () { 5619 process3d(); 5620 }); 5621 }); 5622 } 5623 } 5624 else { 5625 process3d(); 5626 } 5627 } 5628 ; 5629 5630 updateMockupJs(function () { 5631 5632 //Todo: ability to use anisotropy 5633 5634 _this.container.css({ 5635 minHeight: 300, 5636 minWidth: 300 5637 }); 5638 5639 _this.stage = new PreviewStage(extendOptions(_this.options, {container: _this.container})); 5640 _this.stage.previewObject = _this; 5641 5642 _this.contentProvider = new ContentProvider(_this.contentSource, function (contentProvider) { 5643 // _this.pageCount = contentProvider.pageCount = utils.limitAt(contentProvider.pageCount, 1, 2 * 5); 5644 var options = { 5645 pageCount: (utils.hasCompatibility() === true 5646 ? utils.limitAt(contentProvider.pageCount, 1, 2 * 15) 5647 : contentProvider.pageCount), 5648 stackCount: 6, 5649 segments: 20, 5650 width: contentProvider.bookSize.width, 5651 height: contentProvider.bookSize.height 5652 }; 5653 5654 // _this.checkOpenPage(); 5655 _this.target = book = _this.stage.target = new MOCKUP.Book(extendOptions(_this.options, options), _this.stage); 5656 _this.extendtarget(); 5657 createUI(_this.container, _this); 5658 5659 //bookStage.setTarget(_this.target); 5660 book.ui = _this.ui; 5661 book.container = _this.container; 5662 contentProvider.webgl = webgl; 5663 contentProvider.setTarget(_this.target); 5664 5665 book.getContentLayer = function (pageNumber) { 5666 5667 var isRTL = book.direction == DFLIP.DIRECTION.RTL, 5668 left = _this.stage.cssScene.divLeft.element, 5669 right = _this.stage.cssScene.divRight.element; 5670 5671 var baseActive = getBasePage(book._activePage); 5672 5673 //if(isRTL){ 5674 // if(pageNumber == 0 || pageNumber == 1) return right; 5675 // if(pageNumber == book.pageCount) return left; 5676 //} 5677 5678 if (isBookletMode(book)) return isRTL ? left : right; 5679 5680 if (pageNumber % 2 == 0) 5681 return isRTL ? right : left; 5682 else 5683 return isRTL ? left : right; 5684 //else 5685 // return null; 5686 }; 5687 book.stage = _this.stage; 5688 5689 book.flipCallback = function () { 5690 if (_this.contentProvider) { 5691 _this.contentProvider.review("flipCallback"); 5692 5693 var baseActive = getBasePage(book._activePage); 5694 5695 var width, height; 5696 var pageLeft = book.getPageByNumber(baseActive), 5697 pageRight = book.getPageByNumber(baseActive + 1); 5698 //if (page3d != null) { 5699 // var isLeft = (pageNumber % 2 == 0); 5700 var divLeft = book.parent.cssScene.divLeft, 5701 divRight = book.parent.cssScene.divRight; 5702 5703 var isSingle = book.pageMode == DFLIP.PAGE_MODE.SINGLE; 5704 var isRTL = book.direction == DFLIP.DIRECTION.RTL; 5705
5706 if (pageLeft != null && divLeft != null) { 5707 width = Math.abs(pageLeft.geometry.boundingBox.max.x - pageLeft.geometry.boundingBox.min.x); 5708 height = Math.abs(pageLeft.geometry.boundingBox.max.z - pageLeft.geometry.boundingBox.min.z); 5709 5710 divLeft.rotation.y = -Math.atan2(height, width) * 0.9; 5711 divLeft.position.z = height * 0.8; 5712 divLeft.position.x = height / 2.5; 5713 $(divLeft.element).css({ 5714 width: width, 5715 left: -width / 2//baseActive == 0 && isRTL == true? width 5716 //: baseActive == book.pageCount && isRTL == true ? 0 : -width / 2 5717 }); 5718 5719 } 5720 5721 if (pageRight != null && divRight != null) { 5722 width = Math.abs(pageRight.geometry.boundingBox.max.x - pageRight.geometry.boundingBox.min.x); 5723 height = Math.abs(pageRight.geometry.boundingBox.max.z - pageRight.geometry.boundingBox.min.z); 5724 5725 divRight.rotation.y = Math.atan2(height, width) * 0.9; 5726 divRight.position.z = height * 0.8; 5727 divRight.position.x = -height / 2.5; 5728 $(divRight.element).css({ 5729 width: width, 5730 left: width / 2// == 0 && isRTL == true ? 0 5731 //: baseActive == book.pageCount && isRTL == true ? -width : width / 2 5732 }); 5733 5734 } 5735 5736 if (_this.options.onFlip != null) 5737 _this.options.onFlip(_this); 5738 } 5739 }; 5740 5741 book.resize = function () { 5742 _this.resize(); 5743 }(); 5744 5745 book.updatePageCallback = function () { 5746 _this.ui.update(); 5747 _this.checkCenter(); 5748 _this.stage.renderRequestPending = true; 5749 }; 5750 5751 var divLeft = $(_this.stage.cssScene.divLeft.element); 5752 var divRight = $(_this.stage.cssScene.divRight.element); 5753 5754 book.preFlipCallback = function () { 5755 divLeft.empty(); 5756 divRight.empty(); 5757 if (_this.options.beforeFlip != null) 5758 _this.options.beforeFlip(_this); 5759 5760 _this.playSound(); 5761 }; 5762 5763 $(window).trigger("resize"); 5764 5765 divLeft.css({ 5766 width: contentProvider.bookSize.width, 5767 height: contentProvider.bookSize.height, 5768 left: -contentProvider.bookSize.width / 2 5769 }); 5770 5771 divRight.css({ 5772 width: contentProvider.bookSize.width, 5773 height: contentProvider.bookSize.height, 5774 left: contentProvider.bookSize.width / 2 5775 }); 5776 5777 book.ease = TWEEN.Easing.Cubic.InOut; 5778 //book.ease = TWEEN.Easing.Quadratic.InOut; 5779 book.contentProvider = contentProvider; 5780 book.duration = _this.options.duration; 5781 book.gotoPage(book._activePage); 5782 book.flipCallback(); 5783 5784 if (_this.options.isLightBox == true) { 5785 _this.analytics({ 5786 eventAction: "Book Ready", 5787 options: _this.options 5788 }); 5789 } 5790 5791 if (_this.options.onReady != null) 5792 _this.options.onReady(_this); 5793 5794 }, options, _this); 5795 }); 5796 } 5797 else { 5798 5799 _this.contentProvider = new ContentProvider(_this.contentSource, function (contentProvider) { 5800 // _this.pageCount = contentProvider.pageCount = utils.limitAt(contentProvider.pageCount, 1, 2 * 5); 5801 var options = { 5802 pageCount: (utils.hasCompatibility() === true 5803 ? utils.limitAt(contentProvider.pageCount, 1, 2 * 15) 5804 : contentProvider.pageCount), 5805 contentSourceType: contentProvider.contentSourceType 5806 }; 5807 5808 // _this.checkOpenPage(); 5809 _this.target = book = new BookCSS(extendOptions(_this.options, options), _this.container); 5810 _this.target.previewObject = _this; 5811 _this.extendtarget(); 5812 createUI(_this.container, _this); 5813 contentProvider.webgl = webgl; 5814 contentProvider.setTarget(_this.target);
5815 contentProvider.waitPeriod = 2; 5816 book.ease = TWEEN.Easing.Quadratic.InOut; 5817 book.duration = _this.options.duration; 5818 5819 /* _this.ui.prev.hide(); 5820 _this.ui.next.hide(); 5821 5822 _this.ui.prev = book.prevButton; 5823 _this.ui.next = book.nextButton;*/ 5824 5825 book.container = _this.container; 5826 book.updatePageCallback = function () { 5827 _this.ui.update(); 5828 _this.checkCenter(); 5829 }; 5830 5831 book.resize = function () { 5832 _this.resize(); 5833 }(); 5834 5835 $(window).trigger("resize"); 5836 5837 book.flipCallback = function () { 5838 if (_this.contentProvider) { 5839 _this.contentProvider.review("flipCallback"); 5840 5841 if (_this.options.onFlip != null) 5842 _this.options.onFlip(_this); 5843 } 5844 }; 5845 5846 book.preFlipCallback = function () { 5847 if (_this.options.beforeFlip != null) 5848 _this.options.beforeFlip(_this); 5849 5850 _this.playSound(); 5851 }; 5852 book.gotoPage(book._activePage); 5853 book.flipCallback(); 5854 5855 if (_this.options.onReady != null) 5856 _this.options.onReady(_this); 5857 _this.analytics({ 5858 eventAction: "Book Ready", 5859 options: _this.options 5860 }); 5861 }, options, _this); 5862 5863 } 5864 5865 5866 } 5867 ; 5868 5869 FlipBook.prototype.extendtarget = function () { 5870 var _this = this; 5871 _this.target.previewObject = _this; 5872 _this.target.reset = function () { 5873 for (var pageCount = 0; pageCount < _this.target.children.length; pageCount++) { 5874 var page = _this.target.children[pageCount]; 5875 page.skipFlip = true; 5876 page.name = '-2'; 5877 } 5878 _this.contentProvider.annotedPage = '-2'; 5879 _this.target.refresh(); 5880 5881 } 5882 }; 5883 5884 FlipBook.prototype.getURLHash = function () { 5885 if (this.options.id != null) { 5886 var hash = "dflip-" + (this.options.slug != null ? this.options.slug : this.options.id) + "/"; 5887 if (this.target != null && this.target._activePage != null) { 5888 hash += this.target._activePage + "/"; 5889 } 5890 window.location.hash = hash; 5891 } 5892 return window.location.href; 5893 }; 5894 5895 /* 5896 Depreciated handled through getOptions 5897 FlipBook.prototype.checkOpenPage = function () 5898 { 5899 //options value is overridden by attribute 5900 if (this.options.id != null) { 5901 var book = $("#" + this.options.id); 5902 if (book.length > 0 && book.data("page") != null) { 5903 var pageNumber = parseInt(book.data("page"), 10); 5904 if (!isNaN(pageNumber)) 5905 this.options.openPage = pageNumber; 5906 } 5907 } 5908 };*/ 5909 5910 FlipBook.prototype.end = function () { 5911 5912 this.target.gotoPage(this.target.endPage); 5913 5914 }; 5915 5916 FlipBook.prototype.gotoPage = function (pageNumber) { 5917 5918 this.target.gotoPage(pageNumber); 5919 if (this.ui != null) this.ui.update(); 5920 }; 5921 5922 FlipBook.prototype.prev = function () { 5923 5924 this.target.prev(); 5925 5926 }; 5927 5928 FlipBook.prototype.next = function () { 5929 5930 this.target.next(); 5931 5932 }; 5933 5934 FlipBook.prototype.updateInfo = function (info) { 5935 if (this.container && this.container.info && this.container.info.html) 5936 this.container.info.html(info); 5937 } 5938 5939 FlipBook.prototype.analytics = function (eventData) { 5940 if (this.options.enableAnalytics == true) { 5941 try { 5942 var anaytics = window.ga || window.__gaTracker; 5943 var options = eventData.options, 5944 eventLabel = undefined; 5945 if (options) { 5946 eventLabel = options.bookTitle || options.slug || options.id; 5947 } 5948 anaytics("send", { 5949 hitType: 'event', 5950 eventCategory: 'Flipbook', 5951 eventAction: eventData.eventAction, 5952 eventLabel: eventLabel 5953 }); 5954 } catch (e) { 5955 //silent suppress 5956 } 5957 } 5958 } 5959 return FlipBook; 5960 5961 })(PreviewObject); 5962 5963 $.fn.extend({ 5964 5965 shelf: function () { 5966 5967 }, 5968 flipBook: function (source, options) { 5969 return new FlipBook($(this), source, extendDFlipOptions(options)); 5970 } 5971 }); 5972 5973}) 5974(DFLIP, jQuery); 5975 5976 5977//Polyfills 5978 5979/** 5980 * Blob.js Polyfill 5981 * A Blob implementation. 5982 * 2014-07-24 5983 * 5984 * By Eli Grey, http://eligrey.com 5985 * By Devin Samarin, https://github.com/dsamarin 5986 * License: X11/MIT 5987 */ 5988(function (view) { 5989 "use strict"; 5990 5991 view.URL = view.URL || view.webkitURL; 5992 5993 if (view.Blob && view.URL) { 5994 try { 5995 new Blob; 5996 return; 5997 } catch (e) { 5998 } 5999 } 6000 6001 // Internally we use a BlobBuilder implementation to base Blob off of
vendor: 6,683 bytes, lines 6002-6193
6002 // in order to support older browsers that only have BlobBuilder 6003 var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) { 6004 var 6005 get_class = function (object) { 6006 return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; 6007 }, FakeBlobBuilder = function BlobBuilder() { 6008 this.data = []; 6009 }, FakeBlob = function Blob(data, type, encoding) { 6010 this.data = data; 6011 this.size = data.length; 6012 this.type = type; 6013 this.encoding = encoding; 6014 }, FBB_proto = FakeBlobBuilder.prototype, FB_proto = FakeBlob.prototype, FileReaderSync = view.FileReaderSync, 6015 FileException = function (type) { 6016 this.code = this[this.name = type]; 6017 }, file_ex_codes = ( 6018 "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " 6019 + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" 6020 ).split(" "), file_ex_code = file_ex_codes.length, real_URL = view.URL || view.webkitURL || view, 6021 real_create_object_URL = real_URL.createObjectURL, real_revoke_object_URL = real_URL.revokeObjectURL, 6022 URL = real_URL, btoa = view.btoa, atob = view.atob, ArrayBuffer = view.ArrayBuffer, 6023 Uint8Array = view.Uint8Array, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/ 6024 ; 6025 FakeBlob.fake = FB_proto.fake = true; 6026 while (file_ex_code--) { 6027 FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; 6028 } 6029 // Polyfill URL 6030 if (!real_URL.createObjectURL) { 6031 URL = view.URL = function (uri) { 6032 var 6033 uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a"), uri_origin 6034 ; 6035 uri_info.href = uri; 6036 if (!("origin" in uri_info)) { 6037 if (uri_info.protocol.toLowerCase() === "data:") { 6038 uri_info.origin = null; 6039 } 6040 else { 6041 uri_origin = uri.match(origin); 6042 uri_info.origin = uri_origin && uri_origin[1]; 6043 } 6044 } 6045 return uri_info; 6046 }; 6047 } 6048 URL.createObjectURL = function (blob) { 6049 var 6050 type = blob.type, data_URI_header 6051 ; 6052 if (type === null) { 6053 type = "application/octet-stream"; 6054 } 6055 if (blob instanceof FakeBlob) { 6056 data_URI_header = "data:" + type; 6057 if (blob.encoding === "base64") { 6058 return data_URI_header + ";base64," + blob.data; 6059 } 6060 else if (blob.encoding === "URI") { 6061 return data_URI_header + "," + decodeURIComponent(blob.data); 6062 } 6063 if (btoa) { 6064 return data_URI_header + ";base64," + btoa(blob.data); 6065 } 6066 else { 6067 return data_URI_header + "," + encodeURIComponent(blob.data); 6068 } 6069 } 6070 else if (real_create_object_URL) { 6071 return real_create_object_URL.call(real_URL, blob); 6072 } 6073 }; 6074 URL.revokeObjectURL = function (object_URL) { 6075 if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { 6076 real_revoke_object_URL.call(real_URL, object_URL); 6077 } 6078 }; 6079 FBB_proto.append = function (data/*, endings*/) { 6080 var bb = this.data; 6081 // decode data to a binary string 6082 if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { 6083 var 6084 str = "", buf = new Uint8Array(data), i = 0, buf_len = buf.length 6085 ; 6086 for (; i < buf_len; i++) { 6087 str += String.fromCharCode(buf[i]); 6088 } 6089 bb.push(str); 6090 } 6091 else if (get_class(data) === "Blob" || get_class(data) === "File") { 6092 if (FileReaderSync) { 6093 var fr = new FileReaderSync; 6094 bb.push(fr.readAsBinaryString(data)); 6095 } 6096 else { 6097 // async FileReader won't work as BlobBuilder is sync 6098 throw new FileException("NOT_READABLE_ERR"); 6099 } 6100 } 6101 else if (data instanceof FakeBlob) { 6102 if (data.encoding === "base64" && atob) { 6103 bb.push(atob(data.data)); 6104 } 6105 else if (data.encoding === "URI") { 6106 bb.push(decodeURIComponent(data.data)); 6107 } 6108 else if (data.encoding === "raw") { 6109 bb.push(data.data); 6110 } 6111 } 6112 else { 6113 if (typeof data !== "string") { 6114 data += ""; // convert unsupported types to strings 6115 } 6116 // decode UTF-16 to binary string 6117 bb.push(unescape(encodeURIComponent(data))); 6118 } 6119 }; 6120 FBB_proto.getBlob = function (type) { 6121 if (!arguments.length) { 6122 type = null; 6123 } 6124 return new FakeBlob(this.data.join(""), type, "raw"); 6125 }; 6126 FBB_proto.toString = function () { 6127 return "[object BlobBuilder]"; 6128 }; 6129 FB_proto.slice = function (start, end, type) { 6130 var args = arguments.length; 6131 if (args < 3) { 6132 type = null; 6133 } 6134 return new FakeBlob( 6135 this.data.slice(start, args > 1 ? end : this.data.length), type, this.encoding 6136 ); 6137 }; 6138 FB_proto.toString = function () { 6139 return "[object Blob]"; 6140 }; 6141 FB_proto.close = function () { 6142 this.size = 0; 6143 delete this.data; 6144 }; 6145 return FakeBlobBuilder; 6146 }(view)); 6147 6148 view.Blob = function (blobParts, options) { 6149 var type = options ? (options.type || "") : ""; 6150 var builder = new BlobBuilder(); 6151 if (blobParts) { 6152 for (var i = 0, len = blobParts.length; i < len; i++) { 6153 if (Uint8Array && blobParts[i] instanceof Uint8Array) { 6154 builder.append(blobParts[i].buffer); 6155 } 6156 else { 6157 builder.append(blobParts[i]); 6158 } 6159 } 6160 } 6161 var blob = builder.getBlob(type); 6162 if (!blob.slice && blob.webkitSlice) { 6163 blob.slice = blob.webkitSlice; 6164 } 6165 return blob; 6166 }; 6167 6168 var getPrototypeOf = Object.getPrototypeOf || function (object) { 6169 return object.__proto__; 6170 }; 6171 view.Blob.prototype = getPrototypeOf(new view.Blob()); 6172}(window)); 6173 6174/** 6175 * canvas-toBlob.js Polyfill 6176 * A canvas.toBlob() implementation. 6177 * 2013-12-27 6178 * 6179 * By Eli Grey, http://eligrey.com and Devin Samarin, https://github.com/eboyjr 6180 * License: X11/MIT 6181 * See https://github.com/eligrey/canvas-toBlob.js/blob/master/LICENSE.md 6182 */ 6183(function (view) { 6184 "use strict"; 6185 var 6186 Uint8Array = view.Uint8Array, HTMLCanvasElement = view.HTMLCanvasElement, 6187 canvas_proto = HTMLCanvasElement && HTMLCanvasElement.prototype, is_base64_regex = /\s*;\s*base64\s*(?:;|$)/i, 6188 to_data_url = "toDataURL", base64_ranks, decode_base64 = function (base64) { 6189 var 6190 len = base64.length, buffer = new Uint8Array(len / 4 * 3 | 0), i = 0, outptr = 0, last = [0, 0], state = 0, 6191 save = 0, rank, code; 6192 while (len--) { 6193 code = base64.charCodeAt(i++);
6194 rank = base64_ranks[code - 43]; 6195 if (rank !== 255 && rank != null) { 6196 last[1] = last[0]; 6197 last[0] = code; 6198 save = (save << 6) | rank; 6199 state++; 6200 if (state === 4) { 6201 buffer[outptr++] = save >>> 16; 6202 if (last[1] !== 61 /* padding character */) { 6203 buffer[outptr++] = save >>> 8; 6204 } 6205 if (last[0] !== 61 /* padding character */) { 6206 buffer[outptr++] = save; 6207 } 6208 state = 0; 6209 } 6210 } 6211 } 6212 // 2/3 chance there's going to be some null bytes at the end, but that 6213 // doesn't really matter with most image formats. 6214 // If it somehow matters for you, truncate the buffer up outptr. 6215 return buffer; 6216 } 6217 ; 6218 if (Uint8Array) { 6219 base64_ranks = new Uint8Array([ 6220 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 6221 ]); 6222 } 6223 if (HTMLCanvasElement && !canvas_proto.toBlob) { 6224 canvas_proto.toBlob = function (callback, type /*, ...args*/) { 6225 if (!type) { 6226 type = "image/png"; 6227 } 6228 if (this.mozGetAsFile) { 6229 callback(this.mozGetAsFile("canvas", type)); 6230 return; 6231 } 6232 if (this.msToBlob && /^\s*image\/png\s*(?:$|;)/i.test(type)) { 6233 callback(this.msToBlob()); 6234 return; 6235 } 6236 6237 var 6238 args = Array.prototype.slice.call(arguments, 1), 6239 dataURI = this[to_data_url].apply(this, args), 6240 header_end = dataURI.indexOf(","), 6241 data = dataURI.substring(header_end + 1), 6242 is_base64 = is_base64_regex.test(dataURI.substring(0, header_end)), 6243 blob 6244 ; 6245 if (Blob.fake) { 6246 // no reason to decode a data: URI that's just going to become a data URI again 6247 blob = new Blob; 6248 if (is_base64) { 6249 blob.encoding = "base64"; 6250 } 6251 else { 6252 blob.encoding = "URI"; 6253 } 6254 blob.data = data; 6255 blob.size = data.length; 6256 } 6257 else if (Uint8Array) { 6258 if (is_base64) { 6259 blob = new Blob([decode_base64(data)], {type: type}); 6260 } 6261 else { 6262 blob = new Blob([decodeURIComponent(data)], {type: type}); 6263 } 6264 } 6265 callback(blob); 6266 }; 6267 6268 if (canvas_proto.toDataURLHD) { 6269 canvas_proto.toBlobHD = function () { 6270 to_data_url = "toDataURLHD"; 6271 var blob = this.toBlob(); 6272 to_data_url = "toDataURL"; 6273 return blob; 6274 } 6275 } 6276 else { 6277 canvas_proto.toBlobHD = canvas_proto.toBlob; 6278 } 6279 } 6280}(window)); 6281 6282/** 6283 * performance.now polyfill 6284 **/ 6285(function PerformanceNowPolyfill() { 6286 6287 if ('performance' in window === false) { 6288 window.performance = {}; 6289 } 6290 6291 // IE 8 6292 Date.now = (Date.now || function () { 6293 return new Date().getTime(); 6294 }); 6295 6296 if ('now' in window.performance === false) { 6297 var offset = window.performance.timing && window.performance.timing.navigationStart 6298 ? window.performance.timing.navigationStart 6299 : Date.now(); 6300 6301 window.performance.now = function () { 6302 return Date.now() - offset; 6303 }; 6304 } 6305 6306})(); 6307 6308/** 6309 * Tween.js - Licensed under the MIT license 6310 * https://github.com/tweenjs/tween.js 6311 */ 6312(function TweenJs() { 6313 var TWEEN = TWEEN || (function () { 6314 6315 var _tweens = []; 6316 6317 return { 6318 6319 getAll: function () { 6320 6321 return _tweens; 6322 6323 }, 6324 6325 removeAll: function () { 6326 6327 _tweens = []; 6328 6329 }, 6330 6331 add: function (tween) { 6332 6333 _tweens.push(tween); 6334 6335 }, 6336 6337 remove: function (tween) { 6338 6339 var i = _tweens.indexOf(tween); 6340 6341 if (i !== -1) { 6342 _tweens.splice(i, 1); 6343 } 6344 6345 }, 6346 6347 update: function (time) { 6348 6349 if (_tweens.length === 0) { 6350 return false; 6351 } 6352 6353 var i = 0; 6354 6355 time = time != null ? time : window.performance.now(); 6356 6357 while (i < _tweens.length) { 6358 6359 if (_tweens[i].update(time)) { 6360 i++; 6361 } 6362 else { 6363 _tweens.splice(i, 1); 6364 } 6365 6366 } 6367 6368 return true; 6369 6370 } 6371 }; 6372 6373 })(); 6374 6375 TWEEN.Tween = function (object) { 6376 6377 var _object = object; 6378 var _valuesStart = {}; 6379 var _valuesEnd = {}; 6380 var _valuesStartRepeat = {}; 6381 var _duration = 1000; 6382 var _repeat = 0; 6383 var _yoyo = false;
6384 var _isPlaying = false; 6385 var _reversed = false; 6386 var _delayTime = 0; 6387 var _startTime = null; 6388 var _easingFunction = TWEEN.Easing.Linear.None; 6389 var _interpolationFunction = TWEEN.Interpolation.Linear; 6390 var _chainedTweens = []; 6391 var _onStartCallback = null; 6392 var _onStartCallbackFired = false; 6393 var _onUpdateCallback = null; 6394 var _onCompleteCallback = null; 6395 var _onStopCallback = null; 6396 6397 // Set all starting values present on the target object 6398 for (var field in object) { 6399 _valuesStart[field] = parseFloat(object[field], 10); 6400 } 6401 6402 this.to = function (properties, duration) { 6403 6404 if (duration != null) { 6405 _duration = duration; 6406 } 6407 6408 _valuesEnd = properties; 6409 6410 return this; 6411 6412 }; 6413 6414 this.start = function (time) { 6415 6416 TWEEN.add(this); 6417 6418 _isPlaying = true; 6419 6420 _onStartCallbackFired = false; 6421 6422 _startTime = time != null ? time : window.performance.now(); 6423 _startTime += _delayTime; 6424 6425 for (var property in _valuesEnd) { 6426 6427 // Check if an Array was provided as property value 6428 if (_valuesEnd[property] instanceof Array) { 6429 6430 if (_valuesEnd[property].length === 0) { 6431 continue; 6432 } 6433 6434 // Create a local copy of the Array with the start value at the front 6435 _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]); 6436 6437 } 6438 6439 // If `to()` specifies a property that doesn't exist in the source object, 6440 // we should not set that property in the object 6441 if (_valuesStart[property] === null) { 6442 continue; 6443 } 6444 6445 _valuesStart[property] = _object[property]; 6446 6447 if ((_valuesStart[property] instanceof Array) === false) { 6448 _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings 6449 } 6450 6451 _valuesStartRepeat[property] = _valuesStart[property] || 0; 6452 6453 } 6454 6455 return this; 6456 6457 }; 6458 6459 this.stop = function () { 6460 6461 if (!_isPlaying) { 6462 return this; 6463 } 6464 6465 TWEEN.remove(this); 6466 _isPlaying = false; 6467 6468 if (_onStopCallback !== null) { 6469 _onStopCallback.call(_object); 6470 } 6471 6472 this.stopChainedTweens(); 6473 return this; 6474 6475 }; 6476 6477 this.stopChainedTweens = function () { 6478 6479 for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { 6480 _chainedTweens[i].stop(); 6481 } 6482 6483 }; 6484 6485 this.complete = function () { 6486 if (!_isPlaying) { 6487 return this; 6488 } 6489 6490 TWEEN.remove(this); 6491 _isPlaying = false; 6492 6493 if (_onCompleteCallback !== null) { 6494 _onCompleteCallback.call(_object); 6495 } 6496 6497 this.completeChainedTweens(); 6498 return this; 6499 }; 6500 6501 this.completeChainedTweens = function () { 6502 6503 for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { 6504 _chainedTweens[i].complete(); 6505 } 6506 6507 }; 6508 6509 this.delay = function (amount) { 6510 6511 _delayTime = amount; 6512 return this; 6513 6514 }; 6515 6516 this.repeat = function (times) { 6517 6518 _repeat = times; 6519 return this; 6520 6521 }; 6522 6523 this.yoyo = function (yoyo) { 6524 6525 _yoyo = yoyo; 6526 return this; 6527 6528 }; 6529 6530 6531 this.easing = function (easing) { 6532 6533 _easingFunction = easing == null ? _easingFunction : easing; 6534 return this; 6535 6536 }; 6537 6538 this.interpolation = function (interpolation) { 6539 6540 _interpolationFunction = interpolation; 6541 return this; 6542 6543 }; 6544 6545 this.chain = function () { 6546 6547 _chainedTweens = arguments; 6548 return this; 6549 6550 }; 6551 6552 this.onStart = function (callback) { 6553 6554 _onStartCallback = callback; 6555 return this; 6556 6557 }; 6558 6559 this.onUpdate = function (callback) { 6560 6561 _onUpdateCallback = callback; 6562 return this; 6563 6564 }; 6565 6566 this.onComplete = function (callback) { 6567 6568 _onCompleteCallback = callback; 6569 return this; 6570 6571 }; 6572 6573 this.onStop = function (callback) { 6574 6575 _onStopCallback = callback; 6576 return this; 6577 6578 }; 6579 6580 this.update = function (time) { 6581 6582 var property; 6583 var elapsed; 6584 var value; 6585 6586 if (time < _startTime) { 6587 return true; 6588 } 6589 6590 if (_onStartCallbackFired === false) { 6591 6592 if (_onStartCallback !== null) { 6593 _onStartCallback.call(_object); 6594 } 6595 6596 _onStartCallbackFired = true; 6597 6598 } 6599
6600 elapsed = (time - _startTime) / _duration; 6601 elapsed = elapsed > 1 ? 1 : elapsed; 6602 6603 value = _easingFunction(elapsed); 6604 6605 for (property in _valuesEnd) { 6606 6607 // Don't update properties that do not exist in the source object 6608 if (_valuesStart[property] === null) { 6609 continue; 6610 } 6611 6612 var start = _valuesStart[property] || 0; 6613 var end = _valuesEnd[property]; 6614 6615 if (end instanceof Array) { 6616 6617 _object[property] = _interpolationFunction(end, value); 6618 6619 } 6620 else { 6621 6622 // Parses relative end values with start as base (e.g.: +10, -3) 6623 if (typeof (end) === 'string') { 6624 6625 if (end.startsWith('+') || end.startsWith('-')) { 6626 end = start + parseFloat(end, 10); 6627 } 6628 else { 6629 end = parseFloat(end, 10); 6630 } 6631 } 6632 6633 // Protect against non numeric properties. 6634 if (typeof (end) === 'number') { 6635 _object[property] = start + (end - start) * value; 6636 } 6637 6638 } 6639 6640 } 6641 6642 if (_onUpdateCallback !== null) { 6643 _onUpdateCallback.call(_object, value); 6644 } 6645 6646 if (elapsed === 1) { 6647 6648 if (_repeat > 0) { 6649 6650 if (isFinite(_repeat)) { 6651 _repeat--; 6652 } 6653 6654 // Reassign starting values, restart by making startTime = now 6655 for (property in _valuesStartRepeat) { 6656 6657 if (typeof (_valuesEnd[property]) === 'string') { 6658 _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property], 10); 6659 } 6660 6661 if (_yoyo) { 6662 var tmp = _valuesStartRepeat[property]; 6663 6664 _valuesStartRepeat[property] = _valuesEnd[property]; 6665 _valuesEnd[property] = tmp; 6666 } 6667 6668 _valuesStart[property] = _valuesStartRepeat[property]; 6669 6670 } 6671 6672 if (_yoyo) { 6673 _reversed = !_reversed; 6674 } 6675 6676 _startTime = time + _delayTime; 6677 6678 return true; 6679 6680 } 6681 else { 6682 6683 if (_onCompleteCallback !== null) { 6684 _onCompleteCallback.call(_object); 6685 } 6686 6687 for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { 6688 // Make the chained tweens start exactly at the time they should, 6689 // even if the `update()` method was called way past the duration of the tween 6690 _chainedTweens[i].start(_startTime + _duration); 6691 } 6692 6693 return false; 6694 6695 } 6696 6697 } 6698 6699 return true; 6700 6701 }; 6702 6703 }; 6704 6705 TWEEN.Easing = { 6706 6707 Linear: { 6708 6709 None: function (k) { 6710 6711 return k; 6712 6713 } 6714 6715 }, 6716 6717 Quadratic: { 6718 6719 In: function (k) { 6720 6721 return k * k; 6722 6723 }, 6724 6725 Out: function (k) { 6726 6727 return k * (2 - k); 6728 6729 }, 6730 6731 InOut: function (k) { 6732 6733 if ((k *= 2) < 1) { 6734 return 0.5 * k * k; 6735 } 6736 6737 return -0.5 * (--k * (k - 2) - 1); 6738 6739 } 6740 6741 }, 6742 Quartic: { 6743 6744 In: function (k) { 6745 6746 return k * k * k * k; 6747 6748 }, 6749 6750 Out: function (k) { 6751 6752 return 1 - (--k * k * k * k); 6753 6754 }, 6755 6756 InOut: function (k) { 6757 6758 if ((k *= 2) < 1) { 6759 return 0.5 * k * k * k * k; 6760 } 6761 6762 return -0.5 * ((k -= 2) * k * k * k - 2); 6763 6764 } 6765 6766 }, 6767 Sinusoidal: { 6768 6769 In: function (k) { 6770 6771 return 1 - Math.cos(k * Math.PI / 2); 6772 6773 }, 6774 6775 Out: function (k) { 6776 6777 return Math.sin(k * Math.PI / 2); 6778 6779 }, 6780 6781 InOut: function (k) { 6782 6783 return 0.5 * (1 - Math.cos(Math.PI * k)); 6784 6785 } 6786 6787 }, 6788 Cubic: { 6789 6790 In: function (k) { 6791 6792 return k * k * k; 6793 6794 }, 6795 6796 Out: function (k) { 6797 6798 return --k * k * k + 1; 6799 6800 }, 6801 6802 InOut: function (k) { 6803 6804 if ((k *= 2) < 1) { 6805 return 0.5 * k * k * k; 6806 } 6807 6808 return 0.5 * ((k -= 2) * k * k + 2); 6809 6810 } 6811 6812 } 6813 6814 }; 6815 6816 TWEEN.Interpolation = { 6817 6818 Linear: function (v, k) { 6819 6820 var m = v.length - 1; 6821 var f = m * k; 6822 var i = Math.floor(f); 6823 var fn = TWEEN.Interpolation.Utils.Linear; 6824 6825 if (k < 0) { 6826 return fn(v[0], v[1], f); 6827 } 6828 6829 if (k > 1) { 6830 return fn(v[m], v[m - 1], m - f); 6831 } 6832 6833 return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); 6834 6835 }, 6836 6837 Bezier: function (v, k) { 6838 6839 var b = 0; 6840 var n = v.length - 1; 6841 var pw = Math.pow; 6842 var bn = TWEEN.Interpolation.Utils.Bernstein; 6843 6844 for (var i = 0; i <= n; i++) { 6845 b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); 6846 } 6847 6848 return b; 6849 6850 }, 6851 6852 Utils: { 6853 6854 Linear: function (p0, p1, t) { 6855 6856 return (p1 - p0) * t + p0; 6857 6858 }, 6859 6860 Bernstein: function (n, i) { 6861 6862 var fc = TWEEN.Interpolation.Utils.Factorial; 6863 6864 return fc(n) / fc(i) / fc(n - i); 6865 6866 }, 6867 6868 Factorial: (function () { 6869 6870 var a = [1]; 6871 6872 return function (n) { 6873 6874 var s = 1; 6875 6876 if (a[n]) { 6877 return a[n]; 6878 } 6879 6880 for (var i = n; i > 1; i--) { 6881 s *= i; 6882 } 6883 6884 a[n] = s; 6885 return s; 6886 6887 }; 6888 6889 })(), 6890 6891 CatmullRom: function (p0, p1, p2, p3, t) { 6892 6893 var v0 = (p2 - p0) * 0.5; 6894 var v1 = (p3 - p1) * 0.5; 6895 var t2 = t * t; 6896 var t3 = t * t2; 6897 6898 return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; 6899 6900 } 6901 6902 } 6903 }; 6904 6905 window.TWEEN = TWEEN; 6906})(); 6907 6908DFLIP.createBlob = function createBlob(data, contentType) { 6909 if (typeof Blob !== 'undefined') { 6910 return new Blob([data], {type: contentType}); 6911 }
6912 // Blob builder is deprecated in FF14 and removed in FF18. 6913 var bb = new MozBlobBuilder(); 6914 bb.append(data); 6915 return bb.getBlob(contentType); 6916}; 6917 6918DFLIP.createObjectURL = (function createObjectURLClosure() { 6919 // Blob/createObjectURL is not available, falling back to data schema. 6920 var digits = 6921 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 6922 6923 return function createObjectURL(data, contentType) { 6924 if (typeof URL !== 'undefined' && URL.createObjectURL) { 6925 var blob = DFLIP.createBlob(data, contentType); 6926 return URL.createObjectURL(blob); 6927 } 6928 6929 var buffer = 'data:' + contentType + ';base64,'; 6930 for (var i = 0, ii = data.length; i < ii; i += 3) { 6931 var b1 = data[i] & 0xFF; 6932 var b2 = data[i + 1] & 0xFF; 6933 var b3 = data[i + 2] & 0xFF; 6934 var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4); 6935 var d3 = i + 1 < ii ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64; 6936 var d4 = i + 2 < ii ? (b3 & 0x3F) : 64; 6937 buffer += digits[d1] + digits[d2] + digits[d3] + digits[d4]; 6938 } 6939 return buffer; 6940 }; 6941})(); 6942 6943var ThumbList = (function ThumbListClosure() { 6944 function ThumbList(config) { 6945 var width = (config && config.w + 'px') || '100%'; 6946 var height = (config && config.h + 'px') || '100%'; 6947 var itemHeight = this.itemHeight = config.itemHeight; 6948 6949 this.items = config.items; 6950 this.generatorFn = config.generatorFn; 6951 this.totalRows = config.totalRows || (config.items && config.items.length); 6952 6953 this.addFn = config.addFn; 6954 this.scrollFn = config.scrollFn; 6955 6956 var scroller = ThumbList.createScroller(itemHeight * this.totalRows); 6957 this.container = ThumbList.createContainer(width, height); 6958 this.container.appendChild(scroller); 6959 6960 this.screenItemsLen = Math.ceil(config.h / itemHeight); 6961 this.offsetItems = this.screenItemsLen; 6962 // Cache 4 times the number of items that fit in the container viewport 6963 this.cachedItemsLen = this.screenItemsLen + this.offsetItems * 2; 6964 this._renderChunk(this.container, 0); 6965 6966 var self = this; 6967 self.lastRepaintY = 0; 6968 var maxBuffer = this.screenItemsLen * itemHeight; 6969 var lastScrolled = 0; 6970 6971 var requestInterval; 6972 6973 function onScroll(e) { 6974 var scrollTop = e.target.scrollTop; // Triggers reflow 6975 if (!self.lastRepaintY || Math.abs(scrollTop - self.lastRepaintY) >= (self.offsetItems * self.itemHeight)) { 6976 var first = parseInt(scrollTop / itemHeight, 10) - self.offsetItems; 6977 self._renderChunk(self.container, first < 0 ? 0 : first); 6978 self.lastRepaintY = scrollTop; 6979 } 6980 6981 self.lastScrolled = lastScrolled = Date.now(); 6982 6983 if (self.scrollFn != null) { 6984 self.scrollFn(); 6985 } 6986 6987 e.preventDefault && e.preventDefault(); 6988 } 6989 6990 self.dispose = function () { 6991 if (self.container) { 6992 if (self.container.parentNode) { 6993 self.container.parentNode.removeChild(self.container); 6994 } 6995 } 6996 6997 self.container.removeEventListener('scroll', onScroll); 6998 }; 6999 7000 self.container.addEventListener('scroll', onScroll); 7001 } 7002 7003 ThumbList.prototype.reset = function (height) { 7004 7005 //container.find(".df-vrow").remove(); 7006 this.screenItemsLen = Math.ceil(height / this.itemHeight); 7007 this.cachedItemsLen = this.screenItemsLen + this.offsetItems * 2; 7008 var first = parseInt(this.lastRepaintY / this.itemHeight, 10) - this.offsetItems; 7009 //this.lastRepaintY = 0; 7010 this.needReset = true; 7011 this._renderChunk(this.container, Math.max(first, 0)); 7012 }; 7013 7014 ThumbList.prototype.createRow = function (i) { 7015 var item; 7016 if (this.generatorFn) { 7017 item = this.generatorFn(i); 7018 item.classList.add('df-vrow'); 7019 item.style.position = 'absolute'; 7020 item.style.top = (i * this.itemHeight) + 'px'; 7021 item.setAttribute("index", i); 7022 } 7023 return item; 7024 }; 7025 7026 /** 7027 * Renders a particular, consecutive chunk of the total rows in the list. To 7028 * keep acceleration while scrolling, we mark the nodes that are candidate for 7029 * deletion instead of deleting them right away, which would suddenly stop the 7030 * acceleration. We delete them once scrolling has finished. 7031 * 7032 * @param {Node} node Parent node where we want to append the children chunk. 7033 * @param {Number} from Starting position, i.e. first children index. 7034 * @return {void} 7035 */ 7036 ThumbList.prototype._renderChunk = function (node, from) { 7037 var isEmpty = this.range == null; 7038 this.range = this.range || {min: 0, max: this.cachedItemsLen}; 7039 var range = this.range; 7040 7041 var min = range.min, max = range.max; 7042 7043 var isAdd = isEmpty ? true : from >= min; 7044 7045 if (!isEmpty && from == min && this.needReset == false) return; 7046 7047 var countVar; 7048 7049 var start = isEmpty ? min : isAdd ? max : from;// - this.cachedItemsLen/3; 7050 7051 start = start > this.totalRows ? this.totalRows 7052 : start < 0 ? 0 : start; 7053 7054 var end = from + this.cachedItemsLen;//this.cachedItemsLen/3); 7055 7056 end = end > this.totalRows ? this.totalRows : end; 7057 7058 for (countVar = start; countVar < end; countVar++) { 7059 if (isAdd) 7060 node.appendChild(this.createRow(countVar)); 7061 else 7062 node.insertBefore(this.createRow(countVar), node.childNodes[1 + countVar - start]); 7063 if (this.addFn != null) { 7064 this.addFn(countVar); 7065 } 7066 } 7067 var difference = Math.abs(from - min); 7068 this.needReset = false;
7069 if (!isEmpty && node.childNodes.length > (this.cachedItemsLen + 1)) { 7070 // Hide and mark obsolete nodes for deletion. 7071 var delStart = isAdd ? 1 : 1 + this.cachedItemsLen, 7072 delEnd = delStart + (end - start); 7073 7074 for (var j = delEnd; j > delStart; j--) { 7075 if (node.childNodes[delStart]) 7076 this.container.removeChild(node.childNodes[delStart]); 7077 } 7078 } 7079 this.range.min = from; 7080 this.range.max = end; 7081 }; 7082 7083 ThumbList.createContainer = function (w, h) { 7084 var c = document.createElement('div'); 7085 c.style.width = w; 7086 c.style.height = h; 7087 c.style.overflow = 'auto'; 7088 c.style.position = 'relative'; 7089 c.style.padding = 0; 7090 //c.style.border = '1px solid black'; 7091 return c; 7092 }; 7093 7094 ThumbList.createScroller = function (h) { 7095 var scroller = document.createElement('div'); 7096 scroller.style.opacity = 0; 7097 scroller.style.position = 'absolute'; 7098 scroller.style.top = 0; 7099 scroller.style.left = 0; 7100 scroller.style.width = '1px'; 7101 scroller.style.height = h + 'px'; 7102 return scroller; 7103 }; 7104 return ThumbList; 7105})(); 7106 7107 7108/** 7109 * @typedef {Object} BookMarkViewerOptions 7110 * @property {HTMLDivElement} container - The viewer element. 7111 * @property {IPDFLinkService} linkService - The navigation/linking service. 7112 */ 7113 7114/** 7115 * @typedef {Object} BookMarkViewerRenderParameters 7116 * @property {Array|null} outline - An array of outline objects. 7117 */ 7118 7119/** 7120 * @class 7121 */ 7122var BookMarkViewer = (function BookMarkViewerClosure() { 7123 /** 7124 * @constructs BookMarkViewer 7125 * @param {BookMarkViewerOptions} options 7126 */ 7127 function BookMarkViewer(options) { 7128 this.outline = null; 7129 this.lastToggleIsShow = true; 7130 this.container = options.container; 7131 this.linkService = options.linkService; 7132 this.outlineItemClass = options.outlineItemClass || "outlineItem"; 7133 this.outlineToggleClass = options.outlineToggleClass || "outlineItemToggler"; 7134 this.outlineToggleHiddenClass = options.outlineToggleHiddenClass || "outlineItemsHidden"; 7135 } 7136 7137 BookMarkViewer.prototype = { 7138 7139 dispose: function () { 7140 if (this.container) { 7141 if (this.container.parentNode) { 7142 this.container.parentNode.removeChild(this.container); 7143 } 7144 } 7145 this.linkService = null; 7146 7147 }, 7148 reset: function BookMarkViewer_reset() { 7149 this.outline = null; 7150 this.lastToggleIsShow = true; 7151 7152 var container = this.container; 7153 while (container.firstChild) { 7154 container.removeChild(container.firstChild); 7155 } 7156 }, 7157 7158 /** 7159 * @private 7160 */ 7161 _dispatchEvent: function BookMarkViewer_dispatchEvent(outlineCount) { 7162 var event = document.createEvent('CustomEvent'); 7163 event.initCustomEvent('outlineloaded', true, true, { 7164 outlineCount: outlineCount 7165 }); 7166 this.container.dispatchEvent(event); 7167 }, 7168 7169 /** 7170 * @private 7171 */ 7172 _bindLink: function BookMarkViewer_bindLink(element, item) { 7173 var linkService = this.linkService; 7174 if (item.custom == true) { 7175 element.href = linkService.getCustomDestinationHash(item.dest); 7176 element.onclick = function goToDestination(e) { 7177 linkService.customNavigateTo(item.dest); 7178 return false; 7179 }; 7180 } 7181 else { 7182 if (item.url) { 7183 PDFJS.addLinkAttributes(element, {url: item.url}); 7184 return; 7185 } 7186 7187 element.href = linkService.getDestinationHash(item.dest); 7188 element.onclick = function goToDestination(e) { 7189 linkService.navigateTo(item.dest); 7190 return false; 7191 }; 7192 } 7193 }, 7194 7195 /** 7196 * Prepend a button before an outline item which allows the user to toggle 7197 * the visibility of all outline items at that level. 7198 * 7199 * @private 7200 */ 7201 _addToggleButton: function BookMarkViewer_addToggleButton(div) { 7202 var toggler = document.createElement('div'); 7203 toggler.className = this.outlineToggleClass + " " + this.outlineToggleHiddenClass; 7204 toggler.onclick = function (event) { 7205 event.stopPropagation(); 7206 toggler.classList.toggle(this.outlineToggleHiddenClass); 7207 7208 if (event.shiftKey) { 7209 var shouldShowAll = !toggler.classList.contains(this.outlineToggleHiddenClass); 7210 this._toggleOutlineItem(div, shouldShowAll); 7211 } 7212 }.bind(this); 7213 div.insertBefore(toggler, div.firstChild); 7214 }, 7215 7216 /** 7217 * Toggle the visibility of the subtree of an outline item. 7218 * 7219 * @param {Element} root - the root of the outline (sub)tree. 7220 * @param {boolean} show - whether to show the outline (sub)tree. If false, 7221 * the outline subtree rooted at |root| will be collapsed. 7222 * 7223 * @private 7224 */ 7225 _toggleOutlineItem: function BookMarkViewer_toggleOutlineItem(root, show) { 7226 this.lastToggleIsShow = show; 7227 var togglers = root.querySelectorAll('.' + this.outlineToggleClass); 7228 for (var i = 0, ii = togglers.length; i < ii; ++i) { 7229 togglers[i].classList[show ? 'remove' : 'add'](this.outlineToggleHiddenClass); 7230 } 7231 }, 7232 7233 /** 7234 * Collapse or expand all subtrees of the outline. 7235 */ 7236 toggleOutlineTree: function BookMarkViewer_toggleOutlineTree() { 7237 if (!this.outline) { 7238 return; 7239 } 7240 this._toggleOutlineItem(this.container, !this.lastToggleIsShow); 7241 }, 7242 7243 /** 7244 * @param {BookMarkViewerRenderParameters} params 7245 */ 7246 render: function BookMarkViewer_render(params) { 7247 var outline = (params && params.outline) || null; 7248 var outlineCount = 0; 7249 7250 if (this.outline) { 7251 this.reset(); 7252 } 7253 this.outline = outline; 7254 7255 if (!outline) { 7256 //this._dispatchEvent(outlineCount); 7257 return; 7258 } 7259 7260 var fragment = document.createDocumentFragment(); 7261 var queue = [{parent: fragment, items: this.outline}];
7262 var hasAnyNesting = false; 7263 while (queue.length > 0) { 7264 var levelData = queue.shift(); 7265 var isCustom = levelData.custom; 7266 for (var i = 0, len = levelData.items.length; i < len; i++) { 7267 var item = levelData.items[i]; 7268 7269 var div = document.createElement('div'); 7270 div.className = this.outlineItemClass; 7271 7272 var element = document.createElement('a'); 7273 if (item.custom == null && isCustom != null) 7274 item.custom = isCustom; 7275 7276 this._bindLink(element, item); 7277 //element. 7278 element.textContent = item.title.replace(/\x00/g, ''); 7279 //PDFJS.removeNullCharacters(item.title) || "Untitled Bookmark"; 7280 7281 div.appendChild(element); 7282 7283 if (item.items && item.items.length > 0) { 7284 hasAnyNesting = true; 7285 this._addToggleButton(div); 7286 7287 var itemsDiv = document.createElement('div'); 7288 itemsDiv.className = this.outlineItemClass + "s"; 7289 div.appendChild(itemsDiv); 7290 queue.push({parent: itemsDiv, custom: item.custom, items: item.items}); 7291 } 7292 7293 levelData.parent.appendChild(div); 7294 outlineCount++; 7295 } 7296 } 7297 if (hasAnyNesting) { 7298 if (this.container.classList != null) { 7299 this.container.classList.add(this.outlineItemClass + "s"); 7300 } 7301 else if (this.container.className != null) { 7302 this.container.className += " picWindow"; 7303 } 7304 } 7305 7306 this.container.appendChild(fragment); 7307 7308 this._dispatchEvent(outlineCount); 7309 } 7310 7311 }; 7312 7313 return BookMarkViewer; 7314})(); 7315//PDFJS.PDFOutlineViewer = PDFOutlineViewer; 7316 7317var DFLightBox = (function DFLightBoxClosure($) { 7318 /** 7319 * @constructs DFLightBox 7320 * @param closeCallback callBack function required to dispose object properly when lighbox is closed 7321 */ 7322 function DFLightBox(closeCallback, options) { 7323 7324 this.duration = 300; 7325 7326 //cache this 7327 var _this = this; 7328 //lightbox wrapper div 7329 _this.lightboxWrapper = $("<div>").addClass("df-lightbox-wrapper"); 7330 7331 //lightbox container 7332 _this.container = $("<div>").addClass("df-container").appendTo(_this.lightboxWrapper); 7333 //lightbox controls 7334 _this.controls = $("<div>").addClass("df-lightbox-controls").appendTo(_this.lightboxWrapper); 7335 7336 //lightbox close button 7337 _this.closeButton = $("<div>").addClass("df-lightbox-close df-ui-btn") 7338 .on("click", function () { 7339 _this.close(closeCallback); 7340 }) 7341 .appendTo(_this.controls); 7342 7343 _this.lightboxWrapper.append(_this.container); 7344 7345 return _this; 7346 } 7347 7348 DFLightBox.prototype.show = function (callback) { 7349 7350 if (this.lightboxWrapper.parent().length == 0) 7351 $("body").append(this.lightboxWrapper); 7352 7353 this.lightboxWrapper.fadeIn(this.duration, callback); 7354 7355 return this; 7356 }; 7357 7358 DFLightBox.prototype.close = function (callback) { 7359 7360 this.lightboxWrapper.fadeOut(this.duration); 7361 setTimeout(callback, this.duration); 7362 7363 return this; 7364 }; 7365 7366 return DFLightBox; 7367})(jQuery); 7368 7369DFLIP.Share = (function ShareClosure($) { 7370 7371 function Share(container, options) { 7372 var _this = this; 7373 var htmlDiv = '<div>'; 7374 var shareButtonClass = "df-share-button"; 7375 var windowParameters = "width=500,height=400"; 7376 _this.isOpen = false; 7377 _this.shareUrl = ""; 7378 _this.wrapper = $('<div class="df-share-wrapper" style="display: none;">') 7379 .on("click", function (e) { 7380 _this.close(); 7381 }); 7382 _this.box = $('<div class="df-share-box">') 7383 .on("click", function (e) { 7384 e.preventDefault(); 7385 e.stopPropagation(); 7386 }).appendTo(_this.wrapper).html('<span class="df-share-title">' + options.text.share + '</span>'); 7387 _this.urlInput = $('<textarea class="df-share-url">').on("click", function () { 7388 $(this).select(); 7389 }); 7390 7391 _this.facebook = $(htmlDiv, { 7392 class: shareButtonClass + " df-share-facebook " + options.icons['facebook'] 7393 }).on("click", function (e) { 7394 window.open('https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(_this.shareUrl), "Sharer", windowParameters); 7395 }); 7396 _this.google = $(htmlDiv, { 7397 class: shareButtonClass + " df-share-google " + options.icons['google'] 7398 }).on("click", function (e) { 7399 window.open('https://plus.google.com/share?url=' + encodeURIComponent(_this.shareUrl), "Sharer", windowParameters); 7400 }); 7401 _this.twitter = $(htmlDiv, { 7402 class: shareButtonClass + " df-share-twitter " + options.icons['twitter'] 7403 }).on("click", function (e) { 7404 window.open('http://twitter.com/share?url=' + encodeURIComponent(_this.shareUrl), "Sharer", windowParameters); 7405 }); 7406 _this.mail = $('<a>', { 7407 class: shareButtonClass + " df-share-mail " + options.icons['mail'],
7408 href: 'mailto:?subject=I wanted you to see this FlipBook&body=Check out this site ' + encodeURIComponent(_this.shareUrl), 7409 target: '_blank' 7410 }).on("click", function (e) { 7411 $(this).attr('href', 'mailto:?subject=I wanted you to see this FlipBook&body=Check out this site ' + encodeURIComponent(_this.shareUrl)); 7412 e.stopPropagation();//so the default event is not cancelled by parent element 7413 }); 7414 7415 _this.box.append(_this.urlInput).append(_this.facebook).append(_this.google).append(_this.twitter).append(_this.mail); 7416 $(container).append(_this.wrapper); 7417 7418 } 7419 7420 Share.prototype.show = function () { 7421 this.wrapper.fadeIn(300); 7422 this.urlInput.val(this.shareUrl); 7423 this.urlInput.trigger("click"); 7424 this.isOpen = true; 7425 } 7426 7427 Share.prototype.dispose = function () { 7428 var _this = this; 7429 _this.box.off(); 7430 _this.google.off(); 7431 _this.twitter.off(); 7432 _this.facebook.off(); 7433 _this.mail.off(); 7434 _this.urlInput.off(); 7435 _this.wrapper.off().remove(); 7436 } 7437 7438 Share.prototype.close = function () { 7439 this.wrapper.fadeOut(300); 7440 this.isOpen = false; 7441 } 7442 7443 Share.prototype.update = function (url) { 7444 this.shareUrl = url; 7445 } 7446 7447 return Share; 7448})(jQuery); 7449DFLIP.Popup = (function PopupClosure($) { 7450 7451 function Popup(container, options) { 7452 var _this = this; 7453 var htmlDiv = '<div>'; 7454 var windowParameters = "width=500,height=400"; 7455 _this.isOpen = false; 7456 _this.wrapper = $('<div class="df-popup-wrapper" style="display: none;">') 7457 .on("click", function (e) { 7458 _this.close(); 7459 }); 7460 _this.box = $('<div class="df-popup-box">') 7461 .on("click", function (e) { 7462 e.preventDefault(); 7463 e.stopPropagation(); 7464 }).appendTo(_this.wrapper); 7465 7466 $(container).append(_this.wrapper); 7467 7468 } 7469 7470 Popup.prototype.show = function () { 7471 this.wrapper.fadeIn(300); 7472 this.isOpen = true; 7473 } 7474 7475 Popup.prototype.dispose = function () { 7476 var _this = this; 7477 _this.box.off(); 7478 _this.wrapper.off().remove(); 7479 } 7480 7481 Popup.prototype.close = function () { 7482 this.wrapper.fadeOut(300); 7483 this.isOpen = false; 7484 } 7485 7486 return Popup; 7487})(jQuery); 7488 7489/** 7490 * Performs navigation functions inside PDF, such as opening specified page, 7491 * or destination. 7492 * @class 7493 * @implements {IPDFLinkService} 7494 */ 7495var PDFLinkService = (function () { 7496 /** 7497 * @constructs PDFLinkService 7498 */ 7499 function PDFLinkService() { 7500 this.baseUrl = null; 7501 this.pdfDocument = null; 7502 this.pdfViewer = null; 7503 this.pdfHistory = null; 7504 7505 this._pagesRefCache = null; 7506 } 7507 7508 PDFLinkService.prototype = { 7509 dispose: function () { 7510 this.baseUrl = null; 7511 this.pdfDocument = null; 7512 this.pdfViewer = null; 7513 this.pdfHistory = null; 7514 7515 this._pagesRefCache = null; 7516 }, 7517 setDocument: function PDFLinkService_setDocument(pdfDocument, baseUrl) { 7518 this.baseUrl = baseUrl; 7519 this.pdfDocument = pdfDocument; 7520 this._pagesRefCache = Object.create(null); 7521 }, 7522 7523 setViewer: function PDFLinkService_setViewer(pdfViewer) { 7524 this.pdfViewer = pdfViewer; 7525 }, 7526 7527 setHistory: function PDFLinkService_setHistory(pdfHistory) { 7528 this.pdfHistory = pdfHistory; 7529 }, 7530 7531 /** 7532 * @returns {number} 7533 */ 7534 get pagesCount() { 7535 return this.pdfDocument.numPages; 7536 }, 7537 7538 /** 7539 * @returns {number} 7540 */ 7541 get page() { 7542 return this.pdfViewer.currentPageNumber; 7543 }, 7544 7545 /** 7546 * @param {number} value 7547 */ 7548 set page(value) { 7549 this.pdfViewer.currentPageNumber = value; 7550 }, 7551 7552 /** 7553 * @param dest - The PDF destination object. 7554 */ 7555 navigateTo: function PDFLinkService_navigateTo(dest) { 7556 var destString = ''; 7557 var self = this; 7558 7559 var goToDestination = function (destRef) { 7560 // dest array looks like that: <page-ref> </XYZ|FitXXX> <args..> 7561 var pageNumber = destRef instanceof Object ? self._pagesRefCache[destRef.num + ' ' + destRef.gen + ' R'] 7562 : (destRef + 1); 7563 if (pageNumber) { 7564 //case double internal 7565 if (self.pdfViewer.contentProvider.options.pageSize == DFLIP.PAGE_SIZE.DOUBLEINTERNAL && pageNumber > 2) { 7566 pageNumber = pageNumber * 2 - 1; 7567 } 7568 7569 if (pageNumber >
7569 self.pdfViewer.pageCount) { 7570 pageNumber = self.pdfViewer.pageCount; 7571 } 7572 self.pdfViewer.gotoPage(pageNumber); 7573 // self.pdfViewer.scrollPageIntoView(pageNumber, dest); 7574 7575 if (self.pdfHistory) { 7576 // Update the browsing history. 7577 self.pdfHistory.push({ 7578 dest: dest, 7579 hash: destString, 7580 page: pageNumber 7581 }); 7582 } 7583 } 7584 else { 7585 self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) { 7586 var pageNum = pageIndex + 1; 7587 var cacheKey = destRef.num + ' ' + destRef.gen + ' R'; 7588 self._pagesRefCache[cacheKey] = pageNum; 7589 goToDestination(destRef); 7590 }); 7591 } 7592 }; 7593 7594 var destinationPromise; 7595 if (typeof dest === 'string') { 7596 destString = dest; 7597 destinationPromise = this.pdfDocument.getDestination(dest); 7598 } 7599 else { 7600 destinationPromise = Promise.resolve(dest); 7601 } 7602 destinationPromise.then(function (destination) { 7603 dest = destination; 7604 if (!(destination instanceof Array)) { 7605 return; // invalid destination 7606 } 7607 goToDestination(destination[0]); 7608 }); 7609 }, 7610 7611 7612 /** 7613 * @param dest - The PDF destination object. 7614 */ 7615 customNavigateTo: function PDFLinkService_navigateTo(dest) { 7616 if (dest == '' || dest == null || dest == 'null') return; 7617 var pageNumber = null; 7618 if (!isNaN(Math.round(dest))) { 7619 pageNumber = dest; 7620 } 7621 else if (typeof dest === 'string') { 7622 pageNumber = parseInt(dest.replace("#", ""), 10); 7623 if (isNaN(pageNumber)) { 7624 window.open(dest, (DFLIP.defaults.linkTarget == DFLIP.LINK_TARGET.SELF ? "_self" : "_blank")); 7625 return; 7626 } 7627 } 7628 7629 if (pageNumber != null) 7630 this.pdfViewer.gotoPage(pageNumber); 7631 7632 }, 7633 7634 /** 7635 * @param dest - The PDF destination object. 7636 * @returns {string} The hyperlink to the PDF object. 7637 */ 7638 getDestinationHash: function PDFLinkService_getDestinationHash(dest) { 7639 if (typeof dest === 'string') { 7640 return this.getAnchorUrl('#' + escape(dest)); 7641 } 7642 if (dest instanceof Array) { 7643 var destRef = dest[0]; // see navigateTo method for dest format 7644 var pageNumber = destRef instanceof Object ? this._pagesRefCache[destRef.num + ' ' + destRef.gen + ' R'] 7645 : (destRef + 1); 7646 if (pageNumber) { 7647 var pdfOpenParams = this.getAnchorUrl('#page=' + pageNumber); 7648 var destKind = dest[1]; 7649 if (typeof destKind === 'object' && 'name' in destKind && 7650 destKind.name === 'XYZ') { 7651 var scale = (dest[4] || this.pdfViewer.currentScaleValue); 7652 var scaleNumber = parseFloat(scale); 7653 if (scaleNumber) { 7654 scale = scaleNumber * 100; 7655 } 7656 pdfOpenParams += '&zoom=' + scale; 7657 if (dest[2] || dest[3]) { 7658 pdfOpenParams += ',' + (dest[2] || 0) + ',' + (dest[3] || 0); 7659 } 7660 } 7661 return pdfOpenParams; 7662 } 7663 } 7664 return this.getAnchorUrl(''); 7665 }, 7666 7667 /** 7668 * @param dest - The PDF destination object. 7669 * @returns {string} The hyperlink to the PDF object. 7670 */ 7671 getCustomDestinationHash: function PDFLinkService_getCustomDestinationHash(dest) { 7672 //if (typeof dest === 'string') { 7673 return '#' + escape(dest); 7674 //} 7675 //return this.getAnchorUrl(''); 7676 }, 7677 7678 7679 /** 7680 * Prefix the full url on anchor links to make sure that links are resolved 7681 * relative to the current URL instead of the one defined in <base href>. 7682 * @param {String} anchor The anchor hash, including the #. 7683 * @returns {string} The hyperlink to the PDF object. 7684 */ 7685 getAnchorUrl: function PDFLinkService_getAnchorUrl(anchor) { 7686 return (this.baseUrl || '') + anchor; 7687 }, 7688 7689 /** 7690 * @param {string} hash 7691 */ 7692 setHash: function PDFLinkService_setHash(hash) { 7693 if (hash.indexOf('=') >= 0) { 7694 var params = parseQueryString(hash); 7695 // borrowing syntax from "Parameters for Opening PDF Files" 7696 if ('nameddest' in params) { 7697 if (this.pdfHistory) { 7698 this.pdfHistory.updateNextHashParam(params.nameddest); 7699 } 7700 this.navigateTo(params.nameddest); 7701 return; 7702 } 7703 var pageNumber, dest; 7704 if ('page' in params) { 7705 pageNumber = (params.page | 0) || 1; 7706 } 7707 if ('zoom' in params) { 7708 // Build the destination array.
7709 var zoomArgs = params.zoom.split(','); // scale,left,top 7710 var zoomArg = zoomArgs[0]; 7711 var zoomArgNumber = parseFloat(zoomArg); 7712 7713 if (zoomArg.indexOf('Fit') === -1) { 7714 // If the zoomArg is a number, it has to get divided by 100. If it's 7715 // a string, it should stay as it is. 7716 dest = [null, {name: 'XYZ'}, 7717 zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null, 7718 zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null, 7719 (zoomArgNumber ? zoomArgNumber / 100 : zoomArg)]; 7720 } 7721 else { 7722 if (zoomArg === 'Fit' || zoomArg === 'FitB') { 7723 dest = [null, {name: zoomArg}]; 7724 } 7725 else if ((zoomArg === 'FitH' || zoomArg === 'FitBH') || 7726 (zoomArg === 'FitV' || zoomArg === 'FitBV')) { 7727 dest = [null, {name: zoomArg}, 7728 zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null]; 7729 } 7730 else if (zoomArg === 'FitR') { 7731 if (zoomArgs.length !== 5) { 7732 console.error('PDFLinkService_setHash: ' + 7733 'Not enough parameters for \'FitR\'.'); 7734 } 7735 else { 7736 dest = [null, {name: zoomArg}, 7737 (zoomArgs[1] | 0), (zoomArgs[2] | 0), 7738 (zoomArgs[3] | 0), (zoomArgs[4] | 0)]; 7739 } 7740 } 7741 else { 7742 console.error('PDFLinkService_setHash: \'' + zoomArg + 7743 '\' is not a valid zoom value.'); 7744 } 7745 } 7746 } 7747 if (dest) { 7748 this.pdfViewer.scrollPageIntoView(pageNumber || this.page, dest); 7749 } 7750 else if (pageNumber) { 7751 this.page = pageNumber; // simple page 7752 } 7753 if ('pagemode' in params) { 7754 var event = document.createEvent('CustomEvent'); 7755 event.initCustomEvent('pagemode', true, true, { 7756 mode: params.pagemode 7757 }); 7758 this.pdfViewer.container.dispatchEvent(event); 7759 } 7760 } 7761 else if (/^\d+$/.test(hash)) { // page number 7762 this.page = hash; 7763 } 7764 else { // named destination 7765 if (this.pdfHistory) { 7766 this.pdfHistory.updateNextHashParam(unescape(hash)); 7767 } 7768 this.navigateTo(unescape(hash)); 7769 } 7770 }, 7771 7772 /** 7773 * @param {string} action 7774 */ 7775 executeNamedAction: function PDFLinkService_executeNamedAction(action) { 7776 // See PDF reference, table 8.45 - Named action 7777 switch (action) { 7778 case 'GoBack': 7779 if (this.pdfHistory) { 7780 this.pdfHistory.back(); 7781 } 7782 break; 7783 7784 case 'GoForward': 7785 if (this.pdfHistory) { 7786 this.pdfHistory.forward(); 7787 } 7788 break; 7789 7790 case 'NextPage': 7791 this.page++; 7792 break; 7793 7794 case 'PrevPage': 7795 this.page--; 7796 break; 7797 7798 case 'LastPage': 7799 this.page = this.pagesCount; 7800 break; 7801 7802 case 'FirstPage': 7803 this.page = 1; 7804 break; 7805 7806 default: 7807 break; // No action according to spec 7808 } 7809 7810 var event = document.createEvent('CustomEvent'); 7811 event.initCustomEvent('namedaction', true, true, { 7812 action: action 7813 }); 7814 this.pdfViewer.container.dispatchEvent(event); 7815 }, 7816 7817 /** 7818 * @param {number} pageNum - page number. 7819 * @param {Object} pageRef - reference to the page. 7820 */ 7821 cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) { 7822 var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; 7823 this._pagesRefCache[refStr] = pageNum; 7824 } 7825 }; 7826 7827 return PDFLinkService; 7828})(); 7829//PDFJS.PDFLinkService = PDFLinkService; 7830var FindStates = { 7831 FIND_FOUND: 0, 7832 FIND_NOTFOUND: 1, 7833 FIND_WRAPPED: 2, 7834 FIND_PENDING: 3 7835}; 7836var FIND_SCROLL_OFFSET_TOP = -50; 7837var FIND_SCROLL_OFFSET_LEFT = -400; 7838var CHARACTERS_TO_NORMALIZE = { 7839 '\u2018': '\'', 7840 '\u2019': '\'', 7841 '\u201A': '\'', 7842 '\u201B': '\'', 7843 '\u201C': '"', 7844 '\u201D': '"', 7845 '\u201E': '"', 7846 '\u201F': '"', 7847 '\u00BC': '1/4', 7848 '\u00BD': '1/2', 7849 '\u00BE': '3/4' 7850}; 7851DFLIP.PDFFindController = (function PDFFindControllerClosure() { 7852 function PDFFindController(options) { 7853 this.pdfViewer = options.pdfViewer || null; 7854 this.onUpdateResultsCount = null; 7855 this.onUpdateState = null; 7856 this.reset(); 7857 var replace = Object.keys(CHARACTERS_TO_NORMALIZE).join(''); 7858 this.normalizationRegex = new RegExp('[' + replace + ']', 'g'); 7859 } 7860 7861 PDFFindController.prototype = { 7862 reset: function PDFFindController_reset() { 7863 this.startedTextExtraction = false;
7864 this.extractTextPromises = []; 7865 this.pendingFindMatches = Object.create(null); 7866 this.active = false; 7867 this.pageContents = []; 7868 this.pageMatches = []; 7869 this.pageMatchesLength = null; 7870 this.matchCount = 0; 7871 this.selected = { 7872 pageIdx: -1, 7873 matchIdx: -1 7874 }; 7875 this.offset = { 7876 pageIdx: null, 7877 matchIdx: null 7878 }; 7879 this.pagesToSearch = null; 7880 this.resumePageIdx = null; 7881 this.state = null; 7882 this.dirtyMatch = false; 7883 this.findTimeout = null; 7884 this.firstPagePromise = new Promise(function (resolve) { 7885 this.resolveFirstPage = resolve; 7886 }.bind(this)); 7887 }, 7888 normalize: function PDFFindController_normalize(text) { 7889 return text.replace(this.normalizationRegex, function (ch) { 7890 return CHARACTERS_TO_NORMALIZE[ch]; 7891 }); 7892 }, 7893 _prepareMatches: function PDFFindController_prepareMatches(matchesWithLength, matches, matchesLength) { 7894 function isSubTerm(matchesWithLength, currentIndex) { 7895 var currentElem, prevElem, nextElem; 7896 currentElem = matchesWithLength[currentIndex]; 7897 nextElem = matchesWithLength[currentIndex + 1]; 7898 if (currentIndex < matchesWithLength.length - 1 && currentElem.match === nextElem.match) { 7899 currentElem.skipped = true; 7900 return true; 7901 } 7902 for (var i = currentIndex - 1; i >= 0; i--) { 7903 prevElem = matchesWithLength[i]; 7904 if (prevElem.skipped) { 7905 continue; 7906 } 7907 if (prevElem.match + prevElem.matchLength < currentElem.match) { 7908 break; 7909 } 7910 if (prevElem.match + prevElem.matchLength >= currentElem.match + currentElem.matchLength) { 7911 currentElem.skipped = true; 7912 return true; 7913 } 7914 } 7915 return false; 7916 } 7917 7918 var i, len; 7919 matchesWithLength.sort(function (a, b) { 7920 return a.match === b.match ? a.matchLength - b.matchLength : a.match - b.match; 7921 }); 7922 for (i = 0, len = matchesWithLength.length; i < len; i++) { 7923 if (isSubTerm(matchesWithLength, i)) { 7924 continue; 7925 } 7926 matches.push(matchesWithLength[i].match); 7927 matchesLength.push(matchesWithLength[i].matchLength); 7928 } 7929 }, 7930 calcFindPhraseMatch: function PDFFindController_calcFindPhraseMatch(query, pageIndex, pageContent) { 7931 var matches = []; 7932 var queryLen = query.length; 7933 var matchIdx = -queryLen; 7934 while (true) { 7935 matchIdx = pageContent.indexOf(query, matchIdx + queryLen); 7936 if (matchIdx === -1) { 7937 break; 7938 } 7939 matches.push(matchIdx); 7940 } 7941 this.pageMatches[pageIndex] = matches; 7942 }, 7943 calcFindWordMatch: function PDFFindController_calcFindWordMatch(query, pageIndex, pageContent) { 7944 var matchesWithLength = []; 7945 var queryArray = query.match(/\S+/g); 7946 var subquery, subqueryLen, matchIdx; 7947 for (var i = 0, len = queryArray.length; i < len; i++) { 7948 subquery = queryArray[i]; 7949 subqueryLen = subquery.length; 7950 matchIdx = -subqueryLen; 7951 while (true) { 7952 matchIdx = pageContent.indexOf(subquery, matchIdx + subqueryLen); 7953 if (matchIdx === -1) { 7954 break; 7955 } 7956 matchesWithLength.push({ 7957 match: matchIdx, 7958 matchLength: subqueryLen, 7959 skipped: false 7960 }); 7961 } 7962 } 7963 if (!this.pageMatchesLength) { 7964 this.pageMatchesLength = []; 7965 } 7966 this.pageMatchesLength[pageIndex] = []; 7967 this.pageMatches[pageIndex] = []; 7968 this._prepareMatches(matchesWithLength, this.pageMatches[pageIndex], this.pageMatchesLength[pageIndex]); 7969 }, 7970 calcFindMatch: function PDFFindController_calcFindMatch(pageIndex) { 7971 var pageContent = this.normalize(this.pageContents[pageIndex]); 7972 var query = this.normalize(this.state.query); 7973 var caseSensitive = this.state.caseSensitive; 7974 var phraseSearch = this.state.phraseSearch; 7975 var queryLen = query.length; 7976 if (queryLen === 0) { 7977 return; 7978 } 7979 if (!caseSensitive) { 7980 pageContent = pageContent.toLowerCase(); 7981 query = query.toLowerCase(); 7982 } 7983 if (phraseSearch) { 7984 this.calcFindPhraseMatch(query, pageIndex, pageContent); 7985 } 7986 else { 7987 this.calcFindWordMatch(query, pageIndex, pageContent); 7988 } 7989 this.updatePage(pageIndex); 7990 if (this.resumePageIdx === pageIndex) { 7991 this.resumePageIdx = null; 7992 this.nextPageMatch(); 7993 } 7994 if (this.pageMatches[pageIndex].length > 0) { 7995 this.matchCount += this.pageMatches[pageIndex].length; 7996 this.updateUIResultsCount(); 7997 } 7998 }, 7999 extractText: function PDFFindController_extractText() { 8000 if (this.startedTextExtraction) { 8001 return; 8002 } 8003 this.startedTextExtraction = true; 8004 this.pageContents = [];
8005 var extractTextPromisesResolves = []; 8006 var numPages = this.pdfViewer.contentProvider.pdfDocument.numPages; 8007 for (var i = 0; i < numPages; i++) { 8008 this.extractTextPromises.push(new Promise(function (resolve) { 8009 extractTextPromisesResolves.push(resolve); 8010 })); 8011 } 8012 var self = this; 8013 8014 function extractPageText(pageIndex) { 8015 self.pdfViewer.getPageTextContent(pageIndex).then(function textContentResolved(textContent) { 8016 var textItems = textContent.items; 8017 var str = []; 8018 for (var i = 0, len = textItems.length; i < len; i++) { 8019 str.push(textItems[i].str); 8020 } 8021 self.pageContents.push(str.join('')); 8022 extractTextPromisesResolves[pageIndex](pageIndex); 8023 console.log("extracting Page" + pageIndex); 8024 if (pageIndex + 1 < self.pdfViewer.contentProvider.pdfDocument.numPages) { 8025 extractPageText(pageIndex + 1); 8026 } 8027 }); 8028 } 8029 8030 extractPageText(0); 8031 }, 8032 executeCommand: function PDFFindController_executeCommand(cmd, state) { 8033 if (this.state === null || cmd !== 'findagain') { 8034 this.dirtyMatch = true; 8035 } 8036 this.state = state; 8037 this.updateUIState(FindStates.FIND_PENDING); 8038 this.firstPagePromise.then(function () { 8039 this.extractText(); 8040 clearTimeout(this.findTimeout); 8041 if (cmd === 'find') { 8042 this.findTimeout = setTimeout(this.nextMatch.bind(this), 250); 8043 } 8044 else { 8045 this.nextMatch(); 8046 } 8047 }.bind(this)); 8048 }, 8049 updatePage: function PDFFindController_updatePage(index) { 8050 if (this.selected.pageIdx === index) { 8051 this.pdfViewer.currentPageNumber = index + 1; 8052 } 8053 var page = this.pdfViewer.getPageView(index); 8054 if (page.textLayer) { 8055 page.textLayer.updateMatches(); 8056 } 8057 }, 8058 nextMatch: function PDFFindController_nextMatch() { 8059 var previous = this.state.findPrevious; 8060 var currentPageIndex = this.pdfViewer.currentPageNumber - 1; 8061 var numPages = this.pdfViewer.contentProvider.pageCount; 8062 this.active = true; 8063 if (this.dirtyMatch) { 8064 this.dirtyMatch = false; 8065 this.selected.pageIdx = this.selected.matchIdx = -1; 8066 this.offset.pageIdx = currentPageIndex; 8067 this.offset.matchIdx = null; 8068 this.hadMatch = false; 8069 this.resumePageIdx = null; 8070 this.pageMatches = []; 8071 this.matchCount = 0; 8072 this.pageMatchesLength = null; 8073 var self = this; 8074 for (var i = 0; i < numPages; i++) { 8075 this.updatePage(i); 8076 if (!(i in this.pendingFindMatches)) { 8077 this.pendingFindMatches[i] = true; 8078 this.extractTextPromises[i].then(function (pageIdx) { 8079 delete self.pendingFindMatches[pageIdx]; 8080 self.calcFindMatch(pageIdx); 8081 }); 8082 } 8083 } 8084 } 8085 if (this.state.query === '') { 8086 this.updateUIState(FindStates.FIND_FOUND); 8087 return; 8088 } 8089 if (this.resumePageIdx) { 8090 return; 8091 } 8092 var offset = this.offset; 8093 this.pagesToSearch = numPages; 8094 if (offset.matchIdx !== null) { 8095 var numPageMatches = this.pageMatches[offset.pageIdx].length; 8096 if (!previous && offset.matchIdx + 1 < numPageMatches || previous && offset.matchIdx > 0) { 8097 this.hadMatch = true; 8098 offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1; 8099 this.updateMatch(true); 8100 return; 8101 } 8102 this.advanceOffsetPage(previous); 8103 } 8104 this.nextPageMatch(); 8105 }, 8106 matchesReady: function PDFFindController_matchesReady(matches) { 8107 var offset = this.offset; 8108 var numMatches = matches.length; 8109 var previous = this.state.findPrevious; 8110 if (numMatches) { 8111 this.hadMatch = true; 8112 offset.matchIdx = previous ? numMatches - 1 : 0; 8113 this.updateMatch(true); 8114 return true; 8115 } 8116 this.advanceOffsetPage(previous); 8117 if (offset.wrapped) { 8118 offset.matchIdx = null; 8119 if (this.pagesToSearch < 0) { 8120 this.updateMatch(false); 8121 return true; 8122 } 8123 } 8124 return false;
8125 }, 8126 updateMatchPosition: function PDFFindController_updateMatchPosition(pageIndex, index, elements, beginIdx) { 8127 if (this.selected.matchIdx === index && this.selected.pageIdx === pageIndex) { 8128 var spot = { 8129 top: FIND_SCROLL_OFFSET_TOP, 8130 left: FIND_SCROLL_OFFSET_LEFT 8131 }; 8132 scrollIntoView(elements[beginIdx], spot, true); 8133 } 8134 }, 8135 nextPageMatch: function PDFFindController_nextPageMatch() { 8136 if (this.resumePageIdx !== null) { 8137 console.error('There can only be one pending page.'); 8138 } 8139 do { 8140 var pageIdx = this.offset.pageIdx; 8141 var matches = this.pageMatches[pageIdx]; 8142 if (!matches) { 8143 this.resumePageIdx = pageIdx; 8144 break; 8145 } 8146 } while (!this.matchesReady(matches)); 8147 }, 8148 advanceOffsetPage: function PDFFindController_advanceOffsetPage(previous) { 8149 var offset = this.offset; 8150 var numPages = this.extractTextPromises.length; 8151 offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1; 8152 offset.matchIdx = null; 8153 this.pagesToSearch--; 8154 if (offset.pageIdx >= numPages || offset.pageIdx < 0) { 8155 offset.pageIdx = previous ? numPages - 1 : 0; 8156 offset.wrapped = true; 8157 } 8158 }, 8159 updateMatch: function PDFFindController_updateMatch(found) { 8160 var state = FindStates.FIND_NOTFOUND; 8161 var wrapped = this.offset.wrapped; 8162 this.offset.wrapped = false; 8163 if (found) { 8164 var previousPage = this.selected.pageIdx; 8165 this.selected.pageIdx = this.offset.pageIdx; 8166 this.selected.matchIdx = this.offset.matchIdx; 8167 state = wrapped ? FindStates.FIND_WRAPPED : FindStates.FIND_FOUND; 8168 if (previousPage !== -1 && previousPage !== this.selected.pageIdx) { 8169 this.updatePage(previousPage); 8170 } 8171 } 8172 this.updateUIState(state, this.state.findPrevious); 8173 if (this.selected.pageIdx !== -1) { 8174 this.updatePage(this.selected.pageIdx); 8175 } 8176 }, 8177 updateUIResultsCount: function PDFFindController_updateUIResultsCount() { 8178 if (this.onUpdateResultsCount) { 8179 this.onUpdateResultsCount(this.matchCount); 8180 } 8181 }, 8182 updateUIState: function PDFFindController_updateUIState(state, previous) { 8183 if (this.onUpdateState) { 8184 this.onUpdateState(state, previous, this.matchCount); 8185 } 8186 } 8187 }; 8188 return PDFFindController; 8189})(); 8190/** 8191 * @typedef {Object} TextLayerBuilderOptions 8192 * @property {HTMLDivElement} textLayerDiv - The text layer container. 8193 * @property {EventBus} eventBus - The application event bus. 8194 * @property {number} pageIndex - The page index. 8195 * @property {PageViewport} viewport - The viewport of the text layer. 8196 * @property {PDFFindController} findController 8197 * @property {boolean} enhanceTextSelection - Option to turn on improved 8198 * text selection. 8199 */ 8200 8201/** 8202 * TextLayerBuilder provides text-selection functionality for the PDF. 8203 * It does this by creating overlay divs over the PDF text. These divs 8204 * contain text that matches the PDF text they are overlaying. This object 8205 * also provides a way to highlight text that is being searched for. 8206 * @class 8207 */ 8208DFLIP.TextLayerBuilder = (function TextLayerBuilderClosure() { 8209 function TextLayerBuilder(options) { 8210 this.textLayerDiv = options.textLayerDiv; 8211 this.renderingDone = false; 8212 this.divContentDone = false; 8213 this.pageIdx = options.pageIndex; 8214 this.pageNumber = this.pageIdx + 1; 8215 this.matches = []; 8216 this.viewport = options.viewport; 8217 this.textDivs = []; 8218 this.findController = options.findController || null; 8219 this.textLayerRenderTask = null; 8220 this.enhanceTextSelection = options.enhanceTextSelection; 8221 this._bindMouse(); 8222 } 8223 8224 TextLayerBuilder.prototype = { 8225 _finishRendering: function TextLayerBuilder_finishRendering() { 8226 this.renderingDone = true; 8227 8228 if (!this.enhanceTextSelection) { 8229 var endOfContent = document.createElement('div'); 8230 endOfContent.className = 'endOfContent'; 8231 this.textLayerDiv.appendChild(endOfContent); 8232 } 8233 8234 /* this.eventBus.dispatch('textlayerrendered', { 8235 source: this, 8236 pageNumber: this.pageNumber 8237 });*/ 8238 }, 8239 8240 /**
8241 * Renders the text layer. 8242 * @param {number} timeout (optional) if specified, the rendering waits 8243 * for specified amount of ms. 8244 */ 8245 render: function TextLayerBuilder_render(timeout) { 8246 if (!this.divContentDone || this.renderingDone) { 8247 return; 8248 } 8249 8250 if (this.textLayerRenderTask) { 8251 this.textLayerRenderTask.cancel(); 8252 this.textLayerRenderTask = null; 8253 } 8254 8255 this.textDivs = []; 8256 var textLayerFrag = document.createDocumentFragment(); 8257 this.textLayerRenderTask = PDFJS.renderTextLayer({ 8258 textContent: this.textContent, 8259 container: textLayerFrag, 8260 viewport: this.viewport, 8261 textDivs: this.textDivs, 8262 timeout: timeout, 8263 enhanceTextSelection: this.enhanceTextSelection, 8264 }); 8265 this.textLayerRenderTask.promise.then(function () { 8266 this.textLayerDiv.appendChild(textLayerFrag); 8267 this._finishRendering(); 8268 this.updateMatches(); 8269 }.bind(this), function (reason) { 8270 // canceled or failed to render text layer -- skipping errors 8271 }); 8272 }, 8273 8274 setTextContent: function TextLayerBuilder_setTextContent(textContent) { 8275 if (this.textLayerRenderTask) { 8276 this.textLayerRenderTask.cancel(); 8277 this.textLayerRenderTask = null; 8278 } 8279 this.textContent = textContent; 8280 this.divContentDone = true; 8281 }, 8282 8283 convertMatches: function TextLayerBuilder_convertMatches(matches, 8284 matchesLength) { 8285 var i = 0; 8286 var iIndex = 0; 8287 var bidiTexts = this.textContent.items; 8288 var end = bidiTexts.length - 1; 8289 var queryLen = (this.findController === null ? 0 : this.findController.state.query.length); 8290 var ret = []; 8291 if (!matches) { 8292 return ret; 8293 } 8294 for (var m = 0, len = matches.length; m < len; m++) { 8295 // Calculate the start position. 8296 var matchIdx = matches[m]; 8297 8298 // Loop over the divIdxs. 8299 while (i !== end && matchIdx >= (iIndex + bidiTexts[i].str.length)) { 8300 iIndex += bidiTexts[i].str.length; 8301 i++; 8302 } 8303 8304 if (i === bidiTexts.length) { 8305 console.error('Could not find a matching mapping'); 8306 } 8307 8308 var match = { 8309 begin: { 8310 divIdx: i,
8311 offset: matchIdx - iIndex 8312 } 8313 }; 8314 8315 // Calculate the end position. 8316 if (matchesLength) { // multiterm search 8317 matchIdx += matchesLength[m]; 8318 } 8319 else { // phrase search 8320 matchIdx += queryLen; 8321 } 8322 8323 // Somewhat the same array as above, but use > instead of >= to get 8324 // the end position right. 8325 while (i !== end && matchIdx > (iIndex + bidiTexts[i].str.length)) { 8326 iIndex += bidiTexts[i].str.length; 8327 i++; 8328 } 8329 8330 match.end = { 8331 divIdx: i, 8332 offset: matchIdx - iIndex 8333 }; 8334 ret.push(match); 8335 } 8336 8337 return ret; 8338 }, 8339 8340 renderMatches: function TextLayerBuilder_renderMatches(matches) { 8341 // Early exit if there is nothing to render. 8342 if (matches.length === 0) { 8343 return; 8344 } 8345 8346 var bidiTexts = this.textContent.items; 8347 var textDivs = this.textDivs; 8348 var prevEnd = null; 8349 var pageIdx = this.pageIdx; 8350 var isSelectedPage = (this.findController === null ? false : (pageIdx === this.findController.selected.pageIdx)); 8351 var selectedMatchIdx = (this.findController === null ? -1 : this.findController.selected.matchIdx); 8352 var highlightAll = (this.findController === null ? false : this.findController.state.highlightAll); 8353 var infinity = { 8354 divIdx: -1, 8355 offset: undefined 8356 }; 8357 8358 function beginText(begin, className) { 8359 var divIdx = begin.divIdx; 8360 textDivs[divIdx].textContent = ''; 8361 appendTextToDiv(divIdx, 0, begin.offset, className); 8362 } 8363 8364 function appendTextToDiv(divIdx, fromOffset, toOffset, className) { 8365 var div = textDivs[divIdx]; 8366 var content = bidiTexts[divIdx].str.substring(fromOffset, toOffset); 8367 var node = document.createTextNode(content); 8368 if (className) { 8369 var span = document.createElement('span'); 8370 span.className = className; 8371 span.appendChild(node); 8372 div.appendChild(span); 8373 return; 8374 } 8375 div.appendChild(node); 8376 } 8377 8378 var i0 = selectedMatchIdx, i1 = i0 + 1; 8379 if (highlightAll) { 8380 i0 = 0; 8381 i1 = matches.length; 8382 } 8383 else if (!isSelectedPage) { 8384 // Not highlighting all and this isn't the selected page, so do nothing. 8385 return; 8386 } 8387 8388 for (var i = i0; i < i1; i++) { 8389 var match = matches[i]; 8390 var begin = match.begin; 8391 var end = match.end; 8392 var isSelected = (isSelectedPage && i === selectedMatchIdx); 8393 var highlightSuffix = (isSelected ? ' selected' : ''); 8394 8395 if (this.findController) { 8396 this.findController.updateMatchPosition(pageIdx, i, textDivs, 8397 begin.divIdx); 8398 } 8399 8400 // Match inside new div. 8401 if (!prevEnd || begin.divIdx !== prevEnd.divIdx) { 8402 // If there was a previous div, then add the text at the end. 8403 if (prevEnd !== null) { 8404 appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); 8405 } 8406 // Clear the divs and set the content until the starting point. 8407 beginText(begin); 8408 } 8409 else { 8410 appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset); 8411 } 8412 8413 if (begin.divIdx === end.divIdx) { 8414 appendTextToDiv(begin.divIdx, begin.offset, end.offset, 8415 'highlight' + highlightSuffix); 8416 } 8417 else { 8418 appendTextToDiv(begin.divIdx, begin.offset, infinity.offset, 8419 'highlight begin' + highlightSuffix); 8420 for (var n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) { 8421 textDivs[n0].className = 'highlight middle' + highlightSuffix; 8422 } 8423 beginText(end, 'highlight end' + highlightSuffix); 8424 } 8425 prevEnd = end; 8426 } 8427 8428 if (prevEnd) { 8429 appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); 8430 } 8431 }, 8432 8433 updateMatches: function TextLayerBuilder_updateMatches() { 8434 // Only show matches when all rendering is done. 8435 if (!this.renderingDone) { 8436 return; 8437 } 8438 8439 // Clear all matches. 8440 var matches = this.matches; 8441 var textDivs = this.textDivs; 8442 var bidiTexts = this.textContent.items; 8443 var clearedUntilDivIdx = -1; 8444 8445 // Clear all current matches. 8446 for (var i = 0, len = matches.length; i < len; i++) { 8447 var match = matches[i]; 8448 var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx); 8449 for (var n = begin, end = match.end.divIdx; n <= end; n++) { 8450 var div = textDivs[n]; 8451 div.textContent = bidiTexts[n].str; 8452 div.className = ''; 8453 } 8454 clearedUntilDivIdx = match.end.divIdx + 1; 8455 } 8456 8457 if (this.findController === null || !this.findController.active) { 8458 return; 8459 } 8460 8461 // Convert the matches on the page controller into the match format 8462 // used for the textLayer. 8463 var pageMatches, pageMatchesLength; 8464 if (this.findController !== null) { 8465 pageMatches = this.findController.pageMatches[this.pageIdx] || null; 8466 pageMatchesLength = (this.findController.pageMatchesLength) 8467 ? this.findController.pageMatchesLength[this.pageIdx] || null : null; 8468 } 8469 8470 this.matches = this.convertMatches(pageMatches, pageMatchesLength); 8471 this.renderMatches(this.matches); 8472 }, 8473 8474 /** 8475 * Fixes text selection: adds additional div where mouse was clicked. 8476 * This reduces flickering of the content if mouse slowly dragged down/up. 8477 * @private 8478 */ 8479 _bindMouse: function TextLayerBuilder_bindMouse() { 8480 var div = this.textLayerDiv; 8481 var self = this; 8482 div.addEventListener('mousedown', function (e) { 8483 if (self.enhanceTextSelection && self.textLayerRenderTask) { 8484 self.textLayerRenderTask.expandTextDivs(true); 8485 return; 8486 } 8487 var end = div.querySelector('.endOfContent'); 8488 if (!end) { 8489 return; 8490 } 8491 // On non-Firefox browsers, the selection will feel better if the height 8492 // of the endOfContent div will be adjusted to start at mouse click 8493 // location -- this will avoid flickering when selections moves up. 8494 // However it does not work when selection started on empty space. 8495 var adjustTop = e.target !== div; 8496 adjustTop = adjustTop && window.getComputedStyle(end).getPropertyValue('-moz-user-select') !== 'none'; 8497 if (adjustTop) { 8498 var divBounds = div.getBoundingClientRect(); 8499 var r = Math.max(0, (e.pageY - divBounds.top) / divBounds.height); 8500 end.style.top = (r * 100).toFixed(2) + '%'; 8501 } 8502 end.classList.add('active'); 8503 }); 8504 div.addEventListener('mouseup', function (e) { 8505 if (self.enhanceTextSelection && self.textLayerRenderTask) { 8506 self.textLayerRenderTask.expandTextDivs(false); 8507 return; 8508 } 8509 var end = div.querySelector('.endOfContent'); 8510 if (!end) { 8511 return; 8512 } 8513 end.style.top = ''; 8514 end.classList.remove('active'); 8515 }); 8516 }, 8517 }; 8518 return TextLayerBuilder; 8519})(); 8520 8521DFLIP.ConvertPageLinks = function () { 8522
8523 var w = arguments[0] / 100, h = arguments[1] / 100; 8524 8525 var toPercent = function (_x, _y, _w, _h, _dest) { 8526 return { 8527 x: _x / w, 8528 y: _y / h, 8529 w: _w / w, 8530 h: _h / h, 8531 dest: _dest 8532 }; 8533 }; 8534 8535 var percents = []; 8536 var input; 8537 8538 for (var index = 2; index < arguments.length; index++) { 8539 input = arguments[index]; 8540 percents[index - 2] = toPercent.apply(this, input); 8541 } 8542 8543 return percents; 8544}; 8545 8546DFLIP.parseLinks = function (links) { 8547 var _links; 8548 if (links != null && links.length > 0) { 8549 for (var index = 0; index < links.length; index++) { 8550 _links = links[index]; 8551 8552 if (_links != null && _links[0] != null && _links[0].dest == null) { 8553 8554 _links = DFLIP.ConvertPageLinks.apply(this, _links); 8555 links[index] = _links; 8556 } 8557 } 8558 } 8559 return links; 8560}; 8561 8562/** 8563 * DFLIP.parseBooks 8564 */ 8565(function ($) { 8566 8567 //php and javascript interpret booleans differently so we use string checks 8568 function isTrue(val) { 8569 return val == "true" || val == true; 8570 } 8571 8572 function checkValues(options) { 8573 8574 //boolean values 8575 if (options.webgl != null) options.webgl = isTrue(options.webgl); 8576 if (options.enableDownload != null) options.enableDownload = isTrue(options.enableDownload); 8577 if (options.search != null) options.search = isTrue(options.search); 8578 if (options.enableAnalytics != null) options.enableAnalytics = isTrue(options.enableAnalytics); 8579 if (options.scrollWheel != null) options.scrollWheel = isTrue(options.scrollWheel); 8580 if (options.autoEnableOutline != null) options.autoEnableOutline = isTrue(options.autoEnableOutline); 8581 if (options.autoEnableThumbnail != null) options.autoEnableThumbnail = isTrue(options.autoEnableThumbnail); 8582 if (options.transparent != null) options.transparent = isTrue(options.transparent); 8583 if (options.overwritePDFOutline != null) options.overwritePDFOutline = isTrue(options.overwritePDFOutline); 8584 if (options.soundEnable != null) options.soundEnable = isTrue(options.soundEnable); 8585 if (options.forceFit != null) options.forceFit = isTrue(options.forceFit); 8586 if (options.enableAnnotation != null) options.enableAnnotation = isTrue(options.enableAnnotation); 8587 if (options.webglShadow != null) options.webglShadow = isTrue(options.webglShadow); 8588 if (options.autoPlay != null) options.autoPlay = isTrue(options.autoPlay); 8589 if (options.autoPlayStart != null) options.autoPlayStart = isTrue(options.autoPlayStart); 8590 8591 //integer value 8592 if (options.paddingTop != null) options.paddingTop = parseInt(options.paddingTop, 10); 8593 if (options.paddingRight != null) options.paddingRight = parseInt(options.paddingRight, 10); 8594 if (options.paddingBottom != null) options.paddingBottom = parseInt(options.paddingBottom, 10); 8595 if (options.paddingLeft != null) options.paddingLeft = parseInt(options.paddingLeft, 10); 8596 if (options.zoomRatio != null) options.zoomRatio = parseFloat(options.zoomRatio, 10); 8597 if (options.stiffness != null) options.stiffness = parseFloat(options.stiffness, 10); 8598 if (options.autoPlayDuration != null) options.autoPlayDuration = parseInt(options.autoPlayDuration, 10); 8599 if (options.linkTarget != null) options.linkTarget = parseInt(options.linkTarget, 10); 8600 8601 if (options.pageMode == 0 || options.pageMode == "0") 8602 options.pageMode = null; 8603 if (options.singlePageMode == 0 || options.singlePageMode == "0") 8604 options.singlePageMode = null; 8605 } 8606 8607 function parseOptions(options) { 8608 8609 //bail out if already parsed or failed 8610 if (options.parsed == true) return; 8611 8612 options.parsed = true; 8613 //options.links are in json format 8614 //{"1":[]} 8615 //convert them to array format 8616 var links = []; 8617 checkValues(options); 8618 8619 if (typeof dFlipWPGlobal !== 'undefined' && options.wpOptions == 'true') { 8620 8621 try { 8622 for (var key in options.links) { 8623 var _pagelinks = options.links[key]; 8624 var pagelink = [100, 100]; 8625 for (var l = 0; l < _pagelinks.length; l++) { 8626 var _link = _pagelinks[l]; 8627 var _values = _link.substr(1).slice(0, -1).split(","); 8628 var _linkarr = []; 8629 for (var v = 0; v < 5; v++) { 8630 _linkarr[v] = _values[v]; 8631 } 8632 pagelink.push(_linkarr); 8633 } 8634 links[parseInt(key, 10) + 1] = pagelink; 8635 } 8636 } catch (error) { 8637 console.error(error.stack); 8638 } 8639 options.links = DFLIP.parseLinks(links); 8640 8641 } 8642 else { 8643 options.links = DFLIP.parseLinks(options.links); 8644 } 8645 8646 } 8647 8648 DFLIP.getOptions = function (book) { 8649 8650 book = $(book); 8651 8652 var book_id = book.attr("id"); 8653 8654 var options = "option_" + book_id, 8655 source = book.attr("source") || book.attr("df-source"); 8656 8657 //verify and optimize the values 8658 options = options == null || options == "" || window[options] == null ? {} : window[options]; 8659 8660 options.source = source == null || source == "" ? options.source : source; 8661 8662 /*As of 1.2.6 attribute values are also considered as options in some cases*/ 8663 var attrOptions = { 8664 webgl: book.attr("webgl"), 8665 height: book.attr("height"), 8666 soundEnable: book.attr("sound"), 8667 bookTitle: book.attr("title"), 8668 transparent: book.attr("transparent"), 8669 enableDownload: book.attr("download"), 8670 search: book.attr("search"), 8671 duration: book.attr("duration"), 8672 hard: book.attr("hard"), 8673 openPage: book.data("page"), 8674 pageMode: book.attr("pagemode"), 8675 direction: book.attr("direction"), 8676 backgroundColor: book.attr("backgroundcolor"), 8677 scrollWheel: book.attr("scrollwheel"), 8678 backgroundImage: book.attr("backgroundimage"), 8679 paddingTop: book.attr("paddingtop"), 8680 paddingRight: book.attr("paddingright"), 8681 paddingBottom: book.attr("paddingbottom"), 8682 paddingLeft: book.attr("paddingleft"), 8683 wpOptions: book.attr("wpoptions") 8684 }; 8685 8686 options = $.extend(true, {}, options, attrOptions); 8687 8688 parseOptions(options); 8689 8690 return options; 8691 } 8692 8693 DFLIP.parseBooks = function () { 8694 8695 $('._df_button, ._df_thumb, ._df_custom, ._df_book').each(function () { 8696 8697 var book = $(this); 8698 8699 //fetch any existing values 8700 var parsed = book.attr("parsed") || book.attr("df-parsed"); 8701 8702 //skip if already parsed or failed 8703 if (parsed !== "true") { 8704 book.attr("df-parsed", "true") 8705 8706 if (book.hasClass("_df_book")) { 8707 8708 var book_id = book.attr("id"), 8709 slug = book.attr("slug"); 8710 var options = DFLIP.getOptions(book); 8711 options.id = book_id; 8712 if (slug != null) 8713 options.slug = slug; 8714 if (book_id) { 8715 window[book_id.toString()] = $(book).flipBook(options.source, options); 8716 } 8717 else { 8718 $(book).flipBook(options.source, options); 8719 } 8720 8721 } 8722 else { 8723 8724 if (book.hasClass("_df_thumb")) { 8725 var wrapper = $("<div class='_df_book-cover'>"); 8726 8727 var text = book.html().trim(); 8728 book.html(""); 8729 var title = $("<span class='_df_book-title'>").html(text).appendTo(wrapper); 8730 8731 var thumb = book.attr("thumb") || book.attr("df-thumb"), 8732 thumbType = book.attr("thumbtype") || DFLIP.defaults.thumbElement || "div", 8733 tags = book.attr("tags") || book.attr("df-tags"); 8734 8735 if (tags) { 8736 tags = tags.split(","); 8737 8738 if (tags.length > 0) { 8739 for (var tagcount = 0; tagcount < tags.length; tagcount++) { 8740 book.append("<span class='_df_book-tag'>" + tags[tagcount] + "</span>"); 8741 } 8742 } 8743 } 8744 8745 if (thumb != null && thumb.toString().trim() != '') { 8746 if (thumbType == 'img') { 8747 wrapper.append('<img src="' + thumb + '" alt="' + text
8747+ '"/>'); 8748 book.attr("thumb-type", "img"); 8749 } 8750 else { 8751 wrapper.css({ 8752 backgroundImage: "url('" + thumb + "')" 8753 }); 8754 } 8755 } 8756 else { 8757 wrapper.addClass("_df_thumb-not-found"); 8758 } 8759 8760 book.append(wrapper); 8761 } 8762 8763 } 8764 8765 } 8766 }); 8767 8768 }; 8769 8770 $(document).ready(function () { 8771 8772 //Autodetection if the folder structure is copied properly 8773 if (typeof dFlipLocation == 'undefined' && DFLIP.autoDetectLocation != false) { 8774 $("script").each(function () { 8775 var src = $(this)[0].src; 8776 if ((src.indexOf("/dflip.js") > -1 || src.indexOf("/dflip.min.js") > -1) 8777 && (src.indexOf("https://") > -1 || src.indexOf("http://") > -1) && src.indexOf("js/dflip.") > -1) { 8778 var splits = src.split("/"); 8779 window.dFlipLocation = splits.slice(0, -2).join("/"); 8780 } 8781 }); 8782 } 8783 8784 if (typeof dFlipLocation !== 'undefined') { 8785 8786 //add ending forward slash trail for safety 8787 if (dFlipLocation.length > 2 && dFlipLocation.slice(-1) !== "/") { 8788 window.dFlipLocation += "/"; 8789 } 8790 8791 //PRESENTATION.defaults.backgroundImage = "blank"; "images/textures/white.jpg"; 8792 //PRESENTATION.defaults.textureLoadFallback = dFlipLocation + "images/textures/white.jpg"; 8793 DFLIP.defaults.mockupjsSrc = dFlipLocation + "js/libs/mockup.min.js"; 8794 DFLIP.defaults.pdfjsSrc = dFlipLocation + "js/libs/pdf.min.js"; 8795 DFLIP.defaults.pdfjsCompatibilitySrc = dFlipLocation + "js/libs/compatibility.js"; 8796 DFLIP.defaults.threejsSrc = dFlipLocation + "js/libs/three.min.js"; 8797 DFLIP.defaults.pdfjsWorkerSrc = dFlipLocation + "js/libs/pdf.worker.min.js"; 8798 DFLIP.defaults.soundFile = dFlipLocation + "sound/turn2.mp3"; 8799 DFLIP.defaults.imagesLocation = dFlipLocation + "images"; 8800 DFLIP.defaults.imageResourcesPath = dFlipLocation + "images/pdfjs/"; 8801 DFLIP.defaults.cMapUrl = dFlipLocation + "js/libs/cmaps/"; 8802 8803 if (typeof dFlipWPGlobal !== 'undefined') { 8804 8805 checkValues(dFlipWPGlobal); 8806 8807 $.extend(DFLIP.defaults, dFlipWPGlobal); 8808 } 8809 } 8810 8811 DFLIP.preParseHash = window.location.hash; 8812 DFLIP.parseBooks(); 8813 8814 $('body').on('click', '._df_button, ._df_thumb, ._df_custom', function (event) { 8815 //incase the element is link type 8816 event.preventDefault(); 8817 //cache the book element 8818 var book = $(this); 8819 8820 if (!window.dfLightBox) { 8821 window.dfLightBox = new DFLightBox(function () { 8822 8823 if (window.location.hash.indexOf("#dflip-") == 0) 8824 window.location.hash = "#_"; 8825 window.dfActiveLightBoxBook.analytics({ 8826 eventAction: "Book Closed", 8827 options: window.dfActiveLightBoxBook.options 8828 }); 8829 window.dfActiveLightBoxBook.dispose(); 8830 window.dfActiveLightBoxBook = null; 8831 }); 8832 } 8833 8834 window.dfLightBox.duration = 500; 8835 8836 if (window.dfActiveLightBoxBook && window.dfActiveLightBoxBook.dispose) { 8837 window.dfActiveLightBoxBook.dispose(); 8838 8839 } 8840 else { 8841 window.dfLightBox.show( 8842 function () { 8843 // $("body").addClass("df-no-scroll"); 8844 var options = DFLIP.getOptions(book); 8845 options.transparent = false; 8846 options.height = "100%"; 8847 options.id = book.attr("id"); 8848 var slug = book.attr("slug"); 8849 if (slug != null) 8850 options.slug = slug; 8851 options.isLightBox = true; 8852 window.dfActiveLightBoxBook = $(window.dfLightBox.container).flipBook(options.source, options); 8853 } 8854 ); 8855 } 8856 8857 8858 }); 8859 8860 if (DFLIP.utils.isSafari || DFLIP.utils.isIOS) { 8861 $('body').addClass("df-webkit"); 8862 } 8863 //parse hash and check if any exists 8864 if (DFLIP.preParseHash && DFLIP.preParseHash.indexOf('dflip-') >= 0) { 8865 var id = DFLIP.preParseHash.split('dflip-')[1].split('/')[0]; 8866 var page = DFLIP.preParseHash.split('dflip-')[1].split('/')[1]; 8867 if (page != null) { 8868 page = page.split('/')[0]; 8869 } 8870 var book; 8871 //first check for slug pattern 8872 book = $("[slug=" + id + "]"); 8873 //then id pattern 8874 if (book.length == 0) book = $('#' + id); 8875 8876 if (book.length > 0) { 8877 8878 //var oldHash = window.location.hash; 8879 //window.location.hash = id; 8880 //window.location.hash = DFLIP.preParseHash; 8881 8882 if (page != null) { 8883 book.data("page", page) 8884 } 8885 8886 if (book.is('._df_button, ._df_thumb, ._df_custom')) { 8887 book.trigger("click"); 8888 } 8889 } 8890 } 8891 8892 $('body').on('click', '.df-ui-sidemenu-close', function () { 8893 var $this = $(this); 8894 $this.closest(".df-container").find(".df-ui-outline.df-active , .df-ui-thumbn
8894ail.df-active").trigger("click"); 8895 }); 8896 8897 8898 }); 8899 8900})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.