使用pdfjs实现pdf预览,但是pdfjs本身不支持手势缩放。现两种方式实现PDF手势缩放。
1、调用pdfjs原生方法实现
- 在/pdfjs/web/viewer.html 页面添加如下代码。
- 此方法缩放时有卡顿,不够丝滑。
<script type="text/javascript">
var touchState = null; //记录触屏手势触点信息的对象
//绑定触屏事件
function addPinchListener() {
let element = document.getElementById("viewerContainer");
element.addEventListener("touchstart", onTouchStart, false);
element.addEventListener("touchmove", onTouchMove, false);
element.addEventListener("touchend", onTouchEnd, false);
}
//记录触屏触点坐标 记录起始和结束点
function onTouchStart(evt) {
touchState = {
//多点触屏的第一点
startX: evt.touches[0].pageX,
startY: evt.touches[0].pageY,
endX: evt.touches[0].pageX,
endY: evt.touches[0].pageY,
//多点触屏的第二点 单点触屏时记录坐标为 -1
startX2: evt.touches[1] ? evt.touches[1].pageX : -1,
startY2: evt.touches[1] ? evt.touches[1].pageY : -1,
endX2: evt.touches[1] ? evt.touches[1].pageX : -1,
endY2: evt.touches[1] ? evt.touches[1].pageY : -1
};
}
//记录触屏触点坐标 触屏移动时更新结束点坐标
function onTouchMove(evt) {
if (touchState === null) {
return;
}
touchState.endX = evt.touches[0].pageX;
touchState.endY = evt.touches[0].pageY;
touchState.endX2 = evt.touches[1] ? evt.touches[1].pageX : -1;
touchState.endY2 = evt.touches[1] ? evt.touches[1].pageY : -1;
}
//触屏结束时 判断是否放大缩小
function onTouchEnd(evt) {
if (touchState === null) {
return;
}
//计算两点间距离
var getDistance = function (startX, startY, endX, endY) {
return Math.hypot(endX - startX, endY - startY);
};
if (touchState.startX2 != -1 && touchState.endX2 != -1 && touchState.startY2 != -1 && touchState.endY2 != -1) {
let distanceStart = getDistance(touchState.startX, touchState.startY, touchState.startX2, touchState.startY2);
let distanceEnd = getDistance(touchState.endX, touchState.endY, touchState.endX2, touchState.endY2);
//起始时两点距离和结束时两单距离进行比较,判断是方法还是缩小
if (distanceStart < distanceEnd) {
PDFViewerApplication.pdfViewer.increaseScale();
} else if (distanceStart > distanceEnd) {
PDFViewerApplication.pdfViewer.decreaseScale();
}
}
}
addPinchListener();
</script>
2、手势缩放的同时pdf同步缩放
- 在/pdfjs/web/viewer.html 页面添加如下代码。
- 此方法安卓基本正常使用,且比较缩放丝滑,但是ios缩放会页面崩溃。
<script>
let agent = navigator.userAgent.toLowerCase();
if(!agent.includes("iphone")) {
let pinchZoomEnabled = false;
function enablePinchZoom(pdfViewer) {
let startX = 0,
startY = 0;
let initialPinchDistance = 0;
let pinchScale = 1;
const viewer = document.getElementById("viewer");
const container = document.getElementById("viewerContainer");
const reset = () => {
startX = startY = initialPinchDistance = 0;
pinchScale = 1;
};
// Prevent native iOS page zoom
//document.addEventListener("touchmove", (e) => { if (e.scale !== 1) { e.preventDefault(); } }, { passive: false });
document.addEventListener("touchstart", (e) => {
if (e.touches.length > 1) {
startX = (e.touches[0].pageX + e.touches[1].pageX) / 2;
startY = (e.touches[0].pageY + e.touches[1].pageY) / 2;
initialPinchDistance = Math.hypot(
e.touches[1].pageX - e.touches[0].pageX,
e.touches[1].pageY - e.touches[0].pageY
);
} else {
initialPinchDistance = 0;
}
});
document.addEventListener(
"touchmove",
(e) => {
if (initialPinchDistance <= 0 || e.touches.length < 2) {
return;
}
if (e.scale !== 1) {
e.preventDefault();
}
const pinchDistance = Math.hypot(
e.touches[1].pageX - e.touches[0].pageX,
e.touches[1].pageY - e.touches[0].pageY
);
const originX = startX + container.scrollLeft;
const originY = startY + container.scrollTop;
pinchScale = pinchDistance / initialPinchDistance;
viewer.style.transform = `scale(${pinchScale})`;
viewer.style.transformOrigin = `${originX}px ${originY}px`;
}, {
passive: false
}
);
document.addEventListener("touchend", (e) => {
if (initialPinchDistance <= 0) {
return;
}
viewer.style.transform = `none`;
viewer.style.transformOrigin = `unset`;
PDFViewerApplication.pdfViewer.currentScale *= pinchScale;
const rect = container.getBoundingClientRect();
const dx = startX - rect.left;
const dy = startY - rect.top;
container.scrollLeft += dx * (pinchScale - 1);
container.scrollTop += dy * (pinchScale - 1);
reset();
});
}
document.addEventListener("DOMContentLoaded", () => {
if (!pinchZoomEnabled) {
pinchZoomEnabled = true;
enablePinchZoom();
}
});
}
</script>
每次进来pdf默认第一页和初始缩放比例
- 在view.js中搜到setInitialView方法 ,添加如下代码
// 进来默认第一页
this.pdfViewer.currentPageNumber = 1
// 进来pdf显示默认缩放比例
this.pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE;