3

I have an IntersectionObserver observing an img that works perfectly fine when the root is set to null (viewport). However when i set the root element to be another img element the observer fails to detect the intersection between the two. after spending hours of debugging, I decided to seek help from the community.

the code can be found in this file from the public repo

for visibility i am going to past it here:

<template>
  <section
    id="scene"
    class="flex flex-col content-center justify-center items-center mt-16"
    style="height: calc(100% - 4rem)"
  >
    <div id="trigger1"></div>
    <div class="mb-6 mt-32 inset-x-auto">
      <img
        id="logo"
        data-dis-type="simultaneous"
        data-dis-particle-type="ExplodingParticle"
        src="@/static/pure-logo.png"
        class="w-48 relative left-auto inset-y-auto"
        alt="Logo used in the center of the home page"
      />
    </div>
    <div class="inset-x-auto absolute">
      <h1
        class="font-h text-4xl relative"
        id="tagline"
        style="top: 24rem;"
      >Everything begins with an idea.</h1>
    </div>
    <div class data-depth="0.45">
      <img
        style="top: 23rem; transform: scale(1.2, 1.2);"
        src="@/assets/img/forground.png"
        class="w-full relative hidden"
        alt="the forgoround is a picture of a ground covered with leafs"
      />
    </div>
    <div class data-depth="0.5">
      <img
        id="underground"
        style="top: 38rem; transform: scale(1.2, 1.2);"
        src="@/assets/img/underground.png"
        class="w-full relative opacity-25"
        alt="then there is a picture of the underground"
      />
    </div>
  </section>
</template>

<script>
import Parallax from 'parallax-js'
import disintegrate from 'disintegrate'

export default {
  // head() {
  //   return {
  //     script: [{ src: 'http://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/debug.addIndicators.min.js' }]
  //   }
  // },
  // data() {
  //   return {
  //     initialized: false
  //   }
  // },
  components: {},
  mounted() {
    /* eslint-disable no-unused-vars, nuxt/no-env-in-hooks */
    // excute deligters
    // prepare parallex scene
    const parallaxScene = document.getElementById('scene')
    const parallaxInstance = new Parallax(parallaxScene)
    // scroll magic
    // init controller
    const ScrollMagic = require('scrollmagic')
    const controller = new ScrollMagic.Controller()
    const scrollScene = new ScrollMagic.Scene({
      triggerElement: '#trigger1',
      duration: 570,
      triggerHook: 0, // don't trigger until #pinned-trigger1 hits the top of the viewport
      reverse: true
    })
      .setPin('#logo')
      .setClassToggle('#tagline', 'text-blur-out') // add class toggle
      .addTo(controller)

    // creating promises to make sure the scene is loaded and initialized
    // https://stackoverflow.com/a/23767207
    const loaded = new Promise((resolve) => {
      window.addEventListener('disesLoaded', resolve)
    })
    const initialized = new Promise((resolve) => {
      window.addEventListener('disesLoaded', resolve)
    })
    disintegrate.init()
    Promise.all([loaded, initialized]).then(() => {
      if ('IntersectionObserver' in window) {
        console.log('ALL SET')
        const options = {
          root: document.querySelector('#underground'), // relative to underground element
          rootMargin: '-125px 0px 0px 0px', // margin around root. Values are similar to css property. Unitless values not allowed
          threshold: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0] // visible amount of item shown in relation to root
        }
        const observer = new IntersectionObserver((changes, observer) => {
          changes.forEach((change) => {
            console.log('TCL: desintegrate -> change.intersectionRatio', change.intersectionRatio)
            const e = document.querySelector('[data-dis-type="simultaneous"]')
            const disObj = disintegrate.getDisObj(e)
            disintegrate.createSimultaneousParticles(disObj)
          })
          console.log('TCL: mounted -> observer', observer)
        }, options)
        observer.observe(document.querySelector('#logo'))
      }
    })
  }
}
</script>

<style>
.debug {
  background-color: red;
  width: 100%;
  height: 2px;
}

#logo {
  pointer-events: all;
}
.scrollmagic-pin-spacer > img {
}
.text-blur-out {
  animation: text-blur-out 1s alternate both;
}

/* ----------------------------------------------
 * Generated by Animista on 2019-7-7 16:39:35
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation text-blur-out
 * ----------------------------------------
 */
@keyframes text-blur-out {
  0% {
    filter: blur(0.01);
  }
  100% {
    filter: blur(12px) opacity(0%);
  }
}
</style>
Gimy boya
  • 447
  • 5
  • 22

1 Answers1

2

I think your problem is that your underground image is not a descendant of logo image (And it never can be because an image can't have ancestors)

If you look at the w3c documentation for IO you will see the following:

An IntersectionObserver with a root Element can observe any target Element that is a descendant of the root in the containing block chain.

For me this means that the target Element has to be a descendant of your observed target Element.

cloned
  • 6,346
  • 4
  • 26
  • 38
  • You have to reorder your html so that your target Element is a descendant of the root element. What exactly do you want to achieve? Do you want to check when two images overlap? – cloned Jul 09 '19 at 07:41
  • I wanted to know when the two elements overlap and by how much to generate some particles on the logo when it touches the other image something [like this](https://zachsaucier.github.io/Disintegrate/disintegrate-draggable.html) but i am guessing that I am going to use [mezr](https://github.com/niklasramo/mezr) library instaid – Gimy boya Jul 09 '19 at 08:11