feat: Фазы 6.1–6.3 планиметрии — высоты, прямые углы, удаление объектов
6.1 Стороны полигонов теперь выбираются как опорные линии (_hitTestLine),
через виртуальные сегменты (virtual:true, polyId). Cascade-удаление
исправлено на BFS (transitive deps). Теперь можно строить высоты треугольников.
6.2 Прямой угол (квадратный маркер) рисуется для всех foot-конструкций
в _drawAngleMeasures, независимо от полигона.
6.3 Удаление отдельных объектов: onDeleteRequest callback, диалог
«Только этот» (derived-точки → свободные) / «Со всеми зависимыми»
(cascade) / «Отмена». CSS-панель .geo-del-confirm поверх canvas.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+59
-2
@@ -748,6 +748,27 @@
|
||||
pointer-events: none; white-space: nowrap;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
.geo-del-confirm {
|
||||
display: none; position: absolute; top: 8px; left: 50%; transform: translateX(-50%);
|
||||
gap: 8px; align-items: center; white-space: nowrap;
|
||||
background: rgba(18,10,32,.96); border: 1px solid rgba(155,93,229,.35);
|
||||
border-radius: 10px; padding: 8px 12px; z-index: 20;
|
||||
backdrop-filter: blur(8px); box-shadow: 0 4px 20px rgba(0,0,0,.6);
|
||||
font-size: 0.72rem; color: rgba(255,255,255,.8);
|
||||
}
|
||||
.geo-del-confirm.visible { display: flex; }
|
||||
.geo-del-confirm span { margin-right: 2px; }
|
||||
.geo-del-btn {
|
||||
padding: 3px 9px; border-radius: 6px; border: 1px solid;
|
||||
font-size: 0.7rem; cursor: pointer; font-family: inherit;
|
||||
transition: background .15s;
|
||||
}
|
||||
.geo-del-btn-soft { border-color: rgba(74,222,128,.4); color: #4ADE80; background: rgba(74,222,128,.08); }
|
||||
.geo-del-btn-soft:hover { background: rgba(74,222,128,.18); }
|
||||
.geo-del-btn-hard { border-color: rgba(248,113,113,.4); color: #f87171; background: rgba(248,113,113,.08); }
|
||||
.geo-del-btn-hard:hover { background: rgba(248,113,113,.18); }
|
||||
.geo-del-btn-cancel{ border-color: rgba(255,255,255,.15); color: rgba(255,255,255,.5); background: transparent; }
|
||||
.geo-del-btn-cancel:hover{ background: rgba(255,255,255,.06); }
|
||||
</style>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/lucide@0.469.0/dist/umd/lucide.min.js"></script>
|
||||
@@ -3954,6 +3975,12 @@
|
||||
<div class="geo-canvas-outer">
|
||||
<canvas id="geo-canvas"></canvas>
|
||||
<div class="geo-hint-bar" id="geo-hint">Кликни для добавления точки</div>
|
||||
<div class="geo-del-confirm" id="geo-del-confirm">
|
||||
<span id="geo-del-msg"></span>
|
||||
<button class="geo-del-btn geo-del-btn-soft" id="geo-del-soft">Только этот</button>
|
||||
<button class="geo-del-btn geo-del-btn-hard" id="geo-del-hard">Со всеми зависимыми</button>
|
||||
<button class="geo-del-btn geo-del-btn-cancel" id="geo-del-cancel">Отмена</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- /.sim-body-wrap -->
|
||||
@@ -5441,6 +5468,35 @@
|
||||
if (cEl) cEl.textContent = s.constructions || 0;
|
||||
}
|
||||
|
||||
/* Диалог подтверждения удаления объекта с зависимыми */
|
||||
let _geoDelSoftFn = null, _geoDelHardFn = null;
|
||||
function _geoShowDeleteConfirm(obj, deps, softFn, hardFn) {
|
||||
const panel = document.getElementById('geo-del-confirm');
|
||||
const msg = document.getElementById('geo-del-msg');
|
||||
if (!panel || !msg) { hardFn(); return; }
|
||||
const names = { point:'точка', segment:'отрезок', line:'прямая', ray:'луч',
|
||||
circle:'окружность', polygon:'многоугольник', derived_line:'построение' };
|
||||
const n = names[obj.type] || 'объект';
|
||||
msg.textContent = `Удалить ${n}? Зависимых: ${deps.length}.`;
|
||||
_geoDelSoftFn = softFn;
|
||||
_geoDelHardFn = hardFn;
|
||||
panel.classList.add('visible');
|
||||
}
|
||||
function _geoHideDeleteConfirm() {
|
||||
document.getElementById('geo-del-confirm')?.classList.remove('visible');
|
||||
_geoDelSoftFn = _geoDelHardFn = null;
|
||||
}
|
||||
// Кнопки диалога — подключаем после DOM ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.getElementById('geo-del-soft')?.addEventListener('click', () => {
|
||||
_geoDelSoftFn?.(); _geoHideDeleteConfirm(); _geoUpdateStats();
|
||||
});
|
||||
document.getElementById('geo-del-hard')?.addEventListener('click', () => {
|
||||
_geoDelHardFn?.(); _geoHideDeleteConfirm(); _geoUpdateStats();
|
||||
});
|
||||
document.getElementById('geo-del-cancel')?.addEventListener('click', _geoHideDeleteConfirm);
|
||||
});
|
||||
|
||||
function _openGeometry() {
|
||||
document.getElementById('sim-topbar-title').textContent = 'Планиметрия';
|
||||
_simShow('sim-geometry');
|
||||
@@ -5457,8 +5513,9 @@
|
||||
const canvas = document.getElementById('geo-canvas');
|
||||
if (!geomSim) {
|
||||
geomSim = new GeoSim(canvas);
|
||||
geomSim.onUpdate = _geoUpdateStats;
|
||||
geomSim.onHintChange = (tool, phase) => _geoShowHint(tool, phase > 1);
|
||||
geomSim.onUpdate = _geoUpdateStats;
|
||||
geomSim.onHintChange = (tool, phase) => _geoShowHint(tool, phase > 1);
|
||||
geomSim.onDeleteRequest = _geoShowDeleteConfirm;
|
||||
|
||||
// keyboard shortcuts
|
||||
canvas.setAttribute('tabindex', '0');
|
||||
|
||||
Reference in New Issue
Block a user