目的
蜘蛛纸牌中要实现牌组的连接,就需要吸附功能。从效果图中可以看出我们把一张牌拖到另一张卡牌上的时候,它会自动吸附过去并且左对齐。
效果
代码
<!DOCTYPE html>
<html>
<head>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #2b2b2b;
position: relative;
//这很关键,如果没有这个左对齐不了
margin: 0;
}
.card {
/*设置卡牌的外观*/
width: 150px;
height: 200px;
background-color: #00ffcc;
border-radius: 10px;
/*为卡牌中间的图案设置格式*/
font-size: 100px;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
/*方便左上角和右下角的数字定位*/
position: absolute;
/*避免选择到文本*/
user-select: none;
border: 1px solid black;
}
/*设置卡牌两个对角的数字格式*/
.pos-TL {
position: absolute;
font-size: 20px;
top: 5px;
left: 5px;
}
.pos-BR {
position: absolute;
font-size: 20px;
bottom: 5px;
right: 5px;
transform: rotateZ(180deg);
}
</style>
</head>
<body>
<!--把卡牌里的元素都放到卡牌这个容器里,对卡牌的动画会传到卡牌元素里-->
<div class="card" id="card1">♠️
<div class="card-num pos-TL">6</div>
<div class="card-num pos-BR">6</div>
</div>
<div class="card" id="card2">♠️
<div class="card-num pos-TL">3</div>
<div class="card-num pos-BR">3</div>
</div>
<script>
let offsetX, offsetY, isDragging = false;
const card2 = document.getElementById("card2");
const card1 = document.getElementById("card1");
card2.addEventListener("mousedown", (e) => {
isDragging = true;
offsetX = e.clientX - card2.getBoundingClientRect().left;
offsetY = e.clientY - card2.getBoundingClientRect().top;
})
document.addEventListener("mousemove", (e) => {
if (isDragging) {
card2.style.left = `${e.clientX - offsetX}px`;
card2.style.top = `${e.clientY - offsetY}px`;
}
})
document.addEventListener("mouseup", () => {
isDragging = false;
absorbing()
})
//吸附函数
function absorbing( ) {
const firstCard = card1.getBoundingClientRect();
const lastCard = card2.getBoundingClientRect();
//判断是否大面积重合
if (firstCard.right > lastCard.left && firstCard.left < lastCard.right && firstCard.bottom > lastCard.top && firstCard.top < firstCard.bottom) {
card2.style.left = `${firstCard.left}px`;
}
}
</script>
</body>
</html>
总结
- 先说最重要的就是左对齐,如果你没有在
body
里面设置margin:0;
,那么可能出现这样的情况
无论怎么样对无法让两张卡片左对齐,这就是margin
带来的影响,我们需要将其设为0。 - 判断两个元素重叠用
.style.left
还是用.getBoundingClientrect().left
选择.getBoundingClientrect().left
因为后者是基于窗口的位置来计算的,而前者是基于父元素的相对位置计算的。所以前者更加准确,而后者会根据父元素的变化导致预期外的变化。 - 不能修改DOMrect的属性,因为只读。