美文网首页
sticky妙用之官网视觉差滚动实现

sticky妙用之官网视觉差滚动实现

作者: 硅谷干货 | 来源:发表于2021-12-03 10:10 被阅读0次

    本项目是用vue3做一个炫酷的类苹果官网的项目,很多地方有视觉差滚动特效,所以首先想到了css3中 sticky属性,因为项目庞大而且是多人参与,所以每个人都是其中一个拆分vue组件中开发,所以需要抽取一个公众的计算方法,对想做的动画步骤进行拆解,能形成统一比较统一效果。

    注意

    在自定义组件中,内容去外层还需要再包一层div,而且要大于内容区的高度,这时候stikcy才有效果,所以样式部分这样写:

    .page-section {
      height: 300vh;
      background-color: white;
    }
    .stick-box{
      width: 100%;
      // height: 100vh;
      padding: 5.56vh 270px;
      overflow: hidden;
      position: sticky;
      top: 0;
    }
    

    重点

    然后重点来了,配合sticky的计算方法就派上用场了

    // 默认初始值
    const defaultV = -10;
    
    // 方式一:推荐
    const getScrollRatio = (sectionEl: HTMLElement):number => {
      // 判空处理
      if (!sectionEl) { 
        return defaultV;
      } 
      // 获取窗口滚动条高度
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; 
      // 获取浏览器可视区的高度
      const clientHeight = document.documentElement.clientHeight || document.body.clientHeight; 
      // section元素的高度
      const elClientHeight = sectionEl.clientHeight; 
      // 距离顶部高度少了一屏的高度 卷起 可视区域 一部分高度,大于等于0
      let ps = Math.floor(sectionEl.offsetTop - clientHeight); 
      ps = ps < 0 ? 0 : ps;
      // 每一个section头部滚动到底部  0 ----> 1的变化
      return (scrollTop - ps) / elClientHeight; 
    }
    
    // 方式二:次推荐
    const getScrollProgress = (sectionEl: HTMLElement):number => {
      // 判空处理
      if (!sectionEl) { 
        return defaultV;
      } 
      // const remommendPageDom =  document.getElementById('remommendPage');
      let windowInnerHeight = window.innerHeight;
      let domOffsetHeight = sectionEl.offsetHeight;
      let domClientRectTop = sectionEl.getBoundingClientRect().top;
      return (windowInnerHeight - domClientRectTop) / domOffsetHeight;
    } 
    
    // 方式三:普通
    const getScrollRate = (sectionEl: HTMLElement):number => {
      // 判空处理
      if (!sectionEl) { 
        return defaultV;
      } 
      
      // 视口高度
      const innerHeight = window.innerHeight
      // 获取滚动位置
      const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
      // 自身内容的高度
      // const offsetHeight = sectionEl.offsetHeight;
      // 获取dom偏移量
      const offsetTop = sectionEl.offsetTop;
      // 从rect中获取元素的高度
      const { height: rectHeight } = sectionEl.getBoundingClientRect();
      // 获取粘性高度H值和粘性Y值
      const stickyH = rectHeight - innerHeight;
      // 滚动的相对位置
      const stickyY = scrollTop - offsetTop;
      // 计算滚动比例
      return stickyY / stickyH;
    }
    
    // 设置透明度
    const setOpacityCallback = ({ratio,count}, callBack)=> {
      for (let i = 0; i < count; i++) {
        const start = 1 / count * i;
        const end = 1 / count * (i + 1);
        let progress = (ratio - start) / (end - start);
        if (progress >= 1) progress = 1;
        if (progress <= 0) progress = 0;
        callBack && callBack(i, progress);
      }
    }
    
    // 对外统一暴露计算位置方法
    export const useCalPos = ()=> { 
      return {
        getScrollRatio,
        getScrollProgress,
        getScrollRate,
        setOpacityCallback
      }
    }
    
    

    使用

    在监听滚动的方法中做个打印试试,是不是你想要的输出

    const onScroll = () => {
      const el = document.querySelector(`.page-section`);
      const ratio = getScrollRatio(el);
      const count = opacityList.length;
      setOpacityCallback({ ratio, count }, setOpacity);
    };
    
    const setOpacity = (i, progress) => {
      opacityList[i] = progress;
      console.log(i, progress)
    };
    

    点赞加关注,永远不迷路

    相关文章

      网友评论

          本文标题:sticky妙用之官网视觉差滚动实现

          本文链接:https://www.haomeiwen.com/subject/hnepxrtx.html