(function () { 'use strict'; var definePinchZoom = function ($) { var PinchZoom = function (el, options, viewerContainer) { this.el = $(el); this.viewerContainer = viewerContainer; this.zoomFactor = 1; this.lastScale = 1; this.offset = { x: 0, y: 0 }; this.options = $.extend({}, this.defaults, options); this.setupMarkup(); this.bindEvents(); this.update(); // default enable. this.enable(); this.height = 0; this.load = false; this.direction = null; this.clientY = null; this.lastclientY = null; }, sum = function (a, b) { return a + b; }, isCloseTo = function (value, expected) { return value > expected - 0.01 && value < expected + 0.01; }; PinchZoom.prototype = { defaults: { tapZoomFactor: 2, zoomOutFactor: 1.2, animationDuration: 300, maxZoom: 4, minZoom: 0.8, lockDragAxis: false, use2d: true, zoomStartEventName: 'pz_zoomstart', zoomEndEventName: 'pz_zoomend', dragStartEventName: 'pz_dragstart', dragEndEventName: 'pz_dragend', doubleTapEventName: 'pz_doubletap' }, /** * Event handler for 'dragstart' * @param event */ handleDragStart: function (event) { this.el.trigger(this.options.dragStartEventName); this.stopAnimation(); this.lastDragPosition = false; this.hasInteraction = true; this.handleDrag(event); }, /** * Event handler for 'drag' * @param event */ handleDrag: function (event) { if (this.zoomFactor > 1.0) { var touch = this.getTouches(event)[0]; this.drag(touch, this.lastDragPosition, event); this.offset = this.sanitizeOffset(this.offset); this.lastDragPosition = touch; } }, handleDragEnd: function () { this.el.trigger(this.options.dragEndEventName); this.end(); }, /** * Event handler for 'zoomstart' * @param event */ handleZoomStart: function (event) { this.el.trigger(this.options.zoomStartEventName); this.stopAnimation(); this.lastScale = 1; this.nthZoom = 0; this.lastZoomCenter = false; this.hasInteraction = true; }, /** * Event handler for 'zoom' * @param event */ handleZoom: function (event, newScale) { // a relative scale factor is used var touchCenter = this.getTouchCenter(this.getTouches(event)), scale = newScale / this.lastScale; this.lastScale = newScale; // the first touch events are thrown away since they are not precise this.nthZoom += 1; if (this.nthZoom > 3) { this.scale(scale, touchCenter); this.drag(touchCenter, this.lastZoomCenter); } this.lastZoomCenter = touchCenter; }, handleZoomEnd: function () { this.el.trigger(this.options.zoomEndEventName); this.end(); }, /** * Event handler for 'doubletap' * @param event */ handleDoubleTap: function (event) { var center = this.getTouches(event)[0], zoomFactor = this.zoomFactor > 1 ? 1 : this.options.tapZoomFactor, startZoomFactor = this.zoomFactor, updateProgress = (function (progress) { this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center); }).bind(this); if (this.hasInteraction) { return; } if (startZoomFactor > zoomFactor) { center = this.getCurrentZoomCenter(); } this.animate(this.options.animationDuration, updateProgress, this.swing); this.el.trigger(this.options.doubleTapEventName); }, /** * Max / min values for the offset * @param offset * @return {Object} the sanitized offset */ sanitizeOffset: function (offset) { var maxX = (this.zoomFactor - 1) * this.getContainerX(), maxY = (this.zoomFactor - 1) * this.getContainerY(), maxOffsetX = Math.max(maxX, 0), maxOffsetY = Math.max(maxY, 0), minOffsetX = Math.min(maxX, 0), minOffsetY = Math.min(maxY, 0); var x = Math.min(Math.max(offset.x, minOffsetX), maxOffsetX), y = Math.min(Math.max(offset.y, minOffsetY), maxOffsetY); return { x: x, y: y }; }, /** * Scale to a specific zoom factor (not relative) * @param zoomFactor * @param center */ scaleTo: function (zoomFactor, center) { this.scale(zoomFactor / this.zoomFactor, center); }, /** * Scales the element from specified center * @param scale * @param center */ scale: function (scale, center) { scale = this.scaleZoomFactor(scale); this.addOffset({ x: (scale - 1) * (center.x + this.offset.x), y: (scale - 1) * (center.y + this.offset.y) }); }, /** * Scales the zoom factor relative to current state * @param scale * @return the actual scale (can differ because of max min zoom factor) */ scaleZoomFactor: function (scale) { var originalZoomFactor = this.zoomFactor; this.zoomFactor *= scale; this.zoomFactor = Math.min(this.options.maxZoom, Math.max(this.zoomFactor, this.options.minZoom)); return this.zoomFactor / originalZoomFactor; }, /** * Drags the element * @param center * @param lastCenter */ drag: function (center, lastCenter, event) { if (lastCenter) { if (this.options.lockDragAxis) { // lock scroll to position that was changed the most if (Math.abs(center.x - lastCenter.x) > Math.abs(center.y - lastCenter.y)) { this.addOffset({ x: -(center.x - lastCenter.x), y: 0 }); } else { this.addOffset({ y: -(center.y - lastCenter.y), x: 0 }); } } else { if (center.y - lastCenter.y < 0) { this.direction = "down"; } else if (center.y - lastCenter.y > 10) { this.direction = "up"; } this.addOffset({ y: -(center.y - lastCenter.y), x: -(center.x - lastCenter.x) }); } } }, /** * Calculates the touch center of multiple touches * @param touches * @return {Object} */ getTouchCenter: function (touches) { return this.getVectorAvg(touches); }, /** * Calculates the average of multiple vectors (x, y values) */ getVectorAvg: function (vectors) { return { x: vectors.map(function (v) { return v.x; }).reduce(sum) / vectors.length, y: vectors.map(function (v) { return v.y; }).reduce(sum) / vectors.length }; }, /** * Adds an offset * @param offset the offset to add * @return return true when the offset change was accepted */ addOffset: function (offset) { this.offset = { x: this.offset.x + offset.x, y: this.offset.y + offset.y }; }, sanitize: function () { if (this.zoomFactor < this.options.zoomOutFactor) { this.zoomOutAnimation(); } else if (this.isInsaneOffset(this.offset)) { this.sanitizeOffsetAnimation(); } }, /** * Checks if the offset is ok with the current zoom factor * @param offset * @return {Boolean} */ isInsaneOffset: function (offset) { var sanitizedOffset = this.sanitizeOffset(offset); return sanitizedOffset.x !== offset.x || sanitizedOffset.y !== offset.y; }, /** * Creates an animation moving to a sane offset */ sanitizeOffsetAnimation: function () { var targetOffset = this.sanitizeOffset(this.offset), startOffset = { x: this.offset.x, y: this.offset.y }, updateProgress = (function (progress) { this.offset.x = startOffset.x + progress * (targetOffset.x - startOffset.x); this.offset.y = startOffset.y + progress * (targetOffset.y - startOffset.y); this.update(); }).bind(this); this.animate( this.options.animationDuration, updateProgress, this.swing ); }, /** * Zooms back to the original position, * (no offset and zoom factor 1) */ zoomOutAnimation: function () { var startZoomFactor = this.zoomFactor, zoomFactor = 1, center = this.getCurrentZoomCenter(), updateProgress = (function (progress) { this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center); }).bind(this); this.animate( this.options.animationDuration, updateProgress, this.swing ); }, /** * Updates the aspect ratio */ updateAspectRatio: function () { this.setContainerY(this.getContainerX() / this.getAspectRatio()); }, /** * Calculates the initial zoom factor (for the element to fit into the container) * @return the initial zoom factor */ getInitialZoomFactor: function () { // use .offsetWidth instead of width() // because jQuery-width() return the original width but Zepto-width() will calculate width with transform. // the same as .height() if(this.container[0] && this.el[0]){ return this.container[0].offsetWidth / this.el[0].offsetWidth; }else { return 0 } }, /** * Calculates the aspect ratio of the element * @return the aspect ratio */ getAspectRatio: function () { if(this.el[0]){ var offsetHeight = this.el[0].offsetHeight; return this.container[0].offsetWidth / offsetHeight; }else { return 0 } }, /** * Calculates the virtual zoom center for the current offset and zoom factor * (used for reverse zoom) * @return {Object} the current zoom center */ getCurrentZoomCenter: function () { // uses following formula to calculate the zoom center x value // offset_left / offset_right = zoomcenter_x / (container_x - zoomcenter_x) var length = this.container[0].offsetWidth * this.zoomFactor, offsetLeft = this.offset.x, offsetRight = length - offsetLeft - this.container[0].offsetWidth, widthOffsetRatio = offsetLeft / offsetRight, centerX = widthOffsetRatio * this.container[0].offsetWidth / (widthOffsetRatio + 1), // the same for the zoomcenter y height = this.container[0].offsetHeight * this.zoomFactor, offsetTop = this.offset.y, offsetBottom = height - offsetTop - this.container[0].offsetHeight, heightOffsetRatio = offsetTop / offsetBottom, centerY = heightOffsetRatio * this.container[0].offsetHeight / (heightOffsetRatio + 1); // prevents division by zero if (offsetRight === 0) { centerX = this.container[0].offsetWidth; } if (offsetBottom === 0) { centerY = this.container[0].offsetHeight; } return { x: centerX, y: centerY }; }, canDrag: function () { return !isCloseTo(this.zoomFactor, 1); }, /** * Returns the touches of an event relative to the container offset * @param event * @return array touches */ getTouches: function (event) { var position = this.container.offset(); return Array.prototype.slice.call(event.touches).map(function (touch) { return { x: touch.pageX - position.left, y: touch.pageY - position.top }; }); }, /** * Animation loop * does not support simultaneous animations * @param duration * @param framefn * @param timefn * @param callback */ animate: function (duration, framefn, timefn, callback) { var startTime = new Date().getTime(), renderFrame = (function () { if (!this.inAnimation) { return; } var frameTime = new Date().getTime() - startTime, progress = frameTime / duration; if (frameTime >= duration) { framefn(1); if (callback) { callback(); } this.update(); this.stopAnimation(); this.update(); } else { if (timefn) { progress = timefn(progress); } framefn(progress); this.update(); requestAnimationFrame(renderFrame); } }).bind(this); this.inAnimation = true; requestAnimationFrame(renderFrame); }, /** * Stops the animation */ stopAnimation: function () { this.inAnimation = false; }, /** * Swing timing function for animations * @param p * @return {Number} */ swing: function (p) { return -Math.cos(p * Math.PI) / 2 + 0.5; }, getContainerX: function () { if(this.el[0]){ return this.el[0].offsetWidth; }else { return 0; } }, getContainerY: function () { return this.el[0].offsetHeight; }, setContainerY: function (y) { y = y.toFixed(2); return this.container.height(y); }, /** * Creates the expected html structure */ setupMarkup: function () { this.container = $('
'); this.el.before(this.container); this.container.append(this.el); this.container.css({ 'position': 'relative', // 'width':'auto', // 'height':'auto' }); // Zepto doesn't recognize `webkitTransform..` style this.el.css({ '-webkit-transform-origin': '0% 0%', '-moz-transform-origin': '0% 0%', '-ms-transform-origin': '0% 0%', '-o-transform-origin': '0% 0%', 'transform-origin': '0% 0%', 'position': 'relative' }); }, end: function () { this.hasInteraction = false; this.sanitize(); this.update(); }, /** * Binds all required event listeners */ bindEvents: function () { detectGestures(this.container.eq(0), this, this.viewerContainer); // Zepto and jQuery both know about `on` $(window).on('resize', this.update.bind(this)); $(this.el).find('img').on('load', this.update.bind(this)); }, /** * Updates the css values according to the current zoom factor and offset */ update: function () { if (this.updatePlaned) { return; } this.updatePlaned = true; setTimeout((function () { this.updatePlaned = false; this.updateAspectRatio(); var zoomFactor = this.getInitialZoomFactor() * this.zoomFactor, offsetX = (-this.offset.x / zoomFactor).toFixed(3), offsetY = (-this.offset.y / zoomFactor).toFixed(3); this.lastclientY = offsetY; var transform3d = 'scale3d(' + zoomFactor + ', ' + zoomFactor + ',1) ' + 'translate3d(' + offsetX + 'px,' + offsetY + 'px,0px)', transform2d = 'scale(' + zoomFactor + ', ' + zoomFactor + ') ' + 'translate(' + offsetX + 'px,' + offsetY + 'px)', removeClone = (function () { if (this.clone) { this.clone.remove(); delete this.clone; } }).bind(this); // Scale 3d and translate3d are faster (at least on ios) // but they also reduce the quality. // PinchZoom uses the 3d transformations during interactions // after interactions it falls back to 2d transformations if (!this.options.use2d || this.hasInteraction || this.inAnimation) { this.is3d = true; // removeClone(); this.el.css({ '-webkit-transform': transform3d, '-o-transform': transform2d, '-ms-transform': transform2d, '-moz-transform': transform2d, 'transform': transform3d }); } else { // When changing from 3d to 2d transform webkit has some glitches. // To avoid this, a copy of the 3d transformed element is displayed in the // foreground while the element is converted from 3d to 2d transform if (this.is3d) { // this.clone = this.el.clone(); // this.clone.css('pointer-events', 'none'); // this.clone.appendTo(this.container); // setTimeout(removeClone, 200); } this.el.css({ '-webkit-transform': transform2d, '-o-transform': transform2d, '-ms-transform': transform2d, '-moz-transform': transform2d, 'transform': transform2d }); this.is3d = false; } this.done && this.done.call(this, zoomFactor) }).bind(this), 0); }, /** * Enables event handling for gestures */ enable: function () { this.enabled = true; }, /** * Disables event handling for gestures */ disable: function () { this.enabled = false; }, //销毁还原 destroy: function () { var dom = this.el.clone(); var p = this.container.parent(); this.container.remove(); dom.removeAttr('style'); p.append(dom); } }; var detectGestures = function (el, target, viewerContainer) { var interaction = null, fingers = 0, lastTouchStart = null, startTouches = null, lastTouchY = null, clientY = null, lastclientY = 0, lastTop = 0, setInteraction = function (newInteraction, event) { if (interaction !== newInteraction) { if (interaction && !newInteraction) { switch (interaction) { case "zoom": target.handleZoomEnd(event); break; case 'drag': target.handleDragEnd(event); break; } } switch (newInteraction) { case 'zoom': target.handleZoomStart(event); break; case 'drag': target.handleDragStart(event); break; } } interaction = newInteraction; }, updateInteraction = function (event) { if (fingers === 2) { setInteraction('zoom'); } else if (fingers === 1 && target.canDrag()) { setInteraction('drag', event); } else { setInteraction(null, event); } }, targetTouches = function (touches) { return Array.prototype.slice.call(touches).map(function (touch) { return { x: touch.pageX, y: touch.pageY }; }); }, getDistance = function (a, b) { var x, y; x = a.x - b.x; y = a.y - b.y; return Math.sqrt(x * x + y * y); }, calculateScale = function (startTouches, endTouches) { var startDistance = getDistance(startTouches[0], startTouches[1]), endDistance = getDistance(endTouches[0], endTouches[1]); return endDistance / startDistance; }, cancelEvent = function (event) { event.stopPropagation(); event.preventDefault(); }, detectDoubleTap = function (event) { var time = (new Date()).getTime(); var pageY = event.changedTouches[0].pageY; var top = parentNode.scrollTop || 0; if (fingers > 1) { lastTouchStart = null; lastTouchY = null; cancelEvent(event); } if (time - lastTouchStart < 300 && Math.abs(pageY - lastTouchY) < 10 && Math.abs(lastTop - top) < 10) { cancelEvent(event); target.handleDoubleTap(event); switch (interaction) { case "zoom": target.handleZoomEnd(event); break; case 'drag': target.handleDragEnd(event); break; } } if (fingers === 1) { lastTouchStart = time; lastTouchY = pageY; lastTop = top; } }, firstMove = true; if(viewerContainer){ var parentNode = viewerContainer[0]; } if (parentNode) { parentNode.addEventListener('touchstart', function (event) { if (target.enabled) { firstMove = true; fingers = event.touches.length; detectDoubleTap(event); clientY = event.changedTouches[0].clientY; if (fingers > 1) { cancelEvent(event); } } }); parentNode.addEventListener('touchmove', function (event) { if (target.enabled) { lastclientY = event.changedTouches[0].clientY; if (firstMove) { updateInteraction(event); if (interaction) { // cancelEvent(event); } startTouches = targetTouches(event.touches); } else { switch (interaction) { case 'zoom': target.handleZoom(event, calculateScale(startTouches, targetTouches(event.touches))); break; case 'drag': target.handleDrag(event); break; } if (interaction) { // cancelEvent(event); target.update(lastclientY); } } if (fingers > 1) { cancelEvent(event); } firstMove = false; } }); parentNode.addEventListener('touchend', function (event) { if (target.enabled) { fingers = event.touches.length; if (fingers > 1) { cancelEvent(event); } updateInteraction(event); } }); } }; return PinchZoom; }; var PinchZoom = definePinchZoom($); var Pdfh5 = function (dom, options) { this.container = $(dom); this.currentNum = 1; //当前页数从1开始 this.thePDF = null; this.pdfRender = null; this.totalNum = null; this.pdfLoaded = false; this.pages = null; this.initTime = 0; this.startTime = 0; this.endTime = 0; this.renderTime = 0; this.timer = null; this.loadWidth = 1; this.docWidth = document.documentElement.clientWidth; this.init(options); }; Pdfh5.prototype = { init: function (options) { var self = this; if (self.pdfLoaded) { return; } this.initTime = new Date().getTime(); setTimeout(function () { self.start && self.start(self.initTime) }, 0) options = options ? options : {}; options.pdfurl = options.pdfurl ? options.pdfurl : null; options.data = options.data ? options.data : null; var html = '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + ' 1/' + '1' + '
' + '
' + '
' + '
' + '
' ; if (!this.container.find('.pageNum')[0]) { this.container.append(html); } var viewer = document.createElement("div"); viewer.className = 'pdfViewer'; var viewerContainer = document.createElement("div"); viewerContainer.className = 'viewerContainer'; viewerContainer.appendChild(viewer); this.container.append(viewerContainer); this.viewer = $(viewer); this.viewerContainer = $(viewerContainer); this.pageNum = this.container.find('.pageNum'); this.pageNow = this.pageNum.find('.pageNow'); this.pageTotal = this.pageNum.find('.pageTotal'); this.loadingBar = this.container.find('.loadingBar'); this.progress = this.loadingBar.find('.progress'); this.backTop = this.container.find('.backTop'); this.loading = this.container.find('.loadEffect'); var height = document.documentElement.clientHeight * (1 / 3); viewerContainer.addEventListener('scroll', function () { var scrollTop = viewerContainer.scrollTop; if (scrollTop >= 150) { if(self.backTop){ self.backTop.show(); } } else { if(self.backTop){ self.backTop.fadeOut(200); } } if(self.viewerContainer){ self.pages = self.viewerContainer.find('.page'); } clearTimeout(self.timer); if(self.pageNum){ self.pageNum.show(); } if(self.pages){ self.pages.each(function (index, obj) { var top = obj.getBoundingClientRect().top; var bottom = obj.getBoundingClientRect().bottom; if (top <= height && bottom > height) { if(self.pageNum){ self.pageNow.text(index + 1) } } }) } self.timer = setTimeout(function () { if(self.pageNum){ self.pageNum.fadeOut(200); } }, 1500) self.scroll && self.scroll(scrollTop); }) this.backTop.on('click tap', function () { var mart = self.viewer.css('transform'); var arr = mart.replace(/[a-z\(\)\s]/g, '').split(','); var s1 = arr[0]; var s2 = arr[3]; var x = arr[4] / 2; var left = self.viewer[0].getBoundingClientRect().left; if (left <= -self.docWidth * 2) { x = -self.docWidth / 2 } self.viewer.css({ transform: 'scale(' + s1 + ', ' + s2 + ') translate(' + x + 'px, 0px)' }) if (self.PinchZoom) { self.PinchZoom.offset.y = 0; self.PinchZoom.lastclientY = 0; } self.viewerContainer.animate({ scrollTop: 0 }, 300) }) //获取url带的参数地址 function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if (r != null) return decodeURIComponent(r[2]); return ""; } var pdfurl = GetQueryString("file"); if (pdfurl) { getDoc(pdfurl) } else if(options.pdfurl){ getDoc(options.pdfurl) } else { setTimeout(function () { var time = new Date().getTime(); self.endTime = time - self.initTime; self.complete && self.complete("error", "文件路径不能为空", self.endTime) self.error && self.error("error", "文件路径不能为空", self.endTime) }, 0) } function getDoc(array) { if (self.pdfLoaded) { return; } pdfjsLib.getDocument(array).then(function (pdf) { if (self.pdfLoaded) { return; } self.thePDF = pdf; self.totalNum = pdf.numPages; self.thePDF.getPage(1).then(handlePages); self.pageTotal.text(self.totalNum) var time = new Date().getTime(); self.startTime = time - self.initTime; self.renderStart && self.renderStart(self.startTime) }).catch(function (err) { var time = new Date().getTime(); self.endTime = time - self.initTime; self.complete && self.complete("error", err.responseText, self.endTime) self.error && self.error("error", err.responseText, self.endTime) }) } function handlePages(page) { if (self.pdfLoaded) { return; } if (!options || !options.scale) { if (self.totalNum === 1) { options.scale = 1.8 } else { options.scale = 2.5 // options.scale = 1.8 } } if (options && options.defalutScale) { if (self.totalNum === 1) { options.scale = options.defalutScale // options.scale = 1.8 } else { options.scale = 2.5 // options.scale = 1.8 } } var viewport = page.getViewport(options.scale); var canvas = document.createElement("canvas"); var winRatio = ($(window).width() / viewport.width) * 1; var obj = { 'Cheight': viewport.height * winRatio, 'width': viewport.width, 'height': viewport.height, 'canvas': canvas, 'index': self.currentNum } var context = canvas.getContext('2d'); canvas.height = viewport.height; canvas.width = viewport.width; //在canvas上绘制 self.pdfRender = page.render({ canvasContext: context, viewport: viewport }); obj.src = obj.canvas.toDataURL("image/jpeg"); self.pdfRender.promise.then(function () { self.render(obj); }).then(function () { //开始下一页到绘制 self.currentNum++; if (!self.pdfLoaded && self.thePDF && self.currentNum <= self.totalNum) { self.thePDF.getPage(self.currentNum).then(handlePages); } else { self.pdfLoaded = true; if (self.viewerContainer) { self.pages = self.viewerContainer.find('.page'); } self.currentNum = self.totalNum; var time = new Date().getTime(); self.endTime = time - self.initTime; if (self.progress) { self.progress.css({ width: "100%" }) } if (self.loadingBar) { self.loadingBar.fadeOut(200); } self.renderEnd && self.renderEnd(self.endTime) self.complete && self.complete("success", "PDF解析完毕", self.endTime) self.success && self.success("success", "PDF解析完毕", self.endTime) self.PinchZoom = new PinchZoom(self.viewer, {}, self.viewerContainer); self.PinchZoom.done = function (scale) { if (scale == 1) { if (self.viewerContainer) { self.viewerContainer.css({ '-webkit-overflow-scrolling': 'touch' }) } } else { if (self.viewerContainer) { self.viewerContainer.css({ '-webkit-overflow-scrolling': 'auto' }) } } self.zoomChange && self.zoomChange(scale) } } }).catch(function(err){ console.log(err) }) } }, render: function (obj) { if (this.pdfLoaded) { return; } var img = new Image(); var time = new Date().getTime(); var time2 = 0; if (this.renderTime == 0) { time2 = time - this.startTime } else { time2 = time - this.renderTime } obj.src = obj.canvas.toDataURL("image/jpeg"); img.src = obj.src; var page = document.createElement("div"); page.className = "page page" + obj.index; page.setAttribute('data-index', obj.index); $(page).css({ 'max-width': obj.width }) page.appendChild(img); if (this.viewer) { this.viewer.append(page); } if (this.currentNum == 1) { this.loadWidth = 100 / this.totalNum; if (this.loadingBa) { this.loadingBar.show(); } if (this.loading) { this.loading.fadeOut(200); } } if (this.progress) { this.progress.css({ width: this.loadWidth * this.currentNum + "%" }) } this.renderPages && this.renderPages(page, time - this.initTime, time2) this.renderTime = time; }, show: function (callback) { this.container.show(); callback && callback.call(this) }, hide: function (callback) { this.container.hide() callback && callback.call(this) }, reset: function (callback) { if (this.PinchZoom) { this.PinchZoom.offset.y = 0; this.PinchZoom.offset.x = 0; this.PinchZoom.lastclientY = 0; this.PinchZoom.zoomFactor = 1; this.PinchZoom.update(); } if (this.viewerContainer) { this.viewerContainer.scrollTop(0); } callback && callback.call(this) }, destroy: function (callback) { var self = this; this.reset(); if(this.thePDF){ this.thePDF.destroy(); this.thePDF = null; } if(this.pdfRender){ this.pdfRender.cancel(); this.pdfRender = null; } if(this.viewerContainer){ this.viewerContainer.remove(); this.viewerContainer = null; } if(this.container){ this.container.html(''); this.container = null; } this.backTop.off('tap'); this.backTop.off('click'); this.pdfLoaded = true; this.currentNum = 1; this.totalNum = null; this.pages = null; this.initTime = 0; this.startTime = 0; this.endTime = 0; this.renderTime = 0; this.viewer = null; this.pageNum = null; this.pageNow = null; this.pageTotal = null; this.loadingBar = null; this.progress = null; this.loading = null; this.timer = null; this.loadWidth = 1; this.show = null; this.hide = null; callback && callback.call(this) } } if (typeof define !== 'undefined' && define.amd) { define(['jquery'], function ($) { return Pdfh5 }); } else { window.Pdfh5 = Pdfh5 } }).call(this);