// phys9_palette.js — единая палитра цветов для всех визуализаций Физики 9. // Экспорт в window.PHYS9_COLORS. Используется в phys9_legacy.js для canvas/SVG. // Цвета синхронизированы с phys.js и optics.js (Физика 8). (function(){ 'use strict'; // === Базовые цвета (для светлой темы) === const LIGHT = { /* Кинематические величины */ velocity: '#0891b2', /* cyan-600 — скорость v */ acceleration: '#ea580c', /* orange-600 — ускорение a */ displacement: '#2563eb', /* blue-600 — перемещение Δr */ position: '#475569', /* slate-600 — положение */ time: '#6b7280', /* gray-500 — ось времени */ /* Динамические величины */ force: '#10b981', /* emerald-500 — сила F */ forceGravity: '#2563eb', /* blue-600 — сила тяжести mg */ forceFriction:'#7c3aed', /* violet-600 — трение */ forceNormal: '#94a3b8', /* slate-400 — реакция опоры N */ forceSpring: '#d97706', /* amber-600 — упругая сила */ forceTension: '#16a34a', /* green-600 — натяжение нити */ /* Энергетика */ energyK: '#dc2626', /* red-600 — кинетическая Ek */ energyP: '#2563eb', /* blue-600 — потенциальная Ep */ work: '#9333ea', /* purple-600 — работа A */ power: '#db2777', /* pink-600 — мощность N */ /* Тела */ body: '#475569', /* slate-600 — основной цвет тела */ bodyAccent: '#1e293b', /* slate-800 — обводка/штрих */ bodyLight: '#cbd5e1', /* slate-300 — заливка для светлых тел */ surface: '#a16207', /* yellow-700 — поверхность/опора */ liquid: '#3b82f6', /* blue-500 — жидкость */ liquidLight: '#bfdbfe', /* blue-200 — поверхность жидкости */ gas: '#dbeafe', /* blue-100 — газ/воздух */ /* Углы и геометрия */ angle: '#dc2626', /* red-600 — углы α, β, φ */ axis: '#1e293b', /* slate-800 — координатные оси */ grid: '#e5e7eb', /* gray-200 — сетка */ dashed: '#94a3b8', /* slate-400 — пунктир/перпендикуляр */ /* Графики */ plotPrimary: '#dc2626', /* основной график */ plotSecondary:'#2563eb', /* второй график для сравнения */ plotTertiary: '#10b981', /* третий график */ /* Текст и подписи на канвасе */ text: '#0f172a', /* slate-900 — главный текст */ textMuted: '#64748b', /* slate-500 — приглушённый текст */ textLabel: '#1e293b', /* slate-800 — подписи переменных */ /* Фоны */ bg: '#fafafa', /* фон сцены */ bgSubtle: '#f8fafc', /* мягкий фон */ bgCard: '#ffffff', /* карточка */ /* Состояния */ ok: '#16a34a', /* зелёный — успех */ warn: '#f59e0b', /* янтарный — внимание */ fail: '#dc2626' /* красный — ошибка */ }; // === Цвета для тёмной темы === const DARK = { velocity: '#22d3ee', acceleration: '#fb923c', displacement: '#60a5fa', position: '#94a3b8', time: '#9ca3af', force: '#34d399', forceGravity: '#60a5fa', forceFriction:'#a78bfa', forceNormal: '#cbd5e1', forceSpring: '#fbbf24', forceTension: '#4ade80', energyK: '#f87171', energyP: '#60a5fa', work: '#c084fc', power: '#f472b6', body: '#94a3b8', bodyAccent: '#e2e8f0', bodyLight: '#64748b', surface: '#ca8a04', liquid: '#60a5fa', liquidLight: '#3b82f6', gas: '#1e3a8a', angle: '#f87171', axis: '#e2e8f0', grid: '#374151', dashed: '#94a3b8', plotPrimary: '#f87171', plotSecondary:'#60a5fa', plotTertiary: '#34d399', text: '#f1f5f9', textMuted: '#94a3b8', textLabel: '#e2e8f0', bg: '#0f172a', bgSubtle: '#1e293b', bgCard: '#1f2937', ok: '#4ade80', warn: '#fbbf24', fail: '#f87171' }; // === Активная палитра — возвращает значения текущей темы === function isDark(){ try { return document.documentElement.classList.contains('dark') || document.body.classList.contains('dark'); } catch(e){ return false; } } // Объект, который пересчитывает значения через геттеры const PHYS9_COLORS = {}; for (const key of Object.keys(LIGHT)) { Object.defineProperty(PHYS9_COLORS, key, { enumerable: true, configurable: false, get(){ return isDark() ? (DARK[key] || LIGHT[key]) : LIGHT[key]; } }); } // === Утилиты === // Получить цвет вектора по типу величины (для drawArrow и т.п.) PHYS9_COLORS.vector = function(kind){ switch(kind){ case 'v': case 'velocity': return PHYS9_COLORS.velocity; case 'a': case 'acceleration': return PHYS9_COLORS.acceleration; case 'F': case 'force': return PHYS9_COLORS.force; case 'mg': case 'gravity': return PHYS9_COLORS.forceGravity; case 'N': case 'normal': return PHYS9_COLORS.forceNormal; case 'Ftr': case 'friction': return PHYS9_COLORS.forceFriction; case 'Fspr': case 'spring': return PHYS9_COLORS.forceSpring; case 'T': case 'tension': return PHYS9_COLORS.forceTension; default: return PHYS9_COLORS.text; } }; // Получить цвет по классу величины (kinematic / dynamic / energy / geometry) PHYS9_COLORS.byClass = function(cls){ switch(cls){ case 'kinematic': return PHYS9_COLORS.velocity; case 'dynamic': return PHYS9_COLORS.force; case 'energy': return PHYS9_COLORS.energyK; case 'geometry': return PHYS9_COLORS.angle; default: return PHYS9_COLORS.text; } }; // Полная схема для тёмной/светлой — для отладки PHYS9_COLORS._LIGHT = LIGHT; PHYS9_COLORS._DARK = DARK; window.PHYS9_COLORS = PHYS9_COLORS; })();