toFrankie / blog

种一棵树,最好的时间是十年前。其次,是现在。
20 stars 1 forks source link

perspective 滚动距离计算 #329

Open toFrankie opened 7 months ago

toFrankie commented 7 months ago

假设有以下示例:

<section style="width: 100%; max-width: 100%; perspective: 100px; perspective-origin: top center; overflow-x: scroll; overflow-y: hidden; -webkit-overflow-scrolling: touch; background: #eee">
  <section style="height: 0; transform: scale(1) translate3d(0, 0, 0)">
    <section style="display: flex; align-items: center; width: 400%; max-width: none !important">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 300" preserveAspectRatio="xMidYMin meet" style="flex: 1">
        <rect x="0" y="0" width="100%" height="100%" fill="transparent" stroke="#f00" stroke-width="2"></rect>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 300" preserveAspectRatio="xMidYMin meet" style="flex: 1">
        <rect x="0" y="0" width="100%" height="100%" fill="transparent" stroke="#0f0" stroke-width="2"></rect>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 300" preserveAspectRatio="xMidYMin meet" style="flex: 1">
        <rect x="0" y="0" width="100%" height="100%" fill="transparent" stroke="#00f" stroke-width="2"></rect>
      </svg>
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 300" preserveAspectRatio="xMidYMin meet" style="flex: 1">
        <rect x="0" y="0" width="100%" height="100%" fill="transparent" stroke="#0ff" stroke-width="2"></rect>
      </svg>
    </section>
  </section>

  <section style="height: 0; transform: scale(0.8) translate3d(0, 0, 20px)">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 300" preserveAspectRatio="xMidYMin meet" style="width: 400%; max-width: none !important">
      <rect x="0" y="0" width="100%" height="100%" fill="#f00" style="opacity: 0.2"></rect>
    </svg>
  </section>

  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 300" preserveAspectRatio="xMidYMin meet" style="width: 400%; max-width: none !important"></svg>
</section>

Performant Parallaxing 可知:

它们都相对的,相对于 translateZ 为 0 的情况,也就是没有视差效果。

举个例子,假设一屏的横向宽度为 350px,父级元素设置 perspective 为 100,其下有两个子元素 A 和 B,其中 A 设为 transform: translateZ(0),其中 B 设为 transform: translateZ(20px),此时 A 属于正常的元素,而 B 由于更靠近视点位置(即 perspective 位置),它表现为变大,而滚动速率更快。

假设 A 的速率为 1(正常滚动),而 B 的速率计算方式为「A 的速率 × (100 / (100 - 20))」,等于 1.25。也就是说,若 A 滚动 350px 时,B 会滚动 437.5px。