1(function(){const{is,matchMedia,toArray,debounce,onResize,mergeObjects,prefersReducedMotion}=BreakdanceFrontend.utils;class BreakdanceParallax{tweens=[];enabledClass='breakdance-animation-enabled';animatingClass='is-animating';defaultOptions={enabled:!1,opacity:null,rotation:null,scale:null,x:null,y:null,blur:null,background_color:null,advanced:{ease:'linear',disable_at:null,relative_to:'viewport',origin:null,debug:!1}} 2initialized=!1;constructor(selector,options){gsap.registerPlugin(ScrollTrigger);this.createTween=this.createTween.bind(this);this.update=debounce(this._update,100);this.selector=selector;this.options=mergeObjects(this.defaultOptions,options);this.rootEl=document.documentElement;this.init()} 3parseValue(value){if(!value)return value;if(typeof value==='string'&&value.startsWith('var(')){const cssVar=value.replace(/var\(([^)]+)\)/,'$1');return getComputedStyle(this.element).getPropertyValue(cssVar)} 4return typeof value==='object'?value.style:value} 5parseAnchors(trigger){const[vBottom,vTop]=trigger||[0,100];return{bottom:100-vBottom,top:100-vTop}} 6getTrigger(relativeTo='viewport',selector){if(relativeTo==='page'){return document.documentElement}else if(relativeTo==='custom'&&selector){try{return document.querySelector(selector)}catch(e){}} 7return this.element} 8getScrollTriggerObject(values){const{bottom,top}=this.parseAnchors(values.trigger);const{debug,scrub,relative_to,relative_selector}=this.options.advanced;const speed=this.getDuration(scrub)||!0;let delayedCall;const trigger=this.getTrigger(relative_to,relative_selector);return{trigger:trigger,start:`top ${bottom}%`,end:`bottom ${top}%`,scrub:speed,markers:debug,toggleClass:'is-parallax-active',onUpdate:(self)=>{if(self.getVelocity()===0)return;this.element.classList.add(this.animatingClass);if(delayedCall)delayedCall.kill();delayedCall=gsap.delayedCall(0.3,()=>{this.element.classList.remove(this.animatingClass)})}}} 9createTween([prop,values]){const cssProp=prop.replace(/_/g,'-');const ease=this.options.advanced.ease;const scrollTrigger=this.getScrollTriggerObject(values);const startValue=this.parseValue(values.start);const middleValue=this.parseValue(values.middle);const endValue=this.parseValue(values.end);const from={[cssProp]:startValue,ease};const middle={[cssProp]:middleValue,ease};const to={[cssProp]:endValue,ease};const tl=gsap.timeline({scrollTrigger});const startEndSteps=!is.nil(startValue)&&!is.nil(endValue);const allSteps=startEndSteps&&!is.nil(middleValue);if(allSteps){tl.fromTo(this.element,from,middle);tl.to(this.element,to)}else if(startEndSteps){tl.fromTo(this.element,from,to)}else if(!is.nil(startValue)){tl.from(this.element,from)}else{tl.to(this.element,to)} 10return tl} 11canAnimate(){const breakpoint=this.options.advanced.disable_at;if(!breakpoint)return!0;return!matchMedia(breakpoint)} 12getDuration(value){if(!value)return value;if(value.unit==='s')return value.number;return value.number/1000} 13initTweens(){if(this.initialized)return;this.initialized=!0;const{origin}=this.options.advanced;if(origin){gsap.set(this.element,{transformOrigin:`${origin.x}% ${origin.y}%`})} 14this.tweens=Object.entries(this.options).filter(([,obj])=>!is.nil(obj?.start)||!is.nil(obj?.end)).map(this.createTween)} 15removeDebugMarkers(){const markers=['start','end','scroller-start','scroller-end'];markers.forEach((suffix)=>{const className=`.gsap-marker-${suffix}`;toArray(className).forEach((elem)=>elem.remove())})} 16_update(options){this.options=mergeObjects(this.defaultOptions,options);this.destroy();this.init()} 17destroyTweens(){if(!this.element)return;if(!this.tweens)return;this.tweens.forEach((tween)=>{tween.kill();tween.scrollTrigger?.kill()});this.tweens=[];gsap.set(this.element,{clearProps:'all'});this.initialized=!1} 18refresh(){ScrollTrigger.refresh(!0)} 19destroy(){this.destroyTweens();this.removeDebugMarkers()} 20initOrDestroy(){if(this.canAnimate()){this.initTweens()}else{this.destroyTweens()}} 21init(){if(!this.options.enabled)return;if(prefersReducedMotion())return;this.element=document.querySelector(this.selector);onResize(()=>this.initOrDestroy());this.rootEl.classList.add(this.enabledClass)} 22static autoload(){const loaded=imagesLoaded(document.body);loaded.on('always',()=>{const event=new Event("breakdance_refresh_animations",{bubbles:!0});document.dispatchEvent(event);ScrollTrigger.refresh(!0)})}} 23window.BreakdanceParallax=BreakdanceParallax;BreakdanceParallax.autoload()}())
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.