# 個人作品集

JS 渲染的個人檔案卡（J002 版型）：頭像、社群連結、經歷數據、聯絡按鈕、可依標籤篩選的作品格線與技能年資圓環。

## 概要

| 項目 | 內容 |
|---|---|
| 製作日期 | 2023-02-26 |
| 分類 | 個人頁範例 |
| HTML 檔案 | `index.html` |
| 原始碼 | [target/20230226](https://github.com/pardnio/demo-web/tree/main/target/20230226) |

## 即時預覽

<iframe src="/target/20230226/" title="個人作品集" loading="lazy" style="width:100%;height:640px;border:1px solid #e5e7eb;border-radius:8px"></iframe>

[在新分頁開啟範例](/target/20230226/)

## 頁面區塊

| 區塊 | 說明 |
|---|---|
| 使用者資訊卡 | setTopUser()：頭像（或名稱首字）、名稱與職稱提示、LinkedIn / Instagram / Facebook / GitHub / 部落格連結（null 略過）、3 項經歷數據、「查看原碼」主按鈕與聯絡圖示（Email、Messenger）。 |
| 頁面分頁 | ul#page-tab 含 Portfolio / Skills，以 sel 屬性標示選取。 |
| 作品集（預設，?page=portfolio） | setPortfolio()：20 個範例 figure，含圖片、標題、開啟連結與分享按鈕；浮動 ul#portfolio-tab 依 ALL / 標籤 1 / 標籤 2 篩選。 |
| 技能（?page=skills） | setSkills()：技能群組（iOS、Frontend、Backend、Database、Google Cloud Platform、OS、more），每項顯示年資圓環，依 scrollHeight 比較分配到兩欄瀑布式排列。 |

## 互動行為

- DOMContentLoaded 時依 webConfig 以 PDRenderKit 輔助函式建構 DOM（"tag#id.class"._()、_child、_click、_go、_open，年資以 $timestamp.$gone 計算）。
- #body-container 捲動 &gt;= 40px 時對 #portfolio-tab 加上 show。
- 窄螢幕（頁面分頁 &lt; 640px、作品分頁 &lt; 800px）第一次點擊加 expand，第二次才切換並重繪列表。
- copy(url)：建立暫時唯讀 input，document.execCommand('copy') 後 alert('已拷貝至剪貼簿.')。
- 啟動 _LazyListener()（PDRenderKit）處理圖片延遲載入。

## 相依資源

| 名稱 | 版本 | 來源 |
|---|---|---|
| PDRenderKit | 1.0.0 (script tag; preload tag requests 1.0.2) | https://cdn.jsdelivr.net/npm/pdrenderkit@1.0.0/dist/PDRenderKit.js |
| Font Awesome Free | 6.5.2 | https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css |
| Google Analytics gtag | - | https://www.googletagmanager.com/gtag/js?id=G-L5VYEZPVXX |
| js/index.js (local app code with webConfig sample data) | - | js/index.js |

## 樣式

| 項目 | 內容 |
|---|---|
| SCSS 入口 | `sass/index.scss` |
| 輸出 CSS | `css/index.css` |
| Partials | `J002/_nav.scss`, `J002/_div.scss`, `J002/_portfolio-tab.scss`, `J002/_portfolio-list.scss`, `J002/_skill-list.scss`, `J002/_top-user.scss`, `J002/top-user/_head.scss`, `J002/top-user/_name.scss`, `J002/top-user/_link.scss`, `J002/top-user/_exp.scss`, `J002/top-user/_button.scss`, `J002/top-user/_tab.scss` |

版型以 J002 為命名空間；top-user 拆成 head / name / link / exp / button / tab partial。所有顏色、尺寸與間距取自 index.html 宣告的 CSS 變數。

```bash
cd target/20230226
npx sass sass/index.scss css/index.css --no-source-map || exit 1
```

## 使用技巧

- inline &lt;style&gt; 大量 CSS 變數主題：--global-bg、--user-top-*、--portfolio-*、--skill-*（漸層、尺寸、間距、比例）。
- 技能年資圓環：Sass @for 1..10 產生 [year="N"] 規則，每年旋轉兩個半圓層 36deg。
- 以 content: attr(num) / attr(title) 顯示數據與提示；[num="N"]、[sel="N"] 屬性選擇器由 @for 產生。
- 行動優先斷點 320 / 480 / 640 / 800 / 1024px 與 @media (hover: hover)。

## 外部資源

- https://pardn.io/web-template/target/20230226/image/bg.jpg (--global-bg, absolute URL)
- `https://fakeimg.pl/1024/282828/eae0d0/?text=sample`
- `https://pardn.io/image/head.png`
- `https://pardn.io/web-template/image/20230226.jpg`

## 已知問題

- --global-bg is hard-coded to https://pardn.io/web-template/target/20230226/image/bg.jpg, so the copied page still loads the background from pardn.io instead of its own image/bg.jpg; it breaks if that remote file is unavailable.

## 相關頁面

- [專案結構](/zh/project-structure)
- [樣式工作流程](/zh/styling-workflow)
- [框架使用](/zh/frameworks)
