Мне нужен Node Editor как в Blender только написанные на HTML вообщем я загуглил ничего не нашел, и порасспрашивал ИИ он тоже ничего не нашел, и короче я решил сделать свой Node Editor написанные на канвасе, и вот что у меня получилось:
Node Editor как в Blender
Получилось кастрировано но я сделал чисто тяп ляп на коленке... Можете быть это кому понадобиться!? Получается что я первый кто пытается сделать что-то подобное... Вот моя другая попытка где я попытался сделать нормальную привязанность линий никак эту проблему не удается решить когда хочу от второго добавленного изображения провести линию от квадратика красного к первому добавленному изображению с первый корневом изображением прокатывает, и при перемещения картинки лини привязаны к красному квадратику и следуют за ним, а со второй просто остаются на месте координаты красного квадратика, и я попытался решить эту проблему но у меня ничего не получилось... И я подумал может быть у вас получится сделать что-то либо лучшее? Вот код:
Код:
<html lang="ru"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Добавление изображений с точками и линиями</title><style> #image-container { position: relative; width: 800px; height: 600px; } .image { position: absolute; cursor: move; border: none; z-index: 0; /*Убедитесь, что изображения находятся за точками и линиями */ } .point { position: absolute; width: 20px; height: 20px; border: 2px solid black; border-radius: 50%; cursor: pointer; z-index: 1; /* Убедитесь, что точки находятся над изображениями и линиями */ box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); /* Добавьте тень, чтобы сделать точки более заметными */ } .red-point { background-color: red; } .green-point { background-color: green; } .blue-point { background-color: blue; } .line { position: absolute; border: 2px solid black; } .image .red-point { left: 10px; top: 10px; } .image .green-point { left: 50px; top: 50px; } .image .blue-point { left: 80px; top: 80px; } </style></head><body><input type="text" id="image-url" placeholder="Введите URL изображения"><button id="add-button">Добавить</button><div id="image-container"></div><script> const imageUrlInput = document.getElementById('image-url'); const addButton = document.getElementById('add-button'); const imageContainer = document.getElementById('image-container'); let images = []; let points = []; function addImage() { const imgUrl = imageUrlInput.value.trim(); if (!imgUrl) return; const img = new Image(); img.src = imgUrl; img.className = 'image'; img.lines = []; //Добавьте по три точки к каждому изображению const redPoint = createPoint('red'); const greenPoint = createPoint('green'); const bluePoint = createPoint('blue'); img.appendChild(redPoint); img.appendChild(greenPoint); img.appendChild(bluePoint); console.log('Adding image:', img); img.onload = () => { console.log('Image loaded:', img); imageContainer.appendChild(img); images.push(img); // Добавьте прослушиватели событий для изображения и его точек img.onmousedown = (e) => { const shiftX = e.clientX - img.getBoundingClientRect().left; const shiftY = e.clientY - img.getBoundingClientRect().top; img.style.position = 'absolute'; img.style.zIndex = 1000; document.body.appendChild(img); document.body.onmousemove = (e) => { const left = e.pageX - shiftX; const top = e.pageY - shiftY; img.style.left = `${left}px`; img.style.top = `${top}px`; // Обновите положение линий, соединенных с этим изображением updateLines(img); }; img.onmouseup = () => { document.body.onmousemove = null; img.onmouseup = null; }; }; const imgPoints = img.getElementsByClassName('point'); console.log('Points:', imgPoints); for (const point of imgPoints) { point.onmousedown = (e) => { const shiftX = e.clientX - point.getBoundingClientRect().left; const shiftY = e.clientY - point.getBoundingClientRect().top; point.style.position = 'absolute'; point.style.zIndex = 1000; document.body.appendChild(point); document.body.onmousemove = (e) => { const left = e.pageX - shiftX; const top = e.pageY - shiftY; point.style.left = `${left}px`; point.style.top = `${top}px`; // Обновите положение линий, соединенных с этой точкой updateLines(point); }; point.onmouseup = () => { document.body.onmousemove = null; point.onmouseup = null; }; }; point.onmousedown = (e) => { // Позволяет создать линию между этой точкой и другой точкой document.body.onmousemove = (e) => { let closestPoint = null; let closestDistance = Infinity; for (const otherPoint of points) { if (otherPoint === point) continue; const distance = Math.hypot(e.clientX - otherPoint.getBoundingClientRect().left, e.clientY - otherPoint.getBoundingClientRect().top); if (distance < closestDistance) { closestDistance = distance; closestPoint = otherPoint; } } if (closestPoint && closestDistance < 20) { connectPoints(point, closestPoint); } }; point.onmouseup = () => { document.body.onmousemove = null; point.onmouseup = null; }; }; points.push(point); } }; } function createPoint(color) { const point = document.createElement('div'); point.className = `point ${color}-point`; point.style.left = '10px'; point.style.top = '10px'; console.log(`Created point:`, point); return point; } function updateLines(ref) { for (const line of ref.lines) { const otherPoint = line.otherPoint(ref); const left = (ref.offsetLeft + otherPoint.offsetLeft) / 2; const top = (ref.offsetTop + otherPoint.offsetTop) / 2; line.style.left = `${left}px`; line.style.top = `${top}px`; } } function connectPoints(point1, point2) { const line = document.createElement('div'); line.className = 'line'; line.style.left = `${(point1.offsetLeft + point2.offsetLeft) / 2}px`; line.style.top = `${(point1.offsetTop + point2.offsetTop) / 2}px`; line.style.width = `${Math.abs(point1.offsetLeft - point2.offsetLeft)}px`; line.style.height = `${Math.abs(point1.offsetTop - point2.offsetTop)}px`; point1.lines.push(line); point2.lines.push(line); line.otherPoint = (point) => point === point1 ? point2 : point1; document.body.appendChild(line); return line; } addButton.addEventListener('click', addImage); imageUrlInput.addEventListener('keyup', (e) => { if (e.key === 'Enter') { addImage(); } }); </script></body></html>
Можете посмотреть разжатую версию
ВОТ.