iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0

Day 26: 視覺優化與使用者體驗提升 - 節點樣式、箭頭美化與高亮效果改進

前言

在 GASO 專案的開發過程中,我們不斷地優化使用者體驗和視覺效果。今天我們將專注於三個重要的視覺改進:節點樣式的優化、箭頭顏色的調整,以及高亮效果的改進。這些改進不僅讓學習地圖更加美觀,也提升了使用者的操作體驗。

今日開發重點

1. 節點樣式的全面優化

移除節點背景,提升文字可讀性

首先,我們決定移除所有節點的背景填充,讓節點完全透明:

/* 節點完全透明效果 */
#zoomInner svg g.node rect,
#zoomInner svg g.node ellipse,
#zoomInner svg g.node polygon {
  fill: none !important;
  stroke: none !important;
}

同時,我們將字體顏色改為在淺色背景上更清楚的深藍灰色:

#zoomInner svg g.node text {
  fill: #2c3e50 !important;
  font-weight: bold !important;
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5) !important;
}

起點節點的特殊標識

為了讓使用者能夠清楚識別學習的起點,我們為起點節點添加了特殊的視覺樣式:

/* 起點節點特殊樣式 */
#zoomInner svg g.node.start-node rect,
#zoomInner svg g.node.start-node ellipse,
#zoomInner svg g.node.start-node polygon {
  fill: #e8f4fd !important;
  stroke: #3498db !important;
  stroke-width: 2 !important;
}

