正弦与余弦函数教学演示-探索函数正余弦函数的参数影响
交互式的正弦与余弦函数教学演示,帮助学生理解函数参数A、ω、φ对函数图像的影响。
因生成图像需使用“chart.js”在线加载较慢,已和html文件打包压缩,文末有下载链接,解压后不能删除该文件。

以下是实现代码( 由 deepseek 依据人工指令生成):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>正弦与余弦函数教学演示</title>
<script src="chart.js"></script>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #0a1a3a, #1a3a6a, #2a5a9a);
color: white;
min-height: 100vh;
padding: 15px;
overflow: hidden;
}
.container {
max-width: 1400px;
margin: 0 auto;
background-color: rgba(10, 25, 50, 0.85);
border-radius: 15px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
height: calc(100vh - 30px);
display: flex;
flex-direction: column;
}
header {
text-align: center;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid rgba(100, 150, 255, 0.3);
flex-shrink: 0;
}
h1 {
font-size: 2rem;
margin-bottom: 8px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
color: #a8d1ff;
}
.subtitle {
font-size: 1rem;
opacity: 0.9;
color: #c8e1ff;
}
.main-content {
display: flex;
flex: 1;
overflow: hidden;
gap: 20px;
}
.left-panel {
flex: 3;
display: flex;
flex-direction: column;
gap: 15px;
}
.right-panel {
flex: 2;
display: flex;
flex-direction: column;
gap: 15px;
max-width: 400px;
}
.controls-container {
background: rgba(20, 40, 80, 0.8);
border-radius: 10px;
padding: 15px;
border: 1px solid rgba(100, 150, 255, 0.2);
}
.function-selector {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
.function-option {
flex: 1;
text-align: center;
padding: 10px;
background: rgba(40, 70, 120, 0.8);
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
border: 1px solid rgba(100, 150, 255, 0.3);
}
.function-option:hover {
background: rgba(60, 100, 160, 0.8);
transform: translateY(-2px);
}
.function-option.active {
background: #2a5a9a;
box-shadow: 0 0 15px rgba(80, 140, 255, 0.5);
border: 1px solid rgba(120, 180, 255, 0.5);
}
.function-option input {
display: none;
}
.function-option label {
cursor: pointer;
display: block;
margin: 0;
font-weight: 500;
font-size: 0.9rem;
}
.parameters-container {
display: flex;
flex-direction: column;
gap: 15px;
}
.control-group {
background: rgba(30, 60, 100, 0.6);
border-radius: 8px;
padding: 12px;
border: 1px solid rgba(100, 150, 255, 0.2);
}
h2 {
font-size: 1.2rem;
margin-bottom: 12px;
color: #8cc2ff;
text-align: center;
}
.parameter {
margin-bottom: 12px;
}
label {
display: block;
margin-bottom: 6px;
font-weight: 500;
color: #c8e1ff;
font-size: 0.9rem;
}
input[type="range"] {
width: 100%;
height: 8px;
border-radius: 5px;
background: #1a3a6a;
outline: none;
margin-bottom: 5px;
}
input[type="range"]::-webkit-slider-thumb {
appearance: none;
width: 16px;
height: 16px;
border-radius: 50%;
background: #4a9cff;
cursor: pointer;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}
.value-display {
display: flex;
justify-content: space-between;
font-size: 0.85rem;
color: #a8d1ff;
}
.function-display {
background: rgba(30, 60, 100, 0.6);
border-radius: 10px;
padding: 15px;
display: flex;
justify-content: space-around;
align-items: center;
gap: 15px;
border: 1px solid rgba(100, 150, 255, 0.2);
}
.function-equation {
font-size: 1.1rem;
text-align: center;
font-family: 'Cambria Math', serif;
padding: 12px;
background: rgba(40, 80, 140, 0.5);
border-radius: 8px;
flex: 1;
border: 1px solid rgba(100, 150, 255, 0.3);
}
.sin-equation {
color: #64b4ff;
}
.cos-equation {
color: #ffd166;
}
.chart-container {
background: rgba(20, 40, 80, 0.8);
border-radius: 10px;
padding: 15px;
flex: 1;
overflow: hidden;
border: 1px solid rgba(100, 150, 255, 0.2);
position: relative;
}
canvas {
width: 100% !important;
height: 100% !important;
}
.crosshair {
position: absolute;
pointer-events: none;
z-index: 10;
display: none;
}
.crosshair-line {
position: absolute;
background-color: rgba(255, 255, 255, 0.7);
}
.crosshair-x {
width: 100%;
height: 1px;
top: 0;
left: 0;
}
.crosshair-y {
width: 1px;
height: 100%;
top: 0;
left: 0;
}
.crosshair-label {
position: absolute;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.8rem;
white-space: nowrap;
}
.explanation {
background: rgba(20, 40, 80, 0.8);
border-radius: 10px;
padding: 15px;
border: 1px solid rgba(100, 150, 255, 0.2);
flex-shrink: 0;
max-height: 200px;
overflow-y: auto;
}
.explanation h2 {
color: #8cc2ff;
text-align: left;
font-size: 1.2rem;
margin-bottom: 10px;
}
.explanation p {
line-height: 1.5;
margin-bottom: 10px;
color: #c8e1ff;
font-size: 0.9rem;
}
.parameter-explanation {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 10px;
}
.param-card {
flex: 1;
min-width: 120px;
background: rgba(40, 80, 140, 0.5);
border-radius: 8px;
padding: 10px;
border: 1px solid rgba(100, 150, 255, 0.3);
}
.param-card h3 {
color: #8cc2ff;
margin-bottom: 8px;
font-size: 0.95rem;
}
.param-card p {
color: #c8e1ff;
font-size: 0.85rem;
}
@media (max-width: 1024px) {
.main-content {
flex-direction: column;
}
.right-panel {
max-width: none;
}
.parameters-container {
flex-direction: row;
}
}
@media (max-width: 768px) {
.parameters-container {
flex-direction: column;
}
.function-selector {
flex-direction: column;
}
.function-display {
flex-direction: column;
}
.parameter-explanation {
flex-direction: column;
}
}
</style>
</head>
<body>
<div>
<header>
<h1>正弦与余弦函数教学演示</h1>
<p>探索函数 y = A·sin(ωx+φ) 和 y = A·cos(ωx+φ) 的参数影响</p>
</header>
<div>
<div>
<div>
<div>
<div class="function-option active" id="sinOption">
<input type="radio" id="showSin" name="functionDisplay" value="sin" checked>
<label for="showSin">正弦函数</label>
</div>
<div id="cosOption">
<input type="radio" id="showCos" name="functionDisplay" value="cos">
<label for="showCos">余弦函数</label>
</div>
<div id="bothOption">
<input type="radio" id="showBoth" name="functionDisplay" value="both">
<label for="showBoth">两者叠加</label>
</div>
</div>
<div>
<div class="function-equation sin-equation" id="sinEquation">y = 1·sin(1x + 0)</div>
<div class="function-equation cos-equation" id="cosEquation">y = 1·cos(1x + 0)</div>
</div>
</div>
<div id="chartContainer">
<canvas id="waveChart"></canvas>
<div id="crosshair">
<div class="crosshair-line crosshair-x" id="crosshairX"></div>
<div class="crosshair-line crosshair-y" id="crosshairY"></div>
<div id="crosshairLabel"></div>
</div>
</div>
<div>
<h2>参数说明</h2>
<p>正弦函数和余弦函数是周期函数的基本形式,广泛应用于物理学、工程学和信号处理等领域。</p>
<div>
<div>
<h3>振幅 (A)</h3>
<p>控制函数图像的垂直伸缩。A值越大,波峰和波谷之间的距离越大。</p>
</div>
<div>
<h3>角频率 (ω)</h3>
<p>控制函数图像的周期。ω值越大,函数周期越短,波形越密集。</p>
</div>
<div>
<h3>初相位 (φ)</h3>
<p>控制函数图像的水平位移。正值向左移动,负值向右移动。</p>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<h2>正弦函数参数</h2>
<div>
<label for="sinA">振幅 (A):</label>
<input type="range" id="sinA" min="0.1" max="3" step="0.1" value="1">
<div>
<span>0.1</span>
<span id="sinAValue">1</span>
<span>3</span>
</div>
</div>
<div>
<label for="sinOmega">角频率 (ω):</label>
<input type="range" id="sinOmega" min="0.5" max="4" step="0.1" value="1">
<div>
<span>0.5</span>
<span id="sinOmegaValue">1</span>
<span>4</span>
</div>
</div>
<div>
<label for="sinPhi">初相位 (φ):</label>
<input type="range" id="sinPhi" min="-3.14" max="3.14" step="0.1" value="0">
<div>
<span>-π</span>
<span id="sinPhiValue">0</span>
<span>π</span>
</div>
</div>
</div>
<div>
<h2>余弦函数参数</h2>
<div>
<label for="cosA">振幅 (A):</label>
<input type="range" id="cosA" min="0.1" max="3" step="0.1" value="1">
<div>
<span>0.1</span>
<span id="cosAValue">1</span>
<span>3</span>
</div>
</div>
<div>
<label for="cosOmega">角频率 (ω):</label>
<input type="range" id="cosOmega" min="0.5" max="4" step="0.1" value="1">
<div>
<span>0.5</span>
<span id="cosOmegaValue">1</span>
<span>4</span>
</div>
</div>
<div>
<label for="cosPhi">初相位 (φ):</label>
<input type="range" id="cosPhi" min="-3.14" max="3.14" step="0.1" value="0">
<div>
<span>-π</span>
<span id="cosPhiValue">0</span>
<span>π</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 获取DOM元素
const sinA = document.getElementById('sinA');
const sinOmega = document.getElementById('sinOmega');
const sinPhi = document.getElementById('sinPhi');
const cosA = document.getElementById('cosA');
const cosOmega = document.getElementById('cosOmega');
const cosPhi = document.getElementById('cosPhi');
const sinAValue = document.getElementById('sinAValue');
const sinOmegaValue = document.getElementById('sinOmegaValue');
const sinPhiValue = document.getElementById('sinPhiValue');
const cosAValue = document.getElementById('cosAValue');
const cosOmegaValue = document.getElementById('cosOmegaValue');
const cosPhiValue = document.getElementById('cosPhiValue');
const sinEquation = document.getElementById('sinEquation');
const cosEquation = document.getElementById('cosEquation');
// 函数选择器
const sinOption = document.getElementById('sinOption');
const cosOption = document.getElementById('cosOption');
const bothOption = document.getElementById('bothOption');
const functionDisplayRadios = document.getElementsByName('functionDisplay');
// 十字线元素
const crosshair = document.getElementById('crosshair');
const crosshairX = document.getElementById('crosshairX');
const crosshairY = document.getElementById('crosshairY');
const crosshairLabel = document.getElementById('crosshairLabel');
const chartContainer = document.getElementById('chartContainer');
// 初始化图表
const ctx = document.getElementById('waveChart').getContext('2d');
const waveChart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [
{
label: '正弦函数 y = A·sin(ωx+φ)',
data: [],
borderColor: 'rgb(100, 180, 255)', // 蓝色正弦曲线
backgroundColor: 'rgba(100, 180, 255, 0.1)',
borderWidth: 1.5,
tension: 0.4,
fill: false,
hidden: false,
pointRadius: 0,
pointHoverRadius: 3
},
{
label: '余弦函数 y = A·cos(ωx+φ)',
data: [],
borderColor: 'rgb(255, 209, 102)', // 黄色余弦曲线
backgroundColor: 'rgba(255, 209, 102, 0.1)',
borderWidth: 1.5,
tension: 0.4,
fill: false,
hidden: false,
pointRadius: 0,
pointHoverRadius: 3
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
type: 'linear',
position: 'bottom',
title: {
display: true,
text: 'x',
color: '#a8d1ff'
},
grid: {
color: 'rgba(100, 150, 255, 0.1)'
},
ticks: {
color: '#a8d1ff'
},
min: -Math.PI * 2,
max: Math.PI * 2
},
y: {
title: {
display: true,
text: 'y',
color: '#a8d1ff'
},
min: -3.5,
max: 3.5,
grid: {
color: 'rgba(100, 150, 255, 0.1)'
},
ticks: {
color: '#a8d1ff'
}
}
},
plugins: {
legend: {
labels: {
color: '#a8d1ff',
font: {
size: 12
},
// 自定义图例颜色
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labelsOriginal = original.call(this, chart);
// 设置正弦函数图例颜色
labelsOriginal[0].fillStyle = 'rgb(100, 180, 255)';
// 设置余弦函数图例颜色
labelsOriginal[1].fillStyle = 'rgb(255, 209, 102)';
return labelsOriginal;
}
}
},
tooltip: {
mode: 'index',
intersect: false,
backgroundColor: 'rgba(10, 30, 60, 0.9)',
titleColor: '#a8d1ff',
bodyColor: '#c8e1ff',
borderColor: 'rgba(100, 150, 255, 0.5)',
callbacks: {
label: function(context) {
// 获取当前x值
const x = context.parsed.x;
// 获取当前参数值
const sA = parseFloat(sinA.value);
const sOmega = parseFloat(sinOmega.value);
const sPhi = parseFloat(sinPhi.value);
const cA = parseFloat(cosA.value);
const cOmega = parseFloat(cosOmega.value);
const cPhi = parseFloat(cosPhi.value);
// 计算函数值
const sinY = sA * Math.sin(sOmega * x + sPhi);
const cosY = cA * Math.cos(cOmega * x + cPhi);
// 根据数据集返回相应信息
if (context.datasetIndex === 0) {
return [
`正弦函数: y = ${sA}·sin(${sOmega}·${x.toFixed(2)} + ${sPhi.toFixed(2)})`,
`y = ${sinY.toFixed(4)}`,
`A = ${sA}, ω = ${sOmega}, φ = ${sPhi.toFixed(2)}`
];
} else {
return [
`余弦函数: y = ${cA}·cos(${cOmega}·${x.toFixed(2)} + ${cPhi.toFixed(2)})`,
`y = ${cosY.toFixed(4)}`,
`A = ${cA}, ω = ${cOmega}, φ = ${cPhi.toFixed(2)}`
];
}
}
}
}
},
interaction: {
mode: 'nearest',
axis: 'xy',
intersect: false
}
}
});
// 生成数据点
function generateData() {
const dataPoints = 200;
const xValues = [];
const sinYValues = [];
const cosYValues = [];
// 获取当前参数值
const sA = parseFloat(sinA.value);
const sOmega = parseFloat(sinOmega.value);
const sPhi = parseFloat(sinPhi.value);
const cA = parseFloat(cosA.value);
const cOmega = parseFloat(cosOmega.value);
const cPhi = parseFloat(cosPhi.value);
// 生成x值
for (let i = 0; i < dataPoints; i++) {
const x = -Math.PI * 2 + (i / dataPoints) * Math.PI * 4;
xValues.push(x);
// 计算正弦函数值
sinYValues.push(sA * Math.sin(sOmega * x + sPhi));
// 计算余弦函数值
cosYValues.push(cA * Math.cos(cOmega * x + cPhi));
}
return { xValues, sinYValues, cosYValues };
}
// 更新图表
function updateChart() {
const { xValues, sinYValues, cosYValues } = generateData();
waveChart.data.labels = xValues;
waveChart.data.datasets[0].data = sinYValues;
waveChart.data.datasets[1].data = cosYValues;
// 根据选择显示/隐藏函数
const selectedFunction = document.querySelector('input[name="functionDisplay"]:checked').value;
if (selectedFunction === 'sin') {
waveChart.data.datasets[0].hidden = false;
waveChart.data.datasets[1].hidden = true;
} else if (selectedFunction === 'cos') {
waveChart.data.datasets[0].hidden = true;
waveChart.data.datasets[1].hidden = false;
} else { // both
waveChart.data.datasets[0].hidden = false;
waveChart.data.datasets[1].hidden = false;
}
waveChart.update();
}
// 更新参数显示
function updateParameterDisplay() {
sinAValue.textContent = sinA.value;
sinOmegaValue.textContent = sinOmega.value;
sinPhiValue.textContent = parseFloat(sinPhi.value).toFixed(2);
cosAValue.textContent = cosA.value;
cosOmegaValue.textContent = cosOmega.value;
cosPhiValue.textContent = parseFloat(cosPhi.value).toFixed(2);
// 更新函数表达式
sinEquation.textContent = `y = ${sinA.value}·sin(${sinOmega.value}x + ${parseFloat(sinPhi.value).toFixed(2)})`;
cosEquation.textContent = `y = ${cosA.value}·cos(${cosOmega.value}x + ${parseFloat(cosPhi.value).toFixed(2)})`;
}
// 函数选择器事件处理
function handleFunctionSelection() {
// 更新选项样式
sinOption.classList.toggle('active', functionDisplayRadios[0].checked);
cosOption.classList.toggle('active', functionDisplayRadios[1].checked);
bothOption.classList.toggle('active', functionDisplayRadios[2].checked);
updateChart();
}
// 十字线功能
function initCrosshair() {
chartContainer.addEventListener('mousemove', function(e) {
const rect = chartContainer.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 更新十字线位置
crosshairX.style.top = y + 'px';
crosshairY.style.left = x + 'px';
// 计算对应的坐标值
const xScale = waveChart.scales.x;
const yScale = waveChart.scales.y;
if (xScale && yScale) {
const xValue = xScale.getValueForPixel(x);
const yValue = yScale.getValueForPixel(y);
// 更新坐标标签
crosshairLabel.textContent = `x: ${xValue.toFixed(2)}, y: ${yValue.toFixed(2)}`;
crosshairLabel.style.left = (x + 10) + 'px';
crosshairLabel.style.top = (y - 25) + 'px';
}
});
chartContainer.addEventListener('mouseenter', function() {
crosshair.style.display = 'block';
});
chartContainer.addEventListener('mouseleave', function() {
crosshair.style.display = 'none';
});
}
// 添加事件监听器
[sinA, sinOmega, sinPhi, cosA, cosOmega, cosPhi].forEach(slider => {
slider.addEventListener('input', () => {
updateParameterDisplay();
updateChart();
});
});
// 为函数选择器添加事件监听
functionDisplayRadios.forEach(radio => {
radio.addEventListener('change', handleFunctionSelection);
});
// 初始化
updateParameterDisplay();
updateChart();
handleFunctionSelection();
// 初始化十字线
setTimeout(initCrosshair, 500); // 延迟初始化确保图表已渲染
</script>
</body>
</html>
打开 正弦与余弦函数教学演示_deepseek.html (因需要chart.js插件,可能加载较慢)
目录 返回
首页
