关于仿苹果官网滑动特效记录

843 阅读1分钟

话不多说先直接上源码

//以下代码使用vue3框架setup组合式开发
<template>
  <div class="home" ref="homeScroll" @scroll="getScroll">
    <div class="imac">
      <h2 ref="h2element">only 11.5mm. Now that's thin.</h2>
      <div class="images">
        <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>
  </div>
</template>

<script>
import { ref, onMounted } from "vue";
export default {
  setup() {
      //h2节点
    let h2element = ref(null)
    // 滑动框节点
    let homeScroll = ref(null)
    // 测试是否触发IntersectionObserver回调
    let isPinned = ref(false)
    // 获取滚动时候的缩放参数
    let returnscrolled = ref(1)
    //IntersectionObserver用来监测指定节点的显示属性
    let observer = new IntersectionObserver((e) => {

      e.forEach(function (element) {
        isPinned.value = (element.intersectionRatio < 1)
        //intersectionRatio:显示比例即被遮挡的比例的反比
        console.log(element.intersectionRatio);
        element.target.classList.toggle('pinned', isPinned.value);
      });
    }, {
    //指定根节点
      root: null,
     //指定何时触发 intersectionRatio=1  和第一次不等于1时候
      threshold: [1]
    })
    const getScroll = () => {
        //除去margintop的高度
      let height = parseInt(getComputedStyle(h2element.value).getPropertyValue('height')) +
        parseInt(getComputedStyle(h2element.value).getPropertyValue('margin-bottom'))
        //margintop
      let marginTop = parseInt(getComputedStyle(h2element.value).getPropertyValue('margin-top'))
      // 实时滚动比例
      let scrolled = (homeScroll.value.scrollTop - marginTop) / height
      // h2element.value.style.setProperty('')
      returnscrolled.value = 1-scrolled
    }
    onMounted(() => {
    //绑定监测目标
      observer.observe(h2element.value)
    })

    return {
      h2element,
      homeScroll,
      getScroll,
      returnscrolled
    }
  },
}
</script>
<style lang="less" scoped>
.home {
  height: 100vh;
  overflow: auto;
}
h2 {
  font-weight: normal;
  font-size: 72px;
  width: 290px;
  left: 50%;
  position: sticky;
  top: -1px;
  margin: 100px 0;
  padding: 0;
  /*clamp()函数指定当变量小于0.15时候为0.15 大于1的时候为1*/
  transform: scale( clamp(0.15, v-bind("returnscrolled"), 1) );
  transform-origin: 0 0;
}
.images {
  width: 100%;
  // overflow: hidden;

  img {
    width: 100%;
    position: relative;
    display: block;
    top: 50%;
    left: 50%;
    transform: translate(calc(-50% - 30px), 0);
  }
}
 .pinned {
   /*color: red;*/
 }
</style>

效果如下: testing - Google Chrome 2022-01-11 22-17-13.gif