250 lines
8.9 KiB
HTML
250 lines
8.9 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<title>基本GeoGebra操作页面</title>
|
||
<script src="js/deployggb.js"></script>
|
||
<style>
|
||
.app-container {
|
||
display: flex;
|
||
gap: 10px;
|
||
padding: 10px;
|
||
}
|
||
|
||
#controlPanel {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
min-width: 620px;
|
||
}
|
||
|
||
.control-btn {
|
||
padding: 8px 12px;
|
||
background-color: #4CAF50;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.control-btn:hover {
|
||
background-color: #45a049;
|
||
}
|
||
|
||
/* 批量指令输入框样式 */
|
||
.command-input {
|
||
width: 100%;
|
||
min-height: 150px;
|
||
margin: 10px 0;
|
||
padding: 8px;
|
||
border: 1px solid #ccc;
|
||
border-radius: 4px;
|
||
resize: vertical;
|
||
font-family: monospace;
|
||
font-size: 14px;
|
||
white-space: pre-wrap;
|
||
word-wrap: break-word;
|
||
line-height: 1.5;
|
||
box-sizing: border-box;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>几何题图形交互功能演示</h1>
|
||
<div class="app-container">
|
||
<div id="ggbApplet"></div>
|
||
<div id="controlPanel">
|
||
示例:
|
||
2025年长春中考数学第23题图
|
||
<img src="https://dsideal.obs.cn-north-1.myhuaweicloud.com/wb/math.jpg">
|
||
<!-- 添加批量指令输入区域 -->
|
||
<textarea id="commandInput" class="command-input"
|
||
placeholder="请输入GeoGebra指令,每行一条 例如: A=(1,2) B=(3,4) Line(A,B)"
|
||
wrap="soft"></textarea>
|
||
<button id="aiJieXi" class="control-btn">AI解析指令</button>
|
||
<button id="executeCommands" class="control-btn">执行指令</button>
|
||
<button id="executeErCiCommands" class="control-btn">二次函数示例</button>
|
||
<button id="clearCanvas" class="control-btn">清空画布</button>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 配置GGB小程序参数
|
||
const params = {
|
||
width: 1024,
|
||
height: 600,
|
||
showToolBar: true,
|
||
showAlgebraInput: true,
|
||
showMenuBar: true,
|
||
appletOnLoad: function (api) {
|
||
console.log('GeoGebra applet loaded successfully');
|
||
window.ggbApi = api; // 将API保存到全局变量
|
||
}
|
||
};
|
||
|
||
// 创建并注入GGB小程序
|
||
const ggbApplet = new GGBApplet(params, true);
|
||
window.onload = function () {
|
||
ggbApplet.inject('ggbApplet');
|
||
};
|
||
</script>
|
||
<script>
|
||
// 添加清空画布功能
|
||
document.getElementById('clearCanvas').addEventListener('click', function () {
|
||
if (window.ggbApi) {
|
||
if (confirm('确定要清空当前画布和指令输入框吗?')) {
|
||
// 检查ggbApplet是否已加载
|
||
if (window.ggbApplet && window.ggbApplet.reset) {
|
||
window.ggbApplet.reset();
|
||
// 清空指令输入框
|
||
document.getElementById('commandInput').value = '';
|
||
} else {
|
||
alert('GeoGebra尚未完全加载,请稍候重试');
|
||
}
|
||
}
|
||
} else {
|
||
alert('GeoGebra尚未完全加载,请稍候...');
|
||
}
|
||
});
|
||
document.getElementById('aiJieXi').addEventListener('click', function () {
|
||
document.getElementById('commandInput').value = `t=Slider(0,4*sqrt(2),0.01,1,140,false,true,false,false)
|
||
A=(0,0)
|
||
B=(4*sqrt(2),0)
|
||
C=(2*sqrt(2),2*sqrt(2))
|
||
D=(sqrt(2),sqrt(2))
|
||
E=(t,0)
|
||
F=Rotate(D,-45°,E)
|
||
Segment(A,B)
|
||
Segment(B,C)
|
||
Segment(A,C)
|
||
Segment(D,E)
|
||
Segment(E,F)
|
||
`
|
||
});
|
||
|
||
/**
|
||
* 将 # 开头的行注释全部去掉
|
||
* @param {string} raw - 原始带注释的 GGB 指令
|
||
* @returns {string} - 去掉注释后的可执行指令
|
||
*/
|
||
function stripGGBComments(raw) {
|
||
return raw
|
||
.split('\n') // 按行拆分
|
||
.map(line => line.replace(/#.*$/, '').trim()) // 去掉 # 及之后内容
|
||
.filter(line => line.length > 0) // 去掉空行
|
||
.join('\n'); // 重新拼成多行文本
|
||
}
|
||
|
||
<!-- 在清空画布脚本之后添加 -->
|
||
// 批量执行指令功能
|
||
document.getElementById('executeCommands').addEventListener('click', function () {
|
||
if (!window.ggbApplet || !window.ggbApplet.evalCommand) {
|
||
alert('GeoGebra尚未完全加载,请稍候重试');
|
||
return;
|
||
}
|
||
|
||
const commandInput = document.getElementById('commandInput');
|
||
const commands = commandInput.value.trim().split('\n');
|
||
|
||
if (commands.length === 0 || (commands.length === 1 && commands[0] === '')) {
|
||
alert('请输入至少一条指令');
|
||
return;
|
||
}
|
||
|
||
let successCount = 0;
|
||
let errorCount = 0;
|
||
const errorCommands = [];
|
||
|
||
commands.forEach((command, index) => {
|
||
command = command.trim();
|
||
command = stripGGBComments(command)
|
||
if (!command) return;
|
||
if (command.startsWith("#")) return;
|
||
try {
|
||
window.ggbApplet.evalCommand(command);
|
||
successCount++;
|
||
} catch (e) {
|
||
errorCount++;
|
||
errorCommands.push(`${index + 1}: ${command} (${e.message})`);
|
||
}
|
||
});
|
||
|
||
if (errorCount === 0) {
|
||
//alert(`全部指令执行完成,共成功${successCount}条`);
|
||
} else {
|
||
alert(`执行完成:成功${successCount}条,失败${errorCount}条\n失败指令:\n${errorCommands.join('\n')}`);
|
||
}
|
||
});
|
||
|
||
|
||
document.getElementById('executeErCiCommands').addEventListener('click', function () {
|
||
if (!window.ggbApplet || !window.ggbApplet.evalCommand) {
|
||
alert('GeoGebra尚未完全加载,请稍候重试');
|
||
return;
|
||
}
|
||
|
||
const commandInput = '# ========= 1 二次函数(开口向下,顶点在 (2,3)) =========\n' +
|
||
'a = -0.5\n' +
|
||
'h = 2\n' +
|
||
'k = 3\n' +
|
||
'f(x) = a * (x - h)^2 + k # 形如 y = a(x-h)^2 + k\n' +
|
||
'\n' +
|
||
'# ========= 2 直线(斜率 m、截距 q 可调) =========\n' +
|
||
'm = 0.5\n' +
|
||
'q = -1\n' +
|
||
'g(x) = m * x + q\n' +
|
||
'\n' +
|
||
'# ========= 3 交点 =========\n' +
|
||
'A = Intersect(f, g, 1) # 第 1 个交点\n' +
|
||
'B = Intersect(f, g, 2) # 第 2 个交点(若存在)\n' +
|
||
'\n' +
|
||
'# ========= 4 动点 P 在 f 上滑动 =========\n' +
|
||
'# 用滑动条 t 驱动\n' +
|
||
't = Slider(-3, 6, 0.01, 1, 200, false, true, false, false)\n' +
|
||
'P = (t, f(t)) # 动点\n' +
|
||
'\n' +
|
||
'# ========= 5 动态几何量 =========\n' +
|
||
'# 5.1 P 到直线 g 的垂直距离\n' +
|
||
'd = Distance(P, g)\n' +
|
||
'\n' +
|
||
'# 5.2 P 处切线斜率(修正点:使用导数函数名)\n' +
|
||
'f_prime(x) = Derivative(f) # 合法函数名(避免特殊字符)\n' +
|
||
'TangSlope = f_prime(t) # 在 t 处的导数值\n' +
|
||
'TangLine: y - f(t) = TangSlope * (x - t) # 切线方程(隐式定义)\n' +
|
||
'\n' +
|
||
'# 5.3 三角形 PAB 的面积(修正点:使用 abs 函数)\n' +
|
||
'Area = 0.5 * abs( x(A) * y(B) - x(B) * y(A) + x(B) * y(P) - x(P) * y(B) + x(P) * y(A) - x(A) * y(P) )\n'
|
||
const commands = commandInput.trim().split('\n');
|
||
|
||
if (commands.length === 0 || (commands.length === 1 && commands[0] === '')) {
|
||
alert('请输入至少一条指令');
|
||
return;
|
||
}
|
||
|
||
let successCount = 0;
|
||
let errorCount = 0;
|
||
const errorCommands = [];
|
||
|
||
commands.forEach((command, index) => {
|
||
command = command.trim();
|
||
command = stripGGBComments(command)
|
||
if (!command) return;
|
||
if (command.startsWith("#")) return;
|
||
try {
|
||
window.ggbApplet.evalCommand(command);
|
||
successCount++;
|
||
} catch (e) {
|
||
errorCount++;
|
||
errorCommands.push(`${index + 1}: ${command} (${e.message})`);
|
||
}
|
||
});
|
||
|
||
if (errorCount === 0) {
|
||
//alert(`全部指令执行完成,共成功${successCount}条`);
|
||
} else {
|
||
alert(`执行完成:成功${successCount}条,失败${errorCount}条\n失败指令:\n${errorCommands.join('\n')}`);
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |