https://github.com/ivanvit100/physjs
Библиотека для создания интерактивных лабораторных работ и физических симуляций в веб-браузере
https://github.com/ivanvit100/physjs
experiments javascript laboratory physics physics-simulation
Last synced: about 1 year ago
JSON representation
Библиотека для создания интерактивных лабораторных работ и физических симуляций в веб-браузере
- Host: GitHub
- URL: https://github.com/ivanvit100/physjs
- Owner: ivanvit100
- Created: 2025-03-23T19:33:08.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-06-12T21:06:47.000Z (about 1 year ago)
- Last Synced: 2025-06-12T22:24:39.347Z (about 1 year ago)
- Topics: experiments, javascript, laboratory, physics, physics-simulation
- Language: JavaScript
- Homepage: https://vps.ivanvit.ru/
- Size: 12 MB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Документация библиотеки PhysJS
### Содержание
1. Введение
2. Начало работы
3. Основные концепции
4. API библиотеки
- Инициализация и настройка
- Управление объектами
- Управление точками крепления
- Управление шагами лабораторной работы
- Обработка событий
- Специальные эффекты
- Управление вращением объектов
- Расширенные обработчики событий
- Работа с проводами и соединениями
- Баллистические траектории
5. Классы HTML-элементов
6. Примеры использования
7. Советы по производительности
8. Устранение неполадок
## Введение
PhysJS — это JavaScript библиотека для создания интерактивных лабораторных работ и физических симуляций в веб-браузере. Библиотека позволяет создавать перетаскиваемые объекты, определять точки крепления между ними, и организовывать последовательность шагов для выполнения лабораторной работы.
С примерами использования библиотеки можно ознакомиться [здесь](/demo_app/). В данном каталоге представлена примерная реализация физической лаборатории, содержащей 18 экспериментов из физического практикума для учащихся 10-11 классов. Приложение реализовано с использованием Flask и JavaScript без сторонних библиотек.
### Основные возможности библиотеки
- Создание перетаскиваемых физических объектов
- Определение точек крепления между объектами
- Создание проводов и точек крепления для них
- Организация последовательности шагов лабораторной работы
- Отслеживание событий взаимодействия с объектами
- Создание специальных визуальных эффектов
## Начало работы
Подключение библиотеки
```html
```
Минимальный HTML-шаблон
```html
PhysJS Лабораторная работа
// Включение режима отладки для вывода логов
physjs.setDebugMode(true);
// Добавление точек крепления
physjs.addAttachmentPoint('#object1', 'right', 100, 50, ['object2']);
physjs.addAttachmentPoint('#object2', 'left', 0, 50, ['object1']);
// Создание шагов лабораторной работы
const step1 = physjs.createStep('step1', 'Соедините объекты', ['#object1', '#object2']);
physjs.addStep(step1);
physjs.goToStep('step1');
```
### Основные концепции
#### Физические объекты
Физические объекты — это DOM-элементы, которые могут быть перетаскиваемыми и взаимодействовать друг с другом. Для создания физического объекта необходимо добавить класс `phys` к HTML-элементу:
```html
```
Объекты, которые могут быть прикреплены к другим объектам, должны иметь дополнительный класс `phys-attachable`:
```html
```
#### Точки крепления
Точки крепления определяют, как объекты могут присоединяться друг к другу. Каждая точка крепления имеет:
- Идентификатор
- Координаты относительно родительского объекта (x, y)
- Список типов объектов, которые могут быть прикреплены к этой точке
#### Шаги лабораторной работы
Шаги лабораторной работы определяют последовательность действий, которые должен выполнить пользователь. Каждый шаг имеет:
- Идентификатор
- Описание
- Список разрешенных объектов для прикрепления
- Список разрешенных объектов для открепления
## API библиотеки
### Инициализация и настройка
1. `physjs.init(options)`
Инициализирует библиотеку с настройками.
Параметры:
- `debug (boolean)` - включает/выключает режим отладки
Пример:
```js
physjs.init({ debug: true });
```
2. `physjs.setDebugMode(enabled)`
Включает или выключает режим отладки.
Параметры:
- enabled (boolean) - true для включения, false для выключения
Пример:
```js
physjs.setDebugMode(true); // Включить режим отладки
physjs.setDebugMode(false); // Выключить режим отладки
```
### Управление объектами
3. `physjs.getObject(element)`
Возвращает физический объект по DOM-элементу или селектору.
Параметры:
- element (DOM-элемент или строка) - DOM-элемент или CSS-селектор
Возвращает: объект PhysObject или null, если объект не найден
Пример:
```js
const obj = physjs.getObject('#my-object');
const pos = obj.getPosition();
console.log(`Позиция объекта: x=${pos.x}, y=${pos.y}`);
```
4. `physjs.createObject(element)`
Создает новый физический объект из DOM-элемента.
Параметры:
- element (DOM-элемент или строка) - DOM-элемент или CSS-селектор
Возвращает: созданный объект PhysObject или null в случае ошибки
Пример:
```js
const newObj = physjs.createObject('#new-element');
```
5. `physjs.detachAll()`
Открепляет все прикрепленные объекты.
Пример:
```js
physjs.detachAll();
```
6. `physjs.resetRotations()`
Сбрасывает поворот всех объектов к нулевому значению.
Пример:
```js
physjs.resetRotations();
```
### Управление точками крепления
7. `physjs.addAttachmentPoint(element, pointId, x, y, acceptedTypes)`
Добавляет точку крепления к физическому объекту.
Параметры:
- element (DOM-элемент или строка) - DOM-элемент или CSS-селектор
- pointId (строка) - идентификатор точки крепления
- x (число) - координата X относительно родительского объекта
- y (число) - координата Y относительно родительского объекта
- acceptedTypes (массив строк) - список типов объектов, которые могут быть прикреплены
Пример:
```js
// Добавляем точку крепления 'top' к объекту #cylinder
// в координатах (50, 0) относительно объекта
// и разрешаем прикрепление только объектов с типом 'tube'
physjs.addAttachmentPoint('#cylinder', 'top', 50, 0, ['tube']);
```
### Управление шагами лабораторной работы
8. `physjs.createStep(id, description, allowedAttachments, allowedDetachments)`
Создает новый шаг лабораторной работы.
Параметры:
- id (строка) - уникальный идентификатор шага
- description (строка) - описание шага
- allowedAttachments (массив строк) - CSS-селекторы объектов, которые можно прикреплять
- allowedDetachments (массив строк) - CSS-селекторы объектов, которые можно откреплять
Возвращает: объект LabStep
Пример:
```js
// Создаем шаг с идентификатором 'step1' и описанием
// Разрешаем прикреплять объекты '#tube' и '#flask'
// и откреплять объект '#tube'
const step1 = physjs.createStep('step1', 'Соедините трубку с колбой', ['#tube', '#flask'], ['#tube']);
```
9. `physjs.addStep(step)`
Добавляет шаг в последовательность лабораторной работы.
Параметры:
- step (объект LabStep) - шаг, созданный с помощью createStep
Пример:
```js
physjs.addStep(step1);
physjs.addStep(step2);
physjs.addStep(step3);
```
10. `physjs.nextStep()`
Переходит к следующему шагу лабораторной работы.
Возвращает: следующий шаг или null, если это последний шаг
Пример:
```js
const nextStep = physjs.nextStep();
if (nextStep) {
console.log(`Переход к шагу: ${nextStep.description}`);
}
```
11. `physjs.previousStep()`
Переходит к предыдущему шагу лабораторной работы.
Возвращает: предыдущий шаг или null, если это первый шаг
Пример:
```js
const prevStep = physjs.previousStep();
if (prevStep) {
console.log(`Возврат к шагу: ${prevStep.description}`);
}
```
12. `physjs.getCurrentStep()`
Возвращает текущий шаг лабораторной работы.
Возвращает: текущий шаг или null, если ни один шаг не активен
Пример:
```js
const currentStep = physjs.getCurrentStep();
console.log(`Текущий шаг: ${currentStep.description}`);
```
13. `physjs.goToStep(id)`
Переходит к шагу с указанным идентификатором.
Параметры:
- id (строка) - идентификатор шага
Возвращает: найденный шаг или null, если шаг не найден
Пример:
```js
physjs.goToStep('step3'); // Переход к шагу с id='step3'
```
14. `physjs.resetLab()`
Сбрасывает лабораторную работу к начальному состоянию.
Пример:
```js
physjs.resetLab();
```
### Обработка событий
15. `physjs.onAttachment(callback)`
Регистрирует обработчик события прикрепления объектов.
Параметры:
- callback (функция) - функция обратного вызова, принимающая sourceObject и targetObject
Пример:
```js
physjs.onAttachment(function(sourceObject, targetObject) {
console.log(`Объект ${sourceObject.element.id} был прикреплен к ${targetObject.element.id}`);
});
```
16. `physjs.onDetachment(callback)`
Регистрирует обработчик события открепления объекта.
Параметры:
- callback (функция) - функция обратного вызова, принимающая объект
Пример:
```js
physjs.onDetachment(function(object) {
console.log(`Объект ${object.element.id} был откреплен`);
});
```
17. `physjs.onStepChange(callback)`
Регистрирует обработчик события изменения шага лабораторной работы.
Параметры:
- callback (функция) - функция обратного вызова, принимающая новый шаг
Пример:
```js
physjs.onStepChange(function(step) {
console.log(`Новый шаг: ${step.description}`);
document.getElementById('current-step').textContent = step.description;
});
```
18. `physjs.onLabComplete(callback)`
Регистрирует обработчик завершения лабораторной работы.
Параметры:
- callback (функция) - функция обратного вызова
Пример:
```js
physjs.onLabComplete(function() {
console.log('Лабораторная работа завершена!');
});
```
### Специальные эффекты
19. `physjs.showTemporaryObjectAt(objectToHide, referenceObject, selectorToShow, offsetX, offsetY, durationMs)`
Временно скрывает один объект и показывает другой в указанной позиции.
Функция может быть полезна для создания анимаций для групп объектов, когда взаимодействие с изначальной группой объектов пользователем нежелательно. Например, анимация переливания воды из сосудов по шлангам и тд.
Параметры:
- objectToHide (DOM-элемент или строка) - объект, который нужно скрыть
- referenceObject (DOM-элемент или строка) - объект, относительно которого позиционировать
- selectorToShow (строка) - CSS-селектор объекта, который нужно показать
- offsetX (число) - смещение по оси X относительно referenceObject
- offsetY (число) - смещение по оси Y относительно referenceObject
- durationMs (число) - продолжительность в миллисекундах
Пример:
```js
// Скрывает #flask, показывает #animation-overlay на 2 секунды
// в позиции на 10px правее и 20px ниже #beaker
physjs.showTemporaryObjectAt('#flask', '#beaker', '#animation-overlay', 10, 20, 2000);
```
20. `physjs.swapObjectsWithElement(object1, object2, selectorToShow)`
Скрывает два объекта и показывает вместо них третий объект. Позволяет "соединять объекты", подменяя два постоянно связанных объекта на один цельный.
Параметры:
- object1 (DOM-элемент или строка) - первый объект, который нужно скрыть
- object2 (DOM-элемент или строка) - второй объект, который нужно скрыть
- selectorToShow (строка) - CSS-селектор объекта, который нужно показать
Пример:
```js
// Скрывает #water и #salt, показывает #solution
physjs.swapObjectsWithElement('#water', '#salt', '#solution');
```
### Управление вращением объектов
21. `physjs.disableRotation()`
Отключает возможность вращения для всех объектов.
Пример:
```js
physjs.disableRotation();
```
22. `physjs.enableRotation()`
Включает возможность вращения для всех объектов.
Пример:
```js
physjs.enableRotation();
```
23.`physjs.disableRotationFor(elements)`
Отключает возможность вращения для указанных объектов.
Параметры:
- elements (массив или строка) - объекты или селекторы объектов
Пример:
```js
physjs.disableRotationFor(['#tube', '#flask']);
```
24. `physjs.enableRotationFor(elements)`
Включает возможность вращения для указанных объектов.
Параметры:
- elements (массив или строка) - объекты или селекторы объектов
Пример:
```js
physjs.enableRotationFor('#microscope');
```
25. `physjs.setRotationKeysEnabled(enabled)`
Включает или отключает использование клавиш Q/E для вращения объектов.
Параметры:
- enabled (boolean) - true для включения, false для отключения
Пример:
```js
physjs.setRotationKeysEnabled(false); // Отключение вращения клавишами
```
### Расширенные обработчики событий
26. `physjs.onBeforeAttachment(callback)`
Регистрирует обработчик события перед прикреплением объектов. Позволяет предотвратить прикрепление, вернув false.
Параметры:
- callback (функция) - функция, принимающая sourceObject и targetObject
Пример:
```js
physjs.onBeforeAttachment(function(sourceObject, targetObject) {
// Проверка условий прикрепления
if (someCondition) return false; // Предотвращает прикрепление
return true; // Разрешает прикрепление
});
```
27. `physjs.onBeforeDetachment(callback)`
Регистрирует обработчик события перед откреплением объекта. Позволяет предотвратить открепление, вернув false.
Параметры:
- callback (функция) - функция, принимающая объект
Пример:
```js
physjs.onBeforeDetachment(function(object) {
// Проверка условий открепления
if (someCondition) return false; // Предотвращает открепление
return true; // Разрешает открепление
});
```
28. `physjs.isAttached(element1, element2)`
Проверяет, прикреплены ли два объекта друг к другу.
Параметры:
- element1 (DOM-элемент или строка) - первый объект
- element2 (DOM-элемент или строка) - второй объект
Возвращает: true, если объекты прикреплены друг к другу, иначе false
Пример:
```js
if (physjs.isAttached('#tube', '#flask')) {
console.log('Трубка прикреплена к колбе');
}
```
### Работа с проводами и соединениями
29. `physjs.addConnectionPoint(elementSelector, pointId, x, y)`
Добавляет точку подключения проводов к объекту.
Параметры:
- elementSelector (строка) - CSS-селектор объекта
- pointId (строка) - идентификатор точки подключения
- x (число) - координата X в процентах от ширины элемента (0-100)
- y (число) - координата Y в процентах от высоты элемента (0-100)
Пример:
```js
// Добавляет точку подключения на 80% ширины и 20% высоты элемента
physjs.addConnectionPoint('#power-source', 'power-positive', 80, 20);
```
30. `physjs.onConnect(callback)`
Регистрирует обработчик события подключения проводов.
Параметры:
- callback (функция) - функция обратного вызова, принимающая fromId и toId
Пример:
```js
physjs.onConnect(function(fromPointId, toPointId) {
console.log(`Соединение создано от ${fromPointId} к ${toPointId}`);
});
```
31. `physjs.createWire(fromPointId, toPointId, color)`
Программно создает провод между двумя точками подключения.
Параметры:
- fromPointId (строка) - идентификатор начальной точки
- toPointId (строка) - идентификатор конечной точки
- color (строка) - цвет провода в формате CSS
Возвращает: ID созданного провода или null, если соединение не удалось
Пример:
```js
const wireId = physjs.createWire('power-positive', 'ammeter-input', '#FF0000');
```
32. `physjs.removeWire(wireId)`
Удаляет провод по его идентификатору.
Параметры:
- wireId (строка) - идентификатор провода
Пример:
```js
physjs.removeWire('wire-1');
```
33. `physjs.removeAllWires()`
Удаляет все провода.
Пример:
```js
physjs.removeAllWires();
```
### Баллистические траектории
34. `physjs.calculateTrajectory(v0, alpha, h, g)`
Рассчитывает траекторию полета тела, брошенного с начальной скоростью под углом.
Параметры:
- v0 (число) - начальная скорость
- alpha (число) - угол в радианах
- h (число) - начальная высота
- g (число) - ускорение свободного падения
Возвращает: объект с параметрами траектории (дальность, время полета, максимальная высота)
Пример:
```js
const trajectory = physjs.calculateTrajectory(10, Math.PI/4, 0, 9.8);
console.log(`Дальность полета: ${trajectory.range} м`);
```
35. `physjs.showTrajectory(startX, startY, vx, vy, g, floorArea, id, container_id)`
physjs.showTrajectory(startX, startY, vx, vy, g, floorArea, id, container_id)
Отображает траекторию движения на экране.
Параметры:
- startX, startY (числа) - начальные координаты
- vx, vy (числа) - компоненты скорости
- g (число) - ускорение свободного падения
- floorArea (DOM-элемент) - элемент, представляющий "пол"
- id (строка) - идентификатор для созданного элемента траектории
- container_id (строка) - идентификатор контейнера для размещения траектории
Пример:
```js
physjs.showTrajectory(100, 100, 5, -10, 9.8, document.getElementById('floor'), 'trajectory-1', 'experiment-area');
```
## HTML и CSS
### Классы
Библиотека PhysJS использует специальные CSS-классы для определения поведения элементов:
| Класс | Описание |
|-------|----------|
| `phys` | Базовый класс для всех физических объектов. Делает объект перетаскиваемым |
| `phys-attachable` | Позволяет объекту прикрепляться к другим объектам |
| `phys-fixed` | Создает неподвижный объект, который нельзя перетащить |
| `phys-connectors` | Объект может иметь точки подключения для проводов |
Пример использования классов:
```html
```
### Атрибут data-type
Атрибут data-type используется для определения типа объекта, который проверяется при работе с точками крепления и в обработчиках событий:
```html
```
Этот атрибут используется при настройке точек крепления для определения, какие типы объектов могут быть прикреплены:
```js
physjs.addAttachmentPoint('#stand', 'top', 50, 0, ['tube', 'flask']);
```
## Примеры использования
### Создание лабораторной работы
```js
// Создание шагов
const step1 = physjs.createStep('step1', 'Соедините трубку с колбой', ['#tube', '#flask']);
const step2 = physjs.createStep('step2', 'Нагрейте колбу горелкой', ['#burner', '#flask']);
const step3 = physjs.createStep('step3', 'Перелейте жидкость в пробирку', ['#flask', '#test-tube'], ['#flask']);
// Добавление шагов
physjs.addStep(step1).addStep(step2).addStep(step3);
// Начало лабораторной работы
physjs.goToStep('step1');
// Обработка изменения шага
physjs.onStepChange(function(step) {
document.getElementById('current-step').textContent = step.description;
});
// Обработка завершения лабораторной работы
physjs.onLabComplete(function() {
alert('Поздравляем! Вы успешно выполнили все задания лабораторной работы.');
});
```
### Настройка объектов и точек крепления
```js
// Добавление точек крепления для соединения трубки и колбы
physjs.addAttachmentPoint('#tube', 'bottom', 15, 90, ['flask']); // Нижняя точка трубки
physjs.addAttachmentPoint('#flask', 'top', 50, 0, ['tube']); // Верхняя точка колбы
// Добавление точки крепления для горелки
physjs.addAttachmentPoint('#burner', 'flame', 25, 0, ['flask']); // Пламя горелки
physjs.addAttachmentPoint('#flask', 'bottom', 50, 100, ['burner']); // Нижняя точка колбы
// Добавление точки крепления для пробирки
physjs.addAttachmentPoint('#flask', 'outlet', 90, 60, ['test-tube']); // Выходной патрубок колбы
physjs.addAttachmentPoint('#test-tube', 'inlet', 20, 10, ['flask']); // Входное отверстие пробирки
```
## Советы по производительности
1. **Ограничьте количество физических объектов**
- Старайтесь не превышать 30-50 объектов на одной странице для оптимальной производительности
- При необходимости используйте технику "пулинга" объектов, показывая только нужные в данный момент
2. **Используйте класс `phys-fixed` для неподвижных объектов**
- Это уменьшит количество вычислений при перетаскивании и взаимодействии
3. **Группируйте сложные объекты**
- Для сложных объектов используйте один контейнер с классом `phys` и вложенные элементы без этого класса
- Используйте `physjs.swapObjectsWithElement()` для объединения часто соединяемых объектов
4. **Оптимизируйте работу с проводами**
- Старайтесь не превышать 15-20 проводов на одной схеме
- Используйте `physjs.updateWirePositions()` только при необходимости
## Устранение неполадок
### Проблема: Объекты не прикрепляются друг к другу
Решение:
1. Убедитесь, что оба объекта имеют класс phys-attachable
2. Проверьте правильность настройки точек крепления
3. Проверьте, разрешено ли прикрепление этих объектов на текущем шаге
4. Включите режим отладки для получения подробных логов: physjs.setDebugMode(true)
### Проблема: Объект не перетаскивается
Решение:
1. Убедитесь, что объект имеет класс phys
2. Проверьте, не является ли объект прикрепленным к родительскому объекту
3. Убедитесь, что для объекта установлено position: absolute
### Проблема: Лабораторная работа не переходит к следующему шагу
Решение:
1. Проверьте, правильно ли созданы и добавлены шаги
2. Убедитесь, что вызывается метод physjs.nextStep()
3. Проверьте консоль на наличие ошибок
4. Включите режим отладки для получения подробных логов: physjs.setDebugMode(true)
---
Документация составлена для библиотеки PhysJS версии 1.2.4.