星空体育官网最新活动 - 星空体育官网

校园服务点列表

${category.listName}

${ hasChildren ? `
` : "" }
`; // 如果有子项,渲染子项列表 if (hasChildren) { html += `
`; category.children.forEach((child, childIndex) => { html += `
${childIndex + 1}
${ child.listName }
${ child.description ? `
${child.description}
` : "" }
`; }); html += `
`; } html += `
`; }); listView.innerHTML = html; } // 切换分类展开/收起 function toggleCategory(index) { console.log("toggleCategory called with index:", index); const subItems = document.getElementById(`sub-items-${index}`); const toggleIcon = document.getElementById(`toggle-${index}`); // console.log("subItems:", subItems); // console.log("toggleIcon:", toggleIcon); if (subItems) { subItems.classList.toggle("expanded"); console.log("subItems classList after toggle:", subItems.classList); } if (toggleIcon) { toggleIcon.classList.toggle("rotated"); console.log( "toggleIcon classList after toggle:", toggleIcon.classList ); } } // 显示位置信息 function showLocation(id) { console.log("showLocation called with id:", id); // 在locationData中查找位置信息,包括主项和子项 let locations = null; let parentLocation = null; // 用于存储父级位置 for (const category of locationData) { if (category.id === id) { locations = category; break; } // 检查子项 if (category.children) { const child = category.children.find((child) => child.id === id); if (child) { locations = child; parentLocation = category; // 保存父级位置 break; } } } console.log("Found locations:", locations); if (locations) { // 检查是否是需要显示所有子项的父级项 const showAllChildren = locations.showAllChildrenOnMap || false; // 如果是需要显示所有子项的父级项且有子项 if ( showAllChildren && locations.children && locations.children.length > 0 ) { // 展开子项列表而不是跳转到标记点 // 查找该分类在列表中的索引 const categoryIndex = locationData.findIndex( (cat) => cat.id === id ); if (categoryIndex !== -1) { toggleCategory(categoryIndex); } return; } // 确定要定位到的位置ID // 优先使用点击项的ID进行定位,如果该ID对应的标记存在 // 否则使用父级位置(用于兼容旧逻辑) const targetId = markers[id] ? id : parentLocation && markers[parentLocation.id] ? parentLocation.id : id; // 定位到该位置 if (app && markers[targetId]) { // 获取标记位置(HTML标记) const marker = markers[targetId]; console.log("Marker found:", marker); // 获取标记的原始位置数据 const originalPos = originalMarkerPositions[targetId]; if (!originalPos) return; // 计算标记在画布上的位置 if (!backgroundImage) return; const currentScale = backgroundImage.scale.x; const imgPosX = backgroundImage.x - (originalImgWidth * currentScale) / 2; const imgPosY = backgroundImage.y - (originalImgHeight * currentScale) / 2; const markerX = imgPosX + originalPos.x * currentScale; const markerY = imgPosY + originalPos.y * currentScale; console.log("Marker position: x=", markerX, "y=", markerY); // 放大并移动到标记位置 const zoomLevel = 2; // 放大倍数 // 计算画布中心点 const centerX = app.screen.width / 2; const centerY = app.screen.height / 2; console.log("Canvas center: x=", centerX, "y=", centerY); // 平移到标记位置 const targetX = centerX - markerX * zoomLevel; const targetY = centerY - markerY * zoomLevel; console.log("Target position: x=", targetX, "y=", targetY); // 设置新的视图位置和缩放 app.stage.position.set(targetX, targetY); app.stage.scale.set(zoomLevel); // 更新HTML标记位置 updateHTMLMarkerPositions(); // 显示信息气泡(传递位置信息而不是marker对象) // showInfoBubble(locations, { x: markerX, y: markerY }); } // 隐藏列表 const drawer = document.getElementById("listDrawer"); drawer.classList.remove("open"); // 更新按钮文字 const toggleBtn = document.getElementById("drawerToggle"); toggleBtn.textContent = "◀"; } } // 显示信息气泡 function showInfoBubble(locations, marker) { // 关闭现有的气泡 closeInfoBubble(); const bubble = document.getElementById("infoBubble"); console.log(123); // 检查是否有子项 if (locations.children && locations.children.length > 0) { // 构建子项列表 let childrenList = '
'; locations.children.forEach((child) => { childrenList += `
${ child.name }
${child.description || ""}
`; }); childrenList += "
"; // 设置气泡内容,包含父级信息和子项列表 bubble.innerHTML = `
${locations.listName}
${locations.description || ""}
${childrenList} `; } else { // 设置气泡内容,添加关闭按钮 bubble.innerHTML = `
${locations.name}
${locations.description || ""}
`; } // 显示气泡 bubble.style.display = "block"; // 获取画布元素 const canvas = document.getElementById("campusMap"); const canvasRect = canvas.getBoundingClientRect(); // 计算标记在屏幕上的实际位置 // 使用标记的本地坐标并应用舞台变换 const zoom = app.stage.scale.x; const panX = app.stage.position.x; const panY = app.stage.position.y; // 获取标记的本地坐标 const markerLocalX = marker.x; const markerLocalY = marker.y; // 应用舞台变换 const markerCanvasX = markerLocalX * zoom + panX; const markerCanvasY = markerLocalY * zoom + panY; // 转换为屏幕坐标 const markerScreenX = canvasRect.left + markerCanvasX; const markerScreenY = canvasRect.top + markerCanvasY; // 等待浏览器完成渲染以获取正确的气泡尺寸 requestAnimationFrame(() => { // 获取气泡的实际尺寸 const bubbleWidth = bubble.offsetWidth; const bubbleHeight = bubble.offsetHeight; // 设置气泡位置(在标记上方居中) bubble.style.left = `${markerScreenX - bubbleWidth / 2}px`; bubble.style.top = `${markerScreenY - bubbleHeight - 30}px`; // 10px的间距 }); } // 关闭信息气泡 function closeInfoBubble() { const bubble = document.getElementById("infoBubble"); bubble.style.display = "none"; } // 显示居中弹框 function showModal(locations) { const modal = document.getElementById("modal"); const modalTitle = document.getElementById("modalTitle"); const modalContent = document.getElementById("modalContent"); if (locations.id.indexOf("19") > -1) { // 设置弹框标题 modalTitle.textContent = locations.name; } else { // 隐藏 modalTitle.textContent = locations.listName; } // 检查是否有子项 if (locations.children && locations.children.length > 0) { // 构建子项列表 let childrenList = '
'; locations.children.forEach((child) => { childrenList += `
${ child.name }
${child.description || ""}
`; }); childrenList += "
"; // 设置弹框内容,包含父级信息和子项列表 modalContent.innerHTML = `
${locations.description || ""}
${childrenList} `; } else { // 设置弹框内容 modalContent.innerHTML = `
${locations.description || ""}
`; } // 显示弹框 modal.style.display = "block"; } // 关闭弹框 function closeModal() { const modal = document.getElementById("modal"); modal.style.display = "none"; } // 切换抽屉 function toggleDrawer() { const drawer = document.getElementById("listDrawer"); const toggleBtn = document.getElementById("drawerToggle"); drawer.classList.toggle("open"); // 更新按钮文字 if (drawer.classList.contains("open")) { toggleBtn.textContent = "▶"; } else { toggleBtn.textContent = "◀"; } // 关闭信息气泡 closeInfoBubble(); } // 地图相关代码 let app; let markers = {}; let backgroundImage; let originalMarkerPositions = {}; // 存储标记相对于图片原始尺寸的位置 // 保存原始图片尺寸 let originalImgWidth, originalImgHeight; // 初始化地图 function initMap() { // 获取容器大小 const mapContainer = document.getElementById("map-container"); const containerWidth = mapContainer.clientWidth; const containerHeight = mapContainer.clientHeight; // 初始化PIXI应用 app = new PIXI.Application({ width: containerWidth, height: containerHeight, backgroundColor: 0xf5f5f5, view: document.getElementById("campusMap"), }); // 监听窗口大小变化 window.addEventListener("resize", function () { // 获取新的容器大小 const newWidth = mapContainer.clientWidth; const newHeight = mapContainer.clientHeight; // 更新应用大小 app.renderer.resize(newWidth, newHeight); // 重新调整图片大小以适应画布 if (backgroundImage) { adjustImageToCanvas(originalImgWidth, originalImgHeight); // 重新计算标记位置 initMarkerPositions(); } }); // 加载分割后的地图图片 Promise.all([ PIXI.Assets.load("image/bg2.jpg"), // PIXI.Assets.load('image/bg_02.jpg'), // PIXI.Assets.load('image/bg_03.jpg'), // PIXI.Assets.load('image/bg_04.jpg') ]).then((textures) => { // 创建背景容器 backgroundImage = new PIXI.Container(); // 获取原始图片尺寸(假设原始图片是2x2拼接的) // const imgWidth = textures[0].width * 2; // const imgHeight = textures[0].height * 2; const imgWidth = textures[0].width; const imgHeight = textures[0].height; // 保存原始图片尺寸 originalImgWidth = imgWidth; originalImgHeight = imgHeight; // 创建四个精灵并设置位置 const sprite1 = new PIXI.Sprite(textures[0]); // 左上 sprite1.x = 0; sprite1.y = 0; const sprite2 = new PIXI.Sprite(textures[1]); // 右上 sprite2.x = textures[0].width; sprite2.y = 0; const sprite3 = new PIXI.Sprite(textures[2]); // 左下 sprite3.x = 0; sprite3.y = textures[0].height; const sprite4 = new PIXI.Sprite(textures[3]); // 右下 sprite4.x = textures[0].width; sprite4.y = textures[0].height; // 将精灵添加到容器 backgroundImage.addChild(sprite1); backgroundImage.addChild(sprite2); backgroundImage.addChild(sprite3); backgroundImage.addChild(sprite4); // 调整图片大小以适应画布 adjustImageToCanvas(imgWidth, imgHeight); // 添加地图到舞台 app.stage.addChild(backgroundImage); // initialMarkerPositions已整合到locationData中,此处不再需要 // 添加HTML标记到地图 for (let locations of locationData) { // 检查是否需要显示所有子项 const showAllChildren = locations.showAllChildrenOnMap || false; // 如果有子项且需要显示所有子项 if (locations.children && showAllChildren) { // 为每个子项创建标记 for (let child of locations.children) { // 使用子项的位置信息 const position = child.position || { x: 100, y: 100, }; let adjustedX = position.x; let adjustedY = position.y; // 保存标记相对于图片原始尺寸的位置 originalMarkerPositions[child.id] = { x: adjustedX, y: adjustedY, }; // 创建HTML标记 createHTMLMarker(child.id, child.name); } } else { // 使用locationData中的位置信息 const position = locations.position || { x: 100, y: 100, }; let adjustedX = position.x; let adjustedY = position.y; // 保存标记相对于图片原始尺寸的位置 originalMarkerPositions[locations.id] = { x: adjustedX, y: adjustedY, }; // 创建HTML标记 createHTMLMarker(locations.id, locations.name); } } // 初始化标记位置 // updateMarkerPositions(); initMarkerPositions(); }); // 允许平移和缩放画布 let isDragging = false; let lastPosX = 0; let lastPosY = 0; let lastDistance = 0; // 用于双指缩放 // 用于触摸设备的双指缩放 let touchIds = []; app.stage.eventMode = "static"; app.stage.hitArea = app.screen; // 鼠标按下事件 app.stage.on("pointerdown", function (event) { isDragging = true; lastPosX = event.global.x; lastPosY = event.global.y; // 关闭信息气泡(仅当不是从marker触发时) // 检查事件目标是否为标记容器 let target = event.target; let isMarkerClick = false; // 遍历事件冒泡路径,检查是否有标记容器 while (target) { if (target.name && markers[target.name]) { isMarkerClick = true; break; } target = target.parent; } if (!isMarkerClick) { closeInfoBubble(); } }); // 鼠标移动事件 app.stage.on("pointermove", function (event) { if (isDragging) { const deltaX = event.global.x - lastPosX; const deltaY = event.global.y - lastPosY; // 应用新的位置 app.stage.x += deltaX; app.stage.y += deltaY; // 实时更新标记位置,提高跟手性 updateHTMLMarkerPositions(); lastPosX = event.global.x; lastPosY = event.global.y; } }); // 鼠标释放事件 app.stage.on("pointerup", function () { isDragging = false; // 移动完成后更新标记位置 updateHTMLMarkerPositions(); }); app.stage.on("pointerupoutside", function () { isDragging = false; // 移动完成后更新标记位置 updateHTMLMarkerPositions(); }); // 鼠标滚轮缩放 app.view.addEventListener("wheel", function (event) { event.preventDefault(); // 获取鼠标在画布上的位置 const rect = app.view.getBoundingClientRect(); const mouseX = event.clientX - rect.left; const mouseY = event.clientY - rect.top; // 计算缩放中心点的世界坐标 const worldX = (mouseX - app.stage.x) / app.stage.scale.x; const worldY = (mouseY - app.stage.y) / app.stage.scale.y; // 计算新的缩放比例 const delta = event.deltaY; let zoom = app.stage.scale.x; zoom *= 0.999 ** delta; if (zoom > 3) zoom = 3; if (zoom < 0.5) zoom = 0.5; // 应用新的缩放比例 app.stage.scale.set(zoom); // 调整舞台位置以保持缩放中心点不变 app.stage.x = mouseX - worldX * zoom; app.stage.y = mouseY - worldY * zoom; // 更新标记位置 updateHTMLMarkerPositions(); }); // 触摸开始事件 app.view.addEventListener("touchstart", function (event) { // 记录触摸点ID for (let i = 0; i < event.changedTouches.length; i++) { const touch = event.changedTouches[i]; if (!touchIds.includes(touch.identifier)) { touchIds.push(touch.identifier); } } // 如果只有一个触摸点,开始拖动 if (touchIds.length === 1) { const touch = event.touches[0]; isDragging = true; lastPosX = touch.clientX; lastPosY = touch.clientY; } // 如果有两个触摸点,开始缩放 else if (touchIds.length === 2) { isDragging = false; // 停止拖动 const touch1 = event.touches[0]; const touch2 = event.touches[1]; // 计算两点间距离 const dx = touch1.clientX - touch2.clientX; const dy = touch1.clientY - touch2.clientY; lastDistance = Math.sqrt(dx * dx + dy * dy); } }); // 触摸移动事件 app.view.addEventListener("touchmove", function (event) { event.preventDefault(); // 如果只有一个触摸点且正在拖动 if (touchIds.length === 1 && isDragging) { const touch = event.touches[0]; const deltaX = touch.clientX - lastPosX; const deltaY = touch.clientY - lastPosY; // 应用新的位置 app.stage.x += deltaX; app.stage.y += deltaY; // 实时更新标记位置,提高跟手性 updateHTMLMarkerPositions(); lastPosX = touch.clientX; lastPosY = touch.clientY; } // 如果有两个触摸点,进行缩放 else if (touchIds.length === 2) { const touch1 = event.touches[0]; const touch2 = event.touches[1]; // 计算新的两点间距离 const dx = touch1.clientX - touch2.clientX; const dy = touch1.clientY - touch2.clientY; const newDistance = Math.sqrt(dx * dx + dy * dy); if (lastDistance > 0) { // 计算缩放比例 const scaleChange = newDistance / lastDistance; let newScale = app.stage.scale.x * scaleChange; // 限制缩放范围 if (newScale > 5) newScale = 5; if (newScale < 0.5) newScale = 0.5; // 获取缩放中心点(两指中点) const centerX = (touch1.clientX + touch2.clientX) / 2; const centerY = (touch1.clientY + touch2.clientY) / 2; // 计算缩放中心点的世界坐标 const rect = app.view.getBoundingClientRect(); const localX = centerX - rect.left; const localY = centerY - rect.top; const worldX = (localX - app.stage.x) / app.stage.scale.x; const worldY = (localY - app.stage.y) / app.stage.scale.y; // 应用新的缩放比例 app.stage.scale.set(newScale); // 调整舞台位置以保持缩放中心点不变 app.stage.x = localX - worldX * newScale; app.stage.y = localY - worldY * newScale; // 更新标记位置 updateHTMLMarkerPositions(); // 更新距离 lastDistance = newDistance; } } }); // 触摸结束事件 app.view.addEventListener("touchend", function (event) { // 移除触摸点ID for (let i = 0; i < event.changedTouches.length; i++) { const touch = event.changedTouches[i]; const index = touchIds.indexOf(touch.identifier); if (index > -1) { touchIds.splice(index, 1); } } // 重置状态 isDragging = false; lastDistance = 0; // 移动完成后更新标记位置 updateHTMLMarkerPositions(); }); // 触摸取消事件 app.view.addEventListener("touchcancel", function (event) { // 移除触摸点ID for (let i = 0; i < event.changedTouches.length; i++) { const touch = event.changedTouches[i]; const index = touchIds.indexOf(touch.identifier); if (index > -1) { touchIds.splice(index, 1); } } // 重置状态 isDragging = false; lastDistance = 0; // 移动完成后更新标记位置 updateHTMLMarkerPositions(); }); } // 创建HTML标记 function createHTMLMarker(markerId, markerName) { const mapContainer = document.getElementById("map-container"); // 创建标记元素 const marker = document.createElement("div"); marker.className = "html-marker"; marker.id = "marker-" + markerId; // 检查是否为ID 15、16及其子项,应用对话框样式 const baseId = markerId.split("-")[0]; // if (baseId === "15" || baseId === "16") { // marker.classList.add("dialog-box"); // // 对于对话框样式,使用innerHTML来支持HTML标签解析 // marker.setAttribute("data-name", markerName); // // 创建内部内容容器来显示HTML内容 // const contentDiv = document.createElement("div"); // contentDiv.innerHTML = markerName; // contentDiv.style.cssText = ` // font-size: calc(8px + 0.6vmin); // font-weight: bold; // color: black; // width: 100%; // height: auto; // display: block; // overflow: visible; // white-space: normal; // word-wrap: break-word; // line-height: 1.3; // `; // marker.appendChild(contentDiv); // } else { // 对ID 18-1特殊处理,将"垃圾分类点"转换为换行显示 let displayName = markerName; marker.setAttribute("data-name", displayName); marker.textContent = ""; // } // 不再创建单独的标签元素,名称直接显示在标记内 // const label = document.createElement('div'); // label.className = 'html-marker-label'; // label.textContent = markerName; // marker.appendChild(label); console.log(markerName); // 添加点击事件 marker.addEventListener("click", function (event) { event.stopPropagation(); // 查找对应的locations数据,包括父级数据 let targetLocation = null; // 在locationData中查找位置信息 for (const category of locationData) { if (category.id === markerId) { targetLocation = category; break; } // 检查子项 if (category.children) { const child = category.children.find( (child) => child.id === markerId ); if (child) { targetLocation = child; break; } } } if (targetLocation) { // 只有当是子标记时才查找父级数据 // if (targetLocation.id.includes("-")) { // const parentId = targetLocation.id.split("-")[0]; // const parentLocation = locationData.find( // (item) => item.id === parentId // ); // if (parentLocation) { // targetLocation = parentLocation; // } // } // 显示居中弹框 showModal(targetLocation); } }); // 添加到地图容器 mapContainer.appendChild(marker); markers[markerId] = marker; } // 更新HTML标记位置(优化版本) let updateRequested = false; function updateHTMLMarkerPositions() { if (updateRequested) return; updateRequested = true; console.log("updateHTMLMarkerPositions"); requestAnimationFrame(() => { if ( !backgroundImage || Object.keys(originalMarkerPositions).length === 0 ) { updateRequested = false; return; } // 获取图片的当前缩放比例 const currentScale = backgroundImage.scale.x; // 获取图片在画布中的位置(左上角) const imgPosX = backgroundImage.x - (originalImgWidth * currentScale) / 2; const imgPosY = backgroundImage.y - (originalImgHeight * currentScale) / 2; // 获取画布元素 const canvas = document.getElementById("campusMap"); const canvasRect = canvas.getBoundingClientRect(); // 预计算常用值 const zoom = app.stage.scale.x; const panX = app.stage.position.x; const panY = app.stage.position.y; const canvasLeft = canvasRect.left; const canvasTop = canvasRect.top; // 更新所有标记的位置 Object.keys(originalMarkerPositions).forEach((markerId) => { const originalPos = originalMarkerPositions[markerId]; const marker = markers[markerId]; if (marker) { // 计算标记在画布上的位置(基于图片左上角) const markerX = imgPosX + originalPos.x * currentScale; const markerY = imgPosY + originalPos.y * currentScale; // 计算屏幕坐标 const screenX = canvasLeft + markerX * zoom + panX; const screenY = canvasTop + markerY * zoom + panY; // 设置标记位置 marker.style.left = screenX + "px"; marker.style.top = screenY + "px"; // 设置标记缩放 - 对话框样式使用不同的transform if (marker.classList.contains("dialog-box")) { marker.style.transform = `translate(0%, -100%) scale(${zoom})`; } else { marker.style.transform = `translate(-50%, -100%) scale(${zoom})`; } // 获取标记文字 const markerName = marker.getAttribute("data-name"); if (markerName) { // 根据文字长度调整字体大小,确保文字少时字体大,文字多时字体小 let fontSize; if (markerName.length <= 2) { fontSize = "calc(8px + 0.4vmin)"; } else if (markerName.length <= 4) { fontSize = "calc(7px + 0.55vmin)"; } else if (markerName.length <= 6) { fontSize = "calc(6px + 0.5vmin)"; } else if (markerName.length <= 8) { fontSize = "calc(5px + 0.4vmin)"; } else { fontSize = "calc(5px + 0.35vmin)"; } // 更新文字样式 marker.style.setProperty("--marker-font-size", fontSize); } } }); updateRequested = false; }); } // 初始化标记位置(基于图片左上角位置固定) function initMarkerPositions() { console.log("initMarkerPositions"); // 使用HTML标记位置更新函数 updateHTMLMarkerPositions(); } // 调整图片大小以适应画布 function adjustImageToCanvas(imgWidth, imgHeight) { if (!backgroundImage) return; const canvasWidth = app.screen.width; const canvasHeight = app.screen.height; // 计算缩放比例,确保图片铺满画布 const scaleX = canvasWidth / imgWidth; const scaleY = canvasHeight / imgHeight; const scale = Math.max(scaleX, scaleY); // 使用最大比例确保图片铺满 backgroundImage.scale.set(scale); backgroundImage.pivot.set(imgWidth / 2, imgHeight / 2); backgroundImage.x = canvasWidth / 2; backgroundImage.y = canvasHeight / 2; } // 初始化应用 function initApp() { renderListView(); // 初始化地图 initMap(); // 添加抽屉切换按钮事件监听器 document .getElementById("drawerToggle") .addEventListener("click", toggleDrawer); } // 页面加载完成后初始化 document.addEventListener("DOMContentLoaded", initApp);

继续阅读

本页围绕「星空体育官网最新活动」汇总公开信息,便于结合栏目动态与后续阅读。

移动端与电脑端入口保持一致。如某条暂不可用,可改走栏目列表继续查找。

若从搜索引擎进入,可先确认当前栏目名称,再按需打开相关阅读。

内容目录

主页 / yzxqdldt

正文、栏目列表与相关阅读构成完整路径,适合按主题持续查阅。