最近有个需求,使用到了viewerjs对一个图片进行可缩放预览,但是存在一个问题,通过滚轮缩放图片时会导致图片移动到视窗外面。
翻了一下GitHub上的源码,viewerjs滚轮(触摸板双指)缩放功能是监听了wheel事件,最终还是调用了zoomTo方法,继续定位该方法的执行过程,可以看到缩放过程中图片位置的计算规则:
if (_originalEvent) {
var offset = getOffset(this.viewer);
var center = pointers && Object.keys(pointers).length > 0 ? getPointersCenter(pointers) : {
pageX: _originalEvent.pageX,
pageY: _originalEvent.pageY
};
// Zoom from the triggering point of the event
imageData.x -= offsetWidth * ((center.pageX - offset.left - x) / width);
imageData.y -= offsetHeight * ((center.pageY - offset.top - y) / height);
} else if (isPlainObject(pivot) && isNumber(pivot.x) && isNumber(pivot.y)) {
imageData.x -= offsetWidth * ((pivot.x - x) / width);
imageData.y -= offsetHeight * ((pivot.y - y) / height);
} else {
// Zoom from the center of the image
imageData.x -= offsetWidth / 2;
imageData.y -= offsetHeight / 2;
}
因此,只要调用zoomTo方法时不传递pivot
和_originalEvent
参数,就会以图片中心点进行缩放。这就需要重新zoomTo这个方法,并且拦截上面的两个参数。在Vuejs中可以像下面进行修改:
const initViewer = () => {
// 初始化之前重写原型上的zoomTo方法
const originalZoomTo = Viewer.prototype.zoomTo;
Viewer.prototype.zoomTo = function(radio: number, ...args) {
return originalZoomTo.call(this, radio);
};
viewer.value = new Viewer(imageRef.value!, {
inline: false,
tooltip: false,
title: false,
navbar: false,
button: false,
container: viewerRef.value!,
ready() {
},
viewed() {
},
});
viewer.value?.show();
};