Рейтинг темы:
  • 1 Голос(ов) - 5 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Панель с кнопками для 3D v2
#1
Photo 
В приложении Цифровой двойник довольно часто используются кнопки. Я решил создать вторую версию панели с кнопками для 3D в стиле ЧПУ-станка. Здесь будет представлен расширенный функционал.
В данном посте я хотел бы рассказать о том как добавить их себе в 3D-сцену и настроить. Они смогут помочь стилизовать сцену и улучшить восприятие.

1. Скачать файл ViewButtons (во вложении) и импортировать себе в сцену (Файл - Импорт).
[Изображение: 5db0a2ab-2729-4c02-b9da-12129cf5eba4.png]
2. Если мы начнём воспроизведение сцены они появятся в правом нижнем углу. Здесь можно увидеть название цеха, индикатор и 9 кнопок: 4 кнопки с видами, Автооблёт, Ночной режим, Скриншот, Сброс кнопка ИНФО. У каждой кнопки есть hotkey и подписан в скобках.

Каждая кнопка с видом при нажатии будет перемещать камеру в заданное место. 
При Автооблёте камера будет крутиться вокруг сцены.
Ночной режим выключает освещение на сцене и изменяет её в тёмно-синие оттенки.
Скриншот делает снимок экрана, при этом панель с кнопками не будет на нём отображена.
Сброс отменяет действия и/или возвращает камеру на начальную позицию.
Также снизу есть показатель FPS, текущее время и дата.
[Изображение: 735e2d8f-bdfe-4376-9bf3-4b924b7a9ecf.png]
3. Кнопка ИНФО при нажатии откроет всплывающее окно с системной информацией и технической поддержкой. При нажатии на кнопку support@winnum.ru пользователя будет переносить в почту и начинать письмо в support.
[Изображение: 4b433863-0d38-474c-8b07-124fee8d7174.png]
4. Внутри ViewButtons в Объект - Действия будет лежать код самой панели.
[Изображение: 169d5b16-6e24-4ce7-8048-f329c056a8bc.png]
5. Чтобы настроить кнопки с видами нужно изменить логику для них в коде. (9-47 строки)
Код:
function ScriptSView() {
    console.log('Общий вид активирован');
    camera.position.set(12.51, 77.63, 66.77);
    camera.rotation.set(-52 * Math.PI / 180, 0, 0);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ОБЩИЙ ВИД', '#00ff00');
}

function ScriptView1() {
    console.log('Вид 1 активирован');
    camera.position.set(-54.87, 31.12, 4.72);
    camera.rotation.set(-44 * Math.PI / 180, 0, 0);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ВИД 1', '#00ff00');
}

function ScriptView2() {
    console.log('Вид 2 активирован');
    camera.position.set(-23.77, 24.68, -17.76);
    camera.rotation.set(-141 * Math.PI / 180, -37.89 * Math.PI / 180, -153.5 * Math.PI / 180);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ВИД 2', '#00ff00');
}

function ScriptView3() {
    console.log('Вид 3 активирован');
    camera.position.set(30.25, 52.22, 44.24);
    camera.rotation.set(-58.2 * Math.PI / 180, 0, 0);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ВИД 3', '#00ff00');
}
6. Чтобы изменить названия кнопок видов поменять этот код. (158-164 строки)
Код:
    // Создаем кнопки видов
    var viewButtons = [
        { id: 'btnSView', text: 'ОБЩИЙ ВИД [1]', onClick: ScriptSView },
        { id: 'btnView1', text: 'ВИД 1 [2]', onClick: ScriptView1 },
        { id: 'btnView2', text: 'ВИД 2 [3]', onClick: ScriptView2 },
        { id: 'btnView3', text: 'ВИД 3 [4]', onClick: ScriptView3 },
    ];
7. Чтобы изменить название цеха нужно поменять этот код. (131-132 строки)
Код:
    var header = document.createElement("div");
    header.innerText = 'ЦЕХ 058';
