В приложении Цифровой двойник довольно часто используются кнопки. Я решил создать вторую версию панели с кнопками для 3D в стиле ЧПУ-станка. Здесь будет представлен расширенный функционал.
В данном посте я хотел бы рассказать о том как добавить их себе в 3D-сцену и настроить. Они смогут помочь стилизовать сцену и улучшить восприятие.
1. Скачать файл ViewButtons (во вложении) и импортировать себе в сцену (Файл - Импорт).
![[Изображение: 5db0a2ab-2729-4c02-b9da-12129cf5eba4.png]](https://imglink.io/i/5db0a2ab-2729-4c02-b9da-12129cf5eba4.png)
2. Если мы начнём воспроизведение сцены они появятся в правом нижнем углу. Здесь можно увидеть название цеха, индикатор и 9 кнопок: 4 кнопки с видами, Автооблёт, Ночной режим, Скриншот, Сброс кнопка ИНФО. У каждой кнопки есть hotkey и подписан в скобках.
Каждая кнопка с видом при нажатии будет перемещать камеру в заданное место.
При Автооблёте камера будет крутиться вокруг сцены.
Ночной режим выключает освещение на сцене и изменяет её в тёмно-синие оттенки.
Скриншот делает снимок экрана, при этом панель с кнопками не будет на нём отображена.
Сброс отменяет действия и/или возвращает камеру на начальную позицию.
Также снизу есть показатель FPS, текущее время и дата.
![[Изображение: 735e2d8f-bdfe-4376-9bf3-4b924b7a9ecf.png]](https://imglink.io/i/735e2d8f-bdfe-4376-9bf3-4b924b7a9ecf.png)
3. Кнопка ИНФО при нажатии откроет всплывающее окно с системной информацией и технической поддержкой. При нажатии на кнопку support@winnum.ru пользователя будет переносить в почту и начинать письмо в support.
![[Изображение: 4b433863-0d38-474c-8b07-124fee8d7174.png]](https://imglink.io/i/4b433863-0d38-474c-8b07-124fee8d7174.png)
4. Внутри ViewButtons в Объект - Действия будет лежать код самой панели.
![[Изображение: 169d5b16-6e24-4ce7-8048-f329c056a8bc.png]](https://imglink.io/i/169d5b16-6e24-4ce7-8048-f329c056a8bc.png)
5. Чтобы настроить кнопки с видами нужно изменить логику для них в коде. (9-47 строки)
6. Чтобы изменить названия кнопок видов поменять этот код. (158-164 строки)
7. Чтобы изменить название цеха нужно поменять этот код. (131-132 строки)
8. Чтобы изменить Автооблёт нужно поменять этот код. (333-337 строки)
9. Чтобы изменить Системную информацию в сплывающем окне нужно поменять этот код. (618-633 строки)
Полный код:
Hello World!:
- Сообщений не найдено.
В данном посте я хотел бы рассказать о том как добавить их себе в 3D-сцену и настроить. Они смогут помочь стилизовать сцену и улучшить восприятие.
1. Скачать файл ViewButtons (во вложении) и импортировать себе в сцену (Файл - Импорт).
![[Изображение: 5db0a2ab-2729-4c02-b9da-12129cf5eba4.png]](https://imglink.io/i/5db0a2ab-2729-4c02-b9da-12129cf5eba4.png)
2. Если мы начнём воспроизведение сцены они появятся в правом нижнем углу. Здесь можно увидеть название цеха, индикатор и 9 кнопок: 4 кнопки с видами, Автооблёт, Ночной режим, Скриншот, Сброс кнопка ИНФО. У каждой кнопки есть hotkey и подписан в скобках.
Каждая кнопка с видом при нажатии будет перемещать камеру в заданное место.
При Автооблёте камера будет крутиться вокруг сцены.
Ночной режим выключает освещение на сцене и изменяет её в тёмно-синие оттенки.
Скриншот делает снимок экрана, при этом панель с кнопками не будет на нём отображена.
Сброс отменяет действия и/или возвращает камеру на начальную позицию.
Также снизу есть показатель FPS, текущее время и дата.
![[Изображение: 735e2d8f-bdfe-4376-9bf3-4b924b7a9ecf.png]](https://imglink.io/i/735e2d8f-bdfe-4376-9bf3-4b924b7a9ecf.png)
3. Кнопка ИНФО при нажатии откроет всплывающее окно с системной информацией и технической поддержкой. При нажатии на кнопку support@winnum.ru пользователя будет переносить в почту и начинать письмо в support.
![[Изображение: 4b433863-0d38-474c-8b07-124fee8d7174.png]](https://imglink.io/i/4b433863-0d38-474c-8b07-124fee8d7174.png)
4. Внутри ViewButtons в Объект - Действия будет лежать код самой панели.
![[Изображение: 169d5b16-6e24-4ce7-8048-f329c056a8bc.png]](https://imglink.io/i/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');
}Код:
// Создаем кнопки видов
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 },
];Код:
var header = document.createElement("div");
header.innerText = 'ЦЕХ 058';Код:
function startAnimation() {
var startTime = Date.now();
var radius = 80;
var height = 60;
var speed = 0.3;Код:
// Текст информации
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!:
- Сообщений не найдено.

