拖拽你会吗,啊?会吗? 会!撸一个照片墙

553 阅读2分钟

二话不说先上图

图裂了!

效果就是这样,感兴趣,走起! github源码在 这里

先看下需求

  • 按下后选中图片背景色变为深蓝色,被碰撞的图片背景色变红,位置变化完成后颜色变成原始色
  • 没有碰撞,位置复原;多个碰撞和接触面积最大的交换位置
  • 交换位置时,选中的图片在最上层划过去

别废话,告诉我怎么实现

  • 图片绝对定位,记录鼠标点下去后的起始位置和抬起位置,通过修改图片的topleft值完成移动
  • 鼠标按下记录下鼠标位置和选中图片的位置,柯里化处理this指向
  • 浏览器默认元素是不能拖拽的,想要拖拽就得取消浏览器的默认行为event.preventDefault
  • 拖拽开始时改变被选中图片的z-Index确保在其他图片上移动
  • 移动过程中检测有无和其他图片的碰撞,有,改变碰撞图片的背景色
  • 拖拽结束,和接触面积最大的图片交换位置或者回原来位置

页面结构

<ul class="box" id="box">
    <li><img src="./img/1.png" alt=""></li>
    <li><img src="./img/2.png" alt=""></li>
    <li><img src="./img/3.png" alt=""></li>
    <li><img src="./img/4.png" alt=""></li>
    <li><img src="./img/5.png" alt=""></li>
    <li><img src="./img/6.png" alt=""></li>
    <li><img src="./img/7.png" alt=""></li>
    <li><img src="./img/8.png" alt=""></li>
    <li><img src="./img/9.png" alt=""></li>
</ul>

页面初始化

为了方便,操作DOM我用的jquery

let boxList = $('#box>li');
let zIndex = 0;
//进入页面先记录下每个图片的初始位置,并绑定事件
for (let i = boxList.length - 1; i >= 0; i--) { // 为了防止float塌陷,从最后一张图片开始设置CSS属性
    let curLi = boxList[i];
    // 记录下最开始的top和left值
    curLi.originTop = curLi.offsetTop; 
    curLi.originLeft = curLi.offsetLeft;

    $(curLi).css({
        position: "absolute",
        margin: 0, //绝对定位的时候就不需要margin了
        top: curLi.originTop,
        left: curLi.originLeft
    });
    $(curLi).on("mousedown", down);
    $(curLi).on("dragstart", increaseIndex);
    $(curLi).on("dragstart", preventDefault);
    $(curLi).on("drag", boxMove);
    $(curLi).on("drag", preventDefault);
    $(curLi).on("dragend", changePos);
    $(curLi).on("dragend", preventDefault);
}

如果不太清楚offsetTop,offsetLeft,e.pageX,e.pageY可以参考 这里

更多源码猛戳 这里