1. 程式人生 > >css+jquery 實現圖片局部放大預覽

css+jquery 實現圖片局部放大預覽

leave init float this () 設計 背景 事件 relative

今天有時間開始動手,使用css+jqueryshi實現了圖片局部放大的組件,首先看看效果圖:

技術分享圖片

界面設計思路如下:

   1.兩個div,左邊放圖片的縮略圖
2.在左邊縮略圖鼠標移動的時候,區域(效果圖中的網格)
3.右邊放大圖div,背景為縮略圖的大圖,在鼠標移入縮略圖中,通過獲取鼠標的坐標,將右側背景圖片移動到跟鼠標坐標對應的位置
4.設計時盡量,獲取原大圖的尺寸,和縮略圖視窗計算比例,更大精度的做到左側縮略圖上表示的區域,和右側放大部分匹配

本示例大部分編碼在javascript腳本,以下列出各部分的源碼:

<div class="all-region">
    <div class="image-wrap">
<!--縮略圖div-->
<div class="little-img"> <img src="./images/show-window/timg.jpg"> </div>
<!--圖片放大div-->
<div class="large-img"> </div>
<!--縮略圖上展示被放大的區域,網格區域-->
<div class="relative-region"></div> </div> </div>

css:

    .all-region {
        width: 100%;
        height: auto;
    }

    .all-region .image-wrap {
        width: 1300px;
        margin: 0px auto;
        height: 300px;
        line-height: 300px;
        overflow
: hidden; vertical-align: center; background: #FBFBFB; border-left: 1px solid #ebebeb; position: relative; } .image-wrap .little-img img { width: 600px; height: 300px; } .image-wrap .large-img { width: 600px; height: 300px; background-image: url("./images/show-window/timg.jpg"); border: 1px solid transparent; background-size: inherit; background-repeat: no-repeat; background-position-x: 0px; background-position-y: 0px; position: relative; top: -301px; left: 605px; float: left; z-index: 10; opacity: 0; display: none; transition: opacity 2s linear; overflow: hidden; } .relative-region { background: linear-gradient(45deg, rgba(46, 46, 46, 0.5) 50%, transparent 0), linear-gradient(135deg, rgba(200, 200, 200, .5) 70%, transparent 0); display: none; position: relative; z-index: 99; background-size: 5px 5px; }

Javascript:

class Elements {
        constructor() {
            //縮略圖區域
            this.sourceImage = $(".little-img");
            //放大區域
            this.aimImage = $(".large-img");
            //視圖圖片,與圖片實際尺寸比例
            this.sourceToAimRate = 0.01;
            //原圖高度
            this.sourceHeight = 0;
            //原圖寬度
            this.sourceWidth = 0;
            //視圖高度,div的高度,本例是300px
            this.containerHeight = this.sourceImage.children().height();
            this.containerWidth = this.sourceImage.children().width();
            //鼠標在縮略圖上的坐標 offsetX
            this.cursor_x = 0;
            this.cursor_y = 0;
            //標誌被放大的區域
            this.region = $(".relative-region");

            this.mouseMove = this.mouseMove.bind(this);
            this.regionPosition = this.regionPosition.bind(this);
            this.regionMove = this.regionMove.bind(this);
            this.caculatorRate = this.caculatorRate.bind(this);
        }
        //計算原圖尺寸,思路是內存加載原圖,獲得尺寸,並計算容器視圖和原圖的比例
        caculatorRate() {
            console.log(this.sourceImage.children().attr("src"));
            $("<img/>").attr("src", this.sourceImage.children().attr("src")).load((e) => {
                //let sourceImageWidth=e.target.width;
                this.sourceWidth = e.target.width;
                this.sourceHeight = e.target.height;
                //計算圖片和容器的像素比例
                this.sourceToAimRate = this.sourceWidth / this.containerWidth;
            });
        }
        //鼠標在縮略圖上移動時計算,放大圖的背景位置,並且定位標識被放大的區域
        mouseMove(e) {
            //console.log(`x:${e.offsetX},y:${e.offsetY}`);
            //偏離region的位置
            //由於鼠標實際上是在標識被放大區域(網格區域)的div裏面,所以通過e獲取的實際上是縮略圖內,網格標識的offsetX 要用網格區域的offsetX+offsetLeft-縮略圖的offsetleft才是鼠標對應到縮略圖上的位置
            let r_x = e.offsetX;
            let r_y = e.offsetY;

            let s_t = this.sourceImage.offset().top;
            let s_l = this.sourceImage.offset().left;

            let r_t = this.region.offset().top;
            let r_l = this.region.offset().left;

            let x = r_l - s_l + r_x;
            let y = r_t - s_t + r_y;

            //在原圖上顯示,被放大的區域
            let w = this.region.width();
            let h = this.region.height();

             //由於鼠標在網格區域的中心,所以在計算放大圖的top和left的時候,實際是從網格的左上角位置
            this.cursor_x = (x - w / 2) * this.sourceToAimRate;
            this.cursor_y = (y - h / 2) * this.sourceToAimRate;
            if (this.cursor_x + this.containerWidth > this.sourceWidth) {
                this.cursor_x = this.sourceWidth - this.containerWidth;
            }
            if (this.cursor_y + this.containerHeight > this.sourceHeight) {
                this.cursor_y = this.sourceHeight - this.containerHeight;
            }
            if (this.cursor_y < 0) {
                this.cursor_y = 0;
            }
            if (this.cursor_x < 0) {
                this.cursor_x = 0;
            }
            this.aimImage.css({
                "background-position-x": -this.cursor_x + "px",
                "background-position-y": -this.cursor_y + "px"
            }); 
            this.regionMove(w, h, x, y); 
}
        regionPosition(r_w, r_h, e) {
            let left = e.offsetX - r_w / 2;
            let top = e.offsetY - r_h / 2; 
            if (left < 0) {
                left = 0;
            }
            if (left + r_w > this.containerWidth) {
                left = this.containerWidth - r_w;
            }
            if (top < 0) {
                top = 0;
            }
            if (top + r_h > this.containerHeight) {
                top = this.containerHeight - r_h;
            }
            this.region.css({
                "top": (top - this.containerHeight) + "px",
                "left": left+ "px",
                "cursor": "crosshair"
            });
        } 
        regionMove(r_w, r_h, x, y) {
            let left = x - r_w / 2;
            let top = y - r_h / 2;

            if (left < 0) {
                left = 0;
            }
            if (left + r_w > this.containerWidth) {
                left = this.containerWidth - r_w;
            }
            if (top < 0) {
                top = 0;
            }
            if (top + r_h > this.containerHeight) {
                top = this.containerHeight - r_h;
            }
            this.region.css({"top": (top - this.containerHeight) + "px", "left": left + "px"});
        }

        init() {
            this.caculatorRate();
            //鼠標移入縮略圖區域,由縮略圖區域的hover事件初始化,將鼠標放入網格區域的中心
            this.sourceImage.children().mouseover((e) => {
                this.aimImage.css({"display": "block", "opacity": "1"});
                let r_w = this.containerWidth / this.sourceToAimRate;
                let r_h = this.containerHeight / this.sourceToAimRate;
                let x = e.offsetX;
                let y = e.offsetY;
                this.regionPosition(r_w, r_h, e);
                this.region.css({"display": "block", "height": r_h + "px", "width": r_w + "px"});
            });
            //修復鼠標在region上,右側放大區域閃動
            this.region.mousemove(this.mouseMove);
            this.region.mouseleave(() => {
                this.aimImage.css({"display": "none", "opacity": "0"});
                this.region.css({"display": "none"});
            });
        }
    } 
    $(function () {
        var e = new Elements();
        e.init();
    })

由於原圖是1920*1080不是縮略視窗嚴格的2:1,計算中有小數等原因,使網格標識的區域,和放大區域展示的完全匹配

css+jquery 實現圖片局部放大預覽