From e011382e1007402bfb3e7f5cfb87713a3dfd6aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=AB=E8=B0=B7=E5=89=91=E4=BB=99?= Date: Mon, 12 May 2025 03:41:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=8C=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E5=99=A8=E5=A2=9E=E5=8A=A0=E5=8F=AF=E4=BB=A5=E6=8B=96=E5=8A=A8?= =?UTF-8?q?=E9=98=9F=E4=BC=8D=E8=A7=92=E8=89=B2=E5=9B=BE=E6=A0=87=E5=88=B0?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E4=BD=8D=E7=BD=AE=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- script-universal_function.js | 100 ++++++++++++++++++++++------------- script.js | 53 ++++++++++++++++--- service-worker.js | 6 +-- style.css | 5 ++ 4 files changed, 117 insertions(+), 47 deletions(-) diff --git a/script-universal_function.js b/script-universal_function.js index b15a7030..fea06fd1 100644 --- a/script-universal_function.js +++ b/script-universal_function.js @@ -1245,16 +1245,16 @@ function cardN(id) { monOuterDom.monDom.onclick = cardNClick changeid({ id: id }, monDom); - function cardNClick(event) { - event?.preventDefault(); - const monstersID = document.getElementById("card-id"); - const formIdSearch = document.getElementById("form-id-search"); - monstersID.value = this.getAttribute("data-cardid"); - formIdSearch.onchange(); - editBox.show(); - } return monOuterDom; } +function cardNClick(event) { + event?.preventDefault(); + const monstersID = document.getElementById("card-id"); + const formIdSearch = document.getElementById("form-id-search"); + monstersID.value = this.getAttribute("data-cardid"); + formIdSearch.onchange(); + editBox.show(); +} //产生队伍目标类型 function createTeamFlags(target, type) @@ -1304,42 +1304,68 @@ function showSearchBySeriesId(sId, sType) { } } +function richTextCardNClick(){ + this.querySelector(".monster").click(); +} //创建序号类图标 function createIndexedIcon(type, index) { + const className = "drag-able-icon"; + let icon; if (type == 'card') {//卡片头像 - const avatar = cardN(index); - avatar.contentEditable = false; - //avatar.monDom.setAttribute("onclick", "cardNClick.call(this);return false;") - return avatar; - } - const icon = document.createElement("icon"); - icon.setAttribute("contenteditable", false); - //icon.contentEditable = false; - switch(type) { - case 'awoken': { //觉醒 - icon.className = "awoken-icon"; - icon.setAttribute("data-awoken-icon", index); - break; - } - case 'type': { //类型 - icon.className = "type-icon"; - icon.setAttribute("data-type-icon", index); - break; - } - case 'orb': { //宝珠 - icon.className = "orb"; - icon.setAttribute("data-orb-icon", index); - break; - } - case 'latent': { //潜觉 - icon.className = `latent-icon`; - icon.setAttribute("data-latent-icon", index); - icon.setAttribute("data-latent-hole", 1); - break; + icon = cardN(index); + icon.onclick = richTextCardNClick; + } else { + icon = document.createElement("icon"); + switch(type) { + case 'awoken': { //觉醒 + icon.className = "awoken-icon"; + icon.setAttribute("data-awoken-icon", index); + break; + } + case 'type': { //类型 + icon.className = "type-icon"; + icon.setAttribute("data-type-icon", index); + break; + } + case 'orb': { //宝珠 + icon.className = "orb"; + icon.setAttribute("data-orb-icon", index); + break; + } + case 'latent': { //潜觉 + icon.className = `latent-icon`; + icon.setAttribute("data-latent-icon", index); + icon.setAttribute("data-latent-hole", 1); + break; + } } } + icon.classList.add(className); + icon.contentEditable = false; + icon.draggable = true; + icon.ondragstart = indexedIconOnDragStart; + icon.indexedIcon = {type, index}; //拖拽用的 return icon; } +function indexedIconOnDragStart(event){ + draggedNode = this; // 记录原始节点 + event.dataTransfer.effectAllowed = 'copyMove'; + event.dataTransfer.setData("indexed-icon", JSON.stringify(this.indexedIcon)); +} + +//获取光标插入点位置 +function getCaretRange(event) { + let range; + if (document.caretPositionFromPoint) { + const pos = document.caretPositionFromPoint(event.clientX, event.clientY); + range = document.createRange(); + range.setStart(pos.offsetNode, pos.offset); + } + else if (document.caretRangeFromPoint) { + range = document.caretRangeFromPoint(event.clientX, event.clientY); + } + return range; +} //将怪物的文字介绍解析为HTML function descriptionToHTML(str) { diff --git a/script.js b/script.js index c15d357b..414f283d 100644 --- a/script.js +++ b/script.js @@ -18,6 +18,8 @@ let qrcodeReader; //二维码读取 let qrcodeWriter; //二维码输出 let selectedDeviceId; //视频源id +let draggedNode = null; // 保存被拖动的原始节点 + const dataStructure = 5; //阵型输出数据的结构版本 const cfgPrefix = "PADDF-"; //设置名称的前缀 const className_displayNone = "display-none"; @@ -3742,16 +3744,53 @@ function initialize() { //设置为可以拖放已经编辑好的队伍 function richTextDropHandler(event) { - let formStr = event.dataTransfer.getData('from'); - if (formStr) { + //console.debug(event); + + let isCopy = event.ctrlKey; //默认为按Ctrl是复制,不然是移动 + if (controlBox.querySelector("#change-swap-to-copy").checked) + isCopy = !isCopy; //勾选后逆向操作 + event.dataTransfer.dropEffect = isCopy ? 'copy' : 'move'; + + let newIcon; + const formStr = event.dataTransfer.getData('from'); + if (formStr) { //从队伍里拖下来的,需要重新创建怪物头像,强制复制 event.preventDefault(); + isCopy = true; + event.dataTransfer.dropEffect = 'copy'; const [teamNum, isAssist, indexInTeam] = JSON.parse(formStr); - const mon = formation.teams[teamNum][isAssist][indexInTeam] - event.target.insertAdjacentElement('afterbegin', createIndexedIcon('card', mon.id)); - } + const mon = formation.teams[teamNum][isAssist][indexInTeam]; + newIcon = createIndexedIcon('card', mon.id); + } else if (draggedNode) { + if (event.dataTransfer.dropEffect === 'move') { + newIcon = draggedNode; + } else { + //因为需要保留完整行为,所以不能直接用 cloneNode(true) + const indexed = event.dataTransfer.getData('indexed-icon'); + const {type, index} = JSON.parse(indexed); + newIcon = createIndexedIcon(type, index); + } + } + // 重置引用 + draggedNode = null; + + if (newIcon) { + event.preventDefault(); + const range = getCaretRange(event); //插入点 + if (range) { + range.insertNode(newIcon); + } else { + event.target.insertAdjacentElement('afterbegin', newIcon); + } + } } txtTitleDisplay.ondrop = richTextDropHandler; txtDetailDisplay.ondrop = richTextDropHandler; + txtTitleDisplay.ondragover = richTextDragOverHandler; + txtDetailDisplay.ondragover = richTextDragOverHandler; + //必须加上这个才可以内部拖动 + function richTextDragOverHandler(event) { + event.preventDefault(); + } //这个写法的目的其实是为了确保添加顺序与1、2、3一致,即便打乱了顺序,也能正确添加 for (let ti = 0, ti_len = formationBox.querySelectorAll(".team-bigbox").length; ti < ti_len; ti++) { @@ -3797,7 +3836,7 @@ function initialize() { } //编辑界面每个怪物的头像的放下 function dropMonHead(event) { - let formStr = event.dataTransfer.getData('from'); + const formStr = event.dataTransfer.getData('from'); if (!formStr) return false; const dataFrom = JSON.parse(formStr); const dataTo = getMemberArrayIndexFromMonHead(this); @@ -3882,7 +3921,7 @@ function initialize() { } function interchangeCard(formArr, toArr, isCopy) { //优先使用传入的复制,然后才是考虑开关 - isCopy = isCopy || controlBox.querySelector("#change-swap-to-copy").checked; //储存交换“复制”和“替换” + isCopy = isCopy ?? controlBox.querySelector("#change-swap-to-copy").checked; //储存交换“复制”和“替换” const [fromTeamNum, fromIsAssist, fromIndexInTeam] = formArr; const [toTeamNum, toIsAssist, toIndexInTeam] = toArr; diff --git a/service-worker.js b/service-worker.js index 6c14c3b7..3c0a0168 100644 --- a/service-worker.js +++ b/service-worker.js @@ -48283,11 +48283,11 @@ const cachesMap = new Map([ ], [ "script-universal_function.js", - "3ce2b3d06e12181f692fa5dd50fe9502" + "3642ace4c2c7d66f6e2647e7e056b71a" ], [ "script.js", - "203ca7805c5b2bc4015be3486f677a44" + "fafc4db852bf1cde1c040d73e8536329" ], [ "solo.html", @@ -48303,7 +48303,7 @@ const cachesMap = new Map([ ], [ "style.css", - "df773db29cb3d431cce9f4d3b87d27d5" + "0525027386dca0fe5e28549767eb42d7" ], [ "temp.js", diff --git a/style.css b/style.css index 604a60ca..4696cd51 100644 --- a/style.css +++ b/style.css @@ -1826,6 +1826,7 @@ label[for="search-string"] { .rich-text .detail-mon .monster{ transform: scale(0.5); margin: calc(-100px * (1 - 0.5) / 2); + pointer-events: none; } .custom-addition .detail-mon .monster{ transform: scale(0.35); @@ -1853,12 +1854,16 @@ label[for="search-string"] { .rich-text .detail-mon{ width: 50px; height: 50px; + user-select: none; /* 禁止文本选中 */ } .rich-text .detail-mon .monster .id{ background-color: rgba(0,0,0,0.5); padding: 2px; font-size: 23px; } +.rich-text .drag-able-icon { + cursor: grab; +} /*搜索结果显示觉醒列表的相关css*/ .awoken-preview .awoken-ul {