亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript實現(xiàn)圖片縮放功能

 更新時間:2024年07月10日 08:45:23   作者:Jimmy  
本文,我們來講講如何使用 JavaScript 實現(xiàn)圖片的縮放,當然,我們可以類比到其他的元素,比如視頻的縮放,文中有詳細的代碼示例,對大家的學習或工作有一定的幫助,需要的朋友可以參考下

前言

平常,我們在查看圖片的時候,都有放大縮小的功能。如下圖

那么,我們如何在網頁中,對圖像進行縮放呢?

本文,我們來講講如何使用 JavaScript 實現(xiàn)圖片的縮放。當然,我們可以類比到其他的元素,比如視頻的縮放。

更改寬度

是的,很符合第一直覺邏輯的一種實現(xiàn)方式。電腦上查看相片也是使用的這種模式 - 直接保持外側容器的框高不變,等比例地更改圖片的尺寸。

我們來簡單舉個例子:

<div class="container" style="width: 400px; height: 300px;">
  <img src="path/to/image.png" id="image" style="width: 400px;" />
</div>
(function(){
  const ratio = 4 / 3; // 寬高比例
  let imageDom = document.getElementById("image");
  imageDom.addEventListener("click", function() {
    imageDom.style.width = 400 * ratio + "px";
  })
})()

上面代碼中,我們設定了外部容器的尺寸是 400 * 300 px,內部的圖像的寬度等同外部尺寸。當點擊圖片之后,圖像的寬度變?yōu)?nbsp;400 * 4 / 3 px,外部的容器沒有發(fā)生更改。

那么,我們這種直接更改寬度的方法,在全屏的模式下,生效?

public static gotoFullscreen(dom: any): void {
  if (dom.requestFullscreen) {
    dom.requestFullscreen()
  } else if (dom.mozRequestFullScreen) {
    dom.mozRequestFullScreen()
  } else if (dom.webkitRequestFullscreen) {
    dom.webkitRequestFullscreen()
  } else if (dom.msRequestFullscreen) {
    dom.msRequestFullscreen()
  } else {
    console.error('當前瀏覽器不支持部分全屏!')
  }
}

也就是通過上面的代碼進入到瀏覽器的全屏模式 gotoFullscreen(document.getElementsByClassName("container")[0])。

然而,無論我們怎么設定圖像的寬度,比如 document.getElementById("image").style.width = "200%",都不會生效的。

我們是否還有其他進行縮放的方法在全屏模式下也能夠實現(xiàn)呢?

更改 Scale

我們可以保持圖片的實際的寬高是不變的,然后更改其 scaleXscaleY 來實現(xiàn)。

<div class="container" style="width: 400px; height: 300px;">
  <img src="path/to/image.png" id="image" style="width: 400px;" />
</div>
(function(){
  const ratio = 4 / 3; // 框高比例
  let imageDom = document.getElementById("image");
  imageDom.addEventListener("click", function() {
    imageDom.style.transform = `scale(4/3, 4/3)`;
  })
})()

很明顯,與 更改寬度 小節(jié),唯一不同的點就是 imageDom.style.transform = scale(4/3, 4/3);,我們在點擊圖片的時候,使用 transform 屬性值 scale(x, y) 對其 x 軸和 y 軸進行縮放。

而且,在全屏的模式下,該方法依舊能夠實現(xiàn)對圖片的縮放。因為圖片的寬度不變。

取舍

兩種方案:更改寬度更改 Scale。我們應該選擇 更改 Scale 來對圖像進行縮放。因為:

  • 更改 Scale 涉及的場景比 更改寬度 要廣
  • 更改 Scale 性能比更改寬度性能優(yōu)越。因為更改寬度是對 dom 進行操作,會造成回流和重排,而更改 Scale 是利用 圖形處理器(GPU) 來實現(xiàn)。

更改偏移位置

我們以方案二 - 更改 Scale 為基礎。

當我們希望查看點擊點的圖片。我們需要對其進行放大,并將點擊點放在外容器的中心點的位置。那么,我們就需要對圖像的位置進行處理。

我們可以使用 position: absolute; top: *px; left: *px; 來實現(xiàn),但是通過我們上面取舍小節(jié)的對比。我們有更好的替代方案 - 使用 translate(x, y) 來實現(xiàn)。

這里我們使用 typescript 結合 angular 來實現(xiàn):

<div id="imageContainer">
    <image 
        id="image" 
        [style]="{
            width: imageRealWidth,
            transform: 'scale(' + imageAmplifyMultiple + ', ' + imageAmplifyMultiple + ') translate(' + imageTranslateX + 'px, ' + imageTranslateY + 'px)'
        }"
    />
</div>

對應的 javascript 如下:

