切換語言為:簡體

如何使用JavaScript平移和縮放影象

  • 爱糖宝
  • 2024-08-14
  • 2059
  • 0
  • 0

平移和縮放是檢視影象時常用的功能。我們可以放大影象以檢視更多細節,進行影象編輯。

Dynamsoft Document Viewer是一個用於此目的的SDK,它為文件影象提供了一組檢視器。在本文中,我們將演示如何使用它來平移和縮放影象。此外,我們還將探討如何使用JavaScript從頭實現這一功能。

使用Dynamsoft Document Viewer平移和縮放影象

  1. 建立一個包含以下模板的新HTML檔案。

    <!DOCTYPE html>
    <html>
    <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>

  2. 在頁面中包含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">

  3. 使用許可證初始化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();

  4. 建立一個新的文件例項。

    const docManager = Dynamsoft.DDV.documentManager;
    const doc = docManager.createDocument();

  5. 建立一個Edit Viewer例項,將其繫結到一個容器,然後用它來檢視我們剛剛建立的文件。

    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;
    }

  6. 使用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);
      })
    }

然後,我們可以按住控制鍵,使用滑鼠滾輪放大、縮小和平移影象。在移動裝置上,我們可以透過雙指實現縮放。

演示影片

從頭開始實現平移和縮放

有幾種方法可以實現平移和縮放。

  1. 使用絕對畫素值。它易於理解,可以有捲軸。

  2. 使用CSS transform。它可以使用GPU來獲得更好的效能,但不能保留捲軸。

  3. 使用Canvas。它具有較高的效能和定製性。Dynamsoft Document Viewer使用此方法。

下面,我們將使用第一種方式進行演示。

  1. 建立一個容器作為檢視器。包含一張影象。

    <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;
    }

    圖片的CSS:

    #image {
      margin: auto;
    }

  2. 載入所選影象檔案。使影象的寬度適合檢視器。

    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);
      })
    }

  3. 新增一個wheel事件,以便在按下控制鍵的情況下使用滑鼠進行縮放。

    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);
    }

  4. 新增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;
      }
    });

  5. 新增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實現了平移和縮放功能。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.