feat(labs): Фаза0 — эконом-режим FX + выбор симуляции из списка в редакторе
План улучшения симуляций — plans/simulations-improvement/README.md. - LabFX: reduced-motion/эконом-режим (prefers-reduced-motion + тумблер localStorage labfx-economy). Тряска отключается, частицы ×0.25 — доступность и экономия на слабых устройствах сразу для всех ~50 симуляций. Кнопка-тумблер в lab.html рядом со звуком. - lesson-editor: блок «Симуляция» — выпадающий список из /api/lab/sims (сгруппирован по предметам) вместо сырого ввода simId; неизвестный id не теряется, помечается «(не найдена)». Закрывает хрупкую вставку в урок. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,28 @@
|
||||
/* ── namespace (cooperative init) ── */
|
||||
global.LabFX = global.LabFX || {};
|
||||
|
||||
/* ─────────────────────────────────────────────
|
||||
REDUCED MOTION / ECONOMY MODE
|
||||
Уважает системный prefers-reduced-motion + ручной тумблер
|
||||
(localStorage 'labfx-economy'). Когда LabFX.reduced === true:
|
||||
тряска отключается, частицы эмитятся в разы меньше — это и
|
||||
доступность, и экономия на слабых устройствах.
|
||||
───────────────────────────────────────────── */
|
||||
(function () {
|
||||
var mq = null;
|
||||
try { mq = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)'); } catch (e) {}
|
||||
var manual = null;
|
||||
try { var v = localStorage.getItem('labfx-economy'); if (v === '1') manual = true; else if (v === '0') manual = false; } catch (e) {}
|
||||
function compute() { return manual != null ? manual : !!(mq && mq.matches); }
|
||||
global.LabFX.reduced = compute();
|
||||
global.LabFX.setEconomy = function (on) {
|
||||
manual = !!on;
|
||||
try { localStorage.setItem('labfx-economy', on ? '1' : '0'); } catch (e) {}
|
||||
global.LabFX.reduced = compute();
|
||||
};
|
||||
if (mq && mq.addEventListener) mq.addEventListener('change', function () { global.LabFX.reduced = compute(); });
|
||||
})();
|
||||
|
||||
/* ─────────────────────────────────────────────
|
||||
GLOW — Canvas 2D bloom helper
|
||||
───────────────────────────────────────────── */
|
||||
@@ -59,6 +81,7 @@
|
||||
* @param {number} opts.durMs - duration ms (default 200)
|
||||
*/
|
||||
global.LabFX.shake = function(elementOrCanvas, opts) {
|
||||
if (global.LabFX.reduced) return; // эконом/reduced-motion — без тряски
|
||||
opts = opts || {};
|
||||
var intensity = opts.intensity != null ? opts.intensity : 5;
|
||||
var durMs = opts.durMs != null ? opts.durMs : 200;
|
||||
|
||||
@@ -72,6 +72,9 @@
|
||||
var size = opts.size != null ? opts.size : 3;
|
||||
var sizeFade = opts.sizeFade != null ? opts.sizeFade : true;
|
||||
|
||||
// Эконом/reduced-motion — декоративных частиц в разы меньше
|
||||
if (global.LabFX.reduced) count = Math.max(1, Math.round(count * 0.25));
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
var p = acquire();
|
||||
if (!p) break;
|
||||
|
||||
Reference in New Issue
Block a user