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