Zhiqim UI是一套集成Javascript库、Css库、Font库、常用ico图标等,并在其上开发的大量UI组件组成的前端开发套件。

森中灵 最后提交于3月前 整理V8.0.6
zhiqim_magic_zoom.js9KB
/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙,邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
 *
 * Zhiqim UI is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
 
+(function(Z)
{
/****************************************/
//“图片放大镜”
/****************************************/

// 1、配置举例:
// <ul id="zoomList">
//     <li><img src="https://www.zhiqim.com/document/inc/www/tutorial/guest.jpg"></li>
//     <li><img src="https://www.zhiqim.com/document/inc/www/tutorial/guest.jpg"></li>
//     <li><img src="https://www.zhiqim.com/document/inc/www/tutorial/guest.jpg"></li>
//     <li><img src="https://www.zhiqim.com/document/inc/www/tutorial/guest.jpg"></li>
// </ul>
//
// <script>
//     var newMagicZoom = new Z.MagicZoom(); 
//     newMagicZoom.elem = Z("#zoomList");            // 列表对象
//     newMagicZoom.width = 400;                      // 自定义宽度
//     newMagicZoom.listShow = 5;                     // 自定义小图显示个数
//     newMagicZoom.zoomRatio = 2;                    // 自定义缩放倍数
//     newMagicZoom.execute();
// </script>

/************************************************************************/
/********************************************/

Z.MagicZoom = Z.Class.newInstance();
Z.MagicZoom.prototype = 
{
    //start of Z.MagicZoom.prototype
    defaults: 
    {//定义
        elem: null,          // 列表对象
        width: -1,            // 容器宽度,默认为 -1,动态计算
        listShow: 5,          // 导航最多展示图片数量
        zoomRatio: 2,         // 缩放倍数,默认两倍
    },
    init: function()
    {//初始化
    },
    execute: function()
    {//执行
        this.$elem = Z.$elem(this.elem, "Z.MagicZoom");
        if (this.width < 0){
            this.width = this.$elem.offsetWidth();
        }
        
        //重新组装排版
        var wrapHtml = '<div class="z-magicZoom z-relative" style="width:'+this.width+'px;">';
        wrapHtml +=         '<div class="z-zoomImg z-w100p z-bd z-relative" style="height:'+this.width+'px;">';
        wrapHtml +=             '<img class="z-absolute-center-middle" src="">';
        wrapHtml +=             '<i class="z-font z-query z-absolute z-r0 z-b0 z-w30 z-h30 z-px20 z-lh30 z-text-center"></i>';
        wrapHtml +=             '<div class="z-zoomCover z-absolute z-bd z-hide"></div>';
        wrapHtml +=         '</div>';
        wrapHtml +=         '<div class="z-zoomList z-w100p z-mg-t3 z-relative"><div class="z-relative z-overflow-hidden"></div></div>';
        wrapHtml +=         '<div class="z-zoomShow z-absolute z-overflow-hidden z-hide"><img class="z-absolute z-l0 z-t0" src=""></div>';
        wrapHtml +=     '</div>';
        
        this.$wrap = Z(wrapHtml).insertAfter(this.$elem);
        this.$zoom = this.$wrap.find(".z-zoomImg");
        this.$zoomImg = this.$zoom.find("img");
        this.$zoomIcon = this.$zoom.find(".z-font");
        this.$list = this.$wrap.children(".z-zoomList");
        this.$listUl = this.$list.find("div").append(this.$elem);
        this.$lis = this.$elem.find("li").css("opacity",.5);
        
        //常量
        this.length = this.$lis.length;
        this.zoomWidth = this.$zoom.offsetWidth()-2;
        this.zoomHeight = this.$zoom.offsetHeight()-2;
        this.coverWidth = this.zoomWidth / this.zoomRatio;
        this.coverHeight = this.zoomHeight / this.zoomRatio;
        this.maxX = this.zoomWidth - this.coverWidth;
        this.maxY = this.zoomHeight - this.coverHeight;
        this.minCx = this.coverWidth/2;
        this.minCy = this.coverHeight/2;
        this.maxCx = this.maxX + this.coverWidth/2;
        this.maxCy = this.maxY + this.coverHeight/2;
        
        //遮罩层、展示层
        this.$zoomCover = this.$wrap.find(".z-zoomCover").css("width",this.coverWidth).css("height",this.coverHeight);
        this.$zoomShow = this.$wrap.find(".z-zoomShow").css("width",this.zoomWidth).css("height",this.zoomHeight)
            .css("left",this.zoomWidth + 10).css("top",0);
        this.$showImg = this.$zoomShow.find("img");
        
        if (this.length > this.listShow){
            this.hasBtn = true;
            this.$btnPrev = Z('<div class="z-absolute z-l0 z-t0 z-b0 z-w20 z-h100p z-bd z-text-center z-pointer z-event-none z-text-gray"><i class="z-font z-arrowhead-left z-absolute-center-middle z-w20 z-h20"></i></div>').appendTo(this.$list);
            this.$btnNext = Z('<div class="z-absolute z-r0 z-t0 z-b0 z-w20 z-h100p z-bd z-text-center z-pointer"><i class="z-font z-arrowhead-right z-absolute-center-middle z-w20 z-h20"></i></div>').appendTo(this.$list);
            this.$listUl.addClass("z-mg-l20 z-mg-r20");
            this.$btnPrev.on("click", this.prevList, this);
            this.$btnNext.on("click", this.nextList, this);
        }
        
        //计算每个小图大小
        var ulWidth = this.$listUl.offsetWidth() - 6;
        this.liWidth = Math.round(ulWidth/this.listShow);
        
        this.$listUl.css("height",this.liWidth);
        this.$list.css("height",this.liWidth);
        this.$elem.css("width",this.liWidth * this.length).css("height",this.liWidth);
        this.$lis.css("width",this.liWidth - 6).css("height",this.liWidth - 6);
        
        this.ulShow = ulWidth;
        this.ulWidth = this.$elem.offsetWidth();
        
        //第一张图
        this.setImgSrc(0);
        
        //绑定事件
        this.$zoom.on("mouseenter", this.zoomEnter, this).on("mousemove", this.zoomMove, this).on("mouseleave", this.zoomLeave, this);
        this.$lis.on("mouseenter", this.lisEnter, this);
    },
    setImgSrc: function(index)
    {
        var $li = Z(this.$lis[index]);
        $li.css("opacity",1).siblings("li").css("opacity",.5);
        var imgSrc = $li.find("img").attr("src");
        this.$zoomImg.attr("src", imgSrc);
        this.$showImg.attr("src", imgSrc);
    },
    zoomEnter: function(ev)
    {//进入 zoom ,显示放大镜
        Z.E.forbidden(ev);
        this.$zoomCover.show();
        this.$zoomShow.show();
        
        //设置位置
        var mX = ev.clientX;
        var mY = ev.clientY;
        var rect = this.$zoom[0].getBoundingClientRect();
        var cX = rect.left + rect.width/2;
        var cy = rect.top + rect.height/2;
        
        this.$zoomCover.css("left", (mX > cX)?this.maxX:0)
            .css("top", (mY > cy)?this.maxY:0);
        
        this.$showImg.css("width",this.$zoomImg.offsetWidth() * this.zoomRatio)
            .css("height",this.$zoomImg.offsetHeight() * this.zoomRatio)
            .css("margin-left",parseInt(this.$zoomImg.css("margin-left")) * this.zoomRatio)
            .css("margin-top",parseInt(this.$zoomImg.css("margin-top")) * this.zoomRatio);
    },
    zoomMove: function(ev)
    {//移动放大镜
        Z.E.forbidden(ev);
        
        // cover 位置计算
        var mX = ev.clientX;
        var mY = ev.clientY;
        var rect = this.$zoom[0].getBoundingClientRect();
        mX -= rect.left;
        mY -= rect.top;
        var setX, setY;
        if (mX < this.minCx){
            setX = 0;
        } else if (mX > this.maxCx){
            setX = this.maxX;
        } else {
            setX = mX - this.minCx;
        }
        if (mY < this.minCy){
            setY = 0;
        } else if (mY > this.maxCy){
            setY = this.maxY;
        } else {
            setY = mY - this.minCy;
        }
        
        //cover 位置定义
        this.$zoomCover.css("left", setX).css("top", setY);
        
        //show 位置计算
        setX = -(setX * this.zoomRatio);
        setY = -(setY * this.zoomRatio);
        this.$showImg.css("left", setX).css("top", setY);
    },
    zoomLeave: function(ev)
    {//离开 zoom ,隐藏放大镜
        Z.E.forbidden(ev);
        this.$zoomCover.hide();
        this.$zoomShow.hide();
    },
    lisEnter: function(ev)
    {//hover 小图片,切换图片显示
        Z.E.forbidden(ev);
        var $li = Z(Z.E.current(ev));
        if ($li.css("opacity") == "1")
            return;
        var liIndex = this.getParentIndex($li[0]);
        this.setImgSrc(liIndex)
    },
    prevList: function(ev)
    {//向前切换图片列表
        Z.E.forbidden(ev);
        var nLeft = parseInt(this.$elem.css("left"));
        nLeft += this.ulWidth;
        nLeft = nLeft > 0 ? 0 : nLeft;
        this.$elem.css("left", nLeft);
        
        //按钮状态
        this.$btnNext.removeClass("z-event-none").removeClass("z-text-gray");
        if (nLeft == 0){
            this.$btnPrev.addClass("z-event-none z-text-gray");
        }
        
    },
    nextList: function(ev)
    {//向后切换图片列表
        Z.E.forbidden(ev);
        var nLeft = parseInt(this.$elem.css("left"));
        nLeft -= this.ulShow;
        if ((this.ulShow - nLeft)> this.ulWidth){
            nLeft = this.ulShow - this.ulWidth;
        }
        this.$elem.css("left", nLeft);
        
        //按钮状态
        this.$btnPrev.removeClass("z-event-none").removeClass("z-text-gray");
        if (nLeft == (this.ulShow - this.ulWidth)){
            this.$btnNext.addClass("z-event-none z-text-gray");
        }
    },
    getParentIndex: function(elem)
    {//获取 elem 在父级的 索引值
        var ind = 0;
        while (elem = elem.previousSibling) {
            if (elem.nodeType == 1)
                ind++
        }
        return ind;
    },
    //end of Z.MagicZoom.prototype
}


//END
})(zhiqim);