起點節點現在具有:

  • 淺藍色背景(#e8f4fd)
  • 藍色邊框(#3498db)
  • 2px 邊框寬度

起點節點識別邏輯

我們實現了自動識別起點節點的功能:

// 找到起點(沒有入邊的節點)
function findStartNodes() {
  console.log("=== 尋找起點節點 ===");
  const allNodes = new Set(Object.keys(state.adjacencyList));
  const hasIncoming = new Set();
  
  // 找出所有有入邊的節點
  Object.entries(state.adjacencyList).forEach(([source, neighbors]) => {
    neighbors.forEach(neighbor => {
      hasIncoming.add(neighbor);
    });
  });
  
  // 起點是沒有入邊的節點
  const startNodes = Array.from(allNodes).filter(node => !hasIncoming.has(node));
  console.log("起點節點(沒有入邊的節點):", startNodes);
  
  return startNodes;
}

2. 箭頭樣式的優化

箭頭顏色的改進

我們將箭頭的顏色從黑色改為更符合整體配色的深藍灰色:

/* 箭頭樣式優化 - 只針對箭頭,不影響節點 */
#zoomInner svg g.edge polygon[fill="#000000"],
#zoomInner svg g.edge polygon[fill="black"],
#zoomInner svg g.edge polygon[fill="#000"] {
  fill: #34495e !important;
  stroke: #34495e !important;
  stroke-width: 1 !important;
}

JavaScript 中的箭頭樣式應用

// 優化箭頭樣式 - 只針對箭頭元素
const arrowElements = svg.querySelectorAll('g.edge polygon[fill="#000000"], g.edge polygon[fill="black"], g.edge polygon[fill="#000"]');
console.log('找到的黑色箭頭元素數量:', arrowElements.length);

arrowElements.forEach(arrow => {
  console.log('修改箭頭元素:', arrow);
  arrow.setAttribute('fill', '#34495e');
  arrow.setAttribute('stroke', '#34495e');
  arrow.setAttribute('stroke-width', '1');
});

3. 高亮效果的全面改進

高亮顏色的重新設計

我們將高亮顏色從亮綠色改為更融入整體配色的紅色:

// 對 path 元素應用高亮樣式 - 使用融入整體配色的顏色
pathElement.style.setProperty('stroke', '#e74c3c', 'important');
pathElement.style.setProperty('stroke-width', '4px', 'important');
pathElement.style.removeProperty('stroke-dasharray'); // 移除虛線,變成實線
pathElement.style.setProperty('animation', 'pathPulse 2s infinite', 'important');

// 對箭頭元素也應用高亮樣式,並讓尖端更明顯
if (polygonElement) {
  polygonElement.style.setProperty('fill', '#e74c3c', 'important');
  polygonElement.style.setProperty('stroke', '#e74c3c', 'important');
  polygonElement.style.setProperty('stroke-width', '7px', 'important');
}

箭頭尖端可見性優化

為了讓高亮時的箭頭更加明顯,我們採用了多種方法:

  1. 增加邊框寬度:將箭頭邊框從 2px 增加到 7px
  2. 移除縮放效果:避免 transform: scale() 導致箭頭消失
  3. 保持顏色一致性:確保箭頭與線條使用相同的紅色

CSS 動畫樣式更新

@keyframes pathPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

.path-highlighted {
  stroke: #e74c3c !important;
  stroke-width: 4px !important;
  animation: pathPulse 2s infinite !important;
}

.path-highlighted polygon {
  fill: #e74c3c !important;
  stroke: #e74c3c !important;
  stroke-width: 7px !important;
}

4. 字體大小的優化

我們將預設字體大小從 14px 增加到 20px,提升可讀性:

state = {
  fontSize: 20,
  origFontSize: 20,
  // ... 其他屬性
};

技術挑戰與解決方案

挑戰 1:起點節點識別的時機問題

問題findStartNodes() 函數依賴於 state.adjacencyList,但這個數據是在 Google Apps Script 返回數據後才設置的,而渲染函數在數據加載完成之前就被調用。

解決方案

  1. 在渲染函數中使用 setTimeout 延遲應用起點節點樣式
  2. 在數據加載完成後調用 applyStartNodeStyles() 函數
  3. 添加數據準備狀態檢查
// 為起點節點添加特殊樣式(延遲執行,等待數據加載完成)
setTimeout(() => {
  if (state.adjacencyList && Object.keys(state.adjacencyList).length > 0) {
    const startNodes = findStartNodes();
    console.log('找到起點節點:', startNodes);
    startNodes.forEach(startNodeId => {
      // 應用起點節點樣式
    });
  }
}, 100);

挑戰 2:箭頭選擇器的精確性

問題:初始的箭頭選擇器 polygon[fill="#000000"] 太寬泛,可能影響到節點元素。

解決方案

  1. 使用更精確的選擇器 g.edge polygon[fill="#000000"]
  2. 添加多種顏色格式的支援(#000000, black, #000)
  3. 確保只影響箭頭元素,不影響節點
/* 箭頭樣式優化 - 只針對箭頭,不影響節點 */
#zoomInner svg g.edge polygon[fill="#000000"],
#zoomInner svg g.edge polygon[fill="black"],
#zoomInner svg g.edge polygon[fill="#000"] {
  fill: #34495e !important;
  stroke: #34495e !important;
  stroke-width: 1 !important;
}

挑戰 3:高亮箭頭的可見性

問題:使用 transform: scale(1.5) 讓箭頭變大時,箭頭可能因為縮放而超出可見區域或消失。

解決方案

  1. 移除縮放效果,改用增加邊框寬度
  2. 使用 7px 的邊框寬度讓箭頭更明顯
  3. 保持箭頭位置不變,只改變視覺效果

使用者體驗改進

視覺層次優化

  1. 起點識別:淺藍色背景讓使用者一眼就能找到學習起點
  2. 路徑追蹤:紅色高亮讓學習路徑清晰可見
  3. 箭頭指示:7px 邊框寬度讓箭頭方向更加明確

色彩搭配改進

  • 主色調:深藍灰色(#2c3e50)用於文字和一般箭頭
  • 起點色調:藍色系(#3498db, #e8f4fd)用於起點節點
  • 高亮色調:紅色(#e74c3c)用於路徑高亮
  • 整體協調:所有顏色都經過精心挑選,確保視覺和諧

可讀性提升

  1. 字體大小:從 14px 增加到 20px
  2. 文字陰影:添加陰影效果提升對比度
  3. 透明背景:移除節點背景,讓文字更清晰

程式碼架構改進

樣式管理

我們將樣式分為三個層級:

  1. 基礎樣式:節點和箭頭的預設樣式
  2. 特殊樣式:起點節點的特殊標識
  3. 動態樣式:高亮效果的動態應用

函數模組化

// 起點節點樣式應用
function applyStartNodeStyles() {
  // 應用起點節點樣式的邏輯
}

// 箭頭樣式優化
function optimizeArrowStyles(svg) {
  // 優化箭頭樣式的邏輯
}

// 高亮路徑
function highlightPath(paths) {
  // 高亮路徑的邏輯
}

測試與驗證

功能測試

  1. 起點識別測試:確認起點節點能正確識別並應用特殊樣式
  2. 箭頭樣式測試:驗證箭頭顏色和樣式正確應用
  3. 高亮效果測試:確認高亮時箭頭可見且明顯

視覺測試

  1. 色彩對比測試:確保所有文字在背景上清晰可見
  2. 響應式測試:在不同縮放級別下測試視覺效果
  3. 動畫測試:確認脈衝動畫流暢且不影響性能

總結

今天的開發重點在於視覺優化和使用者體驗提升。通過以下改進:

  1. 節點樣式優化:透明背景、起點標識、字體大小調整
  2. 箭頭美化:顏色改進、樣式統一
  3. 高亮效果改進:顏色重新設計、箭頭可見性優化

我們成功地提升了 GASO 的視覺效果和使用者體驗。這些改進不僅讓學習地圖更加美觀,也讓使用者能夠更直觀地理解學習路徑和節點關係。

在技術層面,我們解決了時機問題、選擇器精確性問題和可見性問題,展現了在複雜前端專案中處理視覺效果的技術能力。

這些改進為 GASO 專案帶來了更專業的視覺呈現,為使用者提供了更好的學習體驗。

鐵人賽剩最後幾天就要收尾了,我差不多也要把這個網站完成所有的基本功能,並且開放給大家了。接下來最後的幾天,我打算來把最核心、最關鍵的部分——就是Prompt的部分,把它寫好。敬請期待!


上一篇
Day 25: 前端開發的血淚教訓 - 從功能實現到視覺美學的漫長征途
系列文
亨利羊帶你 Google Apps Script 從入門到精通:放棄長篇大論的教學吧,你需要的只是一些精心設計的 prompt!26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言