otimizacoes de performance

Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
rodrigo committed 2026-02-21 16:36:19 -03:00
1 parent f23b925a99
commit 685d37e3f6
2 files changed
+70 -118

No files matched your search

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+70 -118
View File
@@ -36,6 +36,7 @@
background-size: 400% 400%;
animation: gradientAnimation 15s ease infinite;
z-index: -2;
will-change: background-position;
}
@keyframes gradientAnimation {
@@ -62,14 +63,10 @@
width: 100px;
height: 100px;
margin: 0 auto 15px;
background-image: url('fotos/logo.png');
background-size: 80%;
background-position: center;
background-repeat: no-repeat;
background: url('fotos/logo.png') center/80% no-repeat rgba(255, 255, 255, 0.95);
border-radius: 50%;
border: 3px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
background-color: rgba(255, 255, 255, 0.95);
}
.header {
@@ -92,19 +89,25 @@
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
}
/* Botão Salvar na Agenda */
.save-contact {
/* Botões principais */
.save-contact,
.pix-button {
display: inline-block;
padding: 12px 30px;
background: linear-gradient(135deg, #20337b, #2d4a9e);
color: white;
text-decoration: none;
border-radius: 50px;
font-size: 0.95em;
font-weight: bold;
margin-bottom: 25px;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
cursor: pointer;
border: none;
}
.save-contact {
background: linear-gradient(135deg, #20337b, #2d4a9e);
margin-bottom: 25px;
}
.save-contact:hover {
@@ -113,7 +116,6 @@
background: linear-gradient(135deg, #2d4a9e, #20337b);
}
/* Container de ícones */
.icons-row {
display: flex;
justify-content: center;
@@ -128,7 +130,7 @@
align-items: center;
text-decoration: none;
color: white;
transition: all 0.3s ease;
transition: transform 0.3s ease;
}
.icon-item:hover {
@@ -214,7 +216,6 @@
transform: translateY(-1px) scale(0.98);
}
/* Modal PIX */
.modal {
display: none;
position: fixed;
@@ -252,6 +253,7 @@
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
transform: translateY(30px) scale(0.9);
opacity: 0;
will-change: transform, opacity;
}
.modal.active .modal-content {
@@ -385,6 +387,7 @@
transition: all 0.2s ease;
border: 2px solid transparent;
position: relative;
will-change: transform, opacity;
}
.pix-code-area::before {
@@ -453,7 +456,6 @@
}
}
/* Ícones pequenos */
.small-icons {
display: flex;
justify-content: center;
@@ -488,7 +490,6 @@
fill: white;
}
/* Responsividade */
@media (max-width: 600px) {
.header h1 {
font-size: 1.5em;
@@ -631,129 +632,89 @@
</div>
<script>
function openPixModal() {
const modal = document.getElementById('pixModal');
modal.classList.add('active');
setTimeout(() => {
document.getElementById('pixValue').focus();
}, 100);
}
// Cache de elementos DOM para melhor performance
const pixModal = document.getElementById('pixModal');
const pixValue = document.getElementById('pixValue');
const pixCodeArea = document.getElementById('pixCodeArea');
const copyNotification = document.getElementById('copyNotification');
const modalContent = pixModal.querySelector('.modal-content');
function closePixModal() {
const modal = document.getElementById('pixModal');
const modalContent = modal.querySelector('.modal-content');
const openPixModal = () => {
pixModal.classList.add('active');
setTimeout(() => pixValue.focus(), 100);
};
// Animação de saída
const closePixModal = () => {
modalContent.style.animation = 'slideDownScale 0.3s ease forwards';
modal.style.animation = 'fadeOut 0.3s ease forwards';
pixModal.style.animation = 'fadeOut 0.3s ease forwards';
setTimeout(() => {
modal.classList.remove('active');
modal.style.animation = '';
pixModal.classList.remove('active');
pixModal.style.animation = '';
modalContent.style.animation = '';
document.getElementById('pixValue').value = '';
document.getElementById('pixCodeArea').classList.remove('active');
document.getElementById('copyNotification').classList.remove('active');
pixValue.value = '';
pixCodeArea.classList.remove('active');
copyNotification.classList.remove('active');
}, 300);
}
};
function generatePix() {
const value = parseFloat(document.getElementById('pixValue').value);
const generatePix = () => {
const value = parseFloat(pixValue.value);
if (!value || value <= 0) {
alert('Por favor, digite um valor válido');
return;
}
// Gera código PIX EMV (padrão brasileiro)
const pixKey = 'financeiro@martinsevieira.adv.br';
const merchantName = 'MARTINS E VIEIRA';
const city = 'PALMAS';
const txid = 'PAGAMENTO' + Date.now().toString().slice(-10);
const pixCode = buildPixCode(
'financeiro@martinsevieira.adv.br',
'MARTINS E VIEIRA',
'PALMAS',
value.toFixed(2),
'PAGAMENTO' + Date.now().toString().slice(-10)
);
// Formata o valor com 2 casas decimais
const formattedValue = value.toFixed(2);
// Constrói o código PIX Copia e Cola (EMV)
const pixCode = buildPixCode(pixKey, merchantName, city, formattedValue, txid);
// Exibe o código
const pixCodeArea = document.getElementById('pixCodeArea');
pixCodeArea.textContent = pixCode;
pixCodeArea.classList.add('active');
// Adiciona evento de clique para copiar
pixCodeArea.onclick = function() {
pixCodeArea.onclick = () => copyToClipboard(pixCode);
copyToClipboard(pixCode);
};
// Copia automaticamente na primeira vez
copyToClipboard(pixCode);
}
function buildPixCode(pixKey, merchantName, city, value, txid) {
// Função auxiliar para criar campo EMV
function emvField(id, value) {
const length = value.length.toString().padStart(2, '0');
return id + length + value;
}
// Monta a chave PIX
const buildPixCode = (pixKey, merchantName, city, value, txid) => {
const emvField = (id, value) => id + value.length.toString().padStart(2, '0') + value;
const merchantAccountInfo = emvField('00', 'BR.GOV.BCB.PIX') + emvField('01', pixKey);
let emv = '';
emv += emvField('00', '01'); // Payload Format Indicator
emv += emvField('26', merchantAccountInfo); // Merchant Account Information
emv += emvField('52', '0000'); // Merchant Category Code
emv += emvField('53', '986'); // Transaction Currency (986 = BRL)
emv += emvField('54', value); // Transaction Amount
emv += emvField('58', 'BR'); // Country Code
emv += emvField('59', merchantName); // Merchant Name
emv += emvField('60', city); // Merchant City
emv += emvField('62', emvField('05', txid)); // Additional Data Field
let emv = emvField('00', '01') + emvField('26', merchantAccountInfo) +
emvField('52', '0000') + emvField('53', '986') + emvField('54', value) +
emvField('58', 'BR') + emvField('59', merchantName) + emvField('60', city) +
emvField('62', emvField('05', txid)) + '6304';
// Calcula CRC16
emv += '6304';
const crc = crc16(emv);
emv += crc;
return emv + crc16(emv);
};
return emv;
}
function crc16(str) {
const crc16 = str => {
let crc = 0xFFFF;
for (let i = 0; i < str.length; i++) {
crc ^= str.charCodeAt(i) << 8;
for (let j = 0; j < 8; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;
}
}
return (crc & 0xFFFF).toString(16).toUpperCase().padStart(4, '0');
}
};
function copyToClipboard(text) {
// Usa a API moderna de clipboard
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(() => {
showCopyNotification();
}).catch(err => {
// Fallback para método antigo
fallbackCopy(text);
});
const copyToClipboard = text => {
if (navigator.clipboard?.writeText) {
navigator.clipboard.writeText(text).then(showCopyNotification, () => fallbackCopy(text));
} else {
fallbackCopy(text);
}
}
};
function fallbackCopy(text) {
const fallbackCopy = text => {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
textarea.style.cssText = 'position:fixed;opacity:0';
document.body.appendChild(textarea);
textarea.select();
try {
@@ -763,31 +724,22 @@
alert('Erro ao copiar. Por favor, copie manualmente.');
}
document.body.removeChild(textarea);
}
};
function showCopyNotification() {
const notification = document.getElementById('copyNotification');
notification.classList.remove('active'); // Remove primeiro para reiniciar animação
setTimeout(() => {
notification.classList.add('active');
}, 10);
setTimeout(() => {
notification.classList.remove('active');
}, 3000);
}
const showCopyNotification = () => {
copyNotification.classList.remove('active');
setTimeout(() => copyNotification.classList.add('active'), 10);
setTimeout(() => copyNotification.classList.remove('active'), 3000);
};
// Fecha modal ao clicar fora
document.getElementById('pixModal').addEventListener('click', function(e) {
if (e.target === this) {
closePixModal();
}
pixModal.addEventListener('click', e => {
if (e.target === pixModal) closePixModal();
});
// Permite gerar PIX ao pressionar Enter
document.getElementById('pixValue').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
generatePix();
}
pixValue.addEventListener('keypress', e => {
if (e.key === 'Enter') generatePix();
});
</script>
</body>