Files
dsProject/dsLightRag/static/ggb_draw.html

250 lines
8.9 KiB
HTML
Raw Normal View History

2025-08-14 15:45:08 +08:00
<!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指令每行一条&#10;例如:&#10;A=(1,2)&#10;B=(3,4)&#10;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>