* 3. Конфигуратор автоматически инициализируется
*/
(function() {
'use strict';
// Проверяем, что скрипт не был уже загружен
if (window.IrisConfigurator) {
return;
}
// Конфигурация по умолчанию
const DEFAULT_CONFIG = {
containerId: 'iris-configurator',
droneImageUrl: 'https://i.imgur.com/your-drone-image.jpg', // Замените на ваш URL
showNavigation: true,
showBottomPanel: true,
currency: 'RUB',
language: 'ru'
};
// Данные компонентов
const COMPONENTS = {
motor: {
'tracker-640': {
name: 'Tracker 3115 640KV',
price: 14000,
weight: 440,
specs: 'Для 9-11 дюймовых дронов\n7075 корпус, статор Kawasaki\nВысокая производительность',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=Tracker+3115+640kv+motor'
},
'tracker-900': {
name: 'Tracker 3115 900KV',
price: 14400,
weight: 440,
specs: 'Для 9-11 дюймовых дронов\n7075 корпус, статор Kawasaki\nВысокая производительность',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=Tracker+3115+900kv+motor'
},
'emax-640': {
name: 'EMAX ECOII 3115 640KV',
price: 10000,
weight: 232,
specs: 'Высокопроизводительный\nПрочная конструкция\nУлучшенное охлаждение',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=EMAX+ECOII+3115+640kv+motor'
},
'neebrc-900': {
name: 'NEEBRC 3115 900KV',
price: 8000,
weight: 260,
specs: 'Совместимость 3-6S\nДля 8/10 дюймовых дронов\nХороший баланс цены и качества',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=NEEBRC+3115+900kv+motor'
}
},
propeller: {
'gemfan': {
name: 'Gemfan F1051 10" Складные',
price: 1200,
weight: 80,
specs: '2-лопастные / 3-лопастные\nСтекловолокно-нейлон\nВысокая прочность, легкий вес',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=Gemfan+F1051+10+inch+folding+propeller'
},
'carbon': {
name: 'Универсальные 10" Карбоновые',
price: 2000,
weight: 100,
specs: 'Карбоновое волокно\nВысокая прочность\nУлучшенная аэродинамика',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=10+inch+carbon+fiber+folding+propeller'
}
},
battery: {
'4s': {
name: '4S LiPo 6000mAh',
price: 8000,
weight: 600,
specs: 'Стандартный вариант\nСтабильная работа\nНадежный выбор',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=4S+6000mAh+LiPo+battery+drone'
},
'6s': {
name: '6S LiHv 9000mAh',
price: 12000,
weight: 900,
specs: 'Повышенная мощность\n⚠️ Возможны: шум, вибрации\nСбои связи, ошибки ESC',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=6S+9000mAh+LiHv+battery+drone'
}
},
payload: {
'none': {
name: 'Без полезной нагрузки',
price: 0,
weight: 0,
specs: 'Максимальная дальность полета\nИдеально для тренировок\nОптимальная производительность',
aliexpress: ''
},
'camera': {
name: 'Подвес для камеры',
price: 15000,
weight: 500,
specs: 'Для разведывательных задач\nДополнительная камера\nСтабилизация изображения',
aliexpress: 'https://www.aliexpress.com/wholesale?SearchText=camera+gimbal+drone'
},
'rpg': {
name: 'Имитация снаряда РПГ-7',
price: 5000,
weight: 1800,
specs: 'Демонстрация грузоподъемности\n⚠️ Крепление может быть уничтожено\nПосле падения',
aliexpress: ''
}
}
};
// CSS стили
const CSS_STYLES = `
.iris-configurator * {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.iris-configurator {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
color: #ffffff;
overflow: hidden;
height: 100vh;
position: relative;
}
.iris-configurator .top-nav {
background: rgba(0, 0, 0, 0.8);
padding: 10px 20px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid #d4af37;
}
.iris-configurator .nav-left {
display: flex;
gap: 20px;
}
.iris-configurator .nav-item {
color: #d4af37;
text-decoration: none;
font-weight: bold;
font-size: 14px;
text-transform: uppercase;
padding: 5px 10px;
border-radius: 3px;
transition: background-color 0.3s;
}
.iris-configurator .nav-item:hover {
background-color: rgba(212, 175, 55, 0.2);
}
.iris-configurator .nav-right {
display: flex;
gap: 15px;
align-items: center;
}
.iris-configurator .battle-button {
background: linear-gradient(45deg, #ff4444, #cc0000);
color: white;
padding: 8px 20px;
border: none;
border-radius: 5px;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
box-shadow: 0 0 10px rgba(255, 68, 68, 0.5);
}
.iris-configurator .main-container {
display: flex;
height: calc(100vh - 60px);
position: relative;
}
.iris-configurator .drone-display {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 40px;
position: relative;
background: radial-gradient(ellipse at center, rgba(255,255,255,0.1) 0%, transparent 70%);
}
.iris-configurator .drone-title {
text-align: center;
margin-bottom: 30px;
}
.iris-configurator .drone-name {
font-size: 36px;
font-weight: bold;
color: #ffffff;
text-shadow: 2px 2px 4px rgba(0,0,0,0.8);
margin-bottom: 10px;
}
.iris-configurator .drone-type {
font-size: 18px;
color: #d4af37;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.iris-configurator .drone-type::before {
content: "⚡";
font-size: 20px;
}
.iris-configurator .drone-image-container {
width: 500px;
height: 350px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
border-radius: 10px;
box-shadow: 0 0 30px rgba(212, 175, 55, 0.3);
margin-bottom: 30px;
}
.iris-configurator .drone-info {
position: absolute;
bottom: 40px;
left: 40px;
background: rgba(0, 0, 0, 0.8);
padding: 15px;
border-radius: 8px;
border: 1px solid #d4af37;
}
.iris-configurator .info-item {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
font-size: 14px;
}
.iris-configurator .info-item:last-child {
margin-bottom: 0;
}
.iris-configurator .info-icon {
width: 20px;
height: 20px;
background: #d4af37;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #000;
}
.iris-configurator .modifications-panel {
width: 600px;
background: rgba(0, 0, 0, 0.6);
border-left: 2px solid #d4af37;
padding: 30px;
overflow-y: auto;
position: relative;
}
.iris-configurator .modifications-title {
font-size: 24px;
color: #d4af37;
text-align: center;
margin-bottom: 30px;
text-transform: uppercase;
font-weight: bold;
}
.iris-configurator .mod-tree {
position: relative;
display: flex;
flex-direction: column;
gap: 40px;
}
.iris-configurator .mod-tier {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
position: relative;
}
.iris-configurator .mod-item {
width: 80px;
height: 80px;
background: linear-gradient(145deg, #2a2a2a, #1a1a1a);
border: 2px solid #555;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.iris-configurator .mod-item:hover {
border-color: #d4af37;
box-shadow: 0 0 15px rgba(212, 175, 55, 0.5);
transform: translateY(-2px);
}
.iris-configurator .mod-item.selected {
border-color: #d4af37;
background: linear-gradient(145deg, #d4af37, #b8941f);
color: #000;
box-shadow: 0 0 20px rgba(212, 175, 55, 0.8);
}
.iris-configurator .mod-item.available {
border-color: #4CAF50;
background: linear-gradient(145deg, #2e5c2e, #1e3f1e);
}
.iris-configurator .mod-icon {
font-size: 24px;
margin-bottom: 5px;
}
.iris-configurator .mod-name {
font-size: 10px;
text-align: center;
font-weight: bold;
text-transform: uppercase;
}
.iris-configurator .mod-price {
position: absolute;
bottom: -20px;
left: 50%;
transform: translateX(-50%);
font-size: 11px;
color: #d4af37;
font-weight: bold;
white-space: nowrap;
}
.iris-configurator .bottom-panel {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.9);
border-top: 2px solid #d4af37;
padding: 20px;
display: flex;
justify-content: space-between;
align-items: center;
}
.iris-configurator .total-cost {
display: flex;
align-items: center;
gap: 15px;
}
.iris-configurator .cost-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 16px;
font-weight: bold;
}
.iris-configurator .cost-icon {
width: 24px;
height: 24px;
background: #d4af37;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #000;
font-size: 12px;
}
.iris-configurator .action-buttons {
display: flex;
gap: 15px;
}
.iris-configurator .btn {
padding: 12px 24px;
border: none;
border-radius: 5px;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
}
.iris-configurator .btn-primary {
background: linear-gradient(45deg, #d4af37, #b8941f);
color: #000;
box-shadow: 0 0 10px rgba(212, 175, 55, 0.3);
}
.iris-configurator .btn-primary:hover {
box-shadow: 0 0 20px rgba(212, 175, 55, 0.6);
transform: translateY(-1px);
}
.iris-configurator .btn-secondary {
background: linear-gradient(45deg, #555, #333);
color: #fff;
border: 1px solid #777;
}
.iris-configurator .btn-secondary:hover {
background: linear-gradient(45deg, #666, #444);
}
.iris-configurator .tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.95);
color: #fff;
padding: 15px;
border-radius: 8px;
border: 1px solid #d4af37;
font-size: 12px;
z-index: 1000;
max-width: 250px;
box-shadow: 0 0 15px rgba(0,0,0,0.8);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease;
}
.iris-configurator .tooltip.visible {
opacity: 1;
}
.iris-configurator .tooltip-title {
color: #d4af37;
font-weight: bold;
margin-bottom: 8px;
font-size: 14px;
}
.iris-configurator .tooltip-specs {
margin-bottom: 8px;
line-height: 1.4;
white-space: pre-line;
}
.iris-configurator .tooltip-price {
color: #4CAF50;
font-weight: bold;
}
@media (max-width: 1200px) {
.iris-configurator .modifications-panel {
width: 500px;
}
.iris-configurator .mod-item {
width: 60px;
height: 60px;
}
.iris-configurator .mod-icon {
font-size: 18px;
}
.iris-configurator .mod-name {
font-size: 8px;
}
}
@media (max-width: 900px) {
.iris-configurator .main-container {
flex-direction: column;
}
.iris-configurator .modifications-panel {
width: 100%;
height: 50vh;
}
.iris-configurator .drone-display {
height: 50vh;
}
}
`;
// Основной класс конфигуратора
class IrisConfigurator {
constructor(config = {}) {
this.config = { ...DEFAULT_CONFIG, ...config };
this.selectedComponents = {
motor: 'tracker-640',
propeller: 'gemfan',
battery: '4s',
payload: 'none'
};
this.baseWeight = 816; // Базовый вес дрона
this.tooltip = null;
this.init();
}
init() {
this.injectStyles();
this.createHTML();
this.bindEvents();
this.updateTotals();
}
injectStyles() {
if (document.getElementById('iris-configurator-styles')) {
return;
}
const style = document.createElement('style');
style.id = 'iris-configurator-styles';
style.textContent = CSS_STYLES;
document.head.appendChild(style);
}
createHTML() {
const container = document.getElementById(this.config.containerId);
if (!container) {
console.error(`Container with ID '${this.config.containerId}' not found`);
return;
}
container.className = 'iris-configurator';
container.innerHTML = this.getHTML();
}
getHTML() {
return `
${this.config.showNavigation ? this.getNavigationHTML() : ''}
IX 🔶 ИРИС-1РП
Средний дрон универсальный
Доступны модификации
${this.getModTreeHTML()}
${this.config.showBottomPanel ? this.getBottomPanelHTML() : ''}
`;
}
getNavigationHTML() {
return `
`;
}
getModTreeHTML() {
const tiers = [
{ name: 'Моторы', component: 'motor', icon: '⚙️' },
{ name: 'Пропеллеры', component: 'propeller', icon: '🌀' },
{ name: 'Аккумуляторы', component: 'battery', icon: '🔋' },
{ name: 'Полезная нагрузка', component: 'payload', icon: '📦' }
];
return tiers.map(tier => {
const components = COMPONENTS[tier.component];
const items = Object.keys(components).map(id => {
const comp = components[id];
const isSelected = this.selectedComponents[tier.component] === id;
const classes = ['mod-item'];
if (isSelected) classes.push('selected');
if (tier.component === 'motor' || tier.component === 'payload') classes.push('available');
return `
${tier.icon}
${comp.name.split(' ').slice(-1)[0]}
${comp.price.toLocaleString('ru-RU')} руб.
`;
}).join('');
return `
${items}
`;
}).join('');
}
getBottomPanelHTML() {
return `
`;
}
bindEvents() {
const container = document.getElementById(this.config.containerId);
// Клики по модификациям
container.addEventListener('click', (e) => {
const modItem = e.target.closest('.mod-item');
if (modItem) {
const component = modItem.dataset.component;
const id = modItem.dataset.id;
this.selectComponent(component, id);
}
});
// Тултипы
container.addEventListener('mouseenter', (e) => {
const modItem = e.target.closest('.mod-item');
if (modItem) {
this.showTooltip(e, modItem);
}
}, true);
container.addEventListener('mouseleave', (e) => {
const modItem = e.target.closest('.mod-item');
if (modItem) {
this.hideTooltip();
}
}, true);
// Кнопка сброса
const resetBtn = container.querySelector('#reset-btn');
if (resetBtn) {
resetBtn.addEventListener('click', () => this.reset());
}
}
selectComponent(component, id) {
if (!COMPONENTS[component] || !COMPONENTS[component][id]) {
return;
}
// Убираем выделение с предыдущего
const container = document.getElementById(this.config.containerId);
const prevSelected = container.querySelector(`[data-component="${component}"].selected`);
if (prevSelected) {
prevSelected.classList.remove('selected');
}
// Добавляем выделение новому
const newSelected = container.querySelector(`[data-component="${component}"][data-id="${id}"]`);
if (newSelected) {
newSelected.classList.add('selected');
this.selectedComponents[component] = id;
this.updateTotals();
}
}
updateTotals() {
let totalCost = 0;
let totalWeight = this.baseWeight;
for (const [component, id] of Object.entries(this.selectedComponents)) {
if (COMPONENTS[component] && COMPONENTS[component][id]) {
totalCost += COMPONENTS[component][id].price;
totalWeight += COMPONENTS[component][id].weight;
}
}
const container = document.getElementById(this.config.containerId);
const costElements = container.querySelectorAll('#total-cost, #bottom-total-cost');
const weightElements = container.querySelectorAll('#total-weight, #bottom-total-weight');
costElements.forEach(el => {
if (el) el.textContent = `${totalCost.toLocaleString('ru-RU')} руб.`;
});
weightElements.forEach(el => {
if (el) el.textContent = `${totalWeight.toLocaleString('ru-RU')} г`;
});
}
showTooltip(event, modItem) {
const component = modItem.dataset.component;
const id = modItem.dataset.id;
if (!COMPONENTS[component] || !COMPONENTS[component][id]) {
return;
}
const data = COMPONENTS[component][id];
const container = document.getElementById(this.config.containerId);
const tooltip = container.querySelector('#tooltip');
if (!tooltip) return;
tooltip.querySelector('#tooltip-title').textContent = data.name;
tooltip.querySelector('#tooltip-specs').textContent = data.specs;
tooltip.querySelector('#tooltip-price').textContent = `${data.price.toLocaleString('ru-RU')} руб.`;
const rect = modItem.getBoundingClientRect();
const containerRect = container.getBoundingClientRect();
tooltip.style.left = (rect.right - containerRect.left + 10) + 'px';
tooltip.style.top = (rect.top - containerRect.top) + 'px';
tooltip.classList.add('visible');
}
hideTooltip() {
const container = document.getElementById(this.config.containerId);
const tooltip = container.querySelector('#tooltip');
if (tooltip) {
tooltip.classList.remove('visible');
}
}
reset() {
this.selectedComponents = {
motor: 'tracker-640',
propeller: 'gemfan',
battery: '4s',
payload: 'none'
};
const container = document.getElementById(this.config.containerId);
// Убираем все выделения
container.querySelectorAll('.mod-item').forEach(item => {
item.classList.remove('selected');
});
// Выделяем начальные элементы
for (const [component, id] of Object.entries(this.selectedComponents)) {
const item = container.querySelector(`[data-component="${component}"][data-id="${id}"]`);
if (item) {
item.classList.add('selected');
}
}
this.updateTotals();
}
// Публичные методы для внешнего использования
getSelectedConfiguration() {
const config = {};
for (const [component, id] of Object.entries(this.selectedComponents)) {
config[component] = {
id: id,
...COMPONENTS[component][id]
};
}
return config;
}
getTotalCost() {
let total = 0;
for (const [component, id] of Object.entries(this.selectedComponents)) {
if (COMPONENTS[component] && COMPONENTS[component][id]) {
total += COMPONENTS[component][id].price;
}
}
return total;
}
getTotalWeight() {
let total = this.baseWeight;
for (const [component, id] of Object.entries(this.selectedComponents)) {
if (COMPONENTS[component] && COMPONENTS[component][id]) {
total += COMPONENTS[component][id].weight;
}
}
return total;
}
}
// Автоматическая инициализация при загрузке DOM
function autoInit() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', autoInit);
return;
}
const container = document.getElementById(DEFAULT_CONFIG.containerId);
if (container && !container.hasAttribute('data-iris-initialized')) {
container.setAttribute('data-iris-initialized', 'true');
window.irisConfiguratorInstance = new IrisConfigurator();
}
}
// Экспорт в глобальную область
window.IrisConfigurator = IrisConfigurator;
// Автоматическая инициализация
autoInit();
})();