D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
var
/
www
/
html
/
novonote
/
Filename :
testeimagemJSVersao2.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 */ #canvasWrapper { position: relative; display: inline-block; } #HsaiaDir { width: 36px; text-align: center; } #inputSaiaDirWrapper { position: absolute; top: 50%; left: 100%; transform: translate(10px, -50%); display: none; /* inicia escondido */ text-align: center; display: flex; flex-direction: column; align-items: center; gap: 4px; /* espaçamento entre label e input */ font-family: Arial, sans-serif; font-size: 12px; } 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"> <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 = n('largura', 5, 300); const altura = n('altura', 5, 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(); // Mostrar/ocultar input lateral da direita document.getElementById('inputSaiaDirWrapper').style.display = 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; // calcula o deslocamento do segundo tampo (o mesmo usado depois) const offsetSegundo = alturaTampo + (Math.floor(largura/3) + altura) - extraBaixo - altura - extraTopo - 3; // altura mínima necessária: top desenho começa em esp; bottom depende do tampo(s) const topY = esp; const bottomTop = esp + extraTopo + altura + extraBaixo; const bottomSecond = esp + extraTopo + offsetSegundo + altura + extraBaixo; // CORREÇÃO: usar a coordenada de fundo diretamente para definir a altura do canvas const alturaTotal = tpoDuplo ? Math.ceil(Math.max(bottomTop, bottomSecond)) : Math.ceil(bottomTop); // Canvas const canvas = document.getElementById('canvasPreview'); // canvas.width = largura + extraEsq + extraDir + 2*esp; // valores fixos desejados const fixedWidth = 335; const fixedHeight = 245; // defina as dimensões antes de obter o contexto canvas.width = fixedWidth; canvas.height = fixedHeight; // canvas.height = alturaTotal; 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 // Meia esquadria inferior direita - diagonal + fechamento externo até a diagonal (linha horizontal removida) if (!includeExtras && saiaDir && tpoDuplo && meia){ // diagonal principal (da base inferior direita até o topo esquerdo da esquadria) ctx.beginPath(); ctx.moveTo(rightX, origY + altura); ctx.lineTo(rightX - altura, origY); ctx.stroke(); // linha externa inferior da saia direita até encontrar a diagonal removida intencionalmente ctx.beginPath(); ctx.moveTo(rightX, origY + altura); ctx.lineTo(rightX - altura, origY + altura); ctx.stroke(); // acréscimo mínimo solicitado: estender a linha direita até a ponta inferior da diagonal ctx.beginPath(); ctx.moveTo(rightX, origY); // topo da barra (mantido) ctx.lineTo(rightX, origY + altura); // vai até a ponta inferior da diagonal ctx.stroke(); } // Meia esquadria inferior esquerda - diagonal + fechamento externo até a diagonal (linha horizontal removida) if (!includeExtras && saiaEsq && tpoDuplo && meia){ // diagonal principal (da base inferior esquerda até o topo direito da esquadria) ctx.beginPath(); ctx.moveTo(origX, origY + altura); ctx.lineTo(origX + altura, origY); ctx.stroke(); // linha externa inferior da saia esquerda até encontrar a diagonal removida intencionalmente ctx.beginPath(); ctx.moveTo(origX, origY + altura); ctx.lineTo(origX + altura, origY + altura); ctx.stroke(); // acréscimo mínimo solicitado anteriormente: estender a linha esquerda até a ponta inferior da diagonal ctx.beginPath(); ctx.moveTo(origX, origY); // começa no topo da barra ctx.lineTo(origX, origY + altura); // vai até a ponta inferior da diagonal ctx.stroke(); } } // Tampo superior desenharTampo(0, true); console.log('altura da área desenhada (pixels):', canvas.height); // Tampo inferior (opcional) if (tpoDuplo){ desenharTampo(offsetSegundo, false); } } // 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>