<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>平行四边形面积推导</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #6e8efb, #a777e3);
color: #333;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.container {
background: rgba(255, 255, 255, 0.92);
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
padding: 30px;
max-width: 900px;
width: 100%;
margin: 20px 0;
}
h1 {
color: #2c3e50;
text-align: center;
margin-bottom: 25px;
font-size: 2.4rem;
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
}
.animation-container {
display: flex;
justify-content: center;
align-items: center;
height: 350px;
margin: 25px 0;
position: relative;
background: #f8f9fa;
border-radius: 15px;
box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.grid-lines {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: 20px 20px;
background-image:
linear-gradient(to right, rgba(0, 0, 0, 0.05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(0, 0, 0, 0.05) 1px, transparent 1px);
z-index: 1;
}
.coordinate-system {
position: absolute;
bottom: 80px;
left: 50%;
transform: translateX(-50%);
width: 500px;
height: 200px;
z-index: 2;
}
.x-axis, .y-axis {
position: absolute;
background: #7f8c8d;
}
.x-axis {
width: 100%;
height: 2px;
bottom: 0;
left: 0;
}
.y-axis {
width: 2px;
height: 100%;
left: 50%;
bottom: 0;
transform: translateX(-50%);
}
.axis-label {
position: absolute;
font-weight: bold;
color: #2c3e50;
}
.x-label {
bottom: -25px;
left: 50%;
transform: translateX(-50%);
}
.y-label {
top: -20px;
left: calc(50% + 15px);
}
.triangle {
position: absolute;
width: 0;
height: 0;
border-style: solid;
z-index: 3;
}
.triangle-original {
border-width: 0 0 150px 200px;
border-color: transparent transparent #ff6b6b transparent;
bottom: 80px;
left: calc(50% - 100px);
transform-origin: bottom left;
}
.triangle-copy {
border-width: 0 0 150px 200px;
border-color: transparent transparent #4ecdc4 transparent;
bottom: 80px;
left: calc(50% - 100px);
transform-origin: bottom left;
opacity: 0;
}
.parallelogram {
position: absolute;
width: 200px;
height: 150px;
background: linear-gradient(135deg, rgba(255, 107, 107, 0.7), rgba(78, 205, 196, 0.7));
bottom: 80px;
left: calc(50% - 100px);
z-index: 4;
opacity: 0;
clip-path: polygon(0 0, 100% 0, 200% 100%, 100% 100%);
}
.measurement {
position: absolute;
background: #3498db;
border-radius: 3px;
}
.base {
width: 200px;
height: 3px;
bottom: 70px;
left: calc(50% - 100px);
}
.height {
width: 3px;
height: 150px;
bottom: 80px;
left: calc(50% + 110px);
}
.measurement-label {
position: absolute;
color: #3498db;
font-weight: bold;
background: rgba(255, 255, 255, 0.8);
padding: 2px 8px;
border-radius: 5px;
}
.base-label {
bottom: 55px;
left: 50%;
transform: translateX(-50%);
}
.height-label {
bottom: 155px;
left: calc(50% + 125px);
transform: translateY(50%);
}
.controls {
display: flex;
justify-content: center;
gap: 20px;
margin: 25px 0;
}
button {
background: #3498db;
color: white;
border: none;
padding: 14px 30px;
border-radius: 50px;
cursor: pointer;
font-size: 1.1rem;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
button:hover {
background: #2980b9;
transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.25);
}
button:active {
transform: translateY(0);
}
button:disabled {
background: #95a5a6;
cursor: not-allowed;
}
.explanation {
background: #e8f4fc;
border-left: 5px solid #3498db;
padding: 20px;
border-radius: 8px;
margin: 25px 0;
}
.formula {
font-size: 1.6rem;
text-align: center;
margin: 30px 0;
font-weight: bold;
color: #2c3e50;
background: linear-gradient(135deg, #6e8efb, #a777e3);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
padding: 10px;
}
.step-indicator {
text-align: center;
font-weight: bold;
margin: 15px 0;
color: #2c3e50;
font-size: 1.2rem;
}
.footer {
margin-top: 20px;
text-align: center;
color: #ecf0f1;
font-size: 0.9rem;
}
@media (max-width: 768px) {
.container {
padding: 20px;
}
h1 {
font-size: 2rem;
}
.animation-container {
height: 300px;
}
.coordinate-system {
width: 90%;
}
button {
padding: 12px 25px;
font-size: 1rem;
}
}
</style>
</head>
<body>
<div class="container">
<h1>平行四边形面积公式推导</h1>
<div class="step-indicator" id="stepIndicator">第1步:初始三角形</div>
<div class="animation-container">
<div class="grid-lines"></div>
<div class="coordinate-system">
<div class="x-axis"></div>
<div class="y-axis"></div>
<div class="axis-label x-label">底边</div>
<div class="axis-label y-label">高</div>
<div class="triangle triangle-original"></div>
<div class="triangle triangle-copy" id="triangleCopy"></div>
<div class="parallelogram" id="parallelogram"></div>
<div class="measurement base"></div>
<div class="measurement height"></div>
<div class="measurement-label base-label">底 = 200</div>
<div class="measurement-label height-label">高 = 150</div>
</div>
</div>
<div class="controls">
<button id="startBtn">开始动画</button>
<button id="resetBtn" disabled>重置</button>
</div>
<div class="explanation">
<p>通过这个动画,我们可以直观地理解平行四边形的面积公式:</p>
<ol>
<li>我们从一个大三角形开始,它的面积是平行四边形的一半</li>
<li>复制这个三角形并将其旋转180度</li>
<li>将旋转后的三角形平移到原始三角形的右侧</li>
<li>两个三角形组合形成一个完整的平行四边形</li>
<li>因此,平行四边形的面积等于两个三角形的面积之和</li>
<li>由于三角形面积 = (底 × 高) ÷ 2,所以平行四边形面积 = 底 × 高</li>
</ol>
</div>
<div class="formula">
平行四边形面积 = 底 × 高
</div>
</div>
<div class="footer">
<p>平行四边形面积推导动画 © 2023</p>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const startBtn = document.getElementById('startBtn');
const resetBtn = document.getElementById('resetBtn');
const stepIndicator = document.getElementById('stepIndicator');
const triangleCopy = document.getElementById('triangleCopy');
const parallelogram = document.getElementById('parallelogram');
let animationPhase = 0;
let animationId = null;
// 开始动画
startBtn.addEventListener('click', startAnimation);
// 重置动画
resetBtn.addEventListener('click', resetAnimation);
function startAnimation() {
startBtn.disabled = true;
resetBtn.disabled = false;
animate();
}
function animate() {
if (animationPhase === 0) {
// 第一步:显示复制的三角形
stepIndicator.textContent = "第2步:复制三角形";
triangleCopy.style.opacity = "1";
animationPhase = 1;
setTimeout(() => {
animationId = requestAnimationFrame(animate);
}, 1000);
} else if (animationPhase === 1) {
// 第二步:旋转复制的三角形
stepIndicator.textContent = "第3步:旋转三角形";
let rotation = 0;
const rotateInterval = setInterval(() => {
rotation += 2;
triangleCopy.style.transform = `rotate(${rotation}deg)`;
if (rotation >= 180) {
clearInterval(rotateInterval);
animationPhase = 2;
animationId = requestAnimationFrame(animate);
}
}, 20);
} else if (animationPhase === 2) {
// 第三步:平移三角形
stepIndicator.textContent = "第4步:平移三角形";
let translateX = 0;
const translateInterval = setInterval(() => {
translateX += 2;
triangleCopy.style.left = `calc(50% - 100px + ${translateX}px)`;
if (translateX >= 200) {
clearInterval(translateInterval);
animationPhase = 3;
animationId = requestAnimationFrame(animate);
}
}, 20);
} else if (animationPhase === 3) {
// 第四步:显示平行四边形
stepIndicator.textContent = "第5步:形成平行四边形";
parallelogram.style.opacity = "0";
stepIndicator.textContent = "完成!平行四边形已形成";
animationPhase = 4;
}
}
function resetAnimation() {
cancelAnimationFrame(animationId);
// 重置所有元素
triangleCopy.style.opacity = "0";
triangleCopy.style.transform = "rotate(0deg)";
triangleCopy.style.left = "calc(50% - 100px)";
parallelogram.style.opacity = "0";
parallelogram.style.clipPath = "polygon(0 0, 100% 0, 200% 100%, 100% 100%)";
stepIndicator.textContent = "第1步:初始三角形";
startBtn.disabled = false;
resetBtn.disabled = true;
animationPhase = 0;
}
});
</script>
</body>
</html>
index.html