Alternative To Hypes Enter Viewport when using Scale and Scrolling

I ran into a problem where the Actions for Enter Viewport or the native waypoints.js would not fire unless I jiggled the size of the browser window when coupled with a target inside a scrolling group within a scaled (width and height) Hype document

@jonathan confirmed this was a known and common issue and probably can explain more on it.

So to get around this I had a look at the Intersection Observer API which I have used in the past ( hit test etc.. )

My Approach :

Give each target element ( in my case groups) an Additional HTML attribute named.

data-target

The value of data-target can be anything even empty

In this case I add the timeline name I want the waypoint to run when a target is intersected.

A single Intersection Observer can observer multiple targets.
I use a simple bit of code to get all targets with the correct attributes and ask the observer to observe them.

Options
You can add a few options that help determine how and where the triggers will take place.
Please read the above link for an explanation on how that works.

This is fully explained in the link above.

  // margin from bottom top, right, bottom, left
 // -55% from bottom// yours may not be  the same 
 var halfway =  "0% 0% -55% 0%"  
 if (hypeDocument.currentLayoutName() == 'iPhone'){
 var halfway =  "0% 0% -25% 0%" 
 }
 
 
	let options = {
  root: rootEl,
  rootMargin: halfway,
  threshold: 1
  }

Root: intersection point/waypoint element

There is no point as such. Generally you will use the top, right, bottom, left margins ( rootMargin) of what ever element you choose to be your root/intersection point/waypoint

The observer has a callback function.

The callback function can be customised as you need it with the normal Hype logic and coding to run animations.

In this example I simply use the attribute value from the target (observer entry object ) to know what timeline to run.


Full code:

	let callback = (entries, observer) => {
	 
		  entries.forEach(entry => {
		  
		  	if (entry.isIntersecting){
		  	//-- elements attibute value
		  
			 var target_waypoint = entry.target.dataset.target
 	  	
			 
			   //-- use attibute value for timeline name
			  	hypeDocument.startTimelineNamed(target_waypoint, hypeDocument.kDirectionForward)
			  
			  //-- only run once, stop observing
			 	observer.unobserve(entry.target);
 
			}
									    
 
									    // Each entry describes an intersection change for one observed
									    // target element:
									    //   entry.boundingClientRect
									    //   entry.intersectionRatio
									    //   entry.intersectionRect
									    //   entry.isIntersecting
									    //   entry.rootBounds
									    //   entry.target
									    //   	
  			});
	};
	
	

	 //-- intersection root.
var rootEl=   document.querySelector( hypeDocument.documentId() )  //-- we in this case and for simplicity using the Hypdoc as the viewport

 // margin from bottom top, right, bottom, left
 // -55% from bottom// yours may not be  the same  
 var halfway =  "0% 0% -55% 0%" 
 
 
	let options = {
  root: rootEl,
  rootMargin: halfway,
  threshold: 1
  }


var observer = new IntersectionObserver(callback, options);	
		// all target elements with attribute ddata-target
 var targets =  document.querySelectorAll( "[data-target]" )
  
  
  // observe each ellement with the waypoint attribute
for (let i = 0; i < targets.length; i++) { 
  
   observer.observe( targets[i])
	
}

Example doc

example 1

intersect 1.hype.zip (281.5 KB)

example 2

intersect 2.hype.zip (285.3 KB)

4 Likes

Small update to remove bug in example. iPhone layout was using old attribute name data-waypoint instead of data-target.

Added a second example showing more usage. Scroll bar colour changes. ( which @Daniel 's post LinkCollection: Quick & Easy Social Links Template when I saw his scroll bar made me think of )