网站首页 » 前端开发 » JavaScript » JavaScript 实现图片放大效果
上一篇:
下一篇:

JavaScript 实现图片放大效果

图片放大效果在商城类网站最为党见。这种效果不仅提升了网站的性能,切省了流量,还能带来更好的用户体验,何乐而不为。当你在网上商城看某个产品时,注重细节的你是不是会很自然地去把鼠标放到左边的小图片上查看产品的大图。这种效果可能会让人的购买欲倍增,毕业图片都是做得很高大尚的。好了现在回到正题上,这个效果要怎么做?

首先人们得理清下思路,想想这个功能都有会涉及到什么东西。不要觉得这个效果看起来这么高大尚,其实要实现这个效果的原理是非常地简单的。简单得难以自信。

下面我们先来看一个简单版的DEMO:http://yunkus.com/demo/image-zoom-effect/index-basic.html

这个是基础版,代码随着思路一泻而出,所以很容易就看明白。代码也没有经过特别的封装处理,也没有加一些其它的效果。想看源码的话可以访问 DEMO 直接查看源码,在这篇文章里就不贴出来了。

接下来我们就对这个基础版进行增强,添加多图,增加一些效果淡入淡出,景深等。下面就是这个加强版的经过封装整理的代码,把这段代码封装了就想练练手,贴出来方便日后自已查看,以及让各位也可以对对象的封装有个印象。如果是大神可以直接跳过啦!

CSS 代码

*{
    margin: 0;
    padding: 0;
}
#samll-box{
    position: relative;
    width: 250px;
    height: 250px;
}
#samll-box img{
    width: 250px;
    height: 250px;
}
#select-area{
    display: block;
    position: absolute;
    left: 0;
    top: 0;
    width: 100px;
    height: 100px;
    background: #fff;
    opacity: 0.5;
    display: none;
    z-index: 2
}
#mark-prevent{
    display: block;
    position: absolute;
    left: 0;
    top: 0;
    width: 250px;
    height: 250px;
    background: #333;
    z-index: 3;
    opacity: 0
}
#big-box{
    display: none;
    position: absolute;
    top: 0;
    left: 350px;
    width:300px;
    height: 300px;
    overflow:hidden;
    -webkit-perspective: 300px;
    perspective: 300px;
    transition: all 0.3s ease 0s;
}
#big-box img{
    display: block;
    position: absolute;
    left: 0;
    top: 0;
  /* 不限制宽高 * /
  /*width:700px;
    height: 700px;*/ 
    transition: all 0.2s linear 0s;
}
#next{
    background: #23282d;
    border: none;
    outline: none;
    height: 28px;
    width: 50px;
    text-align: center;
    line-height: 28px;
    border-radius: 5px;
    color: #fff;
    cursor: pointer;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    margin-top: 12px;
}
#next:hover{
    opacity: 0.8
}

HTML 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片放大效果自适应版-云库前端</title>
    <meta name="description" content="图片放大效果自适应版,产品详情页不能少的装逼功能。" />
    <meta name="keywords" content="图片效果,放大效果,图片放大" />
</head>
<body>
    <div id="samll-box">
        <img id="small-img" src="http://yunkus.com/demo/lib/images/demo-1.jpg" alt="">
        <div id="mark-prevent"></div> <!--  在这里多加一个 div 层是为了解决 .select-area 在IE 浏览器下会颤抖的问题。 -->
        <span id="select-area"></span> <!-- 模拟的放大区 -->
    </div>
    <div id="big-box">
        <img id="big-img" src="http://yunkus.com/demo/lib/images/demo-1.jpg" alt="">
    </div>
    <button id="next">下一张</button> <!-- 下一张按钮 -->
</body>
</html>

JavaScript 代码

window.onload = function(){
    var imgShow = new Img();
    imgShow.init();
}

function Img(){
    this.iSamllBox = null;
    this.iSamllImg = null;
    this.iSelectArea = null;
    this.iBigBox = null;
    this.iBigImg = null;
    this.iNext = null;
    this.timer = null;
    this.iMask = null;
    this.num = 1;
};

Img.prototype.init = function(){
    this.iSamllBox = document.getElementById("samll-box");
    this.iSamllImg = document.getElementById("small-img");
    this.iSelectArea = document.getElementById("select-area");
    this.iBigBox = document.getElementById("big-box");
    this.iBigImg = document.getElementById("big-img");
    this.iNext = document.getElementById("next");
    this.iMask = document.getElementById("mark-prevent");
    this.iFnOver();
    this.iFnOut();
    this.iFnMove();
    this.iFnNext();
    this.iFnResponsive();
};

Img.prototype.iFnOver = function(){
    var _this = this; // 保证 this 指向
    this.iSamllBox.onmouseover = function(){
        _this.fnOver();
    }
};

Img.prototype.fnOver = function(){
    this.iSelectArea.style.display = "block";
    this.iBigImg.style.WebkitTransform = this.iBigImg.style.transform = "translateZ(50px)";
    clearTimeout(this.timer);
    this.iBigBox.style.display = "block";
    this.iBigBox.style.opacity = 1;
};

Img.prototype.iFnOut = function(){
    var _this = this; // 保证 this 指向
    this.iSamllBox.onmouseout = function(){
        _this.fnOut();
    }
};

Img.prototype.fnOut = function(){
    var _this = this; // 保证 this 指向
    this.iSelectArea.style.display = "none";
    this.iBigImg.style.WebkitTransform = "translateZ(0)";
    this.iBigBox.style.opacity = 0;
    this.timer = setTimeout(function(){
        _this.iBigBox.style.display = "none";
        clearTimeout(this.timer);
    },1000);
};

