PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
| Dir : /home/distinctdesign/codenwebz.com/website-design-3/js/ |
| Server: Linux premium131.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64 IP: 162.0.232.53 |
| Dir : /home/distinctdesign/codenwebz.com/website-design-3/js/parallax.js |
/* global gsap, ScrollTrigger, imagesLoaded */
(function () {
const {
is,
matchMedia,
toArray,
debounce,
onResize,
mergeObjects,
prefersReducedMotion
} = BreakdanceFrontend.utils;
class BreakdanceParallax {
tweens = [];
enabledClass = 'breakdance-animation-enabled';
animatingClass = 'is-animating';
defaultOptions = {
enabled: false,
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: false
}
}
initialized = false;
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();
}
parseValue(value) {
if (!value) return value;
if (typeof value === 'string' && value.startsWith('var(')) {
// CSS variable
const cssVar = value.replace(/var\(([^)]+)\)/, '$1');
return getComputedStyle(this.element).getPropertyValue(cssVar);
}
// Unit value is an object.
return typeof value === 'object' ? value.style : value;
}
parseAnchors(trigger) {
const [vBottom, vTop] = trigger || [0, 100];
return {
bottom: 100 - vBottom,
top: 100 - vTop
}
}
getTrigger(relativeTo = 'viewport', selector) {
if (relativeTo === 'page') {
return document.documentElement;
} else if (relativeTo === 'custom' && selector) {
try {
return document.querySelector(selector);
} catch (e) {}
}
return this.element;
}
getScrollTriggerObject(values) {
const { bottom, top } = this.parseAnchors(values.trigger);
const { debug, scrub, relative_to, relative_selector } = this.options.advanced;
const speed = this.getDuration(scrub) || true;
let delayedCall;
const trigger = this.getTrigger(relative_to, relative_selector);
return {
trigger: trigger,
start: `top ${bottom}%`, // Element x Viewport
end: `bottom ${top}%`, // Element x Viewport
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);
});
}
};
}
createTween([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) {
// Start -> Middle -> End
tl.fromTo(this.element, from, middle);
tl.to(this.element, to);
} else if (startEndSteps) {
// Start -> End
tl.fromTo(this.element, from, to);
} else if (!is.nil(startValue)) {
// Start -> Original Value
tl.from(this.element, from);
} else {
// Original Value -> End
tl.to(this.element, to);
}
return tl;
}
canAnimate() {
const breakpoint = this.options.advanced.disable_at;
if (!breakpoint) return true;
return !matchMedia(breakpoint);
}
getDuration(value) {
if (!value) return value;
if (value.unit === 's') return value.number;
return value.number / 1000; // Convert MS to S
}
initTweens() {
if (this.initialized) return;
this.initialized = true;
const { origin } = this.options.advanced;
if (origin) {
gsap.set(this.element, {
transformOrigin: `${origin.x}% ${origin.y}%`
});
}
this.tweens = Object.entries(this.options)
.filter(([, obj]) => !is.nil(obj?.start) || !is.nil(obj?.end))
.map(this.createTween);
}
removeDebugMarkers() {
// Remove ScrollTrigger markers
const markers = [
'start',
'end',
'scroller-start',
'scroller-end'
];
markers.forEach((suffix) => {
const className = `.gsap-marker-${suffix}`;
toArray(className).forEach((elem) => elem.remove());
});
}
_update(options) {
this.options = mergeObjects(this.defaultOptions, options);
this.destroy();
this.init();
}
destroyTweens() {
if (!this.element) return;
if (!this.tweens) return;
this.tweens.forEach((tween) => {
// Killing the tween should automatically kill scrollTrigger,
// but that's always not the case for some reason.
tween.kill();
tween.scrollTrigger?.kill();
});
this.tweens = [];
// Remove all inline styles
gsap.set(this.element, {
clearProps: 'all'
});
this.initialized = false;
}
refresh() {
ScrollTrigger.refresh(true);
}
destroy() {
this.destroyTweens();
this.removeDebugMarkers();
}
initOrDestroy() {
if (this.canAnimate()) {
this.initTweens();
} else {
this.destroyTweens();
}
}
init() {
if (!this.options.enabled) return;
if (prefersReducedMotion()) return;
this.element = document.querySelector(this.selector);
onResize(() => this.initOrDestroy());
this.rootEl.classList.add(this.enabledClass);
}
static autoload() {
const loaded = imagesLoaded(document.body);
loaded.on('always', () => {
// Refresh all instances.
const event = new Event("breakdance_refresh_animations", { bubbles: true });
document.dispatchEvent(event);
// Refresh ScrollTrigger only once.
ScrollTrigger.refresh(true);
});
}
}
window.BreakdanceParallax = BreakdanceParallax;
// Autoload
BreakdanceParallax.autoload();
}());