So animieren Sie die Höhe mit Transformation, ohne den Inhalt zu komprimieren
P粉208469050
P粉208469050 2024-01-01 11:51:20
0
1
442

In meinem Projekt habe ich jQuery slideUp() verwendet, um ein Element in einer Liste mit 200 Elementen nach oben zu verschieben, wenn der Benutzer auf eine Schaltfläche klickt. Es ist jedoch bekannt, dass CSS-Höhenanimationen einen Reflow erfordern, was zu instabilen Animationen führt. Die Animation ist ein integraler Bestandteil der Anwendung und ich bin bereit, viel Arbeit zu leisten, damit sie funktioniert und reibungslos funktioniert.

Ich entschied, dass CSS transform der richtige Weg ist, damit es reibungslos funktioniert, da es auf der GPU verarbeitet wird und in einigen modernen Browsern sogar außerhalb des Hauptthreads liegt und die schwere JS-Arbeit keinen Einfluss auf die Transformationen hat. (Ich habe viel JS-Arbeit).

Ich suche nach einer Möglichkeit, CSS zu verwenden. transition的巧妙解决方案:transform来复制jQuery slideUp,它只是为height属性设置动画。以下是我的尝试,但似乎 scaletranslate Synchronisierung nicht wie erwartet.

$("button").on("click", function() {
  $(".collapsible").addClass("collapsed")
  setTimeout(function() {
    $(".collapsible").removeClass("collapsed")
  }, 5000);
});
.list-item {
  width: 400px;
  height: 100px;
  background-color: blue;
  margin-top: 10px;
  overflow-y: hidden;
}

.collapsible.collapsed .content {
  transition: transform 3s linear;
  transform: scale(1, 1) translate(0, -100%);
}

.collapsible.collapsed {
  transition: transform 3s linear;
  transform: translate(0, -50%) scale(1, 0);
}

.collapsible.collapsed ~ .list-item {
  transition: transform 3s linear;
  transform: translate(0, -100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<button>Collapse</button>
<div class="list-item collapsible">
  <div class="content">
    Just an example <br>
    Just an example <br>
    Just an example <br>
    Just an example <br>
    Just an example <br>
  </div>
</div>
<div class="list-item">
  
</div>
<div class="list-item">
  
</div>

Ich habe die Werte ein wenig abgeändert und sie näher gebracht, indem ich ihnen content 转换更改为 transform:scale(1, 3) translate(0, -50%); hinzugefügt habe.

Es scheint, als wäre ich meinem Ziel sehr nahe gekommen, aber es ist mir nie ganz gelungen. Gibt es dafür fertige Tricks?

Anforderungen:

  • Vorzugsweise ohne JS
  • Abseits des Hauptthreads

P粉208469050
P粉208469050

Antworte allen(1)
P粉005134685

经过几个晚上的睡眠,我找到了一个完全符合我需要的解决方案。我必须使用三层 div 并确保内部两层设置为 height: 100%;。然后,我取消了 scale() 并使用 transform() 将中间层向上滑动。

这符合我的要求:

  • 使用 Transform(),其在 GPU 上的运行速度应高达 60fps
  • 不会使用 Scale() 压缩内容
  • 内容像 jQuery 一样从下到上消失 SlideUp()
  • 无论目标元素的高度如何,下面的其他元素都会向上滑动以填充间隙
  • 一旦触发动画,就不再涉及 JS

$("button").on("click", function() {
  const height = $(".collapsible").css("height");
  $(":root").css("--height", height);
  $(".collapsible").addClass("collapsed");
  setTimeout(function() {
    $(".collapsible").removeClass("collapsed");
  }, 4000);
});
:root {
  --height: unset;
}

.outer-container {
  width: 400px;
  height: fit-content;
  background-color: transparent;
  margin-top: 10px;
  overflow-y: hidden;
}

.inner-container {
  height: 100%;
  background-color: blue;
  overflow: hidden;
}

.content {
  height: 100%;
}

.collapsible.collapsed .inner-container {
  transition: transform 3s linear;
  transform: translate(0, -100%);
}

.collapsible.collapsed .content {
  transition: transform 3s linear;
  transform: translate(0, 100%);
}

.collapsible.collapsed ~ .outer-container {
  transition: transform 3s linear;
  transform: translate(0, calc((var(--height) * -1) - 10px));
}

.collapsible .inner-container {
  transition: transform .5s ease-in-out;
  transform: translate(0, 0);
}

.collapsible .content {
  transition: transform .5s ease-in-out;
  transform: translate(0, 0);
}

.collapsible ~ .outer-container {
  transition: transform .5s ease-in-out;
  transform: translate(0, 0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<button>Collapse</button>
<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
<div class="outer-container collapsible">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage