圖片放大鏡(有意思的JS 二)

我是你們的索兒呀,很幸運我的文章能與你相見
願萌新能直觀的感受到Javascript的趣味性,願有一定基礎者有所收穫,願大佬不吝賜教

在這裏插入圖片描述

在我們逛淘寶、京東等購物網站時,每一個商品都是以圖片顯示,當我們鼠標劃圖片的時候,在旁邊可以顯示局部放大的圖片

本篇文章的目的是,介紹JavaScript實現放大鏡效果

思路及代碼實現

文件結構

  • 對於一個看起來很清晰的圖片,如果將圖片放大,你會發現圖片越來越模糊
  • 所以右邊div的背景圖片需要一個更加清晰的圖片文件,防止左邊圖片局部放大顯示後變的模糊

一般,網站需要考慮到圖片的大小和圖片的清晰度之間的平衡:如果圖片清晰度高,就需要佔用過多空間;如果需要爲了節省空間,那麼勢必要犧牲圖片清晰度

html代碼:

<div class="small">
    <div class="magnifier"></div>
</div>
<div class="big"></div>

css代碼:
div.small設置爲相對定位,
div.magnifier設置爲絕對定位,其left、right由JS控制
三個div的width、height都由JS控制

其餘內容皆由JavaScript完成

一:思維導圖

二:遊戲配置

/**
 * 配置
 */
var config = {
    smallBg: "imgs/small.jpg",
    bigBg: "imgs/big.jpg",
    smallDiv: document.querySelector(".small"),
    bigDiv: document.querySelector(".big"),
    magnifierDiv: document.querySelector(".small .magnifier"),
    smallDivSize: {  //小圖尺寸(即小的div的尺寸)
        width: 384,
        height: 216
    },
    bigDivSize: {  //大的div的尺寸
        width: 576,
        height: 324
    },
    bigBgSize: {  //大圖尺寸
        width: 1920,
        height: 1080
    },
    

};
//放大鏡div的寬、高
config.magnifierDivSize = {
    width: config.bigDivSize.width / config.bigBgSize.width * config.smallDivSize.width,
    height: config.bigDivSize.height / config.bigBgSize.height * config.smallDivSize.height
};
  1. 小圖尺寸 = div.small尺寸
  2. div.magnifier的尺寸 / 小圖尺寸 = div.big尺寸 / 大圖尺寸

小圖尺寸、大圖尺寸:取決於提供的圖片大小,是確定的;div.small尺寸、div.big尺寸:取決於網頁佈局,是確定的;而div.magnifier的尺寸,需要使用第二個公式進行計算

三:初始化div.small、div.big

設置它們的寬高和背景圖片

/**
 * 初始化div.small、div.big
 */
function initDiv(){
    //div.small
    style = config.smallDiv.style;
    style.width = config.smallDivSize.width + 'px';
    style.height = config.smallDivSize.height + 'px';
    style.background = 'url("' + config.smallBg + '") no-repeat left top/100% 100%';
    //div.big
    style = config.bigDiv.style;
    style.width = config.bigDivSize.width + 'px';
    style.height = config.bigDivSize.height + 'px';
    style.background = 'url("' + config.bigBg + '") no-repeat';
    style.display = 'none';
}

四:初始化放大鏡div

設置放大鏡div寬高

/**
 * 初始化div.magnifier
 */
function initMagnifierDiv(){
    style = config.magnifierDiv.style;
    style.width = config.magnifierDivSize.width + 'px';
    style.height = config.magnifierDivSize.height + 'px';
    style.display = 'none';
}

五:鼠標事件

首先,給放大鏡div註冊:鼠標進入事件、鼠標移出事件

  • 當鼠標進入div.small時,div.magnifier、div.big顯現出來
  • 與之相對,當鼠標離開div.small時,div.magnifier、div.big消失
dom = config.smallDiv;

dom.onmouseenter = function(){
    config.magnifierDiv.style.display = 'block';
    config.bigDiv.style.display = 'block';
}

