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

JavaScript 实现照片墙效果

照片墙效果相信你也看到过不少,在这里我们也尝试去做了一个,没有炫丽的效果,没有多余的文字,一时按捺不住成就感,在此把在大神眼里不值一提的照片墙效果献上。请多多包含!

HTML 代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>照片墙效果-云库前端</title>
    <link rel="stylesheet" href="./css/style.css">
    <meta name="description" content="纯 JavaScript 实现照片墙效果" />
    <meta name="keywords" content="照片墙" />
</head>
<body>
<ul class="picture-box" id="iPictureBox">
    <li><img src="http://yunkus.com/demo/lib/images/demo-1.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-2.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-3.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-4.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-5.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-6.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-7.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-8.jpg" alt=""></li>
    <li><img src="http://yunkus.com/demo/lib/images/demo-9.jpg" alt=""></li>
</ul>
<script src="./js/dynamics.min.js"></script>
<script src="./js/index.js"></script>
</body>
</html>

CSS 代码:

*{
    padding: 0;
    margin: 0;
}
ul{
    list-style: none;
}
.picture-box{
    position: relative;
    width: 680px;
    margin: 0 auto;
}
.picture-box li{
    float: left;
    margin-right: 12px;
    margin-bottom: 12px;
    width: 200px;
    height: 200px;
    z-index: 1;
}
.picture-box li img{
    width: 200px;
    height: 200px;
}
.picture-box li.select{
   z-index: 2;
   box-shadow: 0 0 8px #ccc;
}

JavaScript 代码:

window.onload = function(){
    var drag = new Drag();
    drag.init();
}

function Drag(){
    this.iPictureBox = null;
    this.iLi = null;
    this.iLiLen = null;
    this.originPosition = [];
    this.currentIndex = null;
    this.oldIndex = null;
    this.disX = null;
    this.disY = null;
    this.changeTarget = null;
    this.rX = null;
    this.rR = null;
    this.disPoint = null;
    this.currentObj = null;
    this.targetObj = null;
    this.targetNum = 0;
}

Drag.prototype.init = function(){
    var _this = this; // 保存 this 对像,后面会用到,这个也是值得注意的地方
    this.iPictureBox = document.getElementById("iPictureBox");
    this.iLi = this.iPictureBox.getElementsByTagName("li");
    this.iLiLen = this.iLi.length;
    for(var i=0;i<this.iLiLen;i++){
        // 保存图片更改而已前各个 li 对应的位置信息
        this.originPosition.push([this.iLi[i].offsetLeft,this.iLi[i].offsetTop]);
    }

    // 切换布局方式
    for(var j=0;j<this.iLiLen;j++){
        this.iLi[j].style.position = "absolute";
        this.iLi[j].style.left = this.originPosition[j][0] + "px";
        this.iLi[j].style.top = this.originPosition[j][1] + "px";
    }

    for(var k=0;k<this.iLiLen;k++){ // 给所有的 li 添加事件
        this.iLi[k].index = k;
        this.iLi[k].onmousedown = function(ev){
            var ev = ev || window.event;
            _this.currentObj = this;
            _this.FnDown(ev);
            _this.oldIndex = _this.currentObj.index;
            ev.preventDefault();
        }
    }
}

// 鼠标按下时处理函数
Drag.prototype.FnDown = function(ev){
    var _this = this;
    if (this.rectW == null && this.rectH == null) {
        this.rectW = this.iLi[this.currentObj.index].offsetWidth/2;
        this.rectH = this.iLi[this.currentObj.index].offsetHeight/2;
        this.disPoint = this.iLi[this.currentObj.index].offsetHeight;
    }
    
    this.disX = ev.clientX - this.currentObj.offsetLeft;
    this.disY = ev.clientY - this.currentObj.offsetTop;
    this.currentObj.classList.add("select");

    document.onmousemove = function(ev){
        var ev = ev || window.event;
        _this.FnMove(ev);
    }
    document.onmouseup = function(){
        for(var i=0;i<_this.iLiLen;i++){
            if(_this.currentObj != _this.iLi[i] && _this.FnTouch(i)){
                _this.targetObj = _this.FnMinDis();
                _this.targetNum++;
            }
        }

        if(_this.targetNum == 0){ // 判断是鼠标抬起时是否有碰到其它图片,没有则回到原位置
            dynamics.animate(_this.currentObj, {
              left: _this.originPosition[_this.currentObj.index][0],
              top: _this.originPosition[_this.currentObj.index][1]
            }, {
              type: dynamics.spring,
              frequency: 200,
              friction: 200,
              duration: 500
            })
        }else{
              _this.FnChange(); // 两张图片交换
        }
        _this.targetNum = 0;
        document.onmousemove = null;
        document.onmouseup = null;
        _this.currentObj.classList.remove("select");
    }
}