8. Чтобы изменить Автооблёт нужно поменять этот код. (333-337 строки)
Код:
function startAnimation() {
    var startTime = Date.now();
    var radius = 80;
    var height = 60;
    var speed = 0.3;
9. Чтобы изменить Системную информацию в сплывающем окне нужно поменять этот код. (618-633 строки)
Код:
    // Текст информации
    var infoText = document.createElement("div");
    infoText.innerHTML =
        '<p style="margin-bottom: 12px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">3D-СЦЕНА:</strong> ЦЕХ 058' +
        '</p>' +
        '<p style="margin-bottom: 12px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">РАЗРАБОТЧИК:</strong> ПОНЯТОВ НИКИТА' +
        '</p>' +
        '<p style="margin-bottom: 12px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">ВЕРСИЯ:</strong> 2.0' +
        '</p>' +
        '<p style="margin-bottom: 15px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">СТАТУС:</strong> СИСТЕМА АКТИВНА' +
        '</p>';
    modal.appendChild(infoText);
Полный код:
Код:
var SView, View1, View2, View3, View4;
var currentAnimation = null;
var isNightMode = false;
var frameCount = 0;
var lastTime = performance.now();
var fps = 0;

// Обновите функции видов для отображения правильных углов
function ScriptSView() {
    console.log('Общий вид активирован');
    camera.position.set(12.51, 77.63, 66.77);
    camera.rotation.set(-52 * Math.PI / 180, 0, 0);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ОБЩИЙ ВИД', '#00ff00');
}

function ScriptView1() {
    console.log('Вид 1 активирован');
    camera.position.set(-54.87, 31.12, 4.72);
    camera.rotation.set(-44 * Math.PI / 180, 0, 0);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ВИД 1', '#00ff00');
}

function ScriptView2() {
    console.log('Вид 2 активирован');
    camera.position.set(-23.77, 24.68, -17.76);
    camera.rotation.set(-141 * Math.PI / 180, -37.89 * Math.PI / 180, -153.5 * Math.PI / 180);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ВИД 2', '#00ff00');
}

function ScriptView3() {
    console.log('Вид 3 активирован');
    camera.position.set(30.25, 52.22, 44.24);
    camera.rotation.set(-58.2 * Math.PI / 180, 0, 0);
    camera.updateProjectionMatrix();
    camera.updateMatrix();
    // Убираем вызов updateCoordinates()
    updateStatus('ВИД 3', '#00ff00');
}

function start() {
    createButtonContainer();
    SView = document.getElementById('btnSView');
    View1 = document.getElementById('btnView1');
    View2 = document.getElementById('btnView2');
    View3 = document.getElementById('btnView3');
    View4 = document.getElementById('btnView4');
    initHotkeys();
    // Запускаем подсчет FPS
    requestAnimationFrame(updateFPS);
}

// Функция для добавления техно-деталей ЧПУ
function addCNCDetails(container) {
    // Добавляем угловые элементы
    const corners = [
        { top: '0', left: '0', transform: 'none' },
        { top: '0', right: '0', transform: 'scaleX(-1)' },
        { bottom: '0', left: '0', transform: 'scaleY(-1)' },
        { bottom: '0', right: '0', transform: 'scale(-1)' }
    ];

    corners.forEach(corner => {
        var cornerElement = document.createElement("div");
        cornerElement.style.position = 'absolute';
        cornerElement.style.width = '15px';
        cornerElement.style.height = '15px';
        cornerElement.style.background = 'linear-gradient(135deg, #00cccc, #008080)';
        cornerElement.style.border = '1px solid #00ffff';
        cornerElement.style.boxShadow = '0 0 5px rgba(0, 255, 255, 0.4)';
        cornerElement.style.transform = corner.transform;
        Object.assign(cornerElement.style, corner);
        container.appendChild(cornerElement);
    });

    // Добавляем техно-сетку на фон
    var gridOverlay = document.createElement("div");
    gridOverlay.style.position = 'absolute';
    gridOverlay.style.top = '0';
    gridOverlay.style.left = '0';
    gridOverlay.style.width = '100%';
    gridOverlay.style.height = '100%';
    gridOverlay.style.backgroundImage = 'linear-gradient(to right, rgba(0, 204, 204, 0.1) 1px, transparent 1px), linear-gradient(to bottom, rgba(0, 204, 204, 0.1) 1px, transparent 1px)';
    gridOverlay.style.backgroundSize = '10px 10px';
    gridOverlay.style.pointerEvents = 'none';
    gridOverlay.style.zIndex = '1';
    container.appendChild(gridOverlay);
}

function createButtonContainer() {
    var sceneView = document.querySelector("#player > div");
   
    // Создаем основной контейнер в стиле ЧПУ станка
    var mainContainer = document.createElement("div");
    mainContainer.style.position = "absolute";
    mainContainer.style.right = '20px';
    mainContainer.style.bottom = '20px';
    mainContainer.style.zIndex = '1000';
    mainContainer.style.background = 'linear-gradient(145deg, #1e1e1e, #2d2d2d)';
    mainContainer.style.border = '3px solid #404040';
    mainContainer.style.borderRadius = '2px';
    mainContainer.style.padding = '15px';
    mainContainer.style.fontFamily = '"Share Tech Mono", "Courier New", monospace';
    mainContainer.style.minWidth = '250px';
    mainContainer.style.overflow = 'hidden';
    mainContainer.style.boxShadow = '0 0 15px rgba(0, 255, 255, 0.2), inset 0 0 10px rgba(0, 0, 0, 0.5)';

    // Добавляем техно-детали
    addCNCDetails(mainContainer);

    // Верхняя панель с названием и статусом
    var headerPlate = document.createElement("div");
    headerPlate.style.background = 'linear-gradient(to bottom, #00b3b3, #008080)';
    headerPlate.style.border = '2px solid #00cccc';
    headerPlate.style.borderRadius = '1px';
    headerPlate.style.padding = '8px 15px';
    headerPlate.style.marginBottom = '15px';
    headerPlate.style.textAlign = 'center';
    headerPlate.style.position = 'relative';
    headerPlate.style.boxShadow = 'inset 0 0 10px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.5)';
    headerPlate.style.textShadow = '0 0 5px rgba(0, 255, 255, 0.7)';
   
    var header = document.createElement("div");
    header.innerText = 'ЦЕХ 058';
    header.style.color = '#00ffff';
    header.style.fontSize = '16px';
    header.style.fontWeight = 'bold';
    header.style.textTransform = 'uppercase';
    header.style.letterSpacing = '3px';
    header.style.marginBottom = '5px';
   
    // Статус бар
    var statusBar = document.createElement("div");
    statusBar.id = 'status-bar';
    statusBar.innerHTML = '<span style="color:#00ff00">■</span> СИСТЕМА АКТИВНА';
    statusBar.style.fontSize = '10px';
    statusBar.style.color = '#00ff00';
   
    headerPlate.appendChild(header);
    headerPlate.appendChild(statusBar);
    mainContainer.appendChild(headerPlate);

    // Контейнер для кнопок
    var btnContainer = document.createElement("div");
    btnContainer.style.display = 'flex';
    btnContainer.style.flexDirection = 'column';
    btnContainer.style.gap = '8px';
    mainContainer.appendChild(btnContainer);

    // Создаем кнопки видов
    var viewButtons = [
        { id: 'btnSView', text: 'ОБЩИЙ ВИД [1]', onClick: ScriptSView },
        { id: 'btnView1', text: 'ВИД 1 [2]', onClick: ScriptView1 },
        { id: 'btnView2', text: 'ВИД 2 [3]', onClick: ScriptView2 },
        { id: 'btnView3', text: 'ВИД 3 [4]', onClick: ScriptView3 },
    ];

    viewButtons.forEach(button => {
        var btn = createCNCButton(button.text, function() { button.onClick(); }, button.id);
        btnContainer.appendChild(btn);
    });

    // Разделитель
    var separator = document.createElement("div");
    separator.style.height = '1px';
    separator.style.background = 'linear-gradient(to right, transparent, #00cccc, transparent)';
    separator.style.margin = '10px 0';
    separator.style.opacity = '0.5';
    btnContainer.appendChild(separator);

    // Дополнительные функциональные кнопки
    var funcButtons = [
        { id: 'btnAnimation', text: 'АВТООБЛЕТ [A]', onClick: toggleAnimation },
        { id: 'btnNightMode', text: 'НОЧНОЙ РЕЖИМ [N]', onClick: toggleNightMode },
        { id: 'btnScreenshot', text: 'СКРИНШОТ [P]', onClick: takeScreenshot },
        { id: 'btnReset', text: 'СБРОС [R]', onClick: resetView },
        { id: 'btnInfo', text: 'ИНФО [I]', onClick: showInfoModal }
    ];

    funcButtons.forEach(button => {
        var btn = createCNCButton(button.text, button.onClick, button.id);
        if (button.id === 'btnInfo') {
            styleEmergencyButton(btn);
        }
        btnContainer.appendChild(btn);
    });

// Панель информации (убираем coordDisplay)
var infoPanel = document.createElement("div");
infoPanel.style.marginTop = '15px';
infoPanel.style.padding = '5px';
infoPanel.style.background = 'rgba(0, 0, 0, 0.3)';
infoPanel.style.border = '1px solid #00cccc';
infoPanel.style.borderRadius = '1px';
infoPanel.style.textAlign = 'center';
infoPanel.style.fontSize = '10px';
infoPanel.style.color = '#00cccc';

// Убираем создание coordDisplay
// var coordDisplay = document.createElement("div");
// coordDisplay.id = 'coord-display';
// coordDisplay.textContent = 'X: 0.0 Y: 0.0 Z: 0.0';
// infoPanel.appendChild(coordDisplay);

var fpsDisplay = document.createElement("div");
fpsDisplay.id = 'fps-display';
fpsDisplay.textContent = 'FPS: 0';
fpsDisplay.style.marginTop = '3px';
infoPanel.appendChild(fpsDisplay);

var timeDisplay = document.createElement("div");
timeDisplay.id = 'time-display';
timeDisplay.style.marginTop = '3px';
infoPanel.appendChild(timeDisplay);

var dateDisplay = document.createElement("div");
dateDisplay.id = 'date-display';
dateDisplay.style.fontSize = '9px';
dateDisplay.style.opacity = '0.7';
dateDisplay.style.marginTop = '3px';
infoPanel.appendChild(dateDisplay);

btnContainer.appendChild(infoPanel);

    // Нижняя техно-полоса
    var footerStrip = document.createElement("div");
    footerStrip.style.height = '3px';
    footerStrip.style.background = 'linear-gradient(to right, #00cccc, #008080, #00cccc)';
    footerStrip.style.marginTop = '15px';
    footerStrip.style.borderRadius = '1px';
    footerStrip.style.boxShadow = '0 0 5px rgba(0, 255, 255, 0.3)';
    mainContainer.appendChild(footerStrip);

    sceneView.appendChild(mainContainer);
   
    // Запускаем обновление времени и координат
    updateTime();
    updateCoordinates();
    setInterval(updateTime, 1000);
    setInterval(updateCoordinates, 100);
}

// Создание универсальной кнопки
function createCNCButton(text, onClick, id) {
    var btn = document.createElement("BUTTON");
    btn.id = id;
    btn.innerText = text;
    styleCNCButton(btn);
    btn.onclick = onClick;
    return btn;
}

// Новый функционал: Ночной режим
function toggleNightMode() {
    isNightMode = !isNightMode;
   
    if (isNightMode) {
        // Сохраняем оригинальные настройки освещения
        if (!window.originalLights) {
            window.originalLights = [];
            scene.traverse(function(object) {
                if (object.isLight) {
                    window.originalLights.push({
                        object: object,
                        intensity: object.intensity,
                        visible: object.visible
                    });
                }
            });
        }
       
        // Уменьшаем интенсивность света
        scene.traverse(function(object) {
            if (object.isLight) {
                object.intensity *= 0.3;
            }
        });
       
        // Добавляем синее ночное освещение
        if (!window.nightLight) {
            window.nightLight = new THREE.AmbientLight(0x003366, 0.5);
            scene.add(window.nightLight);
        }
       
        updateStatus('НОЧНОЙ РЕЖИМ', '#0066cc');
    } else {
        // Восстанавливаем оригинальное освещение
        if (window.originalLights) {
            window.originalLights.forEach(light => {
                light.object.intensity = light.intensity;
                light.object.visible = light.visible;
            });
        }
       
        // Убираем ночное освещение
        if (window.nightLight) {
            scene.remove(window.nightLight);
            window.nightLight = null;
        }
       
        updateStatus('ДНЕВНОЙ РЕЖИМ', '#00ff00');
    }
}

// Новый функционал: Сброс вида
function resetView() {
    if (currentAnimation) {
        stopAnimation();
    }
    ScriptSView();
    updateStatus('ВИД СБРОШЕН', '#00ff00');
}

// Новый функционал: АВТООБЛЕТ
function toggleAnimation() {
    if (currentAnimation) {
        stopAnimation();
        updateStatus('АВТООБЛЕТ ОСТАНОВЛЕН', '#ff4444');
    } else {
        startAnimation();
        updateStatus('АВТООБЛЕТ АКТИВЕН', '#00ff00');
    }
}

function startAnimation() {
    var startTime = Date.now();
    var radius = 80;
    var height = 60;
    var speed = 0.3;
   
    // Сохраняем начальную позицию для возврата
    if (!window.originalCameraPosition) {
        window.originalCameraPosition = camera.position.clone();
        window.originalCameraRotation = camera.rotation.clone();
    }
   
    currentAnimation = function() {
        var time = (Date.now() - startTime) * 0.001 * speed;
        camera.position.x = Math.cos(time) * radius;
        camera.position.z = Math.sin(time) * radius;
        camera.position.y = height + Math.sin(time * 0.5) * 15;
        camera.lookAt(new THREE.Vector3(0, 20, 0));
        camera.updateMatrix();
       
        if (currentAnimation) {
            requestAnimationFrame(currentAnimation);
        }
    };
    currentAnimation();
}

function stopAnimation() {
    currentAnimation = null;
    // Возвращаем камеру в исходное положение
    if (window.originalCameraPosition) {
        camera.position.copy(window.originalCameraPosition);
        camera.rotation.copy(window.originalCameraRotation);
        camera.updateMatrix();
    }
}

// Новый функционал: Скриншот
function takeScreenshot() {
    try {
        renderer.render(scene, camera);
        var imageData = renderer.domElement.toDataURL('image/png');
       
        var link = document.createElement('a');
        link.href = imageData;
        link.download = 'cnc_screenshot_' + new Date().toISOString().replace(/:/g, '-') + '.png';
        link.click();
       
        updateStatus('СКРИНШОТ СОХРАНЕН', '#00ff00');
        setTimeout(() => updateStatus('СИСТЕМА АКТИВНА', '#00ff00'), 2000);
    } catch (error) {
        updateStatus('ОШИБКА СКРИНШОТА', '#ff4444');
    }
}

// Обновление статус бара
function updateStatus(message, color) {
    var statusBar = document.getElementById('status-bar');
    if (statusBar) {
        statusBar.innerHTML = '<span style="color:' + color + '">■</span> ' + message;
        statusBar.style.color = color;
    }
}

// Обновление времени
function updateTime() {
    var now = new Date();
    var timeDisplay = document.getElementById('time-display');
    var dateDisplay = document.getElementById('date-display');
   
    if (timeDisplay) {
        timeDisplay.textContent = now.toLocaleTimeString();
    }
    if (dateDisplay) {
        dateDisplay.textContent = now.toLocaleDateString();
    }
}

// Обновление координат камеры
// Альтернатива если THREE.Math.radToDeg не работает
function updateCoordinates() {
    var coordDisplay = document.getElementById('coord-display');
    if (coordDisplay && camera) {
        // Ручное преобразование радиан в градусы
        var radToDeg = function(rad) {
            return (rad * (180 / Math.PI) + 360) % 360;
        };
       
        var euler = new THREE.Euler();
        euler.setFromQuaternion(camera.quaternion, 'YXZ');
       
        var pitch = radToDeg(euler.x);
        var yaw = radToDeg(euler.y);
        var roll = radToDeg(euler.z);
       
        // Агрессивное округление
        var x = Math.round(camera.position.x);
        var y = Math.round(camera.position.y);
        var z = Math.round(camera.position.z);
       
        coordDisplay.innerHTML =
            '<div style="margin-bottom: 3px; color: #00cccc;">' +
            'ПОЗИЦИЯ: X: ' + x + ' Y: ' + y + ' Z: ' + z +
            '</div>' +
            '<div style="color: #00ff99;">' +
            'ПОВОРОТ: Pitch: ' + Math.round(pitch) + '° ' +
            'Yaw: ' + Math.round(yaw) + '° ' +
            'Roll: ' + Math.round(roll) + '°' +
            '</div>';
    }
}


// Обновление FPS
function updateFPS() {
    frameCount++;
    var currentTime = performance.now();
   
    if (currentTime - lastTime >= 1000) {
        fps = Math.round((frameCount * 1000) / (currentTime - lastTime));
        frameCount = 0;
        lastTime = currentTime;
       
        var fpsDisplay = document.getElementById('fps-display');
        if (fpsDisplay) {
            fpsDisplay.textContent = 'FPS: ' + fps;
            // Меняем цвет в зависимости от FPS
            if (fps < 30) {
                fpsDisplay.style.color = '#ff4444';
            } else if (fps < 50) {
                fpsDisplay.style.color = '#ff9900';
            } else {
                fpsDisplay.style.color = '#00ff00';
            }
        }
    }
   
    requestAnimationFrame(updateFPS);
}

// Горячие клавиши
function initHotkeys() {
    document.addEventListener('keydown', function(event) {
        switch(event.key.toLowerCase()) {
            case 'a': toggleAnimation(); break;
            case 'n': toggleNightMode(); break;
            case 'p': takeScreenshot(); break;
            case 'r': resetView(); break;
            case 'i': showInfoModal(); break;
            case '1': ScriptSView(); break;
            case '2': ScriptView1(); break;
            case '3': ScriptView2(); break;
            case '4': ScriptView3(); break;
        }
    });
}

// Функция для стилизации аварийной кнопки INFO
function styleEmergencyButton(btn) {
    btn.style.fontSize = '11px';
    btn.style.padding = '8px 12px';
    btn.style.color = '#fff';
    btn.style.background = 'linear-gradient(to bottom, #ff4444, #cc0000)';
    btn.style.border = '2px solid #ff6666';
    btn.style.borderRadius = '1px';
    btn.style.cursor = 'pointer';
    btn.style.transition = 'all 0.2s ease';
    btn.style.fontWeight = 'bold';
    btn.style.textTransform = 'uppercase';
    btn.style.letterSpacing = '0.5px';
    btn.style.textShadow = '0 0 2px rgba(255, 0, 0, 0.8)';
    btn.style.fontFamily = '"Share Tech Mono", "Courier New", monospace';
    btn.style.boxShadow = 'inset 0 0 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3)';
    btn.style.width = '100%';
    btn.style.marginBottom = '2px';

    btn.onmouseenter = function () {
        btn.style.background = 'linear-gradient(to bottom, #ff6666, #ff0000)';
        btn.style.boxShadow = 'inset 0 0 5px rgba(0, 0, 0, 0.3), 0 0 8px rgba(255, 0, 0, 0.4)';
        btn.style.transform = 'scale(1.05)';
    };
   
    btn.onmouseleave = function () {
        btn.style.background = 'linear-gradient(to bottom, #ff4444, #cc0000)';
        btn.style.boxShadow = 'inset 0 0 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3)';
        btn.style.transform = 'scale(1)';
    };
   
    btn.onmousedown = function () {
        btn.style.transform = 'scale(0.95)';
        btn.style.boxShadow = 'inset 0 0 5px rgba(0, 0, 0, 0.6), 0 1px 1px rgba(0, 0, 0, 0.2)';
    };
   
    btn.onmouseup = function () {
        btn.style.transform = 'scale(1.05)';
        btn.style.boxShadow = 'inset 0 0 5px rgba(0, 0, 0, 0.3), 0 0 8px rgba(255, 0, 0, 0.4)';
    };
}

// Стилизация кнопок
function styleCNCButton(btn) {
    btn.style.fontSize = '11px';
    btn.style.padding = '8px 12px';
    btn.style.color = '#00ffff';
    btn.style.background = 'linear-gradient(to bottom, #333, #222)';
    btn.style.border = '2px solid #00cccc';
    btn.style.borderRadius = '1px';
    btn.style.cursor = 'pointer';
    btn.style.transition = 'all 0.2s ease';
    btn.style.fontWeight = 'bold';
    btn.style.textTransform = 'uppercase';
    btn.style.letterSpacing = '0.5px';
    btn.style.textShadow = '0 0 2px rgba(0, 255, 255, 0.8)';
    btn.style.fontFamily = '"Share Tech Mono", "Courier New", monospace';
    btn.style.boxShadow = 'inset 0 0 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3)';
    btn.style.width = '100%';
    btn.style.marginBottom = '2px';

    btn.onmouseenter = function () {
        btn.style.background = 'linear-gradient(to bottom, #00cccc, #008080)';
        btn.style.color = '#000';
        btn.style.textShadow = '0 0 2px rgba(255, 255, 255, 0.8)';
        btn.style.boxShadow = 'inset 0 0 5px rgba(0, 0, 0, 0.3), 0 0 8px rgba(0, 204, 204, 0.4)';
    };
   
    btn.onmouseleave = function () {
        btn.style.background = 'linear-gradient(to bottom, #333, ' +
            '#222)';
        btn.style.color = '#00ffff';
        btn.style.textShadow = '0 0 2px rgba(0, 255, 255, 0.8)';
        btn.style.boxShadow = 'inset 0 0 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3)';
    };
   
    btn.onmousedown = function () {
        btn.style.transform = 'translateY(1px)';
        btn.style.boxShadow = 'inset 0 0 5px rgba(0, 0, 0, 0.6), 0 1px 1px rgba(0, 0, 0, 0.2)';
    };
   
    btn.onmouseup = function () {
        btn.style.transform = 'translateY(0)';
        btn.style.boxShadow = 'inset 0 0 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3)';
    };
}

// Функция для показа модального окна в стиле ЧПУ
function showInfoModal() {
    // Создаем overlay
    var overlay = document.createElement("div");
    overlay.style.position = 'fixed';
    overlay.style.top = '0';
    overlay.style.left = '0';
    overlay.style.width = '100%';
    overlay.style.height = '100%';
    overlay.style.background = 'rgba(0, 0, 0, 0.9)';
    overlay.style.zIndex = '2000';
    overlay.style.display = 'flex';
    overlay.style.justifyContent = 'center';
    overlay.style.alignItems = 'center';
   
    // Создаем модальное окно в стиле ЧПУ дисплея
    var modal = document.createElement("div");
    modal.style.background = 'linear-gradient(145deg, #1a1a1a, #2a2a2a)';
    modal.style.border = '3px solid #00cccc';
    modal.style.borderRadius = '2px';
    modal.style.padding = '25px';
    modal.style.maxWidth = '500px';
    modal.style.width = '80%';
    modal.style.boxShadow = '0 0 30px rgba(0, 204, 204, 0.4), inset 0 0 20px rgba(0, 0, 0, 0.6)';
    modal.style.position = 'relative';
    modal.style.color = '#00ffff';
    modal.style.fontFamily = '"Share Tech Mono", "Courier New", monospace';
    modal.style.textShadow = '0 0 3px rgba(0, 255, 255, 0.7)';

    // Заголовок модального окна
    var title = document.createElement("h2");
    title.textContent = 'СИСТЕМНАЯ ИНФОРМАЦИЯ';
    title.style.color = '#00ff00';
    title.style.marginBottom = '20px';
    title.style.textAlign = 'center';
    title.style.fontSize = '18px';
    title.style.fontWeight = 'bold';
    title.style.textTransform = 'uppercase';
    title.style.letterSpacing = '2px';
    modal.appendChild(title);
   
    // Текст информации
    var infoText = document.createElement("div");
    infoText.innerHTML =
        '<p style="margin-bottom: 12px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">3D-СЦЕНА:</strong> ЦЕХ 058' +
        '</p>' +
        '<p style="margin-bottom: 12px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">РАЗРАБОТЧИК:</strong> ПОНЯТОВ НИКИТА' +
        '</p>' +
        '<p style="margin-bottom: 12px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">ВЕРСИЯ:</strong> 2.0' +
        '</p>' +
        '<p style="margin-bottom: 15px; line-height: 1.5; font-size: 14px; color: #00cccc;">' +
            '<strong style="color: #00ff00;">СТАТУС:</strong> СИСТЕМА АКТИВНА' +
        '</p>';
    modal.appendChild(infoText);
   
    // Контейнер для контактов
    var contactContainer = document.createElement("div");
    contactContainer.style.textAlign = 'center';
    contactContainer.style.marginBottom = '20px';
    contactContainer.style.padding = '12px';
    contactContainer.style.background = 'linear-gradient(145deg, #0d2b2b, #1a4040)';
    contactContainer.style.border = '1px solid #00cccc';
    contactContainer.style.borderRadius = '1px';
    contactContainer.style.boxShadow = 'inset 0 0 10px rgba(0, 0, 0, 0.4)';
   
    var contactTitle = document.createElement("div");
    contactTitle.textContent = 'ТЕХНИЧЕСКАЯ ПОДДЕРЖКА';
    contactTitle.style.color = '#00ff00';
    contactTitle.style.marginBottom = '8px';
    contactTitle.style.fontSize = '12px';
    contactTitle.style.fontWeight = 'bold';
    contactContainer.appendChild(contactTitle);
   
    // Ссылка на email
    var emailLink = document.createElement("a");
    emailLink.href = 'mailto:support@winnum.ru';
    emailLink.textContent = 'support@winnum.ru';
        emailLink.style.color = '#00ffff';
    emailLink.style.textDecoration = 'none';
    emailLink.style.fontWeight = 'bold';
    emailLink.style.fontSize = '14px';
    emailLink.style.padding = '6px 12px';
    emailLink.style.display = 'inline-block';
    emailLink.style.transition = 'all 0.3s ease';
    emailLink.style.border = '1px solid #00cccc';
    emailLink.style.background = 'rgba(0, 204, 204, 0.1)';
   
    emailLink.onmouseenter = function() {
        emailLink.style.background = 'rgba(0, 204, 204, 0.3)';
        emailLink.style.color = '#00ff00';
        emailLink.style.boxShadow = '0 0 10px rgba(0, 204, 204, 0.4)';
    };
   
    emailLink.onmouseleave = function() {
        emailLink.style.background = 'rgba(0, 204, 204, 0.1)';
        emailLink.style.color = '#00ffff';
        emailLink.style.boxShadow = 'none';
    };
   
    contactContainer.appendChild(emailLink);
    modal.appendChild(contactContainer);
   
    // Кнопка закрытия
    var closeButton = document.createElement("button");
    closeButton.textContent = 'ЗАКРЫТЬ [ESC]';
    closeButton.style.background = 'linear-gradient(to bottom, #333, #222)';
    closeButton.style.color = '#00cccc';
    closeButton.style.border = '2px solid #00cccc';
    closeButton.style.padding = '8px 20px';
    closeButton.style.borderRadius = '1px';
    closeButton.style.cursor = 'pointer';
    closeButton.style.fontWeight = 'bold';
    closeButton.style.margin = '0 auto';
    closeButton.style.display = 'block';
    closeButton.style.transition = 'all 0.3s ease';
    closeButton.style.fontFamily = '"Share Tech Mono", "Courier New", monospace';
    closeButton.style.textTransform = 'uppercase';
   
    closeButton.onmouseenter = function() {
        closeButton.style.background = 'linear-gradient(to bottom, #00cccc, #008080)';
        closeButton.style.color = '#000';
    };
   
    closeButton.onmouseleave = function() {
        closeButton.style.background = 'linear-gradient(to bottom, ' +
            '#333, #222)';
        closeButton.style.color = '#00cccc';
    };
   
    closeButton.onclick = function() {
        document.body.removeChild(overlay);
    };
   
    modal.appendChild(closeButton);
    overlay.appendChild(modal);
   
    // Добавляем overlay на страницу
    document.body.appendChild(overlay);
   
    // Закрытие по клику на overlay
    overlay.onclick = function(e) {
        if (e.target === overlay) {
            document.body.removeChild(overlay);
        }
    };
   
    // Закрытие по ESC
    document.addEventListener('keydown', function closeModal(e) {
        if (e.key === 'Escape') {
            document.body.removeChild(overlay);
            document.removeEventListener('keydown', closeModal);
        }
    });
}

 


Hello World!:

- Сообщений не найдено.


Файлы вложений
.zip   ViewButtons (2).zip (Размер: 18.75 KB / Загрузок: 2)
Ответ


Перейти к сообществу:


Пользователи, просматривающие эту тему: 1 Гость(ей)