Re: 正在做etani,ejtile的動畫套件
发表于 : 2025年 11月 13日 16:56
大功告成?
當前代碼:
當前代碼:
手捧一份淨土,劃分文學、外語、音樂、茶座、IT等圈子,寓意為在一個個圈子裡與你相遇,在這里圈圈和朋友們討論酷的東西
https://quanquan.space/
代码: 全选
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>兩直線交點計算器</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 30px auto;
padding: 20px;
background-color: #f9f9f9;
line-height: 1.6;
}
h1 {
text-align: center;
color: #333;
}
.container {
background: white;
padding: 25px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.input-mode {
text-align: center;
margin-bottom: 20px;
}
.input-mode button {
padding: 8px 16px;
margin: 0 5px;
cursor: pointer;
}
.input-mode button.active {
background-color: #007bff;
color: white;
}
.line-input {
margin-bottom: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 8px;
display: none;
}
.line-input.active {
display: block;
}
.line-title {
font-weight: bold;
margin-bottom: 10px;
color: #555;
font-size: 1.1em;
}
.point-input {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.point-input label {
width: 30px;
}
.point-input input {
width: 80px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
.param-input {
display: flex;
gap: 10px;
margin-bottom: 10px;
align-items: center;
}
.param-input label {
width: 20px;
}
.param-input input {
width: 80px;
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
.controls {
text-align: center;
margin: 20px 0;
}
button.calculate {
background-color: #28a745;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 1em;
}
button.calculate:hover {
background-color: #218838;
}
.decimal-control {
margin: 15px 0;
text-align: center;
}
.decimal-control input {
width: 60px;
padding: 5px;
text-align: center;
}
.result {
margin-top: 20px;
padding: 15px;
background-color: #e9f7ef;
border-radius: 8px;
text-align: center;
font-size: 1.2em;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.error {
background-color: #f8d7da;
color: #721c24;
}
.footer {
text-align: center;
margin-top: 30px;
color: #666;
font-size: 0.9em;
}
</style>
</head>
<body>
<div class="container">
<h1>兩直線交點計算器</h1>
<div class="input-mode">
<button id="mode-points" class="active">兩點定義</button>
<button id="mode-params">參數方程 (y = ax + b)</button>
</div>
<!-- 兩點定義模式 -->
<div id="input-points" class="line-input active">
<div class="line-title">直線 1:經過兩點</div>
<div class="point-input">
<label>P1:</label>
<input type="number" step="any" id="p1x1" placeholder="x" value="-2">
<span>,</span>
<input type="number" step="any" id="p1y1" placeholder="y" value="3">
</div>
<div class="point-input">
<label>P2:</label>
<input type="number" step="any" id="p1x2" placeholder="x" value="4">
<span>,</span>
<input type="number" step="any" id="p1y2" placeholder="y" value="-1">
</div>
<div class="line-title" style="margin-top: 20px;">直線 2:經過兩點</div>
<div class="point-input">
<label>P3:</label>
<input type="number" step="any" id="p2x1" placeholder="x" value="-1">
<span>,</span>
<input type="number" step="any" id="p2y1" placeholder="y" value="5">
</div>
<div class="point-input">
<label>P4:</label>
<input type="number" step="any" id="p2x2" placeholder="x" value="3">
<span>,</span>
<input type="number" step="any" id="p2y2" placeholder="y" value="1">
</div>
</div>
<!-- 參數方程模式 -->
<div id="input-params" class="line-input">
<div class="line-title">直線 1:y = ax + b</div>
<div class="param-input">
<label>a:</label>
<input type="number" step="any" id="a1" placeholder="斜率" value="1">
<span style="margin-left: 10px;">b:</span>
<input type="number" step="any" id="b1" placeholder="截距" value="1">
</div>
<div class="line-title" style="margin-top: 20px;">直線 2:y = ax + b</div>
<div class="param-input">
<label>a:</label>
<input type="number" step="any" id="a2" placeholder="斜率" value="-1">
<span style="margin-left: 10px;">b:</span>
<input type="number" step="any" id="b2" placeholder="截距" value="3">
</div>
</div>
<div class="decimal-control">
<label>小數位數:</label>
<input type="number" id="decimal-places" min="0" max="10" value="3">
</div>
<div class="controls">
<button class="calculate" onclick="calculateIntersection()">計算交點</button>
</div>
<div id="result" class="result">
請輸入直線參數並點擊「計算交點」
</div>
</div>
<div class="footer">
支持兩種輸入方式:兩點定義或 y = ax + b 形式<br>
結果預設保留 3 位小數,可自定義 0~10 位
</div>
<script>
// 切換輸入模式
document.getElementById('mode-points').addEventListener('click', function() {
document.getElementById('input-points').classList.add('active');
document.getElementById('input-params').classList.remove('active');
this.classList.add('active');
document.getElementById('mode-params').classList.remove('active');
});
document.getElementById('mode-params').addEventListener('click', function() {
document.getElementById('input-params').classList.add('active');
document.getElementById('input-points').classList.remove('active');
this.classList.add('active');
document.getElementById('mode-points').classList.remove('active');
});
// 計算交點
function calculateIntersection() {
const resultDiv = document.getElementById('result');
resultDiv.className = 'result';
try {
let x, y;
const decimals = parseInt(document.getElementById('decimal-places').value) || 3;
if (decimals < 0 || decimals > 10) throw new Error("小數位數請輸入 0~10");
const isPointsMode = document.getElementById('input-points').classList.contains('active');
if (isPointsMode) {
// 兩點定義模式
const p1 = {
x1: parseFloat(document.getElementById('p1x1').value),
y1: parseFloat(document.getElementById('p1y1').value),
x2: parseFloat(document.getElementById('p1x2').value),
y2: parseFloat(document.getElementById('p1y2').value)
};
const p2 = {
x1: parseFloat(document.getElementById('p2x1').value),
y1: parseFloat(document.getElementById('p2y1').value),
x2: parseFloat(document.getElementById('p2x2').value),
y2: parseFloat(document.getElementById('p2y2').value)
};
// 檢查點是否重合
if (isNaN(p1.x1) || isNaN(p1.y1) || isNaN(p1.x2) || isNaN(p1.y2) ||
isNaN(p2.x1) || isNaN(p2.y1) || isNaN(p2.x2) || isNaN(p2.y2)) {
throw new Error("請輸入完整的坐標值");
}
if (p1.x1 === p1.x2 && p1.y1 === p1.y2) {
throw new Error("直線1的兩個點相同,無法定義直線");
}
if (p2.x1 === p2.x2 && p2.y1 === p2.y2) {
throw new Error("直線2的兩個點相同,無法定義直線");
}
// 計算兩直線的參數 a, b
const a1 = (p1.y2 - p1.y1) / (p1.x2 - p1.x1);
const b1 = p1.y1 - a1 * p1.x1;
const a2 = (p2.y2 - p2.y1) / (p2.x2 - p2.x1);
const b2 = p2.y1 - a2 * p2.x1;
// 檢查是否平行
if (Math.abs(a1 - a2) < 1e-10) {
if (Math.abs(b1 - b2) < 1e-10) {
throw new Error("兩直線重合(無限多交點)");
} else {
throw new Error("兩直線平行(無交點)");
}
}
// 計算交點
x = (b2 - b1) / (a1 - a2);
y = a1 * x + b1;
} else {
// 參數方程模式
const a1 = parseFloat(document.getElementById('a1').value);
const b1 = parseFloat(document.getElementById('b1').value);
const a2 = parseFloat(document.getElementById('a2').value);
const b2 = parseFloat(document.getElementById('b2').value);
if (isNaN(a1) || isNaN(b1) || isNaN(a2) || isNaN(b2)) {
throw new Error("請輸入完整的參數值");
}
// 檢查是否平行
if (Math.abs(a1 - a2) < 1e-10) {
if (Math.abs(b1 - b2) < 1e-10) {
throw new Error("兩直線重合(無限多交點)");
} else {
throw new Error("兩直線平行(無交點)");
}
}
// 計算交點
x = (b2 - b1) / (a1 - a2);
y = a1 * x + b1;
}
// 格式化結果
const format = (num) => Number(num.toFixed(decimals));
resultDiv.innerHTML = `<strong>交點坐標:(${format(x)}, ${format(y)})</strong>`;
} catch (error) {
resultDiv.className = 'result error';
resultDiv.textContent = '錯誤:' + error.message;
}
}
// 按 Enter 鍵也觸發計算
document.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
calculateIntersection();
}
});
</script>
</body>
</html>代码: 全选
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>兩直線交點計算器(進階版)</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 30px auto;
padding: 20px;
background-color: #f9f9f9;
line-height: 1.6;
}
h1 {
text-align: center;
color: #333;
}
.container {
background: white;
padding: 25px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.line-section {
margin-bottom: 25px;
padding: 18px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #fdfdfd;
}
.line-title {
font-weight: bold;
margin-bottom: 12px;
color: #444;
font-size: 1.1em;
display: flex;
justify-content: space-between;
align-items: center;
}
.mode-selector {
display: flex;
gap: 8px;
}
.mode-selector button {
padding: 5px 10px;
font-size: 0.9em;
cursor: pointer;
border: 1px solid #ccc;
border-radius: 4px;
background: #f0f0f0;
}
.mode-selector button.active {
background-color: #007bff;
color: white;
border-color: #007bff;
}
.input-group {
display: none;
margin-top: 12px;
}
.input-group.active {
display: block;
}
.point-input {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.point-input label {
display: flex;
align-items: center;
gap: 5px;
min-width: 160px;
}
.point-input input {
width: 140px;
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
font-family: monospace;
}
.param-input {
display: flex;
gap: 15px;
align-items: center;
flex-wrap: wrap;
}
.param-input label {
display: flex;
align-items: center;
gap: 5px;
min-width: 80px;
}
.param-input input {
width: 100px;
padding: 6px;
border: 1px solid #ccc;
border-radius: 4px;
}
.decimal-control {
margin: 20px 0;
text-align: center;
}
.decimal-control input {
width: 60px;
padding: 5px;
text-align: center;
}
.controls {
text-align: center;
margin: 25px 0;
}
button.calculate {
background-color: #28a745;
color: white;
padding: 12px 28px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 1.1em;
font-weight: bold;
}
button.calculate:hover {
background-color: #218838;
}
.result {
margin-top: 20px;
padding: 18px;
background-color: #e9f7ef;
border-radius: 8px;
text-align: center;
font-size: 1.3em;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
.error {
background-color: #f8d7da;
color: #721c24;
}
.footer {
text-align: center;
margin-top: 30px;
color: #666;
font-size: 0.9em;
}
.example {
font-size: 0.85em;
color: #666;
font-style: italic;
margin-top: 4px;
}
</style>
</head>
<body>
<div class="container">
<h1>兩直線交點計算器(進階版)</h1>
<!-- 直線 1 -->
<div class="line-section">
<div class="line-title">
<span>直線 1</span>
<div class="mode-selector">
<button class="active" data-line="1" data-mode="points">兩點定義</button>
<button data-line="1" data-mode="params">y = ax + b</button>
</div>
</div>
<div id="line1-points" class="input-group active">
<div class="point-input">
<label>
點1:<input type="text" id="l1p1" placeholder="x1,y1" value="-2,3">
</label>
<label>
點2:<input type="text" id="l1p2" placeholder="x2,y2" value="4,-1">
</label>
</div>
<div class="example">範例:-2,3 或 1.5,0</div>
</div>
<div id="line1-params" class="input-group">
<div class="param-input">
<label>a:<input type="number" step="any" id="l1a" value="1"></label>
<label>b:<input type="number" step="any" id="l1b" value="1"></label>
</div>
</div>
</div>
<!-- 直線 2 -->
<div class="line-section">
<div class="line-title">
<span>直線 2</span>
<div class="mode-selector">
<button class="active" data-line="2" data-mode="points">兩點定義</button>
<button data-line="2" data-mode="params">y = ax + b</button>
</div>
</div>
<div id="line2-points" class="input-group active">
<div class="point-input">
<label>
點1:<input type="text" id="l2p1" placeholder="x1,y1" value="-1,5">
</label>
<label>
點2:<input type="text" id="l2p2" placeholder="x2,y2" value="3,1">
</label>
</div>
<div class="example">範例:0,0 或 2.5,-3</div>
</div>
<div id="line2-params" class="input-group">
<div class="param-input">
<label>a:<input type="number" step="any" id="l2a" value="-1"></label>
<label>b:<input type="number" step="any" id="l2b" value="3"></label>
</div>
</div>
</div>
<div class="decimal-control">
<label>小數位數:</label>
<input type="number" id="decimal-places" min="0" max="10" value="3">
</div>
<div class="controls">
<button class="calculate" onclick="calculateIntersection()">計算交點</button>
</div>
<div id="result" class="result">
請輸入直線參數並點擊「計算交點」
</div>
</div>
<div class="footer">
每條直線可獨立選擇「兩點定義」或「y = ax + b」<br>
兩點格式:x,y(逗號分隔)<br>
結果保留 0~10 位小數,預設 3 位
</div>
<script>
// 切換模式
document.querySelectorAll('.mode-selector button').forEach(btn => {
btn.addEventListener('click', function() {
const line = this.dataset.line;
const mode = this.dataset.mode;
const selector = `.mode-selector button[data-line="${line}"]`;
document.querySelectorAll(selector).forEach(b => b.classList.remove('active'));
this.classList.add('active');
document.getElementById(`line${line}-points`).classList.toggle('active', mode === 'points');
document.getElementById(`line${line}-params`).classList.toggle('active', mode === 'params');
});
});
// 解析 x,y 字串
function parsePoint(str) {
if (!str || !str.trim()) return null;
const parts = str.trim().split(',');
if (parts.length !== 2) return null;
const x = parseFloat(parts[0]);
const y = parseFloat(parts[1]);
return (isNaN(x) || isNaN(y)) ? null : { x, y };
}
// 計算交點
function calculateIntersection() {
const resultDiv = document.getElementById('result');
resultDiv.className = 'result';
try {
const decimals = Math.max(0, Math.min(10, parseInt(document.getElementById('decimal-places').value) || 3));
let a1, b1, a2, b2;
// 讀取直線 1
const mode1 = document.querySelector(`.mode-selector button[data-line="1"].active`).dataset.mode;
if (mode1 === 'points') {
const p1 = parsePoint(document.getElementById('l1p1').value);
const p2 = parsePoint(document.getElementById('l1p2').value);
if (!p1 || !p2) throw new Error("直線1:請輸入正確的兩點格式(x,y)");
if (p1.x === p2.x && p1.y === p2.y) throw new Error("直線1:兩點相同,無法定義直線");
const dx = p2.x - p1.x;
if (Math.abs(dx) < 1e-10) throw new Error("直線1:垂直線無法用 y=ax+b 表示");
a1 = (p2.y - p1.y) / dx;
b1 = p1.y - a1 * p1.x;
} else {
a1 = parseFloat(document.getElementById('l1a').value);
b1 = parseFloat(document.getElementById('l1b').value);
if (isNaN(a1) || isNaN(b1)) throw new Error("直線1:請輸入完整的 a 和 b");
}
// 讀取直線 2
const mode2 = document.querySelector(`.mode-selector button[data-line="2"].active`).dataset.mode;
if (mode2 === 'points') {
const p1 = parsePoint(document.getElementById('l2p1').value);
const p2 = parsePoint(document.getElementById('l2p2').value);
if (!p1 || !p2) throw new Error("直線2:請輸入正確的兩點格式(x,y)");
if (p1.x === p2.x && p1.y === p2.y) throw new Error("直線2:兩點相同,無法定義直線");
const dx = p2.x - p1.x;
if (Math.abs(dx) < 1e-10) throw new Error("直線2:垂直線無法用 y=ax+b 表示");
a2 = (p2.y - p1.y) / dx;
b2 = p1.y - a2 * p1.x;
} else {
a2 = parseFloat(document.getElementById('l2a').value);
b2 = parseFloat(document.getElementById('l2b').value);
if (isNaN(a2) || isNaN(b2)) throw new Error("直線2:請輸入完整的 a 和 b");
}
// 檢查平行或重合
const slopeDiff = a1 - a2;
if (Math.abs(slopeDiff) < 1e-10) {
if (Math.abs(b1 - b2) < 1e-10) {
throw new Error("兩直線重合(無限多交點)");
} else {
throw new Error("兩直線平行(無交點)");
}
}
// 計算交點
const x = (b2 - b1) / slopeDiff;
const y = a1 * x + b1;
const format = (num) => Number(num.toFixed(decimals));
resultDiv.innerHTML = `<strong>交點坐標:(${format(x)}, ${format(y)})</strong>`;
} catch (error) {
resultDiv.className = 'result error';
resultDiv.textContent = '錯誤:' + error.message;
}
}
// Enter 鍵觸發
document.addEventListener('keydown', function(e) {
if (e.key === 'Enter') calculateIntersection();
});
</script>
</body>
</html>