performance: reduzir consumo de memoria
Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
1 parent
685d37e3f6
commit
6058620486
1 file changed
+51
-128
+51
-128
@@ -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>
|
||||||
Reference in new issue
Block a user