/**
* FlexTools - A utility class for handling CSS animations dynamically.
*
* This class provides animation presets, handles viewability detection,
* and applies animations on elements based on user-defined settings.
*/
class FlexTools {
/**
* Constructor initializes animation presets and speed settings.
* Also, loads an external stylesheet for animations.
*/
constructor() {
// Predefined animation presets with corresponding animation types and durations
this.Presets = {
"fade-slow": { animationType: "fadeIn", duration: "2000ms"},
"fade-fast": { animationType: "fadeIn", duration: "800ms"},
"fadedown-slow": { animationType: "fadeInDown", duration: "2000ms"},
"fadedown-fast": { animationType: "fadeInDown", duration: "800ms"},
"fadeup-slow": { animationType: "fadeInUp", duration: "2000ms"},
"fadeup-fast": { animationType: "fadeInUp", duration: "800ms"},
"slidein-left": { animationType: "slideInLeft", duration: "800ms"},
"slidein-right": { animationType: "slideInRight", duration: "800ms"}
}
// Speed presets for quick configuration
this.SpeedPreset = {"fast": {speed: "800ms"},"faster": {speed:"500ms"},"slow": {speed: "2000ms"},"slower": {speed: "3000ms"}}
// Load external animation stylesheet
let externalStyle = document.createElement("link");
externalStyle.href = "https://static01.nytimes.com/ads/tbrandcreativetech/libs/flex-suite/utilities/animation/animateCSS.css";
externalStyle.rel = "stylesheet";
externalStyle.type = "text/css";
document.body.appendChild(externalStyle);
}
/**
* Triggers an animation on an element when it becomes visible in the viewport.
*
* @param {string} element - The CSS selector for the target element.
* @param {string} [type="fadeIn"] - The animation type (default is "fadeIn").
* @param {string} [duration="800ms"] - Duration of the animation.
* @param {string} [delay="0ms"] - Delay before animation starts.
* @param {number} [repeat=0] - Number of times the animation repeats.
*/
Animate = function (element,type = "fadeIn", duration = "800ms", delay = "0ms", repeat = 0) {
let playLimit = 1;
let currentPlayCount = 0;
/**
* Uses Intersection Observer to detect when an element is in the viewport.
* @param {Object} Ad - Object containing container element and visibility handlers.
*/
function VisibilityUsingObserver(Ad) {
const options = {root: null, rootMargin: '0px',threshold: 0.3};
const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => {if (entry.isIntersecting) { Ad.visible(); } else { Ad.hidden(); }});}, options);
observer.observe(Ad.container);
}
// Start viewability detection on the element
VisibilityUsingObserver({
"container": document.querySelector(element),
"visible": () => {
if (currentPlayCount < playLimit) {
currentPlayCount++;
this.AnimateOnDemand (element,type, duration , delay, repeat);
}
},
"hidden": () => {}
});
}
ViewabilityDetection(data) {
let playLimit = 1000;
let currentPlayCount = 0;
if ((data["playOnce"]) || (data["playOnce"] == undefined)) {
playLimit = 1;
}
function VisibilityUsingObserver(Ad) {
const options = {root: null, rootMargin: '0px',threshold: data.threshold ? data.threshold : 0.3};