Skip to content

Instantly share code, notes, and snippets.

@isdaviddong
Created January 15, 2017 06:30
Show Gist options
  • Select an option

  • Save isdaviddong/36046c2a398cb8e943fc520f79c28c4c to your computer and use it in GitHub Desktop.

Select an option

Save isdaviddong/36046c2a398cb8e943fc520f79c28c4c to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script>
function Auth() {
var URL = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize?';
URL += 'response_type=code';
URL += '&client_id={請換成您的Client id}'; //請換成您的App Client id
URL += '&redirect_uri=http://localhost:13555/index.html';  //請換成您的URL
URL += '&scope=openid https://graph.microsoft.com/user.read'; //請換成您要索取的權限
URL += '&response_mode=query';
URL += '&state=12345';
URL += '&nonce=678910';
window.location.href = URL;
}
</script>
</head>
<body>
<button onclick="Auth();">點選這裡連結AAD 2.0 Login</button>
</body>
</html>
@jjabc20120221-ui
Copy link

<!doctype html>

<title>Sky Dodge</title> <style> :root{ --bg:#0b1020; --fg:#e8f1ff; --accent:#4cc9f0; --good:#80ffdb; --bad:#ff4d6d; --muted:#95a1b3; } *{box-sizing:border-box} html,body{height:100%;margin:0;background:radial-gradient(1200px 800px at 50% -200px,#111a33,var(--bg));color:var(--fg);font-family:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,"Noto Sans TC",sans-serif} .wrap{max-width:720px;margin:0 auto;padding:16px;display:flex;flex-direction:column;gap:12px} header{display:flex;align-items:center;justify-content:space-between;gap:12px} h1{font-size:20px;margin:0;letter-spacing:.5px} .btnbar{display:flex;gap:8px;flex-wrap:wrap} button{ appearance:none;border:1px solid #2b3550;background:#111a33;color:var(--fg); padding:8px 12px;border-radius:10px;font-weight:600;cursor:pointer;transition:.15s transform,.2s opacity; } button:active{transform:scale(.98)} button[aria-pressed="true"]{outline:2px solid var(--accent);box-shadow:0 0 0 3px #00000040 inset} #gamebox{position:relative;border:1px solid #223; border-radius:14px;overflow:hidden} canvas{display:block;width:100%;height:auto;background:linear-gradient(#0b1533 0%, #0b1020 60%, #090c1a 100%)} .hud{ position:absolute;inset:0;pointer-events:none;padding:10px;display:flex;flex-direction:column; } .hud .row{display:flex;justify-content:space-between;align-items:center;font-weight:700;font-variant-numeric:tabular-nums} .centerOverlay{ position:absolute;inset:0;display:flex;align-items:center;justify-content:center; backdrop-filter:blur(4px) saturate(120%); background:#0b102088; text-align:center; padding:20px; } .panel{background:#0d1328;border:1px solid #223;border-radius:16px;padding:18px;max-width:480px} .title{font-size:22px;margin:0 0 6px} .muted{color:var(--muted);font-size:14px;line-height:1.4} .kbd{display:inline-block;border:1px solid #3a4466;border-bottom-width:3px;padding:0 6px;border-radius:6px;margin:0 2px;font-weight:700} .tip{margin-top:10px;font-size:13px;color:#b8c4d9} .link{color:var(--accent);text-decoration:none} footer{opacity:.75;font-size:12px;text-align:center;padding-bottom:8px} </style>

🌌 Sky Dodge

開始 / 重新開始 暫停 音效
分數 0
最高 0
<div id="overlay" class="centerOverlay" hidden>
  <div class="panel">
    <h2 class="title" id="overlayTitle">Sky Dodge</h2>
    <p id="overlayMsg" class="muted">左右移動小飛球,避開障礙、吃星星加分。</p>
    <div class="tip">
      電腦:<span class="kbd">←</span> <span class="kbd">→</span> 或 <span class="kbd">A</span>/<span class="kbd">D</span>,<span class="kbd">P</span> 暫停。<br>
      手機:左右半邊螢幕觸控/長按連續移動。
    </div>
    <div style="margin-top:14px;display:flex;gap:8px;justify-content:center">
      <button id="overlayStart">開始</button>
    </div>
  </div>
</div>
© 2025 Sky Dodge · 單檔版(離線可玩)
<script> /* ====== Utility & Setup ====== */ const canvas = document.getElementById('game'); const ctx = canvas.getContext('2d'); const scoreEl = document.getElementById('score'); const hiscoreEl = document.getElementById('hiscore'); const overlay = document.getElementById('overlay'); const overlayTitle = document.getElementById('overlayTitle'); const overlayMsg = document.getElementById('overlayMsg'); const overlayStart = document.getElementById('overlayStart'); const startBtn = document.getElementById('startBtn'); const pauseBtn = document.getElementById('pauseBtn'); const muteBtn = document.getElementById('muteBtn'); let DPR = Math.max(1, Math.min(2, window.devicePixelRatio || 1)); function resizeCanvas(){ const box = document.getElementById('gamebox'); const w = box.clientWidth; const h = Math.min(Math.round(w*1.5), window.innerHeight*0.75); canvas.style.height = h+'px'; canvas.style.width = w+'px'; canvas.width = Math.floor(w*DPR); canvas.height = Math.floor(h*DPR); } addEventListener('resize', resizeCanvas, {passive:true}); resizeCanvas(); const rand = (a,b)=>Math.random()*(b-a)+a; const clamp=(v,a,b)=>Math.max(a,Math.min(b,v)); const nowMs=()=>performance.now(); /* ====== Sound (beeps via WebAudio) ====== */ const audioCtx = new (window.AudioContext||window.webkitAudioContext)(); let muted = false; function beep(type='sine', freq=440, dur=0.08, gain=0.03){ if(muted) return; const t0 = audioCtx.currentTime; const osc = audioCtx.createOscillator(); const g = audioCtx.createGain(); osc.type = type; osc.frequency.setValueAtTime(freq, t0); g.gain.setValueAtTime(gain, t0); g.gain.exponentialRampToValueAtTime(0.0001, t0+dur); osc.connect(g).connect(audioCtx.destination); osc.start(); osc.stop(t0+dur); } /* ====== Game State ====== */ const state = { running:false, paused:false, gameOver:false, score:0, hiscore: parseInt(localStorage.getItem('skydodge_hiscore')||'0',10), tStart:0, tPrev:0, tAccum:0, player:{x:0.5, y:0.88, vx:0, rN:0.018, speed:0.65}, blocks:[], stars:[], spawnTimer:0, starTimer:0, difficulty:1 }; hiscoreEl.textContent = state.hiscore; /* ====== Input (keyboard + touch) ====== */ const keys = new Set(); addEventListener('keydown',e=>{ if(['ArrowLeft','ArrowRight','a','d','A','D','p','P',' '].includes(e.key)) e.preventDefault(); if(e.key==='p'||e.key==='P') togglePause(); else keys.add(e.key); }); addEventListener('keyup',e=>keys.delete(e.key)); let touchDir = 0, touchActive=false; canvas.addEventListener('touchstart',e=>{ touchActive=true; const rect = canvas.getBoundingClientRect(); for(const t of e.touches){ const x = t.clientX - rect.left; touchDir = x < rect.width/2 ? -1 : 1; } e.preventDefault(); },{passive:false}); canvas.addEventListener('touchmove',e=>{ const rect = canvas.getBoundingClientRect(); for(const t of e.touches){ const x = t.clientX - rect.left; touchDir = x < rect.width/2 ? -1 : 1; } e.preventDefault(); },{passive:false}); canvas.addEventListener('touchend',()=>{touchActive=false; touchDir=0;}); /* ====== Start / Pause / UI ====== */ function showOverlay(title,msg){ overlayTitle.textContent = title; overlayMsg.textContent = msg; overlay.hidden = false; } function hideOverlay(){ overlay.hidden = true; } function startGame(){ Object.assign(state,{ running:true, paused:false, gameOver:false, score:0, tStart:nowMs(), tPrev:nowMs(), tAccum:0, blocks:[], stars:[], spawnTimer:0, starTimer:0, difficulty:1 }); pauseBtn.setAttribute('aria-pressed','false'); hideOverlay(); audioCtx.resume?.(); beep('sine',660,0.08,0.04); requestAnimationFrame(loop); } function gameOver(){ state.gameOver = true; state.running = false; state.hiscore = Math.max(state.hiscore, state.score); localStorage.setItem('skydodge_hiscore', String(state.hiscore)); hiscoreEl.textContent = state.hiscore; beep('triangle',180,0.15,0.06); setTimeout(()=>beep('triangle',140,0.2,0.05),60); showOverlay('遊戲結束', `分數:${state.score} | 最高:${state.hiscore}`); } function togglePause(){ if(!state.running || state.gameOver) return; state.paused = !state.paused; pauseBtn.setAttribute('aria-pressed', state.paused?'true':'false'); if(state.paused){ showOverlay('已暫停', '按「暫停」或鍵盤 P 以繼續'); }else{ hideOverlay(); state.tPrev = nowMs(); // prevent big dt requestAnimationFrame(loop); } } startBtn.addEventListener('click', startGame); overlayStart.addEventListener('click', startGame); pauseBtn.addEventListener('click', togglePause); muteBtn.addEventListener('click', ()=>{ muted = !muted; muteBtn.setAttribute('aria-pressed', muted?'true':'false'); if(!muted) beep('sine',520,0.06,0.03); }); /* ====== Spawning & Difficulty ====== */ function spawnBlock(){ const w = 1; const h = canvas.height/canvas.width; // world aspect const bw = rand(0.06, 0.16) * Math.max(0.7, 1.2 - state.difficulty*0.05); const x = clamp(rand(bw/2, 1 - bw/2), 0, 1); const speed = rand(0.25, 0.38) + state.difficulty*0.02; state.blocks.push({x, y:-0.12, w:bw, h:bw*rand(0.8,1.1), v:speed, rot:rand(-0.03,0.03)}); } function spawnStar(){ const x = rand(0.08, 0.92); const v = rand(0.22,0.3) + state.difficulty*0.015; state.stars.push({x, y:-0.08, r:0.012, v}); } /* ====== Physics & Render ====== */ function update(dt){ // difficulty increases over time state.tAccum += dt; state.difficulty = 1 + state.tAccum / 180; // every 3 min ramps +1 // input const p = state.player; let dir = 0; if(keys.has('ArrowLeft')||keys.has('a')||keys.has('A')) dir -= 1; if(keys.has('ArrowRight')||keys.has('d')||keys.has('D')) dir += 1; if(touchActive) dir += touchDir; const baseSpeed = 0.65 + Math.min(0.9, state.difficulty*0.12); p.vx = dir * baseSpeed * dt; p.x = clamp(p.x + p.vx, 0.05, 0.95); // spawn timers state.spawnTimer -= dt; state.starTimer -= dt; if(state.spawnTimer <= 0){ spawnBlock(); state.spawnTimer = Math.max(0.22, 0.9 - state.difficulty*0.08); } if(state.starTimer <= 0){ spawnStar(); state.starTimer = rand(2.2, 3.2) / Math.max(1, state.difficulty*0.8); } // move blocks & check collisions const px = p.x, py = p.y, pr = p.rN; let aliveBlocks=[]; for(const b of state.blocks){ b.y += b.v * dt * 0.6; b.x += b.rot * dt; if(b.y < 1.2) aliveBlocks.push(b); // circle-rect collision (normalized coords) const rx = clamp(px, b.x - b.w/2, b.x + b.w/2); const ry = clamp(py, b.y - b.h/2, b.y + b.h/2); const dx = px - rx, dy = py - ry; if(dx*dx + dy*dy <= pr*pr){ gameOver(); break; } } state.blocks = aliveBlocks; // stars let aliveStars=[]; for(const s of state.stars){ s.y += s.v * dt * 0.6; if(s.y < 1.2) aliveStars.push(s); const dx = px - s.x, dy = py - s.y; if(dx*dx + dy*dy <= (pr + s.r)*(pr + s.r)){ state.score += 15; scoreEl.textContent = state.score; beep('square',880,0.06,0.05); // mark as offscreen to remove s.y = 99; } } state.stars = aliveStars; // passive scoring state.score += Math.max(1, Math.floor(state.difficulty)) ; scoreEl.textContent = state.score; } function draw(){ const W = canvas.width, H = canvas.height; ctx.save(); ctx.scale(DPR,DPR); // starfield background const cols = Math.floor(canvas.width/14); ctx.globalAlpha = 0.5; for(let i=0;i

@pineapple-08081
Copy link

<title>華格納補習班</title> <style> body { margin: 0; font-family: "Noto Sans TC", sans-serif; line-height: 1.6; } header { background: #004aad; color: white; padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; } nav a { color: white; text-decoration: none; margin: 0 10px; font-weight: bold; } nav a:hover { text-decoration: underline; } .hero { background: url("banner.jpg") center/cover no-repeat; height: 400px; display: flex; align-items: center; justify-content: center; color: white; font-size: 2rem; font-weight: bold; text-shadow: 2px 2px 5px rgba(0,0,0,0.7); } .section { padding: 2rem; max-width: 1200px; margin: auto; } .features { display: flex; gap: 1rem; text-align: center; } .feature { flex: 1; background: #f0f4ff; padding: 1.5rem; border-radius: 10px; } .news-list li { margin-bottom: 0.5rem; } .gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; } .gallery img { width: 100%; border-radius: 8px; } footer { background: #002b66; color: white; text-align: center; padding: 1rem; margin-top: 2rem; } </style>

明天要上班不想面隊補習班

首頁 師資介紹 課程 活動成果 最新消息 聯絡我們
歡迎來到本補習班

我們的特色

優秀師資

我們擁有多年經驗的專業教師團隊。

舒適環境

明亮整潔的教室,提供最佳的學習氛圍。

成果亮眼

學生在各類比賽與考試中屢創佳績。

最新消息

  • 2025/08/10 - 暑期結業式圓滿落幕
  • 2025/07/15 - 英語朗讀比賽榮獲第一名
  • 2025/06/30 - 暑期課程開課

活動成果

活動1 活動2 活動3

地址:台中市西區公益路56號2樓|電話:(04) 2319-7118|LINE:23197118

© 2025 華格納補習班. All rights reserved.

@pineapple-08081
Copy link

pineapple-08081 commented Aug 15, 2025

<title>華格納補習班</title> <style> body { margin: 0; font-family: "Noto Sans TC", sans-serif; line-height: 1.6; } header { background: #004aad; color: white; padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; } nav a { color: white; text-decoration: none; margin: 0 10px; font-weight: bold; } nav a:hover { text-decoration: underline; } .hero { background: url("華格納補習班.jpg") center/cover no-repeat; height: 400px; display: flex; align-items: center; justify-content: center; color: white; font-size: 2rem; font-weight: bold; text-shadow: 2px 2px 5px rgba(0,0,0,0.7); } .section { padding: 2rem; max-width: 1200px; margin: auto; } .features { display: flex; gap: 1rem; text-align: center; } .feature { flex: 1; background: #f0f4ff; padding: 1.5rem; border-radius: 10px; } .news-list li { margin-bottom: 0.5rem; } .gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; } .gallery img { width: 100%; border-radius: 8px; } footer { background: #002b66; color: white; text-align: center; padding: 1rem; margin-top: 2rem; } </style>

明天要上班不想面隊補習班

首頁 師資介紹 課程 活動成果 最新消息 聯絡我們
歡迎來到本補習班

我們的特色

優秀師資

我們擁有多年經驗的專業教師團隊。

舒適環境

明亮整潔的教室,提供最佳的學習氛圍。

成果亮眼

學生在各類比賽與考試中屢創佳績。

最新消息

  • 2025/08/10 - 暑期結業式圓滿落幕
  • 2025/07/15 - 英語朗讀比賽榮獲第一名
  • 2025/06/30 - 暑期課程開課

活動成果

活動1 活動2 活動3

地址:台中市西區公益路56號2樓|電話:(04) 2319-7118|LINE:23197118

© 2025 華格納補習班. All rights reserved.

@alan050765-creator
Copy link

<a class="link" href="https://instagram.com/your_instagram_here" target="_blank" ...>Instagram

@alan050765-creator
Copy link

@anita2016001-create
Copy link

<title>Accessories Store</title> <style> /* Reset */ * { margin: 0; padding: 0; box-sizing: border-box; }
body {
  font-family: Arial, sans-serif;
  line-height: 1.6;
  color: #333;
}

header {
  background: url('https://images.unsplash.com/photo-1522312346375-d1a52e2b99b3?auto=format&fit=crop&w=1500&q=80') no-repeat center/cover;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: white;
  position: relative;
}

header::after {
  content: "";
  position: absolute;
  top:0; left:0;
  width:100%; height:100%;
  background: rgba(0,0,0,0.5);
}

header .content {
  position: relative;
  z-index: 1;
}

header h1 {
  font-size: 3rem;
  margin-bottom: 1rem;
}

header p {
  font-size: 1.2rem;
  margin-bottom: 2rem;
}

.btn {
  display: inline-block;
  padding: 12px 24px;
  background: #ff6b6b;
  color: white;
  text-decoration: none;
  font-weight: bold;
  border-radius: 5px;
  transition: background 0.3s;
}

.btn:hover {
  background: #ff4040;
}

section {
  padding: 60px 20px;
  max-width: 1100px;
  margin: auto;
}

.products {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

.product {
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
  text-align: center;
  background: #fff;
  transition: transform 0.3s;
}

.product:hover {
  transform: translateY(-5px);
}

.product img {
  width: 100%;
  height: 250px;
  object-fit: cover;
}

.product h3 {
  margin: 15px 0 5px;
}

.product p {
  margin-bottom: 15px;
  color: #555;
}

.about {
  text-align: center;
}

.testimonials {
  background: #f9f9f9;
  border-radius: 10px;
  padding: 30px;
}

.testimonial {
  margin-bottom: 20px;
  font-style: italic;
}

footer {
  background: #333;
  color: white;
  text-align: center;
  padding: 20px;
}

footer a {
  color: #ff6b6b;
  text-decoration: none;
}
</style>

Elevate Your Style

Discover premium accessories that define confidence.

Shop Now

Featured Accessories

Watch

Luxury Watch

$199

View More
Bag

Elegant Bag

$249

View More
Sunglasses

Classic Sunglasses

$99

View More

Why Choose Us?

We design timeless accessories that combine elegance with durability. Every piece is crafted with care to elevate your everyday look.

What Our Customers Say

“Absolutely love my new watch. It goes with everything!” – Sarah
“High-quality products at great prices. Will shop again.” – David
“Fast shipping and amazing service!” – Emily

© 2025 Accessories Store | Contact Us

@AnonymousTalent
Copy link

<title>Snake Game + GPT AI Chat</title> <style> body { font-family: monospace; background: #222; color: #eee; text-align: center; } canvas { background: #111; margin: 20px auto; display: block; } #aiResponse { background: #333; color: #fff; min-height: 2em; margin: 10px auto; max-width: 400px; border-radius: 8px; padding: 10px; } #chat { margin-top: 16px; } input, button { font-size: 16px; } </style>

🐍 Snake Game + GPT AI Chat

問 AI
<script> // 簡易 Snake 遊戲 const canvas = document.getElementById('game'); const ctx = canvas.getContext('2d'); const tileCount = 20; const gridSize = canvas.width / tileCount; let tail = 5; let snakeTrail = []; let snake = { x: 10, y: 10 }; let velocity = { x: 0, y: 0 }; let fruit = { x: 5, y: 5 };
function gameLoop() {
  snake.x += velocity.x;
  snake.y += velocity.y;

  // 撞牆
  if (snake.x < 0 || snake.x >= tileCount || snake.y < 0 || snake.y >= tileCount) {
    resetGame();
  }

  // 吃到自己
  for (let t of snakeTrail) {
    if (t.x === snake.x && t.y === snake.y) resetGame();
  }

  // 畫面
  ctx.fillStyle = "#111";
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  ctx.fillStyle = "lime";
  for (let t of snakeTrail) ctx.fillRect(t.x * gridSize, t.y * gridSize, gridSize - 2, gridSize - 2);

  ctx.fillStyle = "yellow";
  ctx.fillRect(snake.x * gridSize, snake.y * gridSize, gridSize - 2, gridSize - 2);

  ctx.fillStyle = "red";
  ctx.fillRect(fruit.x * gridSize, fruit.y * gridSize, gridSize - 2, gridSize - 2);

  snakeTrail.push({ x: snake.x, y: snake.y });
  while (snakeTrail.length > tail) snakeTrail.shift();

  // 吃到果實
  if (snake.x === fruit.x && snake.y === fruit.y) {
    tail++;
    fruit.x = Math.floor(Math.random() * tileCount);
    fruit.y = Math.floor(Math.random() * tileCount);
  }
}

function resetGame() {
  tail = 5;
  snakeTrail = [];
  snake = { x: 10, y: 10 };
  velocity = { x: 0, y: 0 };
}

document.addEventListener('keydown', e => {
  switch (e.key) {
    case 'ArrowLeft': velocity = { x: -1, y: 0 }; break;
    case 'ArrowUp': velocity = { x: 0, y: -1 }; break;
    case 'ArrowRight': velocity = { x: 1, y: 0 }; break;
    case 'ArrowDown': velocity = { x: 0, y: 1 }; break;
  }
});

setInterval(gameLoop, 100);

// --- AI 聊天區 ---
const apiKey = '你的API Key'; // ←←←這裡貼上你的API Key!

async function chatWithGPT(prompt) {
  const endpoint = 'https://api.openai.com/v1/chat/completions';
  const response = await fetch(endpoint, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${apiKey}`
    },
    body: JSON.stringify({
      model: 'gpt-3.5-turbo',
      messages: [{ role: 'user', content: prompt }],
      max_tokens: 300
    })
  });
  const data = await response.json();
  return data.choices?.[0]?.message?.content || "AI 沒有回應";
}

async function askAI() {
  const question = document.getElementById('userInput').value;
  if (!question) return;
  document.getElementById('aiResponse').innerText = "AI 正在思考...";
  try {
    const answer = await chatWithGPT(question);
    document.getElementById('aiResponse').innerText = answer;
  } catch (err) {
    document.getElementById('aiResponse').innerText = "AI 請求失敗,請檢查 API Key 或網路";
  }
}
</script>

@gxzhjjnm2y-blip
Copy link

<title>智慧分帳計算機</title> <script src="https://cdn.tailwindcss.com"></script> <style> /* 讓輸入欄位文字靠右對齊,符合金額輸入習慣 */ #totalBill { text-align: right; } /* 隱藏 Chrome/Safari 的數字輸入框上下箭頭 */ input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } /* 隱藏 Firefox 的數字輸入框上下箭頭 */ input[type=number] { -moz-appearance: textfield; } </style> <script> // 設定 Tailwind CSS 配置,使用一個現代高對比配色 tailwind.config = { theme: { extend: { colors: { 'primary': '#2563EB', // 藍色 'secondary': '#10B981', // 綠色 'background': '#F3F4F6', // 淺灰背景 'card-bg': '#FFFFFF', // 卡片背景 'dark-bg': '#1F2937', // 深色區塊背景 'dark-text': '#F3F4F6', // 深色區塊文字 } } } } </script>
<div class="max-w-md mx-auto bg-card-bg shadow-2xl rounded-xl overflow-hidden">
    <header class="bg-primary text-white p-6">
        <h1 class="text-2xl font-bold text-center">💸 智慧分帳計算機</h1>
    </header>

    <main class="p-6 space-y-6">

        <div class="space-y-4">
            <h2 class="text-lg font-semibold text-gray-700 border-b pb-2">輸入資訊</h2>

            <div>
                <label for="totalBill" class="block text-sm font-medium text-gray-600 mb-1">總金額 (Total Bill)</label>
                <div class="relative rounded-lg shadow-sm">
                    <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                        <span class="text-gray-500">NT$</span>
                    </div>
                    <input type="number" id="totalBill" value="500" min="0" placeholder="0.00"
                        class="block w-full pl-12 pr-4 py-3 border border-gray-300 rounded-lg text-lg focus:ring-primary focus:border-primary">
                </div>
            </div>

            <div>
                <div class="flex justify-between items-center mb-1">
                    <label class="text-sm font-medium text-gray-600">小費百分比 (Tip %)</label>
                    <span id="tipPercentageValue" class="text-lg font-bold text-primary">10%</span>
                </div>
                <input type="range" id="tipPercentage" value="10" min="0" max="30" step="1"
                    class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer range-lg focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2">
            </div>

            <div>
                <label class="block text-sm font-medium text-gray-600 mb-2">人數 (People)</label>
                <div class="flex items-center justify-center space-x-4 bg-gray-100 p-3 rounded-lg">
                    <button id="decrementPeople" class="text-3xl font-bold text-primary hover:text-primary-dark transition duration-150 p-1.5 rounded-full hover:bg-white">-</button>
                    <span id="peopleValue" class="text-3xl font-extrabold text-gray-800 w-16 text-center">2</span>
                    <button id="incrementPeople" class="text-3xl font-bold text-primary hover:text-primary-dark transition duration-150 p-1.5 rounded-full hover:bg-white">+</button>
                </div>
            </div>
        </div>

        <div class="bg-dark-bg text-dark-text p-5 rounded-xl shadow-lg space-y-5">
            <h2 class="text-xl font-bold border-b border-gray-700 pb-3 mb-4">✨ 即時運算結果</h2>
            
            <div class="flex justify-between items-center">
                <span class="text-base font-medium text-gray-400">總金額 (含小費):</span>
                <span id="totalAmountDisplay" class="text-2xl font-bold text-secondary">NT$ 0.00</span>
            </div>

            <div class="text-center pt-4 border-t border-gray-700">
                <p class="text-lg font-medium text-gray-400 mb-1">每人應付金額 (Per Person)</p>
                <p id="perPersonDisplay" class="text-5xl font-extrabold text-white">NT$ 0.00</p>
            </div>
        </div>

    </main>
</div>

<script>
    // 取得所有 DOM 元素
    const totalBillInput = document.getElementById('totalBill');
    const tipPercentageSlider = document.getElementById('tipPercentage');
    const tipPercentageValue = document.getElementById('tipPercentageValue');
    const peopleValueSpan = document.getElementById('peopleValue');
    const incrementPeopleBtn = document.getElementById('incrementPeople');
    const decrementPeopleBtn = document.getElementById('decrementPeople');
    const totalAmountDisplay = document.getElementById('totalAmountDisplay');
    const perPersonDisplay = document.getElementById('perPersonDisplay');

    let totalBill = parseFloat(totalBillInput.value) || 0;
    let tipPercentage = parseInt(tipPercentageSlider.value) || 0;
    let people = parseInt(peopleValueSpan.textContent) || 1; // 確保人數至少為 1

    /**
     * 主計算函式:計算總金額與每人應付金額
     */
    function calculateSplit() {
        // 1. 取得最新數值
        totalBill = parseFloat(totalBillInput.value) || 0;
        tipPercentage = parseInt(tipPercentageSlider.value) || 0;
        people = parseInt(peopleValueSpan.textContent) || 1;

        // 處理小費計算
        const tipAmount = totalBill * (tipPercentage / 100);
        
        // 計算總金額 (含小費)
        const totalAmountWithTip = totalBill + tipAmount;

        // 計算每人應付金額
        const perPersonAmount = people > 0 ? totalAmountWithTip / people : 0;
        
        // 2. 更新介面顯示
        
        // 更新小費百分比顯示
        tipPercentageValue.textContent = `${tipPercentage}%`;

        // 更新總金額 (含小費) 顯示,四捨五入到小數點第二位
        totalAmountDisplay.textContent = `NT$ ${totalAmountWithTip.toFixed(2)}`;

        // 更新每人應付金額顯示,四捨五入到小數點第二位
        perPersonDisplay.textContent = `NT$ ${perPersonAmount.toFixed(2)}`;
    }

    // --- 事件監聽器 ---

    // 1. 總金額輸入變更
    totalBillInput.addEventListener('input', calculateSplit);

    // 2. 小費滑桿變更
    tipPercentageSlider.addEventListener('input', calculateSplit);

    // 3. 人數增加按鈕
    incrementPeopleBtn.addEventListener('click', () => {
        people = parseInt(peopleValueSpan.textContent) + 1;
        peopleValueSpan.textContent = people;
        calculateSplit();
    });

    // 4. 人數減少按鈕
    decrementPeopleBtn.addEventListener('click', () => {
        people = parseInt(peopleValueSpan.textContent);
        if (people > 1) { // 確保人數至少為 1
            people -= 1;
            peopleValueSpan.textContent = people;
            calculateSplit();
        }
    });

    // 頁面載入時先執行一次計算,顯示初始值
    window.onload = calculateSplit;

</script>

@raaq605-cmd
Copy link

<title>SwiftCargo – النقل السريع واللوجستيك الاحترافي</title> <style> body { margin: 0; font-family: Arial, sans-serif; color: #222; background: #f4f6f9; line-height: 1.6; } header { background: #0d1b2a; padding: 15px 40px; display: flex; justify-content: space-between; align-items: center; color: white; } .logo { font-size: 26px; font-weight: bold; letter-spacing: 1px; } .hero { text-align: center; padding: 60px 20px; background: linear-gradient(120deg, #0d1b2a, #1b263b); color: white; } .hero img { width: 85%; max-width: 900px; border-radius: 10px; margin-top: 25px; } .features { padding: 40px 20px; max-width: 1100px; margin: auto; } .features h2 { text-align: center; margin-bottom: 30px; font-size: 28px; color: #0d1b2a; } .feature-box { background: white; padding: 20px; border-radius: 12px; margin-bottom: 20px; box-shadow: 0 3px 12px rgba(0,0,0,0.1); border-left: 5px solid #1b263b; } .cta { text-align: center; padding: 50px 20px; } .cta a { display: inline-block; background: #1b263b; color: white; padding: 15px 35px; border-radius: 8px; font-size: 20px; text-decoration: none; transition: 0.3s; } .cta a:hover { background: #415a77; } footer { background: #0d1b2a; color: white; padding: 20px; text-align: center; margin-top: 40px; } form { background: white; padding: 20px; border-radius: 12px; max-width: 600px; margin: 20px auto; box-shadow: 0 3px 12px rgba(0,0,0,0.1); } input, textarea { width: 100%; padding: 12px; margin: 10px 0; border-radius: 8px; border: 1px solid #ccc; font-size: 16px; } button { background: #1b263b; color: white; padding: 14px; border: none; border-radius: 8px; width: 100%; cursor: pointer; font-size: 18px; } button:hover { background: #415a77; } </style>
SwiftCargo

النقل اللوجستي بلا حدود

نقل سريع، آمن وموثوق عبر Volkswagen Crafter عالية السعة.

<!-- ★ ضع صورتك هنا بعد تسميتها: crafter-real.jpg -->
<img src="crafter-real.jpg" alt="SwiftCargo Volkswagen Crafter">

لماذا SwiftCargo؟

<div class="feature-box">✔ نقل لوجستي احترافي للشركات والمطارات والموانئ باستخدام Volkswagen Crafter</div>
<div class="feature-box">✔ تتبع مباشر لكل شحنة لضمان وصولها في الوقت المحدد</div>
<div class="feature-box">✔ حلول شحن آمنة، سريعة وفعالة</div>
<div class="feature-box">✔ فريق متخصص، عمليات دقيقة، وانسيابية كاملة في الخدمة</div>
ابدأ شحنتك الآن

تواصل معنا

    <input type="text" name="name" placeholder="الاسم الكامل" required>
    <input type="email" name="email" placeholder="البريد الإلكتروني" required>
    <input type="text" name="phone" placeholder="رقم الهاتف" required>
    <textarea name="message" placeholder="اكتب رسالتك..." rows="5" required></textarea>
    
    <button type="submit">إرسال</button>
</form>
للتواصل:
📧 [email protected]
📞 0666116722

© 2025 SwiftCargo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment