1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162 |
- (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 = $('<div class="pinch-zoom-container"></div>');
- 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 = '<div class="loadingBar">' +
- '<div class="progress">' +
- ' <div class="glimmer">' +
- '</div>' +
- ' </div>' +
- '</div>' +
- '<div class="pageNum">' +
- '<div class="pageNum-bg"></div>' +
- ' <div class="pageNum-num">' +
- ' <span class="pageNow">1</span>/' +
- '<span class="pageTotal">1</span>' +
- '</div>' +
- ' </div>' +
- '<div class="backTop">' +
- '</div>' +
- '<div class="loadEffect"></div>'
- ;
- 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);
|