// 按下鼠标并移动时处理函数
Drag.prototype.FnMove = function(ev){
    var _this = this;
    this.currentObj.style.left = ev.clientX - this.disX + "px";
    this.currentObj.style.top = ev.clientY - this.disY + "px";
    for(var i=0;i<this.iLiLen;i++){
        if(this.currentObj != this.iLi[i] && this.FnTouch(i)){
            this.targetObj = this.iLi[i];
            for(var j=0;j<this.iLiLen;j++){
                this.iLi[i].style.border = "";
            }
            this.FnMinDis().style.border = "1px solid #000";
            _this.targetObj = _this.FnMinDis();
        }else{
            this.iLi[i].style.border = "";
        }
    }
}

// 图片碰撞判断函数
Drag.prototype.FnTouch = function(target){
    var cX = this.currentObj.offsetLeft + this.rectW;
    var cY = this.currentObj.offsetTop + this.rectH;
    var tX = this.iLi[target].offsetLeft + this.rectW;
    var tY = this.iLi[target].offsetTop + this.rectH;
    if(Math.abs(cX-tX)<this.disPoint && Math.abs(cY-tY)<this.disPoint){
        return true;
    }else{
        return false;
    }
}

// 图片位置互换函数
Drag.prototype.FnChange = function(){
   // this.currentObj.style.left = this.originPosition[this.targetObj.index][0] + "px";
   // this.currentObj.style.top = this.originPosition[this.targetObj.index][1] + "px";
   // this.targetObj.style.left = this.originPosition[this.currentObj.index][0] + "px";
   // this.targetObj.style.top = this.originPosition[this.currentObj.index][1] + "px";

    // 把上面的位置变时改成动感的运动变换,可以使用 dynamics.js 库的各种特效实现不同的切换效果
    dynamics.animate(this.currentObj, {
      left: this.originPosition[this.targetObj.index][0],
      top: this.originPosition[this.targetObj.index][1]
    }, {
      type: dynamics.spring,
      frequency: 200,
      friction: 200,
      duration: 500
    })

    dynamics.animate(this.targetObj, {
      left: this.originPosition[this.currentObj.index][0],
      top: this.originPosition[this.currentObj.index][1]
    }, {
      type: dynamics.spring,
      frequency: 200,
      friction: 200,
      duration: 500
    })

   this.targetObj.style.border = "";
   
   // 交换index
   var temp = this.currentObj.index;
   this.currentObj.index = this.targetObj.index;
   this.targetObj.index = temp;
}

// 求出跟拖拽元素距离最近的一个
Drag.prototype.FnMinDis = function(){
    var temp = null;
    var tempObj = null;
    for(var i=0;i<this.iLiLen;i++){
        if(this.currentObj != this.iLi[i]){
            var a = (this.currentObj.offsetLeft + this.rectW) - (this.iLi[i].offsetLeft + this.rectW);
            var b = (this.currentObj.offsetTop + this.rectH) - (this.iLi[i].offsetTop + this.rectH);
            var c = Math.sqrt(Math.pow(a,2) + Math.pow(b,2));
            if(temp == null || temp>c){
                temp = c;
                tempObj = this.iLi[i];
            }
        }
    }
    return tempObj;
}

到此照片墙效果代码已经分享完毕。但是这肯定不是你最想看到的,你最想看到的应该是这个效果怎么样?是马是骡,拉出来溜溜就知道,为此放出 DEMO 一枚,坐稳,带好安全带,速度有点快:http://yunkus.com/demo/photo-wall/。这个例子使用了一个 dynamics.js 库实现基本的运动效果,具体的用法可以到官网去看看:http://dynamicsjs.com/。老司机也只能送你到这里了。

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

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

本文永久链接:http://yunkus.com/javascript-photo-wall/

Leave a Reply

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

评论 END