Html笔记()蜘蛛纸牌之卡牌吸附

目的

蜘蛛纸牌中要实现牌组的连接,就需要吸附功能。从效果图中可以看出我们把一张牌拖到另一张卡牌上的时候,它会自动吸附过去并且左对齐。

效果

代码

html 复制代码
<!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的属性,因为只读。
相关推荐
星恒随风10 小时前
MySQL 从零入门(五):MySQL 内置函数详解——日期、字符串、数学函数与实战案例
linux·数据库·笔记·sql·mysql
2603_9696948513 小时前
【JavaWeb学习记录】MyBatis核心知识点与实战笔记:从入门到动态SQL
笔记·sql·学习·mysql·mybatis·javaweb·学习方法
treasure14013 小时前
【复古】浅尝Django前后端不分离
前端·css·python·django·bootstrap·html·web
可乐ea13 小时前
智能体记忆该拆成几层:笔记、记忆表示与注入上下文
服务器·数据库·笔记·ai智能体·提示词工程·上下文工程·记忆系统
Go Work17 小时前
两个等值条件摆着,MySQL 偏要全表扫
经验分享·笔记
Oll Correct17 小时前
Adobe illustrator 案例十四:花元素标志草图绘制
笔记·ui·adobe·illustrator
ZhengEnCi21 小时前
前端项目为什么需要一份统一的 theme.css:用 CSS 变量管住全局样式与主题切换
前端·css·前端工程化
每月一号准时摆烂21 小时前
服务器运维笔记(一)——使用shell编写实时查看BMC功率的脚本
运维·服务器·笔记
牧艺2 天前
弹层不用再手算坐标了:CSS Anchor Positioning 从原理到可上线
前端·javascript·css
柳鲲鹏2 天前
内斗学概论:43、平级内斗
笔记