performance: reduzir consumo de memoria

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2026-02-21 16:56:16 -03:00
1 parent 685d37e3f6
commit 6058620486
1 file changed
+54 -131
+54 -131
View File
@@ -40,9 +40,8 @@
} }
@keyframes gradientAnimation { @keyframes gradientAnimation {
0% { background-position: 0% 50%; } 0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; } 50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
} }
.container { .container {
@@ -157,33 +156,30 @@
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
} }
.icon-box svg { .icon-box svg,
width: 32px; .small-icon svg {
height: 32px;
fill: white; fill: white;
} }
.icon-box svg {
width: 32px;
height: 32px;
}
.small-icon svg {
width: 20px;
height: 20px;
}
.icon-label { .icon-label {
font-size: 0.75em; font-size: 0.7em;
font-weight: 500; font-weight: 500;
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
} }
/* Botão PIX */
.pix-button { .pix-button {
display: inline-block;
padding: 12px 30px;
background: linear-gradient(135deg, #32BCAD, #00A86B); background: linear-gradient(135deg, #32BCAD, #00A86B);
color: white;
text-decoration: none;
border-radius: 50px;
font-size: 0.95em;
font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
cursor: pointer;
border: none;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
@@ -236,12 +232,8 @@
} }
@keyframes fadeIn { @keyframes fadeIn {
from { 0% { background: rgba(0, 0, 0, 0); }
background: rgba(0, 0, 0, 0); 100% { background: rgba(0, 0, 0, 0.8); }
}
to {
background: rgba(0, 0, 0, 0.8);
}
} }
.modal-content { .modal-content {
@@ -261,34 +253,18 @@
} }
@keyframes slideUpScale { @keyframes slideUpScale {
0% { 0% { transform: translateY(30px) scale(0.9); opacity: 0; }
transform: translateY(30px) scale(0.9); 100% { transform: translateY(0) scale(1); opacity: 1; }
opacity: 0;
}
100% {
transform: translateY(0) scale(1);
opacity: 1;
}
} }
@keyframes fadeOut { @keyframes fadeOut {
from { 0% { background: rgba(0, 0, 0, 0.8); }
background: rgba(0, 0, 0, 0.8); 100% { background: rgba(0, 0, 0, 0); }
}
to {
background: rgba(0, 0, 0, 0);
}
} }
@keyframes slideDownScale { @keyframes slideDownScale {
0% { 0% { transform: translateY(0) scale(1); opacity: 1; }
transform: translateY(0) scale(1); 100% { transform: translateY(30px) scale(0.9); opacity: 0; }
opacity: 1;
}
100% {
transform: translateY(30px) scale(0.9);
opacity: 0;
}
} }
.modal-header { .modal-header {
@@ -421,14 +397,8 @@
} }
@keyframes slideInFade { @keyframes slideInFade {
from { 0% { transform: translateY(-10px); opacity: 0; }
transform: translateY(-10px); 100% { transform: translateY(0); opacity: 1; }
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
} }
.copy-notification { .copy-notification {
@@ -446,14 +416,8 @@
} }
@keyframes popIn { @keyframes popIn {
from { 0% { transform: scale(0.8); opacity: 0; }
transform: scale(0.8); 100% { transform: scale(1); opacity: 1; }
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
} }
.small-icons { .small-icons {
@@ -484,34 +448,12 @@
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
} }
.small-icon svg {
width: 20px;
height: 20px;
fill: white;
}
@media (max-width: 600px) { @media (max-width: 600px) {
.header h1 { .header h1 { font-size: 1.5em; }
font-size: 1.5em; .header p { font-size: 0.8em; }
} .icon-box { width: 60px; height: 60px; }
.icon-box svg { width: 28px; height: 28px; }
.header p { .icon-label { font-size: 0.65em; }
font-size: 0.8em;
}
.icon-box {
width: 60px;
height: 60px;
}
.icon-box svg {
width: 28px;
height: 28px;
}
.icon-label {
font-size: 0.7em;
}
} }
</style> </style>
</head> </head>
@@ -526,7 +468,6 @@
<a href="contato.vcf" class="save-contact" download>📇 Salvar na Agenda</a> <a href="contato.vcf" class="save-contact" download>📇 Salvar na Agenda</a>
<!-- Primeira linha de ícones -->
<div class="icons-row"> <div class="icons-row">
<a href="https://wa.me/5563981174175?text=Ol%C3%A1%20Martins%20%26%20Vieira%2C%20gostaria%20de%20obter%20mais%20informa%C3%A7%C3%B5es" target="_blank" class="icon-item"> <a href="https://wa.me/5563981174175?text=Ol%C3%A1%20Martins%20%26%20Vieira%2C%20gostaria%20de%20obter%20mais%20informa%C3%A7%C3%B5es" target="_blank" class="icon-item">
<div class="icon-box"> <div class="icon-box">
@@ -556,7 +497,6 @@
</a> </a>
</div> </div>
<!-- Segunda linha de ícones -->
<div class="icons-row"> <div class="icons-row">
<a href="https://www.instagram.com/rodrigosm_adv" target="_blank" class="icon-item"> <a href="https://www.instagram.com/rodrigosm_adv" target="_blank" class="icon-item">
<div class="icon-box"> <div class="icon-box">
@@ -586,10 +526,8 @@
</a> </a>
</div> </div>
<!-- Botão PIX -->
<button class="pix-button" onclick="openPixModal()">💳 Pagar com PIX</button> <button class="pix-button" onclick="openPixModal()">💳 Pagar com PIX</button>
<!-- Ícones pequenos -->
<div class="small-icons"> <div class="small-icons">
<a href="mailto:rodrigo@martinsevieira.adv.br" class="small-icon" title="E-mail"> <a href="mailto:rodrigo@martinsevieira.adv.br" class="small-icon" title="E-mail">
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
@@ -617,7 +555,6 @@
</div> </div>
</div> </div>
<!-- Modal PIX -->
<div class="modal" id="pixModal"> <div class="modal" id="pixModal">
<div class="modal-content"> <div class="modal-content">
<h2 class="modal-header">Pagamento PIX</h2> <h2 class="modal-header">Pagamento PIX</h2>
@@ -632,12 +569,11 @@
</div> </div>
<script> <script>
// Cache de elementos DOM para melhor performance const pixModal = document.getElementById('pixModal'),
const pixModal = document.getElementById('pixModal'); pixValue = document.getElementById('pixValue'),
const pixValue = document.getElementById('pixValue'); pixCodeArea = document.getElementById('pixCodeArea'),
const pixCodeArea = document.getElementById('pixCodeArea'); copyNotification = document.getElementById('copyNotification'),
const copyNotification = document.getElementById('copyNotification'); modalContent = pixModal.querySelector('.modal-content');
const modalContent = pixModal.querySelector('.modal-content');
const openPixModal = () => { const openPixModal = () => {
pixModal.classList.add('active'); pixModal.classList.add('active');
@@ -645,13 +581,14 @@
}; };
const closePixModal = () => { const closePixModal = () => {
modalContent.style.animation = 'slideDownScale 0.3s ease forwards'; const animStyle = (elem, anim) => elem.style.animation = anim;
pixModal.style.animation = 'fadeOut 0.3s ease forwards'; animStyle(modalContent, 'slideDownScale 0.3s ease forwards');
animStyle(pixModal, 'fadeOut 0.3s ease forwards');
setTimeout(() => { setTimeout(() => {
pixModal.classList.remove('active'); pixModal.classList.remove('active');
pixModal.style.animation = ''; animStyle(pixModal, '');
modalContent.style.animation = ''; animStyle(modalContent, '');
pixValue.value = ''; pixValue.value = '';
pixCodeArea.classList.remove('active'); pixCodeArea.classList.remove('active');
copyNotification.classList.remove('active'); copyNotification.classList.remove('active');
@@ -661,10 +598,7 @@
const generatePix = () => { const generatePix = () => {
const value = parseFloat(pixValue.value); const value = parseFloat(pixValue.value);
if (!value || value <= 0) { if (!value || value <= 0) return alert('Por favor, digite um valor válido');
alert('Por favor, digite um valor válido');
return;
}
const pixCode = buildPixCode( const pixCode = buildPixCode(
'financeiro@martinsevieira.adv.br', 'financeiro@martinsevieira.adv.br',
@@ -681,24 +615,20 @@
}; };
const buildPixCode = (pixKey, merchantName, city, value, txid) => { const buildPixCode = (pixKey, merchantName, city, value, txid) => {
const emvField = (id, value) => id + value.length.toString().padStart(2, '0') + value; const emvField = (id, val) => id + val.length.toString().padStart(2, '0') + val,
const merchantAccountInfo = emvField('00', 'BR.GOV.BCB.PIX') + emvField('01', pixKey); merchantAccountInfo = emvField('00', 'BR.GOV.BCB.PIX') + emvField('01', pixKey),
emv = emvField('00', '01') + emvField('26', merchantAccountInfo) +
let emv = emvField('00', '01') + emvField('26', merchantAccountInfo) + emvField('52', '0000') + emvField('53', '986') + emvField('54', value) +
emvField('52', '0000') + emvField('53', '986') + emvField('54', value) + emvField('58', 'BR') + emvField('59', merchantName) + emvField('60', city) +
emvField('58', 'BR') + emvField('59', merchantName) + emvField('60', city) + emvField('62', emvField('05', txid)) + '6304';
emvField('62', emvField('05', txid)) + '6304';
return emv + crc16(emv); return emv + crc16(emv);
}; };
const crc16 = str => { const crc16 = str => {
let crc = 0xFFFF; let crc = 0xFFFF, i = 0;
for (let i = 0; i < str.length; i++) { for (; i < str.length; i++) {
crc ^= str.charCodeAt(i) << 8; crc ^= str.charCodeAt(i) << 8;
for (let j = 0; j < 8; j++) { for (let j = 0; j < 8; j++) crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
}
} }
return (crc & 0xFFFF).toString(16).toUpperCase().padStart(4, '0'); return (crc & 0xFFFF).toString(16).toUpperCase().padStart(4, '0');
}; };
@@ -720,7 +650,7 @@
try { try {
document.execCommand('copy'); document.execCommand('copy');
showCopyNotification(); showCopyNotification();
} catch (err) { } catch {
alert('Erro ao copiar. Por favor, copie manualmente.'); alert('Erro ao copiar. Por favor, copie manualmente.');
} }
document.body.removeChild(textarea); document.body.removeChild(textarea);
@@ -732,15 +662,8 @@
setTimeout(() => copyNotification.classList.remove('active'), 3000); setTimeout(() => copyNotification.classList.remove('active'), 3000);
}; };
// Fecha modal ao clicar fora pixModal.addEventListener('click', e => e.target === pixModal && closePixModal());
pixModal.addEventListener('click', e => { pixValue.addEventListener('keypress', e => e.key === 'Enter' && generatePix());
if (e.target === pixModal) closePixModal();
});
// Permite gerar PIX ao pressionar Enter
pixValue.addEventListener('keypress', e => {
if (e.key === 'Enter') generatePix();
});
</script> </script>
</body> </body>
</html> </html>