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