打造LINE OA圖文選單產生器:前端開發實戰
用純前端技術製作一個專業的圖文選單工具,讓使用者能自訂文字、上傳背景並一鍵下載
DEMO頁面:https://kuokaikai.github.io/line_oa_menu_img_gen/index.html
專案概述
這個專案是一個純前端的LINE OA圖文選單產生器,主要功能包括:
- 🎨 多種模板選擇(2×2、1×3、3×1、2×3)
- 🖼️ 支援背景圖片上傳與拖拽
- 🎨 自訂顏色與文字描邊
- 📱 響應式設計
- 💾 一鍵下載PNG圖片
技術棧: HTML5 Canvas + CSS3 + Vanilla JavaScript
核心技術解析
1. HTML結構設計
採用語意化標籤構建清晰的頁面結構:
<div class="container">
<header class="header">
<!-- 標題區 -->
</header>
<main class="main-content">
<aside class="controls">
<!-- 控制面板:模板選擇、背景設定、文字輸入 -->
</aside>
<section class="preview">
<canvas id="menuCanvas" width="800" height="540"></canvas>
<!-- 預覽與下載 -->
</section>
</main>
</div>
2. CSS現代化設計
響應式佈局
.main-content {
display: flex;
gap: 30px;
}
/* 手機版垂直排列 */
@media (max-width: 768px) {
.main-content {
flex-direction: column;
}
}
視覺效果
.section {
border-radius: 15px;
transition: all 0.3s ease;
}
.section:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,195,0,0.1);
}
3. JavaScript核心邏輯
狀態管理
let currentTemplate = '2x2';
let menuTexts = ['選單1', '選單2', '選單3', '選單4'];
let backgroundImage = null;
const templates = {
'2x2': { cols: 2, rows: 2, count: 4 },
'1x3': { cols: 1, rows: 3, count: 3 },
// ...其他模板
};
事件驅動架構
function initializeApp() {
setupTemplateButtons();
setupBackgroundControls();
setupColorInputs();
generateMenuInputs();
drawMenu();
}
Canvas繪圖引擎
核心繪製流程
function drawMenu() {
const canvas = document.getElementById('menuCanvas');
const ctx = canvas.getContext('2d');
const template = templates[currentTemplate];
// 1. 清除畫布
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. 繪製背景
if (backgroundType === 'image' && backgroundImage) {
drawBackgroundImage(ctx, canvas);
} else {
ctx.fillStyle = document.getElementById('bgColor').value;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
// 3. 繪製格線和文字
drawMenuGrid(ctx, template);
}
智慧文字處理
function drawWrappedText(ctx, text, x, y, maxWidth) {
const words = text.split('');
let line = '';
const lines = [];
// 自動換行邏輯
for (let char of words) {
const testLine = line + char;
if (ctx.measureText(testLine).width > maxWidth && line !== '') {
lines.push(line);
line = char;
} else {
line = testLine;
}
}
lines.push(line);
// 繪製多行文字
const lineHeight = fontSize * 1.2;
lines.forEach((line, index) => {
ctx.fillText(line, x, y + index * lineHeight);
});
}
檔案上傳系統
多元上傳方式
點擊上傳
const fileInput = document.getElementById('bgImageInput');
const uploadArea = document.getElementById('fileUploadArea');
uploadArea.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', handleFileSelect);
拖拽上傳
function setupDragAndDrop(uploadArea) {
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('dragover');
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.classList.remove('dragover');
const files = e.dataTransfer.files;
if (files[0] && files[0].type.startsWith('image/')) {
loadImageFile(files[0]);
}
});
}
圖片處理
function loadImageFile(file) {
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
backgroundImage = img;
drawMenu(); // 重新繪製
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
}
關鍵特色功能
1. 動態模板切換
function setupTemplateButtons() {
const templateBtns = document.querySelectorAll('.template-btn');
templateBtns.forEach(btn => {
btn.addEventListener('click', () => {
currentTemplate = btn.dataset.template;
generateMenuInputs(); // 重新生成輸入框
drawMenu(); // 重新繪製
});
});
}
2. 背景圖片適配
支援三種填充模式:填滿裁切、完整顯示、拉伸填滿
function drawBackgroundImage(ctx, canvas) {
const fitMode = document.getElementById('bgFitMode').value;
const opacity = document.getElementById('bgOpacity').value;
ctx.save();
ctx.globalAlpha = opacity;
// 根據模式計算尺寸
const dimensions = calculateImageDimensions(backgroundImage, canvas, fitMode);
ctx.drawImage(backgroundImage, dimensions.x, dimensions.y, dimensions.width, dimensions.height);
ctx.restore();
}
3. 一鍵下載功能
function downloadImage() {
const canvas = document.getElementById('menuCanvas');
const link = document.createElement('a');
try {
link.download = `LINE_OA_圖文選單_${currentTemplate}_${Date.now()}.png`;
link.href = canvas.toDataURL('image/png', 1.0);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} catch (error) {
alert('下載失敗,請重新嘗試');
}
}
開發技巧與優化
1. 效能優化
- 使用防抖動避免頻繁重繪
- Canvas高解析度適配
- 圖片預載入優化
2. 使用者體驗
- 即時預覽更新
- 視覺回饋動畫
- 錯誤處理提示
3. 響應式設計
- Mobile-first方法
- 彈性網格系統
- 觸控友善介面
部署與發布
GitHub Pages部署
- 將檔案上傳到GitHub倉庫
- 啟用GitHub Pages功能
- 選擇main分支作為來源
- 專案即可線上使用
檔案結構
line-oa-generator/
├── index.html # 主頁面
├── README.md # 專案說明
└── assets/
├── css/style.css # 樣式檔案
└── js/app.js # 主要邏輯
總結
這個專案展示了如何用純前端技術打造一個實用的圖形設計工具。關鍵學習點包括:
🎨 Canvas API — 學會用程式碼繪製圖形和文字
📱 響應式設計 — 現代化的UI/UX實現
🗂️ 檔案處理 — 拖拽上傳與圖片處理
⚡ 效能優化 — 防抖動與Canvas優化技巧
透過這個專案,你可以掌握前端圖形處理的核心技術,並應用到更多創意專案中!