/*
* 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 );
Add a touch of timeless tradition and vibrant artistry to your home with these exquisite Lipan Art Dreamcatchers, beautifully blending the cultural heritage of Gujarat’s Lippan Kaam with the elegance of contemporary décor.
Material & Finish:
•Made on a premium MDF base
•Adorned with tiny decorative mirrors
•Painted with vibrant acrylic colors
•Sealed with a protective glossy coat for longevity
Rainbow Theme with colorful wool tassels – vibrant and joyful
]]>Add a touch of timeless tradition and vibrant artistry to your home with these exquisite Lipan Art Dreamcatchers, beautifully blending the cultural heritage of Gujarat’s Lippan Kaam with the elegance of contemporary décor.
]]>Made by : Happy Handz
Materials: resin, wood, texture paste
The picture is absolutely stunning 16 inches (40cm) resin art wall clock. It is handmade wall decor, which can be unique wedding gift. Custom black sea clock in black, silver and white.
The clock goes with the working mechanism. The base of the clock is made of pressed wood. The reverse side consists of a metal mount on a wooden canvas. The product has a silent movement, it needs a battery.
IMPORTANT: To avoid damaging of clock’s hands, they are placed separately from the clock. The instruction on how to set up the time will be inside the box.
To prevent yellowing of resin, avoid excessive UV/sunlight.
PRODUCT CARE: In order not to scratch the resin, you need to wipe with microfibre and in no case rub with aggressive chemicals.
MATERIALS: MDF, pigments, non-toxic resin, acrylic accessories.
IMPORTANT NOTE for European countries, Canada and Australia:
In case of the large size of the package, you can pay customs duties and import taxes. The amount of taxes depends on the laws of your country. Import duties, taxes or charges are NOT included in the item price or shipping charges. These charges are the buyer’s responsibility, which are normally collected by the delivering freight (shipping) company or when you pick the item up – do not confuse them for additional shipping charges..
Due to the differences between different monitors, the picture may not reflect the actual colour of the item.
ORDER. PRODUCTION TIME: 10-15 days.
DELIVERY TIME: 1 weeks.
If you could give me a positive feedback, I would appreciate it. Do not hesitate to contact me in case of any questions. For custom orders please message the shop owner (me 
Thank you for your time.
Sincerely,
your – Happy Handz