// 放大圖片區(qū)域
public amplifyImagePortion(event) {
    let imageContainerCenterLeft : number;
    let imageContainerCenterTop : number;
    
    let _imageContainer: any = document.getElementById('imageContainer');
    if(this.imageIsFullscreen) { // 全屏模式
        imageContainerCenterLeft = _imageContainer.getBoundingClientRect().width / 2;
        imageContainerCenterTop =_imageContainer.getBoundingClientRect().height / 2;
    } else {
        // 非全屏的模式下
        imageContainerCenterLeft = _imageContainer.getBoundingClientRect().left + _imageContainer.getBoundingClientRect().width / 2;
        imageContainerCenterTop = _imageContainer.getBoundingClientRect().top + _imageContainer.getBoundingClientRect().height / 2;
    }
    
    let clickPointLeft = event.pageX;
    let clickPointTop = event.pageY;

    this.imageTranslateX =  (this.imageTranslateX * this.imageAmplifyMultiple + ( imageContainerCenterLeft - clickPointLeft)) / this.imageAmplifyMultiple;
    this.imageTranslateY =  (this.imageTranslateY * this.imageAmplifyMultiple +(imageContainerCenterTop - clickPointTop)) / this.imageAmplifyMultiple;

    // 放大的倍數(shù)
    this.imageAmplifyMultiple =  this.imageAmplifyMultiple * this.multipleStep;
}

上面的案例中,我們只是進行放大功能的展示。

引入鼠標滾輪

下面,我們通過引入鼠標滾動,修改下 amplifyVideoPortion 方法來對圖像放大或縮小。

// 滾輪滾動
private mouseWheelFn(event) {
    if(!this.mouseWheel) {
        this.mouseWheel = fromEvent(document.getElementById('imageContainer'), 'wheel');
        this.subscriptions.push(
            this.mouseWheel
            .pipe(throttleTime(50))
            .subscribe((wheel: any) => {
                if(wheel.deltaY > 1) {
                    // 進行局部放大
                    this.amplifyImagePortion(event, true);
                }
                if(wheel.deltaY < -1) {
                    // 進行局部縮小
                    this.amplifyImagePortion(event, true, 'minify');
                }
                // 重置框選數(shù)據
                this.resetCheckBoxVariables();
            })
        );
    }
}

我們監(jiān)聽外部容器選中,滾輪滾動,當正向滾動的時候,我們對圖片進行局部放大,當反向滾動的時候,我們對圖片進行局部縮小。我們這里還引入了 rxjs 中的節(jié)流方法 throttleTime 來優(yōu)化滾輪觸發(fā)事件的時機。

對應的 amplifyImagePortion 方法我們更改如下

// 放大圖像區(qū)域
public amplifyImagePortion(event, isWheel, direction?: string) { // isWheel 是否是鼠標滾動
    let imageContainerCenterLeft : number;
    let imageContainerCenterTop : number;
    
    let _imageContainer: any = document.getElementById('imageContainer');
    if(this.imageIsFullscreen) { // 全屏模式下
        imageContainerCenterLeft = _imageContainer.getBoundingClientRect().width / 2;
        imageContainerCenterTop =_imageContainer.getBoundingClientRect().height / 2;
    } else {
        // 非全屏的模式下
        if(isWheel) {
            imageContainerCenterLeft = _imageContainer.getBoundingClientRect().left + _imageContainer.getBoundingClientRect().width / 2;
            imageContainerCenterTop = _imageContainer.getBoundingClientRect().top + _imageContainer.getBoundingClientRect().height / 2;
        }
    }

    let clickPointLeft: number = 0;
    let clickPointTop: number = 0;
    if(isWheel) {
        clickPointLeft = event.pageX;
        clickPointTop = event.pageY;

    } else {
        clickPointLeft = this.checkboxPositionLeft + this.checkboxWidth / 2;
        clickPointTop = this.checkboxPositionTop + this.checkboxHeight / 2
    }


    // 計算兩點之間的距離
    let diffX: number = imageContainerCenterLeft - clickPointLeft;
    let diffY: number = imageContainerCenterTop - clickPointTop;


    if(!isWheel) {
        this.imageTranslateX =  (this.imageTranslateX * this.imageAmplifyMultiple + diffX) / this.imageAmplifyMultiple;
        this.imageTranslateY =  (this.imageTranslateY * this.imageAmplifyMultiple + diffY) / this.imageAmplifyMultiple;
    }

    // 縮小的倍數(shù)
    if(direction == 'minify') {
        this.imageAmplifyMultiple =  this.imageAmplifyMultiple * (1 / this.multipleStep);
    } else {
        // 放大的倍數(shù) - 默認
        this.imageAmplifyMultiple =  this.imageAmplifyMultiple * this.multipleStep;
    }
}

multipleStep 是放大的倍數(shù),1 / multipleStep 是縮小的倍數(shù)。因為寬度變,我們需要對 translatex 軸和 y 軸的偏移進行合理計算,見上面兩份代碼。

擴展

當然,我們還可以圖片縮放的功能進行擴展,比如,對圖片進行區(qū)域的框選進行縮放;比如,另起一個 canvas 對圖片進行繪制縮放等。

以上就是JavaScript實現(xiàn)圖片縮放功能的詳細內容,更多關于JavaScript圖片縮放的資料請關注腳本之家其它相關文章!

相關文章

最新評論