本文详解如何在Web应用中实现图像的平移与缩放功能。首先介绍使用Dynamsoft Document Viewer SDK的快速集成方案,包括初始化、文档加载及编辑查看器配置。随后深入探讨原生JavaScript实现,对比绝对像素、CSS Transform与Canvas三种方案,并基于绝对像素值提供完整的HTML、CSS及JS代码示例,涵盖鼠标滚轮缩放、拖拽平移及触屏手势支持。
前言
在图像浏览与编辑场景中,平移和缩放是不可或缺的基础交互功能。通过放大图像,用户可以更清晰地观察细节,这对于图像编辑和文档审阅尤为重要。
Dynamsoft Document Viewer是一款专业的文档图像查看SDK,提供了丰富的查看器组件。本文将演示如何利用该SDK实现图像的平移与缩放操作,同时深入探讨如何仅使用JavaScript从零开始构建这一功能。
利用Dynamsoft Document Viewer实现图像平移与缩放
首先,创建一个包含基础模板结构的HTML文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Edit Viewer</title>
<style>
</style>
</head>
<body>
</body>
<script>
</script>
</html>
在页面中引入Dynamsoft Document Viewer的相关资源文件。
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/ddv.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/ddv.css" rel="external nofollow" >
使用有效的许可证初始化Dynamsoft Document Viewer核心模块。如需测试,可在此处申请临时许可证。
Dynamsoft.DDV.Core.license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; //one-day trial
Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/engine";// Lead to a folder containing the distributed WASM files
await Dynamsoft.DDV.Core.init();
实例化一个新的文档管理器对象。
const docManager = Dynamsoft.DDV.documentManager;
const doc = docManager.createDocument();
创建Edit Viewer实例,将其绑定到指定的DOM容器,并利用该实例加载并展示刚才创建的文档对象。
HTML结构代码:
<div id="viewer"></div>
JavaScript逻辑代码:
const uiConfig = {
type: Dynamsoft.DDV.Elements.Layout,
flexDirection: "column",
className: "ddv-edit-viewer-mobile",
children: [
Dynamsoft.DDV.Elements.MainView // the view which is used to display the pages
],
};
editViewer = new Dynamsoft.DDV.EditViewer({
uiConfig: uiConfig,
container: document.getElementById("viewer")
});
editViewer.openDocument(doc.uid);
CSS样式代码:
#viewer {
width: 320px;
height: 480px;
}
通过input元素选择本地图像文件,并将其加载至文档实例中,随后即可在Edit Viewer中查看该图像。
HTML结构代码:
<label>
Select an image:
<br/>
<input type="file" id="files" name="files" onchange="filesSelected()"/>
</label>
JavaScript逻辑代码:
async function filesSelected(){
let filesInput = document.getElementById("files");
let files = filesInput.files;
if (files.length>0) {
const file = files[0];
const blob = await readFileAsBlob(file);
await doc.loadSource(blob); // load image
}
}
function readFileAsBlob(file){
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = async function(e){
const response = await fetch(e.target.result);
const blob = await response.blob();
resolve(blob);
};
fileReader.onerror = function () {
reject('oops, something went wrong.');
};
fileReader.readAsDataURL(file);
})
}
完成上述配置后,用户可按住Control键并滚动鼠标滚轮来对图像进行放大、缩小和平移操作。在移动设备上,支持通过双指捏合手势实现缩放功能。
基于原生JavaScript从零实现平移与缩放
实现图像平移与缩放主要有以下几种技术路径:
- 采用绝对像素值定位。该方法逻辑直观,且能保留原有的滚动条机制。
- 利用CSS transform属性。该方法可借助GPU加速提升渲染性能,但无法直接保留滚动条。
- 使用Canvas绘制。此方案具备高性能和高定制性,Dynamsoft Document Viewer内部即采用此技术路线。
下文将演示第一种方案的具体实现步骤。
构建一个作为查看器的容器元素,并在其中嵌入一张图像。
<div id="viewer">
<img id="image"/>
</div>
相关样式代码:
采用flex布局模式以对齐页面组件。
查看器容器的CSS定义:
#viewer {
width: 320px;
height: 480px;
padding: 10px;
border: 1px solid black;
overflow: auto;
display: flex;
align-items: center;
}
加载用户选择的图像文件,并调整图像宽度以适配查看器容器的尺寸。
let currentPercent;
async function filesSelected(){
let filesInput = document.getElementById("files");
let files = filesInput.files;
if (files.length>0) {
const file = files[0];
const blob = await readFileAsBlob(file);
const url = URL.createObjectURL(blob);
loadImage(url);
}
}
function loadImage(url){
let img = document.getElementById("image");
img.src = url;
img.onload = function(){
let viewer = document.getElementById("viewer");
let percent = 1.0;
resizeImage(percent);
}
}
function resizeImage(percent){
currentPercent = percent;
let img = document.getElementById("image");
let viewer = document.getElementById("viewer");
let borderWidth = 1;
let padding = 10;
let ratio = img.naturalWidth/img.naturalHeight;
let newWidth = (viewer.offsetWidth - borderWidth*2 - padding*2) * percent
img.style.width = newWidth + "px";
img.style.height = newWidth/ratio + "px";
}
function readFileAsBlob(file){
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = async function(e){
const response = await fetch(e.target.result);
const blob = await response.blob();
resolve(blob);
};
fileReader.onerror = function () {
reject('oops, something went wrong.');
};
fileReader.readAsDataURL(file);
})
}
绑定wheel事件监听器,当用户按下Control键并滚动鼠标时,触发图像的缩放逻辑。
img.addEventListener("wheel",function(e){
if (e.ctrlKey || e.metaKey) {
if (e.deltaY < 0) {
zoom(true);
}else{
zoom(false);
}
e.preventDefault();
}
});
function zoom(zoomin,percentOffset){
let offset = percentOffset ?? 0.1;
if (zoomin) {
currentPercent = currentPercent + offset;
}else{
currentPercent = currentPercent - offset;
}
currentPercent = Math.max(0.1,currentPercent);
resizeImage(currentPercent);
}
绑定pointer事件,支持通过鼠标拖拽或触摸屏滑动实现图像的平移操作。
let downPoint;
let downScrollPosition;
img.addEventListener("pointerdown",function(e){
previousDistance = undefined;
downPoint = {x:e.clientX,y:e.clientY};
downScrollPosition = {x:viewer.scrollLeft,y:viewer.scrollTop}
});
img.addEventListener("pointerup",function(e){
downPoint = undefined;
});
img.addEventListener("pointermove",function(e){
if (downPoint) {
let offsetX = e.clientX - downPoint.x;
let offsetY = e.clientY - downPoint.y;
let newScrollLeft = downScrollPosition.x - offsetX;
let newScrollTop = downScrollPosition.y - offsetY;
viewer.scrollLeft = newScrollLeft;
viewer.scrollTop = newScrollTop;
}
});
绑定touchmove事件以增强移动端缩放体验。通过计算两个触摸点之间的距离变化,判断用户意图是放大还是缩小图像。
img.addEventListener("touchmove",function(e){
if (e.touches.length === 2) {
const distance = getDistanceBetweenTwoTouches(e.touches[0],e.touches[1]);
if (previousDistance) {
if ((distance - previousDistance)>0) { //zoom
zoom(true,0.02);
}else{
zoom(false,0.02);
}
previousDistance = distance;
}else{
previousDistance = distance;
}
}
e.preventDefault();
});
function getDistanceBetweenTwoTouches(touch1,touch2){
const offsetX = touch1.clientX - touch2.clientX;
const offsetY = touch1.clientY - touch2.clientY;
const distance = offsetX * offsetX + offsetY + offsetY;
return distance;
}
至此,我们已使用纯JavaScript成功实现了图像的平移与缩放功能。
以上是关于使用JavaScript实现图像平移与缩放功能的完整示例代码。如需获取更多相关技术资料,请持续关注本站发布的其他文章。