dom.onmouseleave = function(){
    config.magnifierDiv.style.display = 'none';
    config.bigDiv.style.display = 'none';
}

然後,重中之重,鼠標移動事件

(1) 當鼠標在div.small中移動時,首先要得到鼠標在div.small的偏移量(座標),分兩種情況:

(1.1)當鼠標移動事件由div.small觸發時,通過offsetX、offsetY即可獲取偏移量

(1.2)當鼠標移動事件由div.magnifier觸發時,通過offsetX、offsetY獲取的只是鼠標相對於div.magnifier的偏移量,所以還要加上div.magnifier的left(top)與div.magnifier的邊框寬度

e.offsetX、e.offsetY:

  • 鼠標相對於事件源的內邊距的座標
/**
 * 得到鼠標在div.small的偏移量(座標)
 * @param {MouseEvent} e 
 */
function getOffset(e){
    if(e.target === config.smallDiv){
        return {
            x: e.offsetX,
            y: e.offsetY
        }
    }else{
        var style = getComputedStyle(config.magnifierDiv);
        var left = parseFloat(style.left);  //parseFloat()去掉單位px
        var top = parseFloat(style.top);
        return {
            x: e.offsetX + left + 1,
            y: e.offsetY + top + 1
        }
    }
}

(2) 根據鼠標的偏移量,設置div.magnifier的left、top

(2.1)鼠標相對於div.small的偏移量 減去 div.magnifier的寬(高)的一半,即div.magnifier的left(top),這樣可以使鼠標在放大鏡div的中心

(2.2)要注意邊界值的判定,並對其進行處理

/**
 * 根據鼠標的偏移量,設置div.magnifier的left、top
 * @param {*} offset 
 */
function setPosition(offset){
    var left = offset.x - config.magnifierDivSize.width / 2;
    var top = offset.y - config.magnifierDivSize.height / 2;
    if(left < 0){
        left = 0;
    }
    if(top < 0){
        top = 0;
    }
    if(left > config.smallDivSize.width - config.magnifierDivSize.width){
        left = config.smallDivSize.width - config.magnifierDivSize.width;
    }
    if(top > config.smallDivSize.height - config.magnifierDivSize.height){
        top = config.smallDivSize.height - config.magnifierDivSize.height;
    }
    config.magnifierDiv.style.left = left + 'px';
    config.magnifierDiv.style.top = top +'px';
}

(3) div.small的背景圖片的某一部分,通過放大鏡(div.magnifier),

在右邊的div.big上進行映射:

有這麼個比值可以用來設置div.big的background-position(通過圖解說)

div.magnifier相對於div.small的left / div.small的寬度
=
background-position-x的絕對值 / div.big的背景圖片的寬度

另一個與此同理

/**
 * 圖片經過放大鏡後,在div.big的映射
 */
function setBigDivBg(){
    var bgLeft = -1 * parseFloat(getComputedStyle(config.magnifierDiv).left) / config.smallDivSize.width * config.bigBgSize.width; 
    var bgTop = -1 * parseFloat(getComputedStyle(config.magnifierDiv).top) / config.smallDivSize.height * config.bigBgSize.height;
    config.bigDiv.style.backgroundPosition = bgLeft + 'px ' + bgTop + 'px';
}

代碼獲取

放大鏡的完整核心代碼,有兩個方式獲取

所謂核心代碼,即本篇文章帶你實現的放大鏡的完整代碼,沒有加入許許多多花裏胡哨的東西,以免文章無法連貫講解

  1. 百度網盤
    文件夾鏈接:https://pan.baidu.com/s/120rZT1r-cDAdpBRU8_9spA
    提取碼:e458
    壓縮包鏈接:https://pan.baidu.com/s/1ldbJ-2v0OCm7g-mk3NuB9w
    提取碼:9g7g
  2. github:https://github.com/Zhangguohao666/demo-front-end/tree/master/magnifier

本文代碼思路參考自:渡一,袁進老師


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章