Cartão de Visitas - Fonte Grande & LocalStorage

by thvinic

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<h2>Gerador de Cartão de Visitas</h2>
<div class="dica">
  <b>Dica:</b> Para máxima qualidade do PNG, aumente o zoom do navegador antes de salvar.
</div>
<div id="controls">
  <label>Nome:
    <input type="text" id="nameInput" placeholder="Seu nome" />
    <input type="color" id="nameColor" value="#000000" title="Cor do Nome" />
  </label>
  <label>Profissão:
    <input type="text" id="professionInput" placeholder="Sua profissão" />
    <input type="color" id="professionColor" value="#000000" title="Cor da Profissão" />
  </label>
  <label>Especialidade:
    <input type="text" id="specialtyInput" placeholder="Sua especialidade" />
    <input type="color" id="specialtyColor" value="#000000" title="Cor da Especialidade" />
  </label>
  <label>Endereço:
    <input type="text" id="addressInput" placeholder="Seu endereço" />
    <input type="color" id="addressColor" value="#000000" title="Cor do Endereço" />
  </label>
  <label>Telefone:
    <input type="tel" id="phoneInput" placeholder="(00) 00000-0000" />
    <input type="color" id="phoneColor" value="#000000" title="Cor do Telefone" />
  </label>
  <label>Endereço Web:
    <input type="url" id="webInput" placeholder="https://seusite.com" />
    <input type="color" id="webColor" value="#0000EE" title="Cor do Endereço Web" />
  </label>
  <label>Foto (imagem redonda):
    <input type="file" id="photoInput" accept="image/*" />
  </label>
  <label>Imagem de Fundo:
    <input type="file" id="backgroundInput" accept="image/*" />
  </label>
  <label>Opacidade da imagem de fundo:
    <input type="range" id="bgOpacityInput" min="0" max="1" step="0.05" value="0.3" />
    <span id="opacityValue">0.3</span>
  </label>
</div>
<button id="downloadBtn">Baixar Cartão como PDF</button>
<button...

CSS

body { font-family: Arial, sans-serif; margin: 20px; }
  #card {
    width: 350px;
    height: 220px;
    border: 1px solid #ccc;
    border-radius: 10px;
    overflow: hidden;
    background-size: cover;
    background-position: center;
    position: relative;
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 10px;
    margin-bottom: 20px;
    background-color: #fff;
  }
  .photo-area {
    width: 110px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .photo-area img {
    width: 100px;
    height: 100px;
    object-fit: cover;
    border-radius: 50%;
    border: 3px solid #fff;
    background: #eee;
    display: none;
  }
  .info-area {
    flex: 1;
    padding-left: 10px;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 8px;
  }
  .info-field { font-size: 20px; word-break: break-all; }
  .info-field strong { font-size: 24px; }
  .info-link { text-decoration: underline; cursor: pointer; font-size: 20px; }
  #controls label { display: block; margin-top: 10px; }
  #controls input[type="text"], 
  #controls input[type="color"], 
  #controls input[type="file"], 
  #controls input[type="range"], 
  #controls input[type="url"], 
  #controls input[type="tel"] {
    width: 100%;
    box-sizing: border-box;
  }
  #controls { max-width: 420px; margin-bottom: 30px; }
  #opacityValue { display: inline-block; width: 30px; text-align: right; }
  button { margin-top: 15px; padding: 10px 20px; font-size: 16px; cursor: pointer; }
  .dica { color: #b96c00; font-size: 13px; margin-bottom: 10px; }

JavaScript

// Funções para LocalStorage
  function saveToStorage() {
    const data = {
      name: nameInput.value,
      nameColor: nameColor.value,
      profession: professionInput.value,
      professionColor: professionColor.value,
      specialty: specialtyInput.value,
      specialtyColor: specialtyColor.value,
      address: addressInput.value,
      addressColor: addressColor.value,
      phone: phoneInput.value,
      phoneColor: phoneColor.value,
      web: webInput.value,
      webColor: webColor.value,
      bgOpacity: bgOpacityInput.value,
      photo: photoPreview.src || "",
      bgImage: card.dataset.bgImage || ""
    };
    localStorage.setItem('cartaoVisitas', JSON.stringify(data));
  }

  function loadFromStorage() {
    const data = JSON.parse(localStorage.getItem('cartaoVisitas') || '{}');
    if (data.name !== undefined) nameInput.value = data.name;
    if (data.nameColor) nameColor.value = data.nameColor;
    if (data.profession !== undefined) professionInput.value = data.profession;
    if (data.professionColor) professionColor.value = data.professionColor;
    if (data.specialty !== undefined) specialtyInput.value = data.specialty;
    if (data.specialtyColor) specialtyColor.value = data.specialtyColor;
    if (data.address !== undefined) addressInput.value = data.address;
    if (data.addressColor) addressColor.value = data.addressColor;
    if (data.phone !== undefined) phoneInput.value = data.phone;
    if (data.phoneColor) phoneColor.value = data.phoneColor;
    if (data.web !== undefined) webInput.value = data.web;
    if (data.webColor) webColor.value = data.webColor;
    if (data.bgOpacity) bgOpacityInput.value = data.bgOpacity;
    if (data.photo) {
      photoPreview.src = data.photo;
      photoPreview.style.display = data.photo ? 'block' : 'none';
    }
    if (data.bgImage) {
      card.dataset.bgImage = data.bgImage;
      updateBackgroundOpacity();
    }
    // Atualiza campos visuais
   ...