Voltar
ESG que roda - Gestão de Sucata
×
Agendar Retirada de Sucata
Estoque de Peças
Balança de Sucata
0.00
toneladas
Peças Recuperadas
Peças Novas
Peças em Trânsito
Peças Vendidas
Peças em Manutenção
Peças Descartadas
const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; // Criar animações sutis de tráfego de dados nas linhas blockchain function createBlockchainAnimations() { const svgNS = "http://www.w3.org/2000/svg"; const svg = document.createElementNS(svgNS, "svg"); svg.setAttribute("width", "100%"); svg.setAttribute("height", "100%"); // Definir número de nós e linhas - aumentado para maior densidade const numNodes = 120; // Aumentado para 120 para muito mais densidade const nodes = []; // Cores para os nós (vermelho-azul) const nodeColors = ['rgba(236, 0, 137, 0.6)', 'rgba(212, 0, 106, 0.6)', 'rgba(183, 0, 76, 0.6)', 'rgba(154, 0, 46, 0.6)', 'rgba(10, 0, 100, 0.6)', 'rgba(26, 26, 138, 0.6)', 'rgba(0, 255, 255, 0.6)', 'rgba(128, 0, 255, 0.6)']; // Adicionar definições para animações const defs = document.createElementNS(svgNS, "defs"); // Criar filtro de brilho para nós const nodeGlow = document.createElementNS(svgNS, "filter"); nodeGlow.setAttribute("id", "nodeGlow"); const feGaussianBlur = document.createElementNS(svgNS, "feGaussianBlur"); feGaussianBlur.setAttribute("stdDeviation", "1"); feGaussianBlur.setAttribute("result", "coloredBlur"); const feMerge = document.createElementNS(svgNS, "feMerge"); const feMergeNode1 = document.createElementNS(svgNS, "feMergeNode"); feMergeNode1.setAttribute("in", "coloredBlur"); const feMergeNode2 = document.createElementNS(svgNS, "feMergeNode"); feMergeNode2.setAttribute("in", "SourceGraphic"); feMerge.appendChild(feMergeNode1); feMerge.appendChild(feMergeNode2); nodeGlow.appendChild(feGaussianBlur); nodeGlow.appendChild(feMerge); defs.appendChild(nodeGlow); svg.appendChild(defs); // Criar nós com distribuição mais aleatória para evitar padrões circulares for (let i = 0; i < numNodes; i++) { // Posição aleatória com distribuição mais uniforme let x, y; // Evitar concentração circular const angle = Math.random() * Math.PI * 2; const radius = Math.random() * Math.min(viewportWidth, viewportHeight) * 0.8; if (i % 5 === 0) { // Distribuição radial x = viewportWidth / 2 + Math.cos(angle) * radius; y = viewportHeight / 2 + Math.sin(angle) * radius; } else if (i % 5 === 1) { // Distribuição em grade x = (Math.random() * 0.8 + 0.1) * viewportWidth; y = (Math.random() * 0.8 + 0.1) * viewportHeight; } else if (i % 5 === 2) { // Distribuição em linhas diagonais const diag = Math.random(); x = diag * viewportWidth; y = (i % 2 === 0) ? diag * viewportHeight : (1 - diag) * viewportHeight; } else if (i % 5 === 3) { // Distribuição em ondas horizontais x = Math.random() * viewportWidth; const wave = Math.sin(x / viewportWidth * Math.PI * 4); y = (viewportHeight / 2) + wave * (viewportHeight / 4); } else { // Distribuição em clusters const clusterX = (Math.random() < 0.5) ? viewportWidth * 0.25 : viewportWidth * 0.75; const clusterY = (Math.random() < 0.5) ? viewportHeight * 0.25 : viewportHeight * 0.75; x = clusterX + (Math.random() - 0.5) * viewportWidth * 0.3; y = clusterY + (Math.random() - 0.5) * viewportHeight * 0.3; } // Cor aleatória const color = nodeColors[Math.floor(Math.random() * nodeColors.length)]; // Criar nó (invisível, apenas para referência de conexão) const node = document.createElementNS(svgNS, "circle"); node.setAttribute("cx", x); node.setAttribute("cy", y); node.setAttribute("r", 0.5); node.setAttribute("fill", "transparent"); svg.appendChild(node); nodes.push({ x, y, element: node, color }); } // Conectar nós com padrões mais orgânicos e variados for (let i = 0; i < nodes.length; i++) { const node = nodes[i]; // Número variável de conexões por nó para evitar padrões regulares const numConnections = Math.floor(Math.random() * 4) + 1; // Aumentado para mais conexões // Conectar a nós próximos e alguns distantes para criar mais variedade for (let j = 0; j < nodes.length; j++) { if (i === j) continue; const otherNode = nodes[j]; const dx = node.x - otherNode.x; const dy = node.y - otherNode.y; const distance = Math.sqrt(dx * dx + dy * dy); // Conectar se estiver próximo ou aleatoriamente para conexões de longa distância if (distance < 180 || (Math.random() < 0.08 && distance < 500)) { // Aumentado para mais conexões // Criar grupo para a linha e os pontos de animação const group = document.createElementNS(svgNS, "g"); // Linha base com curvatura aleatória para mais organicidade const path = document.createElementNS(svgNS, "path"); // Adicionar curvatura aleatória para algumas linhas let pathData; if (Math.random() < 0.4) { // Aumentado para mais curvas // Linha curva const cpx = (node.x + otherNode.x) / 2 + (Math.random() - 0.5) * 120; const cpy = (node.y + otherNode.y) / 2 + (Math.random() - 0.5) * 120; pathData = `M${node.x},${node.y} Q${cpx},${cpy} ${otherNode.x},${otherNode.y}`; } else { // Linha reta pathData = `M${node.x},${node.y} L${otherNode.x},${otherNode.y}`; } path.setAttribute("d", pathData); // Gradiente entre as cores dos nós const gradientId = `gradient-${i}-${j}`; const gradient = document.createElementNS(svgNS, "linearGradient"); gradient.setAttribute("id", gradientId); gradient.setAttribute("x1", "0%"); gradient.setAttribute("y1", "0%"); gradient.setAttribute("x2", "100%"); gradient.setAttribute("y2", "100%"); const stop1 = document.createElementNS(svgNS, "stop"); stop1.setAttribute("offset", "0%"); stop1.setAttribute("stop-color", node.color); const stop2 = document.createElementNS(svgNS, "stop"); stop2.setAttribute("offset", "100%"); stop2.setAttribute("stop-color", otherNode.color); gradient.appendChild(stop1); gradient.appendChild(stop2); defs.appendChild(gradient); path.setAttribute("stroke", `url(#${gradientId})`); path.setAttribute("stroke-width", "0.5"); path.setAttribute("stroke-opacity", "0.3"); path.setAttribute("fill", "none"); group.appendChild(path); // Adicionar pontos de dados animados na linha const numDataPoints = Math.floor(Math.random() * 3) + 1; // 1-3 pontos por linha for (let k = 0; k < numDataPoints; k++) { const dataPoint = document.createElementNS(svgNS, "circle"); // Posição inicial aleatória ao longo da linha const position = Math.random(); // Calcular posição ao longo da linha let px, py; if (pathData.includes('Q')) { // Para linhas curvas, calcular posição ao longo da curva quadrática const t = position; const t1 = 1 - t; const cpxMatch = pathData.match(/Q([\d.-]+),([\d.-]+)/); const cpx = parseFloat(cpxMatch[1]); const cpy = parseFloat(cpxMatch[2]); px = t1 * t1 * node.x + 2 * t1 * t * cpx + t * t * otherNode.x; py = t1 * t1 * node.y + 2 * t1 * t * cpy + t * t * otherNode.y; } else { // Para linhas retas, interpolação linear px = node.x + (otherNode.x - node.x) * position; py = node.y + (otherNode.y - node.y) * position; } dataPoint.setAttribute("cx", px); dataPoint.setAttribute("cy", py); dataPoint.setAttribute("r", 1.5); // Cor aleatória entre as cores dos nós const dataPointColor = Math.random() < 0.5 ? node.color : otherNode.color; dataPoint.setAttribute("fill", dataPointColor); // Adicionar animação de movimento const animate = document.createElementNS(svgNS, "animate"); animate.setAttribute("attributeName", "opacity"); animate.setAttribute("values", "0.2;0.8;0.2"); // Duração e atraso aleatórios para variedade const duration = 2 + Math.random() * 3; // 2-5 segundos const delay = Math.random() * 2; // 0-2 segundos de atraso animate.setAttribute("dur", `${duration}s`); animate.setAttribute("begin", `${delay}s`); animate.setAttribute("repeatCount", "indefinite"); dataPoint.appendChild(animate); // Adicionar animação de movimento ao longo da linha const animateMotion = document.createElementNS(svgNS, "animateMotion"); animateMotion.setAttribute("path", pathData); // Duração e atraso aleatórios para variedade const motionDuration = 10 + Math.random() * 20; // 10-30 segundos const motionDelay = Math.random() * 5; // 0-5 segundos de atraso animateMotion.setAttribute("dur", `${motionDuration}s`); animateMotion.setAttribute("begin", `${motionDelay}s`); animateMotion.setAttribute("repeatCount", "indefinite"); // Direção aleatória if (Math.random() < 0.5) { animateMotion.setAttribute("keyPoints", "1;0"); animateMotion.setAttribute("keyTimes", "0;1"); animateMotion.setAttribute("calcMode", "linear"); } dataPoint.appendChild(animateMotion); group.appendChild(dataPoint); } svg.appendChild(group); } } } blockchainOverlay.appendChild(svg); } // Criar nós do fluxograma function createFluxogramaNodes() { // Nó central - BidChain const nodeCentral = document.createElement('div'); nodeCentral.className = 'node node-central'; nodeCentral.style.left = 'calc(50% - 20px)'; nodeCentral.style.top = 'calc(50% - 20px)'; const nodeGlowCentral = document.createElement('div'); nodeGlowCentral.className = 'node-glow'; nodeCentral.appendChild(nodeGlowCentral); const labelCentral = document.createElement('div'); labelCentral.className = 'node-label'; labelCentral.textContent = 'BidChain'; labelCentral.style.top = '45px'; nodeCentral.appendChild(labelCentral); fluxogramaContainer.appendChild(nodeCentral); // Nós secundários const nodesSecondaryData = [ { name: 'Jurídico', x: -180, y: -120 }, { name: 'Logística', x: -180, y: 120 }, { name: 'Localização', x: 180, y: -120 }, { name: 'Leilão', x: 180, y: 120, link: '../leiloes/index.html' } ]; nodesSecondaryData.forEach(nodeData => { const node = document.createElement('div'); node.className = 'node node-secondary'; node.style.left = `calc(50% + ${nodeData.x}px)`; node.style.top = `calc(50% + ${nodeData.y}px)`; const nodeGlow = document.createElement('div'); nodeGlow.className = 'node-glow'; node.appendChild(nodeGlow); const label = document.createElement('div'); label.className = 'node-label'; label.textContent = nodeData.name; // Posicionar o label com base na posição do nó if (nodeData.y < 0) { label.style.bottom = '30px'; } else { label.style.top = '30px'; } if (nodeData.x < 0) { label.style.right = '15px'; } else { label.style.left = '15px'; } node.appendChild(label); // Adicionar link se especificado if (nodeData.link) { node.style.cursor = 'pointer'; node.addEventListener('click', function() { window.location.href = nodeData.link; }); } // Adicionar link específico para o nó Jurídico if (nodeData.name === 'Jurídico') { node.style.cursor = 'pointer'; node.addEventListener('click', function() { window.location.href = '../juridico/index.html'; }); } fluxogramaContainer.appendChild(node); }); // Nós terciários const nodesTertiaryData = [ { name: 'Veri.Data', x: -250, y: -30 }, { name: 'Veri.Flow', x: 250, y: -30 }, { name: 'Pátios', x: 0, y: 200, link: '../patios/index.html' }, { name: 'DETRAN\'s', x: 0, y: -150, link: '../detrans/index.html' } ]; nodesTertiaryData.forEach(nodeData => { const node = document.createElement('div'); node.className = 'node node-tertiary'; node.style.left = `calc(50% + ${nodeData.x}px)`; node.style.top = `calc(50% + ${nodeData.y}px)`; const nodeGlow = document.createElement('div'); nodeGlow.className = 'node-glow'; node.appendChild(nodeGlow); const label = document.createElement('div'); label.className = 'node-label'; label.textContent = nodeData.name; // Posicionar o label com base na posição do nó if (nodeData.y < 0) { label.style.bottom = '25px'; } else { label.style.top = '25px'; } if (nodeData.x < 0) { label.style.right = '10px'; } else if (nodeData.x > 0) { label.style.left = '10px'; } else { label.style.left = '-25px'; } node.appendChild(label); // Adicionar link se especificado if (nodeData.link) { node.style.cursor = 'pointer'; node.addEventListener('click', function() { window.location.href = nodeData.link; }); } fluxogramaContainer.appendChild(node); }); // Nó BidBank com cor mais rosada const nodeBidBank = document.createElement('div'); nodeBidBank.className = 'node node-secondary bidbank-node'; nodeBidBank.style.left = 'calc(50% + 0px)'; nodeBidBank.style.top = 'calc(50% - 200px)'; const nodeGlowBidBank = document.createElement('div'); nodeGlowBidBank.className = 'node-glow'; nodeBidBank.appendChild(nodeGlowBidBank); const labelBidBank = document.createElement('div'); labelBidBank.className = 'node-label'; labelBidBank.textContent = 'BidBank'; labelBidBank.style.bottom = '30px'; labelBidBank.style.left = '-25px'; nodeBidBank.appendChild(labelBidBank); // Adicionar link para a página BidBank nodeBidBank.style.cursor = 'pointer'; nodeBidBank.addEventListener('click', function() { window.location.href = '../bidbank/index.html'; }); fluxogramaContainer.appendChild(nodeBidBank); } // Inicializar createBlockchainAnimations(); createFluxogramaNodes(); // Adicionar conexões entre os nós function createConnections() { const nodes = document.querySelectorAll('.node'); const nodeArray = Array.from(nodes); // Criar conexões entre nós próximos for (let i = 0; i < nodeArray.length; i++) { const node1 = nodeArray[i]; const node1Rect = node1.getBoundingClientRect(); const node1X = node1Rect.left + node1Rect.width / 2; const node1Y = node1Rect.top + node1Rect.height / 2; for (let j = i + 1; j < nodeArray.length; j++) { const node2 = nodeArray[j]; const node2Rect = node2.getBoundingClientRect(); const node2X = node2Rect.left + node2Rect.width / 2; const node2Y = node2Rect.top + node2Rect.height / 2; // Calcular distância const dx = node2X - node1X; const dy = node2Y - node1Y; const distance = Math.sqrt(dx * dx + dy * dy); // Conectar se estiver dentro de um limite de distância if (distance < 300) { const connectionContainer = document.createElement('div'); connectionContainer.className = 'connection-container'; // Criar segmentos de conexão const numSegments = Math.floor(distance / 30) + 1; for (let k = 0; k < numSegments; k++) { const segment = document.createElement('div'); segment.className = 'connection-segment'; // Posição inicial do segmento const startX = node1X + (dx * k / numSegments); const startY = node1Y + (dy * k / numSegments); // Comprimento e ângulo do segmento const segmentLength = distance / numSegments; const angle = Math.atan2(dy, dx); segment.style.width = `${segmentLength}px`; segment.style.left = `${startX}px`; segment.style.top = `${startY}px`; segment.style.transform = `rotate(${angle}rad)`; // Adicionar variação de opacidade para efeito fragmentado segment.style.opacity = 0.2 + Math.random() * 0.3; connectionContainer.appendChild(segment); } // Adicionar pontos de dados animados const numDataPoints = Math.floor(Math.random() * 3) + 1; for (let k = 0; k < numDataPoints; k++) { const dataPoint = document.createElement('div'); dataPoint.className = 'data-point'; // Posição inicial aleatória ao longo da linha const position = Math.random(); const dataX = node1X + dx * position; const dataY = node1Y + dy * position; dataPoint.style.left = `${dataX}px`; dataPoint.style.top = `${dataY}px`; // Animação CSS dataPoint.style.animation = `pulseGlow ${2 + Math.random() * 3}s infinite alternate ${Math.random() * 2}s`; connectionContainer.appendChild(dataPoint); } fluxogramaContainer.appendChild(connectionContainer); } } } } // Executar após um pequeno atraso para garantir que os nós estejam renderizados setTimeout(createConnections, 500); // Ajustar ao redimensionar a janela window.addEventListener('resize', function() { // Limpar e recriar blockchainOverlay.innerHTML = ''; fluxogramaContainer.innerHTML = ''; createBlockchainAnimations(); createFluxogramaNodes(); setTimeout(createConnections, 500); }); });