Img.prototype.iFnMove = function(){
    var _this = this;
    this.iSamllBox.onmousemove = function(ev){
        _this.fnMove(ev);
    }
};

Img.prototype.fnMove = function(ev){
    var ev = ev || window.event;
    var L = ev.clientX - this.iSamllBox.offsetLeft - this.iSelectArea.offsetWidth/2;
    var T = ev.clientY - this.iSamllBox.offsetTop - this.iSelectArea.offsetHeight/2;
    // 限制显示的边界
    if(L < 0){
        L = 0;
    }else if(L > this.iSamllBox.offsetWidth - this.iSelectArea.offsetWidth){
        L = this.iSamllBox.offsetWidth - this.iSelectArea.offsetWidth;
    }
    if(T < 0){
        T = 0;
    }else if( T > this.iSamllBox.offsetHeight - this.iSelectArea.offsetHeight){
        T = this.iSamllBox.offsetHeight - this.iSelectArea.offsetHeight;
    }
    this.iSelectArea.style.left = L + "px";
    this.iSelectArea.style.top = T + "px";
    // 限制显示的边界 END

    // 小图上的选区转换成大图上的对应的显示区域
    var rateX = L / (this.iSamllBox.offsetWidth - this.iSelectArea.offsetWidth);
    var rateY = T / (this.iSamllBox.offsetHeight - this.iSelectArea.offsetHeight);
    this.iBigImg.style.left = -rateX*(this.iBigImg.offsetWidth - this.iBigBox.offsetWidth) + "px";
    this.iBigImg.style.top = -rateY*(this.iBigImg.offsetHeight - this.iBigBox.offsetHeight) + "px";
    // 小图上的选区转换成大图上的对应的显示区域 END
};

// 切换到下一张
Img.prototype.iFnNext = function(){
    var _this = this;
    this.iNext.onclick = function(){
        _this.fnNext();
    }
};

Img.prototype.fnNext = function(){
    this.num++;
    if(this.num > 9){
        this.num = 1;
    }
    // 设置图片地址
    this.iSamllImg.src = "http://yunkus.com/demo/lib/images/demo-"+ this.num +".jpg";
    this.iBigImg.src = "http://yunkus.com/demo/lib/images/demo-"+ this.num +".jpg";
    // 获取大图真正宽度
    this.iFnResponsive();
};
Img.prototype.iFnResponsive = function(){
    this.iBigBox.style.display = "block"; // 保证在获取宽高之前图片为的 display 为 block,不然获取的宽高都会为零
    var _this = this; 
    this.iSamllBox.style.width = rateScale(0.4).w;
    this.iSamllBox.style.height = rateScale(0.4).h;
    this.iMask.style.width = rateScale(0.4).w;
    this.iMask.style.height = rateScale(0.4).h;
    this.iSamllImg.style.width = rateScale(0.4).w;
    this.iSamllImg.style.height = rateScale(0.4).h;
    this.iBigBox.style.width = rateScale(0.5).w;
    this.iBigBox.style.height = rateScale(0.5).h;
    this.iBigBox.style.display = "none"; // 获取完宽高后隐藏
    function rateScale(n){  // 按比例缩放小图,放大区显示的大小
        return {
            w:_this.iBigImg.offsetWidth*n + "px",
            h:_this.iBigImg.offsetHeight*n + "px"
        }
    }
};

为了便于理解,在一些代码行中我也作为稍微作了一些注解,希望你看了注解后真的能帮到你理解,那么我的注解也算没白写。在IE 浏览器下会颤抖的问题除了可以像上面那样通过添加一个样式的方法来解决外,还可以通过 JavaScript 方法来解决:分别把 JS 中的 mouseover 和 mouseout 改成 mouseenter 和 mouseleave 就可以了。还有一个全兼容的方法,你可以点击这里查看页面并阅读源码:http://yunkus.com/demo/image-zoom-effect/index-compatible.html

主要是通过这个下面这个方法来实现的:

function eleContain(a,b){ // 判断两个元素是否是嵌套或者包含关系
    return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) && 16);
}

加强版的自带自适应功能,也就是会根据原图大小来动态设置小图及放大区的视野大小。

加强版DEMO:DEMO:http://yunkus.com/demo/image-zoom-effect/index-final.html

图片放大效果就分享到这里。代码如生活,如果你会这样想,写代码就不会是一种煎熬,而是一种享受,一种快乐。这里分享下我个人的一点点心得:

心得在此:

1.代码是敲出来的,不是看出来的,除非你很牛逼。

2.不管是写代码,还是在平时的生活中,你可以有畏难心理,但不能让它持续。

3.要把代码里的东西跟生活结合起来。比如:什么是对象?我们可以把它比作生活中的对象,Ta 具有什么特点是白富美还是矮矬穷(属性),你有什么技能,能干什么(方法)。

4.可以跟别人比能力,但不能急,你也急不来,要心静。

5.虽然知足可以让人更快乐,但有一些东西比如:学习千万不能妥协。

6.多跟有追求的人在一起,特别是对代码有一定追求的人,虽然你不知道很久以后你们会不会成为好朋友或者消失在彼此的生活圈里,但至少他有影响过你。

好了,这篇文章就到此为止,费再多的口舌,也不如静心一秒,相信我们都是行动派,即使不是也应都在路上。

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/image-zoom-effect/

Leave a Reply

Your email address will not be published. Required fields are marked *

评论 END