/*
* By Elementor Team
*/
( function( $ ) {
var Sticky = function( element, userSettings ) {
var $element,
isSticky = false,
isFollowingParent = false,
isReachedEffectsPoint = false,
elements = {},
settings,
elementOffsetValue,
elementWidth;
var defaultSettings = {
to: 'top',
offset: 0,
effectsOffset: 0,
parent: false,
classes: {
sticky: 'sticky',
stickyActive: 'sticky-active',
stickyEffects: 'sticky-effects',
spacer: 'sticky-spacer',
},
isRTL: false,
isScrollSnapActive: false,
handleScrollbarWidth: false,
};
var initElements = function() {
$element = $( element ).addClass( settings.classes.sticky );
elements.$window = $( window );
elements.$body = $( document ).find( 'body' );
if ( settings.parent ) {
elements.$parent = $element.parent();
if ( 'parent' !== settings.parent ) {
elements.$parent = elements.$parent.closest( settings.parent );
}
}
};
var initSettings = function() {
settings = jQuery.extend( true, defaultSettings, userSettings );
};
var bindEvents = function() {
elements.$window.on( 'resize', onWindowResize );
if ( settings.isScrollSnapActive ) {
elements.$body.on( 'scroll', onWindowScroll );
} else {
elements.$window.on( 'scroll', onWindowScroll );
}
};
var unbindEvents = function() {
elements.$window
.off( 'scroll', onWindowScroll )
.off( 'resize', onWindowResize );
elements.$body.off( 'scroll', onWindowScroll );
};
var init = function() {
initSettings();
initElements();
bindEvents();
checkPosition();
};
var backupCSS = function( $elementBackupCSS, backupState, properties ) {
var css = {},
elementStyle = $elementBackupCSS[ 0 ].style;
properties.forEach( function( property ) {
css[ property ] = undefined !== elementStyle[ property ] ? elementStyle[ property ] : '';
} );
$elementBackupCSS.data( 'css-backup-' + backupState, css );
};
var getCSSBackup = function( $elementCSSBackup, backupState ) {
return $elementCSSBackup.data( 'css-backup-' + backupState );
};
const updateElementSizesData = () => {
elementWidth = getElementOuterSize( $element, 'width' );
elementOffsetValue = $element.offset().left;
if ( settings.isRTL ) {
// `window.innerWidth` includes the scrollbar while `document.body.offsetWidth` doesn't.
const documentWidth = settings.handleScrollbarWidth ? window.innerWidth : document.body.offsetWidth;
elementOffsetValue = Math.max( documentWidth - elementWidth - elementOffsetValue, 0 );
}
}
var addSpacer = function() {
elements.$spacer = $element.clone()
.addClass( settings.classes.spacer )
.css( {
visibility: 'hidden',
transition: 'none',
animation: 'none',
} );
$element.after( elements.$spacer );
};
var removeSpacer = function() {
elements.$spacer.remove();
};
var stickElement = function() {
backupCSS( $element, 'unsticky', [ 'position', 'width', 'margin-top', 'margin-bottom', 'top', 'bottom', 'inset-inline-start' ] );
const css = {
position: 'fixed',
width: elementWidth,
marginTop: 0,
marginBottom: 0,
};
css[ settings.to ] = settings.offset;
css[ 'top' === settings.to ? 'bottom' : 'top' ] = '';
if ( elementOffsetValue ) {
css[ 'inset-inline-start' ] = elementOffsetValue + 'px';
}
$element
.css( css )
.addClass( settings.classes.stickyActive );
};
var unstickElement = function() {
$element
.css( getCSSBackup( $element, 'unsticky' ) )
.removeClass( settings.classes.stickyActive );
};
var followParent = function() {
backupCSS( elements.$parent, 'childNotFollowing', [ 'position' ] );
elements.$parent.css( 'position', 'relative' );
backupCSS( $element, 'notFollowing', [ 'position', 'inset-inline-start', 'top', 'bottom' ] );
const css = {
position: 'absolute',
};
elementOffsetValue = elements.$spacer.position().left;
if ( settings.isRTL ) {
const parentWidth = $element.parent().outerWidth(),
elementOffsetValueLeft = elements.$spacer.position().left;
elementWidth = elements.$spacer.outerWidth();
elementOffsetValue = Math.max( parentWidth - elementWidth - elementOffsetValueLeft, 0 );
}
css[ 'inset-inline-start' ] = elementOffsetValue + 'px';
css[ settings.to ] = '';
css[ 'top' === settings.to ? 'bottom' : 'top' ] = 0;
$element.css( css );
isFollowingParent = true;
};
var unfollowParent = function() {
elements.$parent.css( getCSSBackup( elements.$parent, 'childNotFollowing' ) );
$element.css( getCSSBackup( $element, 'notFollowing' ) );
isFollowingParent = false;
};
var getElementOuterSize = function( $elementOuterSize, dimension, includeMargins ) {
var computedStyle = getComputedStyle( $elementOuterSize[ 0 ] ),
elementSize = parseFloat( computedStyle[ dimension ] ),
sides = 'height' === dimension ? [ 'top', 'bottom' ] : [ 'left', 'right' ],
propertiesToAdd = [];
if ( 'border-box' !== computedStyle.boxSizing ) {
propertiesToAdd.push( 'border', 'padding' );
}
if ( includeMargins ) {
propertiesToAdd.push( 'margin' );
}
propertiesToAdd.forEach( function( property ) {
sides.forEach( function( side ) {
elementSize += parseFloat( computedStyle[ property + '-' + side ] );
} );
} );
return elementSize;
};
var getElementViewportOffset = function( $elementViewportOffset ) {
var windowScrollTop = elements.$window.scrollTop(),
elementHeight = getElementOuterSize( $elementViewportOffset, 'height' ),
viewportHeight = innerHeight,
elementOffsetFromTop = $elementViewportOffset.offset().top,
distanceFromTop = elementOffsetFromTop - windowScrollTop,
topFromBottom = distanceFromTop - viewportHeight;
return {
top: {
fromTop: distanceFromTop,
fromBottom: topFromBottom,
},
bottom: {
fromTop: distanceFromTop + elementHeight,
fromBottom: topFromBottom + elementHeight,
},
};
};
var stick = function() {
updateElementSizesData();
addSpacer();
stickElement();
isSticky = true;
$element.trigger( 'sticky:stick' );
};
var unstick = function() {
unstickElement();
removeSpacer();
isSticky = false;
$element.trigger( 'sticky:unstick' );
};
var checkParent = function() {
var elementOffset = getElementViewportOffset( $element ),
isTop = 'top' === settings.to;
if ( isFollowingParent ) {
var isNeedUnfollowing = isTop ? elementOffset.top.fromTop > settings.offset : elementOffset.bottom.fromBottom < -settings.offset;
if ( isNeedUnfollowing ) {
unfollowParent();
}
} else {
var parentOffset = getElementViewportOffset( elements.$parent ),
parentStyle = getComputedStyle( elements.$parent[ 0 ] ),
borderWidthToDecrease = parseFloat( parentStyle[ isTop ? 'borderBottomWidth' : 'borderTopWidth' ] ),
parentViewportDistance = isTop ? parentOffset.bottom.fromTop - borderWidthToDecrease : parentOffset.top.fromBottom + borderWidthToDecrease,
isNeedFollowing = isTop ? parentViewportDistance <= elementOffset.bottom.fromTop : parentViewportDistance >= elementOffset.top.fromBottom;
if ( isNeedFollowing ) {
followParent();
}
}
};
var checkEffectsPoint = function( distanceFromTriggerPoint ) {
if ( isReachedEffectsPoint && -distanceFromTriggerPoint < settings.effectsOffset ) {
$element.removeClass( settings.classes.stickyEffects );
isReachedEffectsPoint = false;
} else if ( ! isReachedEffectsPoint && -distanceFromTriggerPoint >= settings.effectsOffset ) {
$element.addClass( settings.classes.stickyEffects );
isReachedEffectsPoint = true;
}
};
var checkPosition = function() {
var offset = settings.offset,
distanceFromTriggerPoint;
if ( isSticky ) {
var spacerViewportOffset = getElementViewportOffset( elements.$spacer );
distanceFromTriggerPoint = 'top' === settings.to ? spacerViewportOffset.top.fromTop - offset : -spacerViewportOffset.bottom.fromBottom - offset;
if ( settings.parent ) {
checkParent();
}
if ( distanceFromTriggerPoint > 0 ) {
unstick();
}
} else {
var elementViewportOffset = getElementViewportOffset( $element );
distanceFromTriggerPoint = 'top' === settings.to ? elementViewportOffset.top.fromTop - offset : -elementViewportOffset.bottom.fromBottom - offset;
if ( distanceFromTriggerPoint <= 0 ) {
stick();
if ( settings.parent ) {
checkParent();
}
}
}
checkEffectsPoint( distanceFromTriggerPoint );
};
var onWindowScroll = function() {
checkPosition();
};
var onWindowResize = function() {
if ( ! isSticky ) {
return;
}
unstickElement();
removeSpacer();
updateElementSizesData();
addSpacer();
stickElement();
if ( settings.parent ) {
// Force recalculation of the relation between the element and its parent.
isFollowingParent = false;
checkParent();
}
};
this.destroy = function() {
if ( isSticky ) {
unstick();
}
unbindEvents();
$element.removeClass( settings.classes.sticky );
};
init();
};
$.fn.sticky = function( settings ) {
var isCommand = 'string' === typeof settings;
this.each( function() {
var $this = $( this );
if ( ! isCommand ) {
$this.data( 'sticky', new Sticky( this, settings ) );
return;
}
var instance = $this.data( 'sticky' );
if ( ! instance ) {
throw Error( 'Trying to perform the `' + settings + '` method prior to initialization' );
}
if ( ! instance[ settings ] ) {
throw ReferenceError( 'Method `' + settings + '` not found in sticky instance' );
}
instance[ settings ].apply( instance, Array.prototype.slice.call( arguments, 1 ) );
if ( 'destroy' === settings ) {
$this.removeData( 'sticky' );
}
} );
return this;
};
window.Sticky = Sticky;
} )( jQuery );
Note on Handmade Products & Materials
All our creations are handmade, and slight variations may occur in color, texture, or finishing compared to the product pictures. These variations are due to the availability of materials and the natural uniqueness of handmade craftsmanship. We ensure that any substitutions will be made with the closest possible materials while maintaining the overall look, quality, and design of the product. This uniqueness makes every piece one-of-a-kind and special for you.
Convenient and mess-free: No need for sprays or liquids—simply place the wax tablet in your desired location and let the fragrance unfold.
Thoughtful gift: Share the gift of luxurious fragrance with friends and loved ones, perfect for any occasion.
Rose Quartz purifies and opens the heart at all levels to promote love, self-love, friendship, deep inner healing and feelings of peace which makes this tray a must gift and an essential to have at home!
Made with Rose quartz theme, this beautiful blush rectangular resin tray is a perfect addition to your home.
Looks extremely gorgeous on table as a vanity tray and for keeping your perfumes.
Comes with the option of 4 beautiful Resin Coasters.
Measurements: 11.81 x 7.87 inches
HANDMADE Resin Tray
The tray is made of epoxy resin and the sides are painted with Gold. Edges are decorated with rose quartz and stones are all around the tray.
How it is made?
The resin of most highest quality is used with gold flakes and crushed glass stones. Once tray is made, it is decorated with gold edges to give it an eye catching look.
Perfect for birthdays, gift parties, valentines gift, gift for loved ones.
Resin Product Care
1. Please handle with care as if. you are handling glass.
2. Keep out of direct sunlight.
3. Do not place in the dishwasher or microwave.
4. Hand wash only.
5. Do not clean with alcohol based products.
]]>