Custom Spectator
Live Demo
Check out the interactive live version here.
Primary Use Case
Writing domain-specific spectator functions that extend or override viewport metrics (e.g. forced visibility for Picture-in-Picture float players, canvas widgets, or iframe overlays).
Annotated Code Walkthrough
1. Nesting Floating Widgets in Markup
<!DOCTYPE html>
<html lang="en">
<head>
<style>
body { height: 2000px; padding: 20px; }
#testdiv { width: 300px; height: 250px; background: #6c63ff; color: #fff; padding: 20px; }
#testcontainer { padding: 10px; background: #8b5cf6; cursor: pointer; margin-top: 10px; }
.float { position: fixed; bottom: 20px; right: 20px; z-index: 1000; }
</style>
</head>
<body>
<div id="testdiv">
Element to Track
<div id="testcontainer">Click to toggle float mode</div>
</div>
</body>
</html>
2. Custom Spectator Function Logic
Inject spectator logic into the spectators evaluation pipeline:
var subContainer = document.getElementById('testcontainer');
// Toggle floating class on container click
subContainer.addEventListener('click', function () {
this.classList.toggle('float');
});
// Custom Spectator function
function floatingWidgetSpectator(perceptorInstance, currentResult, previousRunResult) {
// If inner element has floating layout, force isVisible: true
if (subContainer && subContainer.classList.contains('float')) {
currentResult.isVisible = true;
currentResult.isFloated = true;
}
}
// Pass custom spectator to Perceptor options
var tracker = new Perceptor(document.querySelector('#testdiv'), {
spectators: [floatingWidgetSpectator],
});
tracker.watch();
Expected Behavior & Interactivity
- Standard Viewport Calculation: Initially, scrolling
#testdivout of view causesisVisibleto evaluate tofalse. - Override Mechanism: Clicking
#testcontainertoggles.float, fixing it to the viewport corner. The custom spectator detects.floatand forcesisVisible: trueregardless of scroll position.