From 6b20c045a9cf708bea5df39002d5b499ca8cdffe Mon Sep 17 00:00:00 2001 From: xiebing Date: Thu, 20 Nov 2025 14:30:01 +0800 Subject: [PATCH] =?UTF-8?q?style=20=E7=AE=80=E5=8E=86=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=E8=81=8C=E4=BD=8D=E7=9A=84=E7=82=B9=E5=87=BBemit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/index/components/AIMatch.vue | 73 ++++++++++++++++++++--- pages/index/components/index-refactor.vue | 8 ++- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/pages/index/components/AIMatch.vue b/pages/index/components/AIMatch.vue index aa862ea..9febc2c 100644 --- a/pages/index/components/AIMatch.vue +++ b/pages/index/components/AIMatch.vue @@ -2,7 +2,7 @@ - + @@ -14,7 +14,9 @@ import { onMounted, onUnmounted, ref } from "vue"; import * as PIXI from "pixi.js"; -const appRef = ref(null); // 存储 PIXI 应用实例 +const appRef = ref(null); +const tagsContainer = ref(null); // 标签容器 +const emit = defineEmits(["tag-click"]); // 名称、颜色、大小、位置(角度、半径) const mockTags = [ @@ -147,9 +149,10 @@ onMounted(async () => { canvas.appendChild(app.view); - // 标签容器( - const tagsContainer = new PIXI.Container(); - app.stage.addChild(tagsContainer); + // 标签容器 + const container = new PIXI.Container(); + tagsContainer.value = container; + app.stage.addChild(container); // 存储已放置标签的信息 const placedTags = []; @@ -185,11 +188,17 @@ onMounted(async () => { tag.y = originalY + Math.sin(floatOffset) * floatRange; }); - tagsContainer.addChild(tag); - placedTags.push({ ...tagData, bounds: tag.getBounds() }); + container.addChild(tag); + placedTags.push({ + ...tagData, + bounds: tag.getBounds(), + angle, + radius, + tailRotation, + tagInstance: tag, // 保存标签实例 + }); } }); - // 创建拖尾 function createCometTail(bgColor, tailRotation, tag) { const tailGroup = new PIXI.Container(); @@ -319,6 +328,54 @@ function createTag(tagData, x, y, placedTags, app, index) { return tagGroup; } +//点击事件 +const handleCanvasClick = (event) => { + if (!appRef.value || !tagsContainer.value) return; + + const canvas = document.getElementById("matchCanvas"); + const rect = canvas.getBoundingClientRect(); + + let clientX, clientY; + + if (event.touches && event.touches.length > 0) { + // 移动端事件 + clientX = event.touches[0].clientX; + clientY = event.touches[0].clientY; + } else { + // PC端事件 + clientX = event.clientX; + clientY = event.clientY; + } + + // 点击位置相对于Canvas的坐标 + const x = clientX - rect.left; + const y = clientY - rect.top; + + for (let i = 0; i < mockTags.length; i++) { + const tag = tagsContainer.value.children[i]; + if (!tag) continue; + + // 获取标签边界 + const bounds = tag.getBounds(); + + // 缩小点击范围 上下左右各3 + const shrinkAmount = 3; + const innerBounds = { + x: bounds.x + shrinkAmount, + y: bounds.y + shrinkAmount, + width: bounds.width - shrinkAmount * 2, + height: bounds.height - shrinkAmount * 2, + }; + + // 检查点击位置是否在缩小后的标签边界内 + if (x >= innerBounds.x && x <= innerBounds.x + innerBounds.width && y >= innerBounds.y && y <= innerBounds.y + innerBounds.height) { + // 找到对应标签 + const tagData = mockTags[i]; + emit("tag-click", tagData); + break; + } + } +}; onUnmounted(() => { if (appRef.value) { appRef.value.destroy(true, true); diff --git a/pages/index/components/index-refactor.vue b/pages/index/components/index-refactor.vue index df300b8..02008c8 100644 --- a/pages/index/components/index-refactor.vue +++ b/pages/index/components/index-refactor.vue @@ -55,7 +55,7 @@ 简历匹配职位 - + @@ -292,6 +292,10 @@ const checkStickyStatus = (e) => { }); }; +const handleTagClick = (tagInfo) => { + console.log("点击的标签信息:", tagInfo); +}; + const hexToRgba = (hex, opacity) => { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); @@ -883,6 +887,8 @@ defineExpose({ loadData }); .match-item-container width:100%; margin-top:30rpx; + position :relative; + z-index:1 .match-item-row display: flex; justify-content: center;