Плавная анимация сжатия - PullRequest
0 голосов
/ 07 марта 2019

Я хотел бы иметь возможность уменьшить тег HTML, чтобы он исчез, и иметь плавное исчезновение для оставшихся элементов (чтобы они не перепрыгивали туда, где раньше был тег)

const div = document.querySelector('.toGo');

div.addEventListener('click', event => {
  div.className += ' animate';
  // Simulate Angular's DOM modification
  setTimeout(() => div.style.display = 'none', 1100);
  setTimeout(() => div.style.display = 'block', 1200);
  setTimeout(() => div.className = 'toGo', 1300);
});
.toGo, .toStay {
  height: 50px;
  width: 100%;
  background: coral;
  transition: all 1000ms ease-in-out;
  overflow: hidden;
}

.toStay {
  margin: 12px 0;
}

.animate {
  height: 0;
  width: 0;
  opacity: 0;
}
<div class="toGo">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
<div class="toStay">Lorem Ipsum</div>

<p>Click on the first div</p>

Прямо сейчас, как вы можете видеть, текст смещается, потому что пространство уменьшается.

Сначала я попробовал со свойством transform, но второй div прыгнул на месте первого (потому что я использую Angular, и фреймворк удаляет первый div из DOM после анимациизавершено).

const div = document.querySelector('.toGo');

div.addEventListener('click', event => {
  div.className += ' animate';
  // Simulate Angular's DOM modification
  setTimeout(() => div.style.display = 'none', 1100);
  setTimeout(() => div.style.display = 'block', 2100);
  setTimeout(() => div.className = 'toGo', 2200);
});
.toGo, .toStay {
  height: 50px;
  width: 100%;
  background: coral;
  transition: all 1000ms ease-in-out;
  overflow: hidden;
}

.toStay {
  margin: 12px 0;
}

.animate {
  transform: scale(0);
  opacity: 0;
}
<div class="toGo">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
<div class="toStay">Lorem Ipsum</div>

<p>Click on the first div</p>

Затем я попробовал это решение с шириной / высотой, но текст смещается.Затем я, наконец, попытался с контейнером в нем, но это ничего не изменило (если я не установил фиксированный размер для этого внутреннего контейнера).

Есть ли способ достичь этого, без установки фиксированной ширины / высоты для внутреннего контейнера ?

РЕДАКТИРОВАТЬ Люди на самом деле просят закрытьмой вопрос потому что это "неясно".В случае, если это не было очевидно, я хочу, чтобы первый фрагмент прекратил сдвигать текст, а второй фрагмент плавно перемещал второй div вместо первого (без прыжков).

Примерно так, без использования фиксированных размеров для внутреннего контейнера

const div = document.querySelector('.toGo');

div.addEventListener('click', event => {
  div.className += ' animate';
  // Simulate Angular's DOM modification
  setTimeout(() => div.style.display = 'none', 1100);
  setTimeout(() => div.style.display = 'block', 1200);
  setTimeout(() => div.className = 'toGo', 1300);
});
.toGo, .toStay {
  height: 50px;
  width: 100%;
  background: coral;
  transition: all 1000ms ease-in-out;
  overflow: hidden;
}

.container {
  height: 50px;
  width: 100vw;
}

.toStay {
  margin: 12px 0;
}

.animate {
  height: 0;
  width: 0;
  opacity: 0;
}
<div class="toGo">
  <div class="container">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
  </div>
</div>
<div class="toStay">Lorem Ipsum</div>

<p>Click on the first div</p>

1 Ответ

1 голос
/ 07 марта 2019

Ваша основная проблема в первом фрагменте была связана с разрушением полей, создающим эффект прыжка. Рассмотрим контейнер flexbox, чтобы избежать разрушения полей:

затем вы можете рассмотреть анимацию клипа в сочетании с анимацией высоты (не анимируйте ширину, чтобы избежать эффекта сжатия)

const div = document.querySelector('.toGo');

div.addEventListener('click', event => {
  div.className += ' animate';
  
  // Simulate Angular's DOM modification
  setTimeout(() => div.style.display = 'none', 1100);
  setTimeout(() => div.style.display = 'block', 1200);
  setTimeout(() => div.className = 'toGo', 1300);
});
body {
  display:flex;
  flex-direction:column;
}

.toGo, .toStay {
  height: 50px;
  width: 100%;
  background: coral;
  transition: all 1000ms ease-in-out;
  overflow: hidden;
  clip-path:polygon(0 0,100% 0,100% 100%, 0 100%);
}

.toStay {
  margin: 12px 0;
}

.animate {
  height: 0;
  opacity: 0;
  clip-path:polygon(0 0,0% 0,0% 100%, 0 100%);
}
<div class="toGo">
 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
<div class="toStay">Lorem Ipsum</div>

<p>Click on the first div</p>

Вы можете настроить путь клипа, чтобы управлять тем, как выполняется анимация.

const div = document.querySelector('.toGo');

div.addEventListener('click', event => {
  div.className += ' animate';
  
  // Simulate Angular's DOM modification
  setTimeout(() => div.style.display = 'none', 1100);
  setTimeout(() => div.style.display = 'block', 1200);
  setTimeout(() => div.className = 'toGo', 1300);
});
body {
  display:flex;
  flex-direction:column;
}

.toGo, .toStay {
  height: 50px;
  width: 100%;
  background: coral;
  transition: all 1000ms ease-in-out;
  overflow: hidden;
  clip-path:polygon(0 0,100% 0,100% 100%, 0 100%);
}

.toStay {
  margin: 12px 0;
}

.animate {
  height: 0;
  opacity: 0;
  clip-path:polygon(50% 0,50% 0,50% 100%, 50% 100%);
}
<div class="toGo">
 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam tristique sed nisi id aliquet. Etiam mauris diam, commodo in nisl ac, porttitor auctor mi. Nunc et blandit lacus. Donec facilisis dolor in arcu convallis, eu molestie magna placerat. Etiam blandit diam vitae nibh sollicitudin, ac gravida risus convallis. Nunc aliquet, turpis ac dignissim mollis, nulla nisi cursus leo, quis viverra nisi augue eget leo. Curabitur porta faucibus vestibulum.
</div>
<div class="toStay">Lorem Ipsum</div>

<p>Click on the first div</p>
...