D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
www
/
html
/
crsys_ant
/
Filename :
testeimagemJSVersao3 _com_input_saia_Correto.php
back
Copy
<!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <title>Gerador de Imagem</title> <style> /* Container flex para alinhar canvas e input lado a lado */ #HsaiaDir { width: 36px; text-align: center; } /* garante que o wrapper se posicione relativo ao canvas */ #canvasWrapper { position: relative !important;/* referência para o input absoluto */ } #inputSaiaDirWrapper { position: absolute !important; top: 200px !important; /* fixo */ left: calc(100% + 10px)!important; /* à direita do canvas */ display: flex !important; align-items: center !important; gap: 6px !important; z-index: 2147483647!important; pointer-events: auto !important; } body { font-family: Arial, sans-serif; padding: 20px; } .linha-campos { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; margin-bottom: 15px; } .campo-inline { display: flex; align-items: center; gap: 5px; } .campo-inline label { white-space: nowrap; } input[type="text"], input[type="number"], select { padding: 4px 6px; width: 100px; } .preview { display: inline-block; background: #f4f4f4; padding: 4px 8px; border: 1px solid #ccc; } canvas { display: block; } </style> </head> <body> <h1>Gerador de Imagem com Saia e Frontões - JS</h1> <form id="formImagem"> <!-- Linha 1: cor, largura, altura --> <div class="linha-campos"> <div class="campo-inline"> <label for="cor">Cor (hex):</label> <input type="text" id="cor" value="#4169e1" required> </div> <div class="campo-inline"> <label for="largura">Largura:</label> <input type="number" id="largura" value="300" min="5" required> </div> <div class="campo-inline"> <label for="altura">Altura:</label> <input type="number" id="altura" value="16" min="5" required> </div> </div> <!-- Linha 2: saias --> <div class="linha-campos"> <div class="campo-inline"> <label for="saiaEsq">Saia à esquerda</label> <input type="checkbox" id="saiaEsq" checked> </div> <div class="campo-inline"> <label for="saiaDir">Saia à direita</label> <input type="checkbox" id="saiaDir" checked> </div> </div> <!-- Linha 3: frontões --> <div class="linha-campos"> <div class="campo-inline"> <label for="fronEsq">Frontão à esquerda</label> <input type="checkbox" id="fronEsq"> </div> <div class="campo-inline"> <label for="fronDir">Frontão à direita</label> <input type="checkbox" id="fronDir"> </div> </div> <!-- Linha 4: meia esquadria + tampo duplo --> <div class="linha-campos"> <div class="campo-inline"> <label for="meiaesquad">Meia esquadria (esq/dir)</label> <input type="checkbox" id="meiaesquad" checked> </div> <div class="campo-inline"> <label for="tpo_duplo">Tampo duplo</label> <input type="checkbox" id="tpo_duplo"> </div> </div> </form> <!-- Preview --> <div class="preview"> <!-- <h4>Corte AA</h4> --> <div id="canvasWrapper"> <canvas id="canvasPreview"></canvas> <!-- Input lateral opcional para a Saia Direita --> <div id="inputSaiaDirWrapper"> <label for="HsaiaDir">H</label> <input id="HsaiaDir" type="text" placeholder="auto"> </div> </div> </div> <script> // Utilitário de parse seguro const n = (id, min, def) => { const v = Number(document.getElementById(id).value); return Number.isFinite(v) ? Math.max(min, v) : def; }; // HEX -> RGB (#RGB e #RRGGBB) function hexToRgb(hex){ let h = hex.replace(/^#/, '').toLowerCase(); if (/^[0-9a-f]{3}$/.test(h)) h = h.split('').map(c => c + c).join(''); if (!/^[0-9a-f]{6}$/.test(h)) return [65,105,225]; // royalblue fallback return [parseInt(h.slice(0,2),16), parseInt(h.slice(2,4),16), parseInt(h.slice(4,6),16)]; } function gerarImagem(){ const largura = 300; const altura = 16; // espessura do perfil const saiaEsq = document.getElementById('saiaEsq').checked; const saiaDir = document.getElementById('saiaDir').checked; const fronEsq = document.getElementById('fronEsq').checked; const fronDir = document.getElementById('fronDir').checked; const meia = document.getElementById('meiaesquad').checked; const tpoDuplo = document.getElementById('tpo_duplo').checked; // const corHexRaw = document.getElementById('cor').value.trim(); const corHexRaw = '#4169e1'; // Mostrar/ocultar input lateral da direita // document.getElementById('inputSaiaDirWrapper').style.display = saiaDir ? 'flex' : 'none'; // Mostrar/ocultar input lateral da direita se qualquer saia estiver ativa document.getElementById('inputSaiaDirWrapper').style.display = (saiaEsq || saiaDir) ? 'flex' : 'none'; const [r,g,b] = hexToRgb(corHexRaw); const cor = `rgb(${r},${g},${b})`; const esp = 2; // Dimensões auxiliares const wSaiaEsq = saiaEsq ? altura : 0; const hSaiaEsq = saiaEsq ? Math.floor(largura/3) : 0; const wSaiaDir = saiaDir ? altura : 0; const hSaiaDir = saiaDir ? Math.floor(largura/3) : 0; const wFronEsq = fronEsq ? Math.floor(altura*0.9) : 0; const hFronEsq = fronEsq ? Math.floor(largura/3) : 0; const wFronDir = fronDir ? Math.floor(altura*0.9) : 0; const hFronDir = fronDir ? Math.floor(largura/3) : 0; const extraTopo = Math.max(hFronEsq, hFronDir); const extraBaixo = Math.max(hSaiaEsq, hSaiaDir); const extraEsq = wSaiaEsq + (fronEsq ? altura : 0); const extraDir = wSaiaDir + (fronDir ? altura : 0); const alturaTampo = extraTopo + altura + extraBaixo + 2*esp; const espacoEntre = Math.floor(largura/3) + altura; const alturaTotal = alturaTampo + (tpoDuplo ? espacoEntre + alturaTampo : 0); // Canvas const canvas = document.getElementById('canvasPreview'); canvas.width = largura + extraEsq + extraDir + 2*esp; // canvas.height = alturaTotal; canvas.height = 300; const ctx = canvas.getContext('2d'); // Estilo ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.lineWidth = esp; ctx.strokeStyle = cor; ctx.lineJoin = 'miter'; ctx.lineCap = 'butt'; const origX = esp + extraEsq; // Função que desenha um "tampo" (barra superior + saias/frontões quando includeExtras=true) function desenharTampo(offsetY, includeExtras = true){ const origY = esp + extraTopo + offsetY; const rightX = origX + largura; const baseY = origY + altura; // --- Saia ESQUERDA --- if (includeExtras && saiaEsq){ const xL = origX - wSaiaEsq + altura; // externo da saia const xR = origX + altura; // interno (encosta no corpo) const y1 = origY + altura; // começa abaixo da barra const y2 = y1 + hSaiaEsq; if (meia){ // bordas da saia (só abaixo da barra) ctx.beginPath(); ctx.moveTo(xL, y1); ctx.lineTo(xL, y2); ctx.stroke(); // linha horizontal inferior removida intencionalmente ctx.beginPath(); ctx.moveTo(xR, y1); ctx.lineTo(xR, y2); ctx.stroke(); // diagonal e risquinhos de fechamento (canto esquerdo) ctx.beginPath(); ctx.moveTo(origX, origY); ctx.lineTo(origX + altura, origY + altura); ctx.stroke(); ctx.beginPath(); ctx.moveTo(origX, origY); ctx.lineTo(origX + altura, origY); ctx.stroke(); ctx.beginPath(); ctx.moveTo(origX, origY); ctx.lineTo(origX, origY + altura); ctx.stroke(); // quando NÃO há tampo duplo, completar a linha horizontal inferior da saia esquerda if (!tpoDuplo){ ctx.beginPath(); ctx.moveTo(xL, y2); ctx.lineTo(xR, y2); ctx.stroke(); } } else { ctx.strokeRect(xL, y1, xR - xL, hSaiaEsq); } } // --- Retângulo principal (barra superior), recuando nos cantos com meia-esquadria --- const topStart = (saiaEsq && meia) ? (origX + altura) : origX; const topEnd = (saiaDir && meia) ? (rightX - altura) : rightX; const baseStart = topStart; const baseEnd = topEnd; // Topo ctx.beginPath(); ctx.moveTo(topStart, origY); ctx.lineTo(topEnd, origY); ctx.stroke(); // Direita (somente se NÃO houver meia-esquadria direita) if (!(saiaDir && meia)){ ctx.beginPath(); ctx.moveTo(rightX, origY); ctx.lineTo(rightX, baseY); ctx.stroke(); } // Base ctx.beginPath(); ctx.moveTo(baseStart, baseY); ctx.lineTo(baseEnd, baseY); ctx.stroke(); // Esquerda (parte visível do corpo) ctx.beginPath(); const leftTopY = (saiaEsq && meia) ? (origY + altura) : origY; ctx.moveTo(origX, leftTopY); ctx.lineTo(origX, baseY); ctx.stroke(); // --- Saia DIREITA --- if (includeExtras && saiaDir){ const xL = rightX - altura; // interno (encosta no corpo) const xR = rightX; // externo const y1 = origY + altura; // começa abaixo da barra const y2 = y1 + hSaiaDir; if (meia){ // bordas da saia (só abaixo da barra) ctx.beginPath(); ctx.moveTo(xR, y1); ctx.lineTo(xR, y2); ctx.stroke(); // linha horizontal inferior removida intencionalmente ctx.beginPath(); ctx.moveTo(xL, y1); ctx.lineTo(xL, y2); ctx.stroke(); // diagonal e risquinhos de fechamento (canto direito) ctx.beginPath(); ctx.moveTo(rightX, origY); ctx.lineTo(rightX - altura, origY + altura); ctx.stroke(); ctx.beginPath(); ctx.moveTo(rightX - altura, origY); ctx.lineTo(rightX, origY); ctx.stroke(); ctx.beginPath(); ctx.moveTo(rightX, origY); ctx.lineTo(rightX, origY + altura); ctx.stroke(); // quando NÃO há tampo duplo, completar a linha horizontal inferior da saia direita if (!tpoDuplo){ ctx.beginPath(); ctx.moveTo(xL, y2); ctx.lineTo(xR, y2); ctx.stroke(); } } else { ctx.strokeRect(xL, y1, altura, hSaiaDir); } } // --- Frontões (opcionais) --- if (includeExtras && fronEsq){ ctx.strokeRect(origX, origY - Math.floor(largura/3), Math.floor(altura*0.9), Math.floor(largura/3)); } if (includeExtras && fronDir){ ctx.strokeRect(rightX - Math.floor(altura*0.9), origY - Math.floor(largura/3), Math.floor(altura*0.9), Math.floor(largura/3)); } // Para o "tampo" de baixo no modo tampo duplo, só desenhamos as diagonais para referência if (!includeExtras && saiaDir && tpoDuplo && meia){ ctx.beginPath(); ctx.moveTo(rightX, origY + altura); ctx.lineTo(rightX - altura, origY); ctx.stroke(); ctx.beginPath(); ctx.moveTo(rightX, origY + altura); ctx.lineTo(rightX - altura, origY + altura); ctx.stroke(); ctx.beginPath(); ctx.moveTo(rightX, origY); ctx.lineTo(rightX, origY + altura); ctx.stroke(); } if (!includeExtras && saiaEsq && tpoDuplo && meia){ ctx.beginPath(); ctx.moveTo(origX, origY + altura); ctx.lineTo(origX + altura, origY); ctx.stroke(); ctx.beginPath(); ctx.moveTo(origX, origY + altura); ctx.lineTo(origX + altura, origY + altura); ctx.stroke(); ctx.beginPath(); ctx.moveTo(origX, origY); ctx.lineTo(origX, origY + altura); ctx.stroke(); } } // calcular deslocamento para colocar a barra superior centrada verticalmente no canvas const canvasCenterY = canvas.height / 2; const offsetSuperior = canvasCenterY - (altura / 2) - (esp + extraTopo); // Tampo superior centralizado verticalmente no canvas desenharTampo(offsetSuperior, true); // Tampo inferior (opcional) if (tpoDuplo){ const alturaTampo = extraTopo + altura + extraBaixo + 2*esp; const offsetSegundo = alturaTampo + (Math.floor(largura/3) + altura) - extraBaixo - altura - extraTopo - 3; desenharTampo(offsetSuperior + offsetSegundo, false); } // --- posicionamento fixo do input lateral: Y = 200 relativo ao topo do canvas --- (function positionInputFixedY200(){ const wrapper = document.getElementById('inputSaiaDirWrapper'); if (!wrapper || !canvas) return; // controlar visibilidade conforme checkboxes const mostrar = (saiaEsq || saiaDir); // forçar display inline com prioridade wrapper.style.setProperty('display', mostrar ? 'flex' : 'none', 'important'); if (!mostrar) return; // garantir que wrapper esteja no document.body para posicionamento absoluto em coordenadas de página if (wrapper.parentNode !== document.body) document.body.appendChild(wrapper); // estilos mínimos seguros com priority important para evitar sobrescrita por outros scripts/CSS wrapper.style.setProperty('position', 'absolute', 'important'); wrapper.style.setProperty('transform', 'none', 'important'); wrapper.style.setProperty('pointer-events', 'auto', 'important'); wrapper.style.setProperty('z-index', '2147483647', 'important'); wrapper.style.setProperty('align-items', 'center', 'important'); wrapper.style.setProperty('gap', '6px', 'important'); const rect = canvas.getBoundingClientRect(); const canvasTopPage = rect.top + window.scrollY; const canvasRightPage = rect.right + window.scrollX; // aplicar left (à direita do canvas) e calcular top para Y=200 no canvas (centrando verticalmente o wrapper sobre esse Y) wrapper.style.setProperty('left', (canvasRightPage + 10) + 'px', 'important'); // colocar o centro do wrapper em Y = canvasTop + 200 const desiredCenterY = canvasTopPage + 200; // medir e ajustar para centralizar verticalmente o wrapper sobre desiredCenterY // garantir render antes de medir const wrapperRect = wrapper.getBoundingClientRect(); const wrapperHeight = wrapperRect.height || 0; const topAdjusted = desiredCenterY - (wrapperHeight / 2); wrapper.style.setProperty('top', Math.max(0, topAdjusted) + 'px', 'important'); // reaplicar uma vez após pequeno atraso para neutralizar outros scripts que possam sobrescrever setTimeout(() => { wrapper.style.setProperty('left', (canvasRightPage + 10) + 'px', 'important'); wrapper.style.setProperty('top', Math.max(0, desiredCenterY - (wrapperHeight / 2)) + 'px', 'important'); wrapper.style.setProperty('transform', 'none', 'important'); }, 120); // reforço final em caso de alteração posterior (uma única reaplicação) setTimeout(() => { const wr = document.getElementById('inputSaiaDirWrapper'); if (!wr) return; wr.style.setProperty('left', (canvasRightPage + 10) + 'px', 'important'); // recalcular altura real caso tenha mudado const newRect = wr.getBoundingClientRect(); const newH = newRect.height || wrapperHeight; wr.style.setProperty('top', Math.max(0, desiredCenterY - (newH / 2)) + 'px', 'important'); wr.style.setProperty('transform', 'none', 'important'); }, 400); })(); } (function () { function updateInputSaiaPosition() { const wrapper = document.getElementById('inputSaiaDirWrapper'); const canvas = document.getElementById('canvasPreview'); const canvasWrapper = document.getElementById('canvasWrapper'); if (!wrapper || !canvas || !canvasWrapper) return; const saiaEsq = document.getElementById('saiaEsq')?.checked; const saiaDir = document.getElementById('saiaDir')?.checked; // só mostra ou esconde const shouldShow = saiaEsq || saiaDir; wrapper.style.display = shouldShow ? 'flex' : 'none'; // garantir que esteja dentro do wrapper if (!canvasWrapper.contains(wrapper)) { canvasWrapper.appendChild(wrapper); } // fixa posição única vez wrapper.style.position = 'absolute'; wrapper.style.top = '200px'; // fixo wrapper.style.left = (canvas.offsetWidth + 10) + 'px'; wrapper.style.transform = 'none'; wrapper.style.visibility = 'visible'; wrapper.style.opacity = '1'; } updateInputSaiaPosition(); window.addEventListener('resize', updateInputSaiaPosition); ['saiaDir', 'saiaEsq', 'fronEsq', 'fronDir', 'tpo_duplo'].forEach(id => { const el = document.getElementById(id); if (el) el.addEventListener('change', updateInputSaiaPosition); }); })(); // Redesenha ao mudar qualquer controle ['cor','largura','altura','saiaEsq','saiaDir','fronEsq','fronDir','meiaesquad','tpo_duplo'].forEach(id => { document.getElementById(id).addEventListener('input', gerarImagem); document.getElementById(id).addEventListener('change', gerarImagem); }); // Gera ao carregar window.addEventListener('load', gerarImagem); </script> </body> </html>