Une petite énigme...

by Ianic

HTML

<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
ECORCE
<br/>
<input type="text" id="code" value="" size="100">
<hr/>
<div id="clic">
  SOUS ECORCE
  <br/>
  <span>?????????????????????????????</span>
</div>
<button id="copy">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"
    fill="none" stroke="rgb(207, 150, 124)" stroke-width="2"
    stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
    <rect x="9" y="9" width="12" height="12" rx="2" />
    <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
  </svg>
  <span>Intéressant, je le note</span>
</button>

CSS

body {
  text-align:center;
  background-color:rgb(127, 70, 44);
  color:rgb(207, 150, 124);
}

#clic {
  cursor: pointer;
  text-align:center;
  background-color:rgb(167, 110, 84);
  color:rgb(127, 70, 44);
  width:100%;
  span {
    color:rgb(127, 70, 44);
  }
}
#copy {
  /* confort */
  all: unset;
  display: none;
  cursor: pointer;
  color: rgb(207, 150, 124);
  align-items: center;
  gap: 0.4em;
  svg {
    display: block;
    flex: 0 0 auto;
  }
}

JavaScript

$(function() {
  $('#clic').click(function() {
    if ($('#code').val() == '') {
      $('#clic span').text('?????????????????????????????');
      $('#copy').css('display','none');
    }
    else {
      let val = atob($('#code').val());
      $('#clic span').text(val);
      $('#code').val('');
      $('#copy').css({display: 'inline-flex'});
    }
  });
  $('#copy').click(function(event) {
    event.stopPropagation();
    const txt = $('#clic span').text();
    if (txt != '' && txt != '?????????????????????????????') {
      navigator.clipboard.writeText(txt);
      $('#clic span').text('');
      pulseCloneThenHide($(this), $(this).find('svg')[0]);
    }
  });
});

function pulseCloneThenHide($parentSource, source, scale = 5.4, duration = 1000) {
  const rect = source.getBoundingClientRect();
  const ghost = source.cloneNode(true);

  ghost.removeAttribute('id');
  ghost.setAttribute('aria-hidden', 'true');
  if ('disabled' in ghost) {
    ghost.disabled = true;
  }

  Object.assign(ghost.style, {
    position: 'fixed',
    left: `${rect.left}px`,
    top: `${rect.top}px`,
    width: `${rect.width}px`,
    height: `${rect.height}px`,
    margin: '0',
    transformOrigin: 'center',
    pointerEvents: 'none',
    zIndex: '9999',
  });

  document.body.append(ghost);

  const animation = ghost.animate(
    [
      { transform: 'scale(1)', opacity: 0.9 },
      { transform: `scale(${scale})`, opacity: 0 },
    ],
    { duration, easing: 'cubic-bezier(0.22, 1, 0.36, 1)' },
  );

  // .catch() avant .then() : une animation annulée rejette `finished`,
  // et on veut retirer le clone dans tous les cas.
  animation.finished
    .catch(() => {})
    .then(() => {
      ghost.remove();
      $parentSource.hide();
    });
}