feat(lab-graph): удобство и красота — скрытие функций, точки, контролы вида, пинч

«График функции», большой апгрейд UX:
- у каждой функции кнопки «глаз» (скрыть/показать, не удаляя) и «очистить»;
  скрытая — приглушена и зачёркнута, исключается из графика/hover/значений
- плавающие контролы вида поверх canvas: зум +/−, сброс вида, тумблер «Особые точки»
- ОСОБЫЕ ТОЧКИ: нули функций, y-перехваты и пересечения кривых — ringed-точки
  с подписью координат (бисекция по смене знака; правка: точные нули на узлах
  сетки больше не теряются; дедуп; подписи скрываются при «частоколе» >22 точек)
- пинч-зум двумя пальцами к центру жеста (к 1-пальцевой панораме)

Движок: setHidden/setShowPoints/_drawPoints/_findZeros/_visible; hover и
инфобар уважают скрытие. Только фронт. node --check OK; zero-finder 5/5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-24 19:11:21 +03:00
parent fa29332bcd
commit cd0ce17a60
3 changed files with 174 additions and 14 deletions
+27
View File
@@ -459,6 +459,33 @@
}
#graph-canvas { display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/* плавающие контролы вида поверх canvas */
.graph-view-ctrls {
position: absolute; top: 12px; right: 12px; z-index: 4;
display: flex; flex-direction: column; gap: 6px;
}
.gv-btn {
width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
border-radius: 10px; border: 1px solid rgba(255,255,255,.12);
background: rgba(13,13,26,.62); color: rgba(255,255,255,.72);
cursor: pointer; transition: all .14s; backdrop-filter: blur(6px);
}
.gv-btn svg { width: 17px; height: 17px; }
.gv-btn:hover { border-color: var(--violet); color: #fff; background: rgba(155,93,229,.32); }
.gv-btn.active { border-color: var(--violet); color: #fff; background: var(--violet); box-shadow: 0 0 12px rgba(155,93,229,.5); }
/* кнопки управления функцией (глаз/очистить) в строке */
.fn-act {
flex-shrink: 0; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center;
border: none; background: transparent; color: var(--text-3);
border-radius: 8px; cursor: pointer; transition: all .14s; padding: 0;
}
.fn-act svg { width: 15px; height: 15px; }
.fn-act:hover { color: var(--fn-color, var(--violet)); background: rgba(155,93,229,.1); }
.fn-act.off { color: var(--text-3); opacity: .85; }
.fn-row.fn-hidden { opacity: .5; }
.fn-row.fn-hidden .fn-math, .fn-row.fn-hidden .fn-input { text-decoration: line-through; text-decoration-color: rgba(255,255,255,.3); }
/* info bar */
.graph-info-bar {
flex-shrink: 0;