fix(labs): SVG-стрелки уравнений рисовались как сырой текст на canvas

Уравнения реакций содержат inline <svg class=ic> стрелки. На canvas
(fillText) разметка показывалась буквально. Добавлен общий хелпер
ChemVisuals.cleanIcons (SVG→Unicode →/↑/↓), применён в flask (eq),
redox (s.txt) и chemsandbox (ответ квиза — был единственный незакрытый
путь мимо _csClean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-24 19:31:35 +03:00
parent 59ea5e7d65
commit 8303d483cc
4 changed files with 16 additions and 3 deletions
+13
View File
@@ -760,8 +760,21 @@ window.ChemVisuals = (() => {
return hex;
}
/* Replace inline icon-SVG (reaction arrows) with Unicode for canvas fillText.
Canvas draws plain strings — embedded <svg> markup would show as raw text. */
function cleanIcons(s) {
if (!s || !s.includes('<svg')) return s;
return s.replace(/<svg[\s\S]*?<\/svg>/g, m => {
if (m.includes('x1="5" y1="12" x2="19"')) return '→'; // right arrow
if (m.includes('x1="12" y1="5" x2="12" y2="19"')) return '↓'; // down (precipitate)
if (m.includes('x1="12" y1="19" x2="12" y2="5"')) return '↑'; // up (gas)
return '';
});
}
/* ── Public API ─────────────────────────────────────────────── */
return {
cleanIcons,
drawErlenmeyer,
drawBeaker,
drawBurette,
+1 -1
View File
@@ -1562,7 +1562,7 @@ class ChemSandboxSim {
if (!isOk && this._quizTask) {
ctx.font = '10px "JetBrains Mono", monospace';
ctx.fillStyle = `rgba(255,255,255,${alpha * 0.45})`;
ctx.fillText('Ответ: ' + this._quizTask.rx.eq, W / 2, bannerY + 65);
ctx.fillText('Ответ: ' + _csClean(this._quizTask.rx.eq), W / 2, bannerY + 65);
}
}
+1 -1
View File
@@ -1146,7 +1146,7 @@ class FlaskSim {
const eqY = g.cy + g.r + 26;
ctx.font = '12.5px monospace'; ctx.fillStyle = 'rgba(185,215,255,0.78)';
ctx.textAlign = 'center'; ctx.fillText(eq, W * 0.44, eqY); ctx.textAlign = 'left';
ctx.textAlign = 'center'; ctx.fillText(ChemVisuals.cleanIcons(eq), W * 0.44, eqY); ctx.textAlign = 'left';
if (this._passiv) {
ctx.font = 'bold 11px sans-serif'; ctx.fillStyle = '#FFD166';
+1 -1
View File
@@ -547,7 +547,7 @@ class RedoxSim {
ctx.fillText(s.lbl, 14, y);
ctx.fillStyle = (i === this._stepIdx && this._phase !== 'done') ? '#FFF' : 'rgba(255,255,255,0.62)';
ctx.font = '9.5px monospace';
ctx.fillText(s.txt, 14 + ctx.measureText(s.lbl).width + 8, y);
ctx.fillText(ChemVisuals.cleanIcons(s.txt), 14 + ctx.measureText(s.lbl).width + 8, y);
ctx.restore();
}