From d50e5329a05fbfba18f8a69d3d59e652c57b888f Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Wed, 10 Sep 2025 07:28:38 +0800 Subject: [PATCH] 'commit' --- dsLightRag/XingJun/css/style.css | 21 + dsLightRag/XingJun/fill.html | 140 ----- dsLightRag/XingJun/history_lesson.html | 92 ---- dsLightRag/XingJun/{ => images}/1.png | Bin dsLightRag/XingJun/{ => images}/2.png | Bin dsLightRag/XingJun/{ => images}/3.png | Bin dsLightRag/XingJun/{ => images}/4.png | Bin dsLightRag/XingJun/{ => images}/5.png | Bin dsLightRag/XingJun/{ => images}/6.png | Bin .../7272f599b59ad372ec5d8e5a104ab9e2.jpeg | Bin .../XingJun/{ => images}/background.png | Bin dsLightRag/XingJun/{ => images}/redArraw.png | Bin .../{ => images}/各种各样的红色箭头.png | Bin dsLightRag/XingJun/js/script.js | 407 ++++++++++++++ dsLightRag/XingJun/move.html | 509 +----------------- dsLightRag/XingJun/{ => txt}/历史行军地图.txt | 0 dsLightRag/XingJun/{ => txt}/改图神器.txt | 0 17 files changed, 443 insertions(+), 726 deletions(-) create mode 100644 dsLightRag/XingJun/css/style.css delete mode 100644 dsLightRag/XingJun/fill.html delete mode 100644 dsLightRag/XingJun/history_lesson.html rename dsLightRag/XingJun/{ => images}/1.png (100%) rename dsLightRag/XingJun/{ => images}/2.png (100%) rename dsLightRag/XingJun/{ => images}/3.png (100%) rename dsLightRag/XingJun/{ => images}/4.png (100%) rename dsLightRag/XingJun/{ => images}/5.png (100%) rename dsLightRag/XingJun/{ => images}/6.png (100%) rename dsLightRag/XingJun/{ => images}/7272f599b59ad372ec5d8e5a104ab9e2.jpeg (100%) rename dsLightRag/XingJun/{ => images}/background.png (100%) rename dsLightRag/XingJun/{ => images}/redArraw.png (100%) rename dsLightRag/XingJun/{ => images}/各种各样的红色箭头.png (100%) create mode 100644 dsLightRag/XingJun/js/script.js rename dsLightRag/XingJun/{ => txt}/历史行军地图.txt (100%) rename dsLightRag/XingJun/{ => txt}/改图神器.txt (100%) diff --git a/dsLightRag/XingJun/css/style.css b/dsLightRag/XingJun/css/style.css new file mode 100644 index 00000000..072f213e --- /dev/null +++ b/dsLightRag/XingJun/css/style.css @@ -0,0 +1,21 @@ +body { margin: 0; padding: 0; height: 100vh; display: flex; overflow: hidden; } +.background-container { position: relative; flex: 1; height: 100vh; background-image: url('../images/background.png'); background-position: center; background-repeat: no-repeat; background-size: contain; z-index: 1; } +.control-panel { width: 200px; background-color: #fff; border-left: 1px solid #ccc; padding: 20px; height: 100vh; box-sizing: border-box; z-index: 2; overflow-y: auto; } +.control-section { margin-bottom: 30px; } +.control-section h3 { margin-top: 0; padding-bottom: 10px; border-bottom: 1px solid #eee; } +.image-selector { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 15px; } +.image-btn { width: 70px; height: 70px; border: 2px solid #ddd; border-radius: 4px; cursor: pointer; background-size: contain; background-repeat: no-repeat; background-position: center; transition: all 0.2s; } +.image-btn:hover { border-color: #4CAF50; transform: scale(1.05); } +.image-btn:active { transform: scale(0.98); } +.arrow-container { position: absolute; pointer-events: auto; } +.arrow-image { width: 155px; height: 173px; background-size: contain; background-repeat: no-repeat; cursor: move; } +.save-btn { width: 100%; padding: 10px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; margin-top: 20px; } +.save-btn:hover { background-color: #45a049; } +.arrow-text { position: absolute; top: '100%'; left: '50%'; transform: translateX(-50%); margin-top: '-5px'; font-weight: bold; color: red; font-size: 16px; white-space: nowrap; text-align: center; width: 100%; background-color: transparent; padding: 3px 8px; border-radius: 4px; } +#contextMenu { position: absolute; display: none; background: white; border: 1px solid #ccc; padding: 5px; z-index: 9999; } +#deleteArrow { padding: 3px 10px; cursor: pointer; } +.menu-separator { height: 1px; background-color: #ccc; margin: 5px 0; } +.menu-item { padding: 3px 10px; cursor: pointer; } +.menu-item:hover { background-color: #f0f0f0; } +.check-mark { display: inline-block; width: 16px; text-align: center; } +.center-dot { position: absolute; width: 8px; height: 8px; background: red; border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; z-index: 5; } \ No newline at end of file diff --git a/dsLightRag/XingJun/fill.html b/dsLightRag/XingJun/fill.html deleted file mode 100644 index 496ef56c..00000000 --- a/dsLightRag/XingJun/fill.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - 双箭头填充动画 - - - -
-

双箭头填充动画演示

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - \ No newline at end of file diff --git a/dsLightRag/XingJun/history_lesson.html b/dsLightRag/XingJun/history_lesson.html deleted file mode 100644 index 9b9dd010..00000000 --- a/dsLightRag/XingJun/history_lesson.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - -军事攻击箭头(点击开始) - - - - -
- -
- - - -
- - - - - - - - - - - - - - - - - - - -
9纵
-
73军
-
莱芜
-
- - - - \ No newline at end of file diff --git a/dsLightRag/XingJun/1.png b/dsLightRag/XingJun/images/1.png similarity index 100% rename from dsLightRag/XingJun/1.png rename to dsLightRag/XingJun/images/1.png diff --git a/dsLightRag/XingJun/2.png b/dsLightRag/XingJun/images/2.png similarity index 100% rename from dsLightRag/XingJun/2.png rename to dsLightRag/XingJun/images/2.png diff --git a/dsLightRag/XingJun/3.png b/dsLightRag/XingJun/images/3.png similarity index 100% rename from dsLightRag/XingJun/3.png rename to dsLightRag/XingJun/images/3.png diff --git a/dsLightRag/XingJun/4.png b/dsLightRag/XingJun/images/4.png similarity index 100% rename from dsLightRag/XingJun/4.png rename to dsLightRag/XingJun/images/4.png diff --git a/dsLightRag/XingJun/5.png b/dsLightRag/XingJun/images/5.png similarity index 100% rename from dsLightRag/XingJun/5.png rename to dsLightRag/XingJun/images/5.png diff --git a/dsLightRag/XingJun/6.png b/dsLightRag/XingJun/images/6.png similarity index 100% rename from dsLightRag/XingJun/6.png rename to dsLightRag/XingJun/images/6.png diff --git a/dsLightRag/XingJun/7272f599b59ad372ec5d8e5a104ab9e2.jpeg b/dsLightRag/XingJun/images/7272f599b59ad372ec5d8e5a104ab9e2.jpeg similarity index 100% rename from dsLightRag/XingJun/7272f599b59ad372ec5d8e5a104ab9e2.jpeg rename to dsLightRag/XingJun/images/7272f599b59ad372ec5d8e5a104ab9e2.jpeg diff --git a/dsLightRag/XingJun/background.png b/dsLightRag/XingJun/images/background.png similarity index 100% rename from dsLightRag/XingJun/background.png rename to dsLightRag/XingJun/images/background.png diff --git a/dsLightRag/XingJun/redArraw.png b/dsLightRag/XingJun/images/redArraw.png similarity index 100% rename from dsLightRag/XingJun/redArraw.png rename to dsLightRag/XingJun/images/redArraw.png diff --git a/dsLightRag/XingJun/各种各样的红色箭头.png b/dsLightRag/XingJun/images/各种各样的红色箭头.png similarity index 100% rename from dsLightRag/XingJun/各种各样的红色箭头.png rename to dsLightRag/XingJun/images/各种各样的红色箭头.png diff --git a/dsLightRag/XingJun/js/script.js b/dsLightRag/XingJun/js/script.js new file mode 100644 index 00000000..32d440fd --- /dev/null +++ b/dsLightRag/XingJun/js/script.js @@ -0,0 +1,407 @@ +// 添加常量定义 +const ARROW_WIDTH = 155; +const ARROW_HEIGHT = 173; +const STOP_DISTANCE = 50; +document.addEventListener('DOMContentLoaded', function() { + const backgroundContainer = document.querySelector('.background-container'); + const imageButtons = document.querySelectorAll('.image-btn'); + const markCenterBtn = document.getElementById('markCenterBtn'); + const startAnimationBtn = document.getElementById('startAnimationBtn'); + const resetBtn = document.getElementById('resetBtn'); + const contextMenu = document.getElementById('contextMenu'); + const deleteArrow = document.getElementById('deleteArrow'); + let selectedArrow = null; + let centerDot = null; + + // 添加重置按钮事件监听器 + resetBtn.addEventListener('click', function() { + location.reload(); + }); + + // 添加开始按钮事件监听器 + startAnimationBtn.addEventListener('click', startAnimation); + + // 动画控制函数 + function startAnimation() { + if (!centerDot) { + alert('请先确定中心点'); + return; + } + + const centerRect = centerDot.getBoundingClientRect(); + const containerRect = backgroundContainer.getBoundingClientRect(); + const centerX = centerRect.left - containerRect.left; + const centerY = centerRect.top - containerRect.top; + + const arrows = document.querySelectorAll('.arrow-container'); + if (arrows.length === 0) { + alert('没有可移动的箭头'); + return; + } + + arrows.forEach(arrow => { + animateArrow(arrow, centerX, centerY); + }); + } + + // 添加偏移量输入框事件处理 + const globalStopDistanceInput = document.getElementById('global-stop-distance'); + + function updateStopDistanceInput() { + if (selectedArrow) { + globalStopDistanceInput.value = selectedArrow.dataset.stopDistance || 20; + globalStopDistanceInput.disabled = false; + } else { + globalStopDistanceInput.value = 20; + globalStopDistanceInput.disabled = true; + } + } + + globalStopDistanceInput.addEventListener('input', function() { + if (selectedArrow) { + selectedArrow.dataset.stopDistance = this.value; + console.log(`[设置] 箭头停止距离: ${this.value}px`); + saveAllElements(); + } + }); + + function selectArrow(arrow) { + document.querySelectorAll('.arrow-container').forEach(el => { + el.style.outline = 'none'; + }); + selectedArrow = arrow; + if (selectedArrow) { + selectedArrow.style.outline = '2px solid blue'; + } + updateStopDistanceInput(); + } + + // 点击空白处取消选择 + document.addEventListener('click', function() { + selectedArrow = null; + document.querySelectorAll('.arrow-container').forEach(el => { + el.style.outline = 'none'; + }); + updateStopDistanceInput(); + contextMenu.style.display = 'none'; + }); + + // 单个箭头动画函数 + function animateArrow(arrow, targetX, targetY) { + const arrowWidth = ARROW_WIDTH; + const arrowHeight = ARROW_HEIGHT; + const centerOffsetX = arrowWidth / 2; + const centerOffsetY = arrowHeight / 2; + const stopDistance = parseInt(arrow.dataset.stopDistance) || STOP_DISTANCE; + + const rect = arrow.getBoundingClientRect(); + const containerRect = backgroundContainer.getBoundingClientRect(); + let currentX = rect.left - containerRect.left + centerOffsetX; + let currentY = rect.top - containerRect.top + centerOffsetY; + + const offsetRange = 20; + const randomOffsetX = (Math.random() - 0.5) * offsetRange; + const randomOffsetY = (Math.random() - 0.5) * offsetRange; + const finalTargetX = targetX + randomOffsetX; + const finalTargetY = targetY + randomOffsetY; + + const dxTotal = finalTargetX - currentX; + const dyTotal = finalTargetY - currentY; + const distanceTotal = Math.sqrt(dxTotal * dxTotal + dyTotal * dyTotal); + + let adjustedTargetX, adjustedTargetY; + if (distanceTotal > stopDistance) { + const ratio = (distanceTotal - stopDistance) / distanceTotal; + adjustedTargetX = currentX + dxTotal * ratio; + adjustedTargetY = currentY + dyTotal * ratio; + } else { + adjustedTargetX = currentX; + adjustedTargetY = currentY; + } + + function updatePosition() { + const dx = adjustedTargetX - currentX; + const dy = adjustedTargetY - currentY; + const distance = Math.sqrt(dx * dx + dy * dy); + + if (distance < 2) { + arrow.style.left = (adjustedTargetX - centerOffsetX) + 'px'; + arrow.style.top = (adjustedTargetY - centerOffsetY) + 'px'; + return; + } + + const step = Math.max(distance * 0.05, 1); + const moveX = (dx / distance) * step; + const moveY = (dy / distance) * step; + + currentX += moveX; + currentY += moveY; + arrow.style.left = (currentX - centerOffsetX) + 'px'; + arrow.style.top = (currentY - centerOffsetY) + 'px'; + + requestAnimationFrame(updatePosition); + } + + updatePosition(); + } + + // 加载保存的元素 + loadAllElements(); + + // 绑定箭头按钮事件 + imageButtons.forEach(button => { + button.addEventListener('click', () => { + const imagePath = button.getAttribute('data-image'); + addImageToContainer(imagePath); + }); + }); + + // 右键菜单事件 + deleteArrow.addEventListener('click', function() { + if (selectedArrow) { + selectedArrow.remove(); + saveAllElements(); + contextMenu.style.display = 'none'; + selectedArrow = null; + } + }); + + // 为匹配角菜单项添加事件监听器 + document.querySelectorAll('.menu-item').forEach(item => { + item.addEventListener('click', function() { + if (selectedArrow) { + const referencePoint = this.getAttribute('data-point'); + selectedArrow.dataset.referencePoint = referencePoint; + saveAllElements(); + contextMenu.style.display = 'none'; + selectedArrow = null; + } + }); + }); + + // 点击空白处关闭菜单 + document.addEventListener('click', function() { + contextMenu.style.display = 'none'; + selectedArrow = null; + }); + + // 标记中心点功能 + markCenterBtn.addEventListener('click', function() { + if (centerDot) { + centerDot.remove(); + centerDot = null; + } + + function handleMapClick(e) { + const rect = backgroundContainer.getBoundingClientRect(); + const x = e.clientX - rect.left; + const y = e.clientY - rect.top; + + centerDot = document.createElement('div'); + centerDot.className = 'center-dot'; + centerDot.style.left = x + 'px'; + centerDot.style.top = y + 'px'; + + backgroundContainer.appendChild(centerDot); + backgroundContainer.removeEventListener('click', handleMapClick); + + console.log('[中心点] 已标记中心点:', { left: centerDot.style.left, top: centerDot.style.top }); + saveAllElements(); + } + + backgroundContainer.addEventListener('click', handleMapClick); + }); + + // 添加箭头函数 + function addImageToContainer(imagePath, position = null, textContent = '') { + const container = document.createElement('div'); + container.className = 'arrow-container'; + container.dataset.imagePath = imagePath; + + const newImage = document.createElement('div'); + newImage.className = 'arrow-image'; + newImage.style.backgroundImage = `url('${imagePath}')`; + + container.appendChild(newImage); + + // 添加文字元素 + if (textContent) { + const textElement = document.createElement('div'); + textElement.className = 'arrow-text'; + textElement.textContent = textContent; + container.dataset.text = textContent; + container.appendChild(textElement); + } + + // 设置位置 + const arrowWidth = ARROW_WIDTH; + const arrowHeight = ARROW_HEIGHT; + const centerOffsetX = arrowWidth / 2; + const centerOffsetY = arrowHeight / 2; + + if (position) { + container.style.left = parseFloat(position.left) + 'px'; + container.style.top = parseFloat(position.top) + 'px'; + if (position.referencePoint) { + container.dataset.referencePoint = position.referencePoint; + } + if (position.stopDistance) { + container.dataset.stopDistance = position.stopDistance; + } + } else { + const x = Math.random() * (backgroundContainer.offsetWidth - arrowWidth) + centerOffsetX; + const y = Math.random() * (backgroundContainer.offsetHeight - arrowHeight) + centerOffsetY; + container.style.left = (x - centerOffsetX) + 'px'; + container.style.top = (y - centerOffsetY) + 'px'; + } + + // 双击编辑文字 + container.addEventListener('dblclick', (e) => { + e.stopPropagation(); + const currentText = container.dataset.text || ''; + const textContent = prompt('请输入文字:', currentText); + if (textContent !== null) { + if (textContent.trim() === '') { + container.querySelector('.arrow-text')?.remove(); + delete container.dataset.text; + } else { + let textElement = container.querySelector('.arrow-text'); + if (!textElement) { + textElement = document.createElement('div'); + textElement.className = 'arrow-text'; + container.appendChild(textElement); + } + textElement.textContent = textContent; + container.dataset.text = textContent; + saveAllElements(); + } + } + }); + + // 右键菜单支持 + container.addEventListener('contextmenu', function(e) { + e.preventDefault(); + selectedArrow = this; + contextMenu.style.left = `${e.clientX}px`; + contextMenu.style.top = `${e.clientY}px`; + contextMenu.style.display = 'block'; + + const currentPoint = selectedArrow.dataset.referencePoint || 'top-left'; + document.querySelectorAll('.menu-item').forEach(item => { + const checkMark = item.querySelector('.check-mark'); + if (!checkMark) return; + checkMark.textContent = item.getAttribute('data-point') === currentPoint ? '✓' : ''; + }); + }); + + // 拖拽功能 + let isDragging = false; + let offsetX, offsetY; + + newImage.addEventListener('mousedown', startDrag); + + function startDrag(e) { + e.preventDefault(); + isDragging = true; + selectedArrow = container; + container.style.zIndex = '10'; + + const rect = container.getBoundingClientRect(); + offsetX = e.clientX - rect.left; + offsetY = e.clientY - rect.top; + + document.addEventListener('mousemove', drag); + document.addEventListener('mouseup', stopDrag); + } + + function drag(e) { + if (!isDragging) return; + const containerRect = backgroundContainer.getBoundingClientRect(); + const x = e.clientX - containerRect.left - offsetX; + const y = e.clientY - containerRect.top - offsetY; + + container.style.left = x + 'px'; + container.style.top = y + 'px'; + } + + function stopDrag() { + if (isDragging) { + isDragging = false; + container.style.zIndex = '1'; + saveAllElements(); + document.removeEventListener('mousemove', drag); + document.removeEventListener('mouseup', stopDrag); + } + } + + backgroundContainer.appendChild(container); + saveAllElements(); + return container; + } + + // 保存所有元素状态 + function saveAllElements() { + const elements = []; + + // 保存中心点 + if (centerDot) { + localStorage.setItem('centerPoint', JSON.stringify({ + left: centerDot.style.left, + top: centerDot.style.top + })); + } else { + localStorage.removeItem('centerPoint'); + } + + // 保存箭头 + document.querySelectorAll('.arrow-container').forEach(arrow => { + elements.push({ + type: 'arrow', + imagePath: arrow.dataset.imagePath, + left: arrow.style.left, + top: arrow.style.top, + text: arrow.dataset.text || '', + referencePoint: arrow.dataset.referencePoint || 'top-left', + stopDistance: arrow.dataset.stopDistance || 20 + }); + }); + + localStorage.setItem('savedElements', JSON.stringify(elements)); + console.log('[保存] 已保存元素:', elements); + } + + // 加载所有元素状态 + function loadAllElements() { + // 加载中心点 + const savedCenter = localStorage.getItem('centerPoint'); + if (savedCenter) { + const center = JSON.parse(savedCenter); + centerDot = document.createElement('div'); + centerDot.className = 'center-dot'; + centerDot.style.left = center.left; + centerDot.style.top = center.top; + backgroundContainer.appendChild(centerDot); + } + + // 加载箭头 + const savedElements = localStorage.getItem('savedElements'); + if (savedElements) { + const elements = JSON.parse(savedElements); + elements.forEach(element => { + if (element.type === 'arrow') { + // Fix image path by adding 'images/' prefix if missing + if (!element.imagePath.startsWith('images/')) { + element.imagePath = `images/${element.imagePath}`; + } + addImageToContainer(element.imagePath, element, element.text); + } + }); + console.log('[加载] 已加载元素:', elements); + } + } + + // 阻止右键菜单冒泡 + contextMenu.addEventListener('click', function(e) { + e.stopPropagation(); + }); +}); \ No newline at end of file diff --git a/dsLightRag/XingJun/move.html b/dsLightRag/XingJun/move.html index 5c777eca..b7f756c7 100644 --- a/dsLightRag/XingJun/move.html +++ b/dsLightRag/XingJun/move.html @@ -4,44 +4,28 @@ 箭头动画 - +
+

增加箭头

-
-
-
-
-
-
+
+
+
+
+
+
+
+ +
+ + +

* 选择箭头后设置生效

- @@ -54,472 +38,9 @@ - - -
- + diff --git a/dsLightRag/XingJun/历史行军地图.txt b/dsLightRag/XingJun/txt/历史行军地图.txt similarity index 100% rename from dsLightRag/XingJun/历史行军地图.txt rename to dsLightRag/XingJun/txt/历史行军地图.txt diff --git a/dsLightRag/XingJun/改图神器.txt b/dsLightRag/XingJun/txt/改图神器.txt similarity index 100% rename from dsLightRag/XingJun/改图神器.txt rename to dsLightRag/XingJun/txt/改图神器.txt