首页 > 解决方案 > 在 Nuxtjs 的视口中如何平滑地扩展视频容器

问题描述

我必须制作一个与此非常相似的网页。我为此使用 Nuxt,我在以完全相同的方式使视频扩展和缩小时遇到了问题。

我试图在这里复制 StackBlitz上的问题。该指令实际上无法正常工作。一旦视频进入视口,我想实现完全相同的过渡。

自定义指令的代码 -

export default {
  directives: {
    inView: {
      isLiteral: true,
      inserted: (el, binding, _) => {
        const isInView = () => {
          const rect = el.getBoundingClientRect();
          const inView = (rect.width > 0 && rect.height > 0 && rect.top >= 0 &&
            (rect.bottom + 100) <= (window.innerHeight || document.documentElement.clientHeight));
          if (inView) {
            el.classList.add(binding.value);
            // window.removeEventListener('scroll', isInView);
          } else {
            el.classList.remove(binding.value);
          }
        };
        window.addEventListener('scroll', isInView);
        isInView();
      }
    }
  }
}

标签: javascriptvue.jsnuxt.jsvue-directives

解决方案


代替scroll监听器,使用 anIntersectionObserver来跟踪元素何时进入或离开视图。以下观察者创建了IntersectionObserver一个阈值为 30% 的值,binding.arg在视图中将该值作为 CSS 类添加到元素中:

export default {
  directives: {
    inView: {
      mounted(el, binding) {
        const threshold = 0.3 // trigger callback when element is 30% in view
        const observer = new IntersectionObserver(entries => {
          const elem = entries[0]
          if (elem.intersectionRatio >= threshold) {
            el.classList.add(binding.arg);
          } else {
            el.classList.remove(binding.arg);
          }
        }, { threshold })
        observer.observe(el)
        binding.instance.observer = observer
      },
      unmounted(el, binding) {
        binding.instance.observer.disconnect()
      },
    }
  },
}

然后使用video-wrapper元素上的指令进行动画处理(scale动画类在哪里):

<div v-in-view:scale class="video-wrapper">

演示


推荐阅读