文字压缩效果

306 阅读1分钟

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

以上图片来自B站CodingStartup起码课文字压缩效果。

实现效果

tupan.gif

代码

元素结构

  <div class="imac">
    <h2 style="--scale: 1">Only 11.5mm. Now that's thin.</h2>
    <div class="image">
      <img src="https://www.apple.com/105/media/us/imac-24/2021/5e004d75-3ad6-4bb9-ab59-41f891fc52f0/anim/design-hero/large/flow/flow_startframe.jpg" alt="">
    </div>
  </div>

逻辑结构

<script>
    let isPinned = false
    const h2 = document.querySelector('h2')
    const observer = new IntersectionObserver(([e]) => {
      isPinned = (e.intersectionRatio < 1)
      e.target.classList.toggle('pinned', isPinned)
    }, { threshold: [1] })
    observer.observe(h2)

    document.addEventListener('scroll', (e) => {
      if (isPinned) {
        let html = document.documentElement
        let height = parseInt(getComputedStyle(h2).getPropertyValue('height')) + parseInt(getComputedStyle(h2).getPropertyValue('margin-bottom'))
        let marginTop = parseInt(getComputedStyle(h2).getPropertyValue('margin-top'))
        let scrolled = (html.scrollTop - marginTop) / height
        h2.style.setProperty('--scale', (1 - scrolled))
      }
    })
  </script>

样式结构

<style>
    body {
        margin: 0;
        padding: 0;
    }
    .image {
        position: relative;
        overflow: hidden;
    }

    .imac img {
        display: block;
        position: relative;
        top: 50%;
        left: 50%;
        transform: translate(calc(-50% - 30px), 0);
    }
    h2 {
        font-size: 72px;
        font-family: Helvetica;
        letter-spacing: -.012em;
        width: 290px;
        font-weight: normal;
        position: relative;
        left: 50%;
        position: sticky;
        top: -1px;
        margin: 100px 0;
        padding: 0;
        transform: scale(clamp(0.15, var(--scale), 1));
        transform-origin: 0% 0%;
    }

    .pinned {
    	color: red;
    }
</style>
  • 第一种

    • <style>
          h2 {
            transform: scale(clamp(0.15, var(--scale), 1));
          }
      </style>
      
    • 利用transform: scale(clamp(0.15, var(--scale), 1));该声明来对文字进行缩放

    • 其中clamp(0.15,var(--scale),1)是选取合适的大小值,参数分别代表是(最小值、首选值、最大值),当首选值大于1 的时候 返回的值是1 小于0.15时返回的值是0.15

    • IntersectionObserver用来监听h2是否是在视口中,e.intersectionRatio表示h2元素和视口相交区域的比值,如果小于了1 就说明元素已经并不完全在视口中了,所以h2position:sticky这个属性已经发挥作用了

    • getComputedStyle获取元素的样式属性 ,使用parseInt的缘故是因为这些值返回的都是xxpx这样的字符串需要转换成数字

    • 以上的内容是:当滚动条向下滑动的时候,当h2元素的sticky发挥效果的时候,就让元素根据滚动的距离和元素的高度的比值进行缩放,缩放到一定程度就不在进行缩放。

  • 第二种:缩放

    • <style>
          h2 {
            transform:matrix(var(--scale), 0, 0, var(--scale), 0, 0);
          }
      </style>
      
    • matrix(var(--scale), 0, 0, var(--scale), 0, 0):主要是试下2D的缩放运动等的

    • 链接