Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

vanilla-marquee

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vanilla-marquee - npm Package Compare versions

Comparing version 1.0.4 to 1.1.0

35

dist/vanilla-marquee.d.ts

@@ -33,2 +33,6 @@ declare module "vanilla-marquee" {

/**
* - Recalculate the marquee position on resize (breaks compatibility with jquery.marquee)
*/
recalcResize?: boolean | undefined;
/**
* - Speed will override duration. Speed allows you to set a relatively constant marquee speed regardless of the width of the containing element. Speed is measured in pixels/second

@@ -54,13 +58,10 @@ */

constructor(el: Element, opts: defaultOptions);
el: Element;
_loopCount: number;
_marqWrap: any;
_contHeight: number | undefined;
_elHeight: any;
_completeDuration: number | undefined;
_contWidth: number | undefined;
_elWidth: number | undefined;
_marqWrap: Element;
_vertical: boolean;
_duration: number | undefined;
_opts: defaultOptions;
_animName: string;
_animStr: string;
el: Element;
/**

@@ -70,2 +71,3 @@ * Method for animation end event

_animEnd: () => void;
_instance: number;
/**

@@ -90,2 +92,3 @@ * Build the css string for the animation

private _animate;
_status: string | undefined;
/**

@@ -110,6 +113,22 @@ * Event fired on Animation iteration

/**
* Calculates the speed and the dimension of the marquee
*
* @private
*/
private _calcSizes;
_contHeight: number | undefined;
_elHeight: number | undefined;
_completeDuration: number | undefined;
_contWidth: number | undefined;
_elWidth: number | undefined;
/**
* Recalculates the dimensions and positon of the marquee on page resize
*
* @private
*/
private _recalcResize;
/**
* Pause the animation
*/
pause(): void;
_status: string | undefined;
/**

@@ -116,0 +135,0 @@ * Resume the animation

@@ -0,7 +1,41 @@

/**
* Shorthand for `document.getElementById`
*
* @param {String} id - The selector's id
*
* @returns {Element|null} - The selected element
*/
/**
* Shorthand for `document.getElementsByClassName`
*
* @param {String} selClass - The selector's class
* @param {Element} [parent=document] - Parent element
*
* @returns {HTMLCollection} - The selected elements
*/
function byClass(selClass, parent = document) {
return parent.getElementsByClassName(selClass);
}
/**
* Shorthand for `document.querySelector`
*
* @param {String} selector - Selector
* @param {Element} [parent=document] - Parent element
*
* @returns {Element|null} - The selected element
*/
function query(selector, parent = document) {
return parent.querySelector(selector);
}
/**
* Shorthand per `document.querySelectorAll`
*
* @param {String} selector - Selector
* @param {Element} [parent=document] - Parent element
*
* @returns {NodeList} - The selected element
*/
function queryAll(selector, parent = document) {

@@ -11,2 +45,10 @@ return parent.querySelectorAll(selector);

/**
* Foreach polyfill for NodeList and HTMLCollection
* https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/
*
* @param {Array|NodeList|HTMLCollection} els - A list of elements
* @param {foreachCB} fn - Callback containing ( value, index ) as arguments
* @param {Scope} [scope] - Scope
*/
function forEachHTML(els, fn, scope) {

@@ -16,2 +58,9 @@ for (let i = 0, numEls = els.length; i < numEls; i++) fn.call(scope, els[i], i);

/**
* Shorthand for `element.classList.add`, works with multiple nodes
*
* @param {Element|HTMLCollection|NodeList} el - A list of elements
* @param {...String} classes - Classes to add
*/
function addClass(el, ...classes) {

@@ -23,2 +72,8 @@ if (el.length === undefined) addClassEl(el, ...classes);else {

}
/**
* Adds classes to a single element
*
* @param {Element} elem - An HTML element
* @param {...String} remClass - Classes to add
*/

@@ -32,5 +87,22 @@ function addClassEl(elem, ...remClass) {

/**
* Shorthand for `element.addEventListener`
*
* @param {Element|HTMLCollection|NodeList} el - A list of elements
* @param {String} ev - Event's name
* @param {Function} fn - Event's function
* @param {Object} [opts] - Optional event options
*/
function addEvent(el, ev, fn, opts) {
el.addEventListener(ev, fn, opts);
}
/**
* Shorthand for `element.removeEventListener`
*
* @param {Element|HTMLCollection|NodeList} el - A list of elements
* @param {String} ev - Event's name
* @param {Function} fn - Event's function
* @param {Object} [opts] - Optional event options
*/
function removeEvent(el, ev, fn, opts) {

@@ -40,8 +112,31 @@ el.removeEventListener(ev, fn, opts);

/**
* Shorthand for `element.getAttribute`
*
* @param {Element} el - An HTML element
* @param {String} attr - The attribute to retrieve
*
* @returns {String} - The attribute's value
*/
function getAttr(el, attr) {
return el.getAttribute(attr);
}
/**
* Shorthand for `element.setAttribute`
*
* @param {Element} el - An HTML element
* @param {String} attr - The attribute to retrieve
* @param {String} val - The value to set to the attribute
*/
function setAttr(el, attr, val) {
el.setAttribute(attr, val);
}
/**
* Shorthand for `element.removeAttribute`
*
* @param {Element} el - An HTML element
* @param {String} attr - The attribute to remove
*/
function remAttr(el, attr) {

@@ -60,2 +155,3 @@ el.removeAttribute(attr);

* @property {Boolean} [pauseOnHover=false] - Pause the marquee on hover
* @property {Boolean} [recalcResize=false] - Recalculate the marquee position on resize (breaks compatibility with jquery.marquee)
* @property {Number} [speed=0] - Speed will override duration. Speed allows you to set a relatively constant marquee speed regardless of the width of the containing element. Speed is measured in pixels/second

@@ -72,2 +168,3 @@ * @property {Boolean} [startVisible=false] - The marquee will be visible from the start if set to `true`

pauseOnHover: false,
recalcResize: false,
speed: 0,

@@ -77,2 +174,4 @@ startVisible: false,

let instances = 0;
/**

@@ -106,2 +205,3 @@ * Vanilla js marquee based on jQuery.marquee

this.el = el;
this._loopCount = 3;

@@ -154,71 +254,9 @@

this._marqWrap = marqWrap;
this._vertical = vertical;
this._duration = opts.duration;
this._opts = opts;
// If direction is up or down, get the height of main element
if ( vertical ) {
this._calcSizes();
const contHeight = el.clientHeight;
this._contHeight = contHeight;
remAttr( marqWrap, 'style' );
el.style.clientHeight = `${contHeight}px`;
const marqs = byClass( 'js-marquee', el ),
marqNums = marqs.length - 1;
// Change the CSS for js-marquee element
forEachHTML( marqs, ( currEl, ind ) => {
currEl.style.float = 'none';
currEl.style.marginRight = '0px';
// Remove bottom margin from 2nd element if duplicated
if ( opts.duplicated && ind === marqNums )
currEl.style.marginBottom = '0px';
else
currEl.style.marginBottom = `${opts.gap}px`;
});
const elHeight = parseInt( marqs[0].clientHeight + opts.gap );
this._elHeight = el_elHeight;
// adjust the animation duration according to the text length
if ( opts.startVisible && !opts.duplicated ) {
// Compute the complete animation duration and save it for later reference
// formula is to: (Height of the text node + height of the main container / Height of the main container) * duration;
this._completeDuration = ( elHeight + contHeight) / parseInt( contHeight ) * opts.duration;
opts.duration = elHeight / parseInt( contHeight ) * opts.duration;
} else // formula is to: (Height of the text node + height of the main container / Height of the main container) * duration;
opts.duration = elHeight / parseInt( contHeight ) / parseInt( contHeight ) * opts.duration;
} else {
// Save the width of the each element so we can use it in animation
const elWidth = parseInt( byClass( 'js-marquee', el )[0].clientWidth + opts.gap ),
contWidth = el.clientWidth;
this._contWidth = contWidth;
this._elWidth = elWidth;
// adjust the animation duration according to the text length
if ( opts.startVisible && !opts.duplicated ) {
// Compute the complete animation duration and save it for later reference
// formula is to: (Width of the text node + width of the main container / Width of the main container) * duration;
this._completeDuration = ( elWidth + contWidth) / parseInt( contWidth ) * opts.duration;
// (Width of the text node / width of the main container) * duration
opts.duration = elWidth / parseInt( contWidth ) * opts.duration;
} else // formula is to: (Width of the text node + width of the main container / Width of the main container) * duration;
opts.duration = ( elWidth + parseInt( contWidth ) ) / parseInt( contWidth ) * opts.duration;
}
// if duplicated then reduce the duration
if ( opts.duplicated )
opts.duration = opts.duration / 2;
this._opts = opts;
const animationName = 'marqueeAnimation-' + Math.floor( Math.random() * 10000000 ),
const animationName = `marqueeAnimation-${Math.floor( Math.random() * 10000000 )}`,
animStr = this._animationStr(

@@ -228,3 +266,3 @@ animationName,

opts.delayBeforeStart / 1000,
'infinite'
'infinite',
);

@@ -243,10 +281,10 @@

else
this._marqWrap.style.transform = `translateY(${opts.direction === 'up' ? this._contHeight : ( -1 * ( ( this._elHeight * 2 ) - opts.gap ) ) }px)`;
this._marqWrap.style.transform = `translateY(${opts.direction === 'up' ? this._contHeight : ( -1 * ( ( this._elHeight * 2 ) - opts.gap ) )}px)`;
} else {
if ( opts.startVisible )
if ( opts.startVisible ) // eslint-disable-line no-lonely-if
this._marqWrap.style.transform = 'translateX(0px)';
else
this._marqWrap.style.transform = `translateX(${opts.direction === 'left' ? this._contWidth : ( -1 * ( ( this._elWidth * 2 ) - opts.gap ) ) }px)`;
this._marqWrap.style.transform = `translateX(${opts.direction === 'left' ? this._contWidth : ( -1 * ( ( this._elWidth * 2 ) - opts.gap ) )}px)`;

@@ -265,10 +303,10 @@ }

} else {
if ( vertical )
if ( vertical ) // eslint-disable-line no-lonely-if
this._repositionVert();
else
this._repositionHor();
}
this.el = el;
addEvent( this.el, 'pause', this.pause.bind( this ) );

@@ -292,4 +330,10 @@ addEvent( this.el, 'resume', this.resume.bind( this ) );

this._instance = instances;
instances++;
this._animate( vertical );
if ( opts.recalcResize )
addEvent( window, 'resize', this._recalcResize.bind( this ) );
}

@@ -337,3 +381,3 @@

duration / 1000,
opts.delayBeforeStart / 1000
opts.delayBeforeStart / 1000,
);

@@ -348,3 +392,3 @@

0,
'infinite'
'infinite',
);

@@ -366,3 +410,3 @@ }

animationCss = `translateY(${( opts.direction === 'up' ) ? -1 * this._elHeight : 0 }px)`;
animationCss = `translateY(${( opts.direction === 'up' ) ? -1 * this._elHeight : 0}px)`;

@@ -375,8 +419,8 @@ } else if ( opts.startVisible ) {

// Adjust the css3 animation as well
this._animStr = _animationStr(
this._animStr = this._animationStr(
this._animName,
opts.duration / 1000,
opts.delayBeforeStart / 1000
opts.delayBeforeStart / 1000,
);
animationCss = `translateY(${( opts.direction === 'up' ) ? -1 * this._elHeight : this._contHeight }px)`;
animationCss = `translateY(${( opts.direction === 'up' ) ? -1 * this._elHeight : this._contHeight}px)`;

@@ -388,7 +432,7 @@ this._loopCount++;

this._animName = `${this._animName}0`;
this._animStr = _animationStr(
this._animStr = this._animationStr(
this._animName,
this._completeDuration / 1000,
0,
'infinite'
'infinite',
);

@@ -406,4 +450,5 @@ this._repositionVert();

} else {
if ( opts.duplicated ) {
if ( opts.duplicated ) { // eslint-disable-line no-lonely-if
// Adjust the starting point of animation only when first loops finishes

@@ -413,3 +458,3 @@ if ( this._loopCount > 2 )

animationCss = `translateX(${( opts.direction === 'left' ) ? -1 * this._elWidth : 0 }px)`;
animationCss = `translateX(${( opts.direction === 'left' ) ? -1 * this._elWidth : 0}px)`;

@@ -422,8 +467,8 @@ } else if ( opts.startVisible ) {

// Adjust the css3 animation as well
this._animStr = _animationStr(
this._animStr = this._animationStr(
this._animName,
opts.duration / 1000,
opts.delayBeforeStart / 1000
opts.delayBeforeStart / 1000,
);
animationCss = `translateX(${( opts.direction === 'left' ) ? -1 * this._elWidth : this._contWidth }px)`;
animationCss = `translateX(${( opts.direction === 'left' ) ? -1 * this._elWidth : this._contWidth}px)`;

@@ -436,7 +481,7 @@ this._loopCount++;

this._animName = `${this._animName}0`;
this._animStr = _animationStr(
this._animStr = this._animationStr(
this._animName,
opts.duration / 1000,
0,
'infinite'
'infinite',
);

@@ -460,17 +505,16 @@ this._repositionHor();

const keyFrameCss = `@keyframes ${this._animName} {
100% {
transform: ${animationCss};
}
}`;
100% {
transform: ${animationCss};
}
}`,
styles = queryAll( 'style', this._marqWrap );
const styles = queryAll( 'style', this._marqWrap );
if ( styles.length )
styles[styles.length - 1].innerHTML = keyFrameCss;
else if ( byClass( 'marq-wrap-style' ).length )
byClass( 'marq-wrap-style' )[0].innerHTML = keyFrameCss;
else if ( byClass( `marq-wrap-style-${this._instance}` ).length )
byClass( `marq-wrap-style-${this._instance}` )[0].innerHTML = keyFrameCss;
else {
const styleEl = document.createElement( 'style' );
addClass( styleEl, 'marq-wrap-style' );
addClass( styleEl, `marq-wrap-style-${this._instance}` );
styleEl.innerHTML = keyFrameCss;

@@ -492,3 +536,3 @@

this._status === 'running';
this._status = 'running';
setAttr( this.el, 'data-runningStatus', 'resumed' );

@@ -513,3 +557,3 @@

_repositionVert() {
this._marqWrap.style.transform = `translateY(${ this._opts.direction === 'up' ? this._contHeight : ( this._elHeight * -1 ) }px)`;
this._marqWrap.style.transform = `translateY(${this._opts.direction === 'up' ? this._contHeight : ( this._elHeight * -1 )}px)`;
}

@@ -523,6 +567,95 @@

_repositionHor() {
this._marqWrap.style.transform = `translateX(${ this._opts.direction === 'left' ? this._contWidth : ( this._elWidth * -1 ) }px)`;
this._marqWrap.style.transform = `translateX(${this._opts.direction === 'left' ? this._contWidth : ( this._elWidth * -1 )}px)`;
}
/**
* Calculates the speed and the dimension of the marquee
*
* @private
*/
_calcSizes() {
const el = this.el,
opts = this._opts;
// If direction is up or down, get the height of main element
if ( this._vertical ) {
const contHeight = el.clientHeight;
this._contHeight = contHeight;
remAttr( this._marqWrap, 'style' );
el.style.clientHeight = `${contHeight}px`;
const marqs = byClass( 'js-marquee', el ),
marqNums = marqs.length - 1;
// Change the CSS for js-marquee element
forEachHTML( marqs, ( currEl, ind ) => {
currEl.style.float = 'none';
currEl.style.marginRight = '0px';
// Remove bottom margin from 2nd element if duplicated
if ( opts.duplicated && ind === marqNums )
currEl.style.marginBottom = '0px';
else
currEl.style.marginBottom = `${opts.gap}px`;
});
const elHeight = parseInt( marqs[0].clientHeight + opts.gap );
this._elHeight = elHeight;
// adjust the animation duration according to the text length
if ( opts.startVisible && !opts.duplicated ) {
// Compute the complete animation duration and save it for later reference
// formula is to: (Height of the text node + height of the main container / Height of the main container) * duration;
this._completeDuration = ( elHeight + contHeight ) / parseInt( contHeight ) * this._duration; // eslint-disable-line max-len
opts.duration = elHeight / parseInt( contHeight ) * this._duration;
} else // formula is to: (Height of the text node + height of the main container / Height of the main container) * duration;
opts.duration = elHeight / parseInt( contHeight ) / parseInt( contHeight ) * this._duration;
} else {
// Save the width of the each element so we can use it in animation
const elWidth = parseInt( byClass( 'js-marquee', el )[0].clientWidth + opts.gap ),
contWidth = el.clientWidth;
this._contWidth = contWidth;
this._elWidth = elWidth;
// adjust the animation duration according to the text length
if ( opts.startVisible && !opts.duplicated ) {
// Compute the complete animation duration and save it for later reference
// formula is to: (Width of the text node + width of the main container / Width of the main container) * duration;
this._completeDuration = ( elWidth + contWidth ) / parseInt( contWidth ) * this._duration;
// (Width of the text node / width of the main container) * duration
opts.duration = elWidth / parseInt( contWidth ) * this._duration;
} else // formula is to: (Width of the text node + width of the main container / Width of the main container) * duration;
opts.duration = ( elWidth + parseInt( contWidth ) ) / parseInt( contWidth ) * this._duration; // eslint-disable-line max-len
}
// if duplicated then reduce the duration
if ( opts.duplicated )
opts.duration = opts.duration / 2;
}
/**
* Recalculates the dimensions and positon of the marquee on page resize
*
* @private
*/
_recalcResize() {
this._calcSizes();
this._loopCount = 2;
this._animEnd();
}
/**
* Pause the animation

@@ -584,2 +717,5 @@ */

if ( this._opts.recalcResize )
removeEvent( window, 'resize', this._recalcResize.bind( this ) );
}

@@ -586,0 +722,0 @@

@@ -1,1 +0,1 @@

function t(t,s=document){return s.getElementsByClassName(t)}function s(t,s,i){for(let e=0,n=t.length;e<n;e++)s.call(i,t[e],e)}function i(t,s,i,e){t.addEventListener(s,i,e)}function e(t,s,i,e){t.removeEventListener(s,i,e)}function n(t,s){return t.getAttribute(s)}function h(t,s,i){t.setAttribute(s,i)}const a={css3easing:"linear",delayBeforeStart:1e3,direction:"left",duplicated:!1,duration:5e3,gap:20,pauseOnHover:!1,speed:0,startVisible:!1};export default class{constructor(e,h){if(void 0===e)throw new Error("el cannot be undefined");if("string"==typeof e)throw new Error("el cannot be just a selector");if(null===e)throw new Error("el cannot be null");h={...a,...h},this.t=3;for(const t in a){let s=n(e,`data-${a[t]}`);null!==s&&""!==s&&("true"!==s&&"false"!==s||(s=Boolean(s)),h[t]=s)}h.speed&&(h.duration=parseInt(e.clientWidth)/h.speed*1e3),h.gap=h.duplicated?parseInt(h.gap):0,e.innerHTML=`<div class="js-marquee">${e.innerHTML}</div>`;const r=t("js-marquee",e)[0];r.style.marginRight=`${h.gap}px`,r.style.willChange="transform",r.style.float="left",h.duplicated&&e.appendChild(r.cloneNode(!0)),e.innerHTML=`<div style="width:100000px" class="js-marquee-wrapper">${e.innerHTML}</div>`;const o=t("js-marquee-wrapper",e)[0],u="up"===h.direction||"down"===h.direction;if(this.i=o,u){const i=e.clientHeight;this.h=i,function(t,s){t.removeAttribute(s)}(o,"style"),e.style.clientHeight=`${i}px`;const n=t("js-marquee",e),a=n.length-1;s(n,((t,s)=>{t.style.float="none",t.style.marginRight="0px",h.duplicated&&s===a?t.style.marginBottom="0px":t.style.marginBottom=`${h.gap}px`}));const r=parseInt(n[0].clientHeight+h.gap);this.o=el_elHeight,h.startVisible&&!h.duplicated?(this.u=(r+i)/parseInt(i)*h.duration,h.duration=r/parseInt(i)*h.duration):h.duration=r/parseInt(i)/parseInt(i)*h.duration}else{const s=parseInt(t("js-marquee",e)[0].clientWidth+h.gap),i=e.clientWidth;this.p=i,this.l=s,h.startVisible&&!h.duplicated?(this.u=(s+i)/parseInt(i)*h.duration,h.duration=s/parseInt(i)*h.duration):h.duration=(s+parseInt(i))/parseInt(i)*h.duration}h.duplicated&&(h.duration=h.duration/2),this.m=h;const p="marqueeAnimation-"+Math.floor(1e7*Math.random()),l=this.$(p,h.duration/1e3,h.delayBeforeStart/1e3,"infinite");this.v=p,this.g=l,h.duplicated?(u?h.startVisible?this.i.style.transform="translateY(0px)":this.i.style.transform=`translateY(${"up"===h.direction?this.h:-1*(2*this.o-h.gap)}px)`:h.startVisible?this.i.style.transform="translateX(0px)":this.i.style.transform=`translateX(${"left"===h.direction?this.p:-1*(2*this.l-h.gap)}px)`,h.startVisible||(this.t=1)):h.startVisible?this.t=2:u?this.I():this.q(),this.S=e,i(this.S,"pause",this.pause.bind(this)),i(this.S,"resume",this.resume.bind(this)),h.pauseOnHover&&(i(this.S,"mouseover",this.pause.bind(this)),i(this.S,"mouseout",this.resume.bind(this))),this._=()=>{this.j(u),this.S.dispatchEvent(new CustomEvent("finished"))},this.j(u)}$(t="",s=0,i=0,e=""){return`${t} ${s}s ${i}s ${e} ${this.m.css3easing}`}j(e=!1){const n=this.m;if(n.duplicated){if(1===this.t){let t=n.duration;t=e?"up"===n.direction?t+this.h/(this.o/t):2*t:"left"===n.direction?t+this.p/(this.l/t):2*t,this.g=this.$(this.v,t/1e3,n.delayBeforeStart/1e3)}else 2===this.t&&(this.v=`${this.v}0`,this.g=this.$(this.v,n.duration/1e3,0,"infinite"));this.t++}let a="";e?n.duplicated?(this.t>2&&(this.i.style.transform=`translateY(${"up"===n.direction?0:-1*this.o}px)`),a=`translateY(${"up"===n.direction?-1*this.o:0}px)`):n.startVisible?2===this.t?(this.g=_animationStr(this.v,n.duration/1e3,n.delayBeforeStart/1e3),a=`translateY(${"up"===n.direction?-1*this.o:this.h}px)`,this.t++):3===this.t&&(this.v=`${this.v}0`,this.g=_animationStr(this.v,this.u/1e3,0,"infinite"),this.I()):(this.I(),a=`translateY(${"up"===n.direction?-1*this.i.clientHeight:this.h}px)`):n.duplicated?(this.t>2&&(this.i.style.transform=`translateX(${"left"===n.direction?0:-1*this.l}px)`),a=`translateX(${"left"===n.direction?-1*this.l:0}px)`):n.startVisible?2===this.t?(this.g=_animationStr(this.v,n.duration/1e3,n.delayBeforeStart/1e3),a=`translateX(${"left"===n.direction?-1*this.l:this.p}px)`,this.t++):3===this.t&&(this.v=`${this.v}0`,this.g=_animationStr(this.v,n.duration/1e3,0,"infinite"),this.q()):(this.q(),a=`translateX(${"left"===n.direction?-1*this.l:this.h}px)`),this.S.dispatchEvent(new CustomEvent("beforeStarting")),this.i.style.animation=this.g;const r=`@keyframes ${this.v} {\n 100% {\n transform: ${a};\n }\n }`,o=function(t,s=document){return s.querySelectorAll(t)}("style",this.i);if(o.length)o[o.length-1].innerHTML=r;else if(t("marq-wrap-style").length)t("marq-wrap-style")[0].innerHTML=r;else{const t=document.createElement("style");!function(t,...i){function e(t,...s){s.forEach((s=>{t.classList.add(s)}))}void 0===t.length?e(t,...i):s(t,(t=>{e(t,...i)}))}(t,"marq-wrap-style"),t.innerHTML=r,function(t,s=document){return s.querySelector(t)}("head").appendChild(t)}i(this.i,"animationiteration",this.X.bind(this),{once:!0}),i(this.i,"animationend",this._.bind(this),{once:!0}),this.Y,h(this.S,"data-runningStatus","resumed")}X(){this.S.dispatchEvent(new CustomEvent("finished"))}I(){this.i.style.transform=`translateY(${"up"===this.m.direction?this.h:-1*this.o}px)`}q(){this.i.style.transform=`translateX(${"left"===this.m.direction?this.p:-1*this.l}px)`}pause(){this.i.style.animationPlayState="paused",this.Y="paused",h(this.S,"data-runningStatus","paused"),this.S.dispatchEvent(new CustomEvent("paused"))}resume(){this.i.style.animationPlayState="running",this.Y="running",h(this.S,"data-runningStatus","resumed"),this.S.dispatchEvent(new CustomEvent("resumed"))}toggle(){"paused"===this.Y?this.resume():"running"===this.Y&&this.pause()}C(){e(this.S,"pause",this.pause.bind(this)),e(this.S,"resume",this.resume.bind(this)),this.m.pauseOnHover&&(e(this.S,"mouseover",this.pause.bind(this)),e(this.S,"mouseout",this.resume.bind(this))),e(this.i,"animationiteration",this.X.bind(this),{once:!0}),e(this.i,"animationend",this._.bind(this),{once:!0})}}
function t(t,s=document){return s.getElementsByClassName(t)}function s(t,s,i){for(let e=0,h=t.length;e<h;e++)s.call(i,t[e],e)}function i(t,s,i,e){t.addEventListener(s,i,e)}function e(t,s,i,e){t.removeEventListener(s,i,e)}function h(t,s){return t.getAttribute(s)}function n(t,s,i){t.setAttribute(s,i)}const a={css3easing:"linear",delayBeforeStart:1e3,direction:"left",duplicated:!1,duration:5e3,gap:20,pauseOnHover:!1,recalcResize:!1,speed:0,startVisible:!1};let r=0;export default class{constructor(s,e){if(void 0===s)throw new Error("el cannot be undefined");if("string"==typeof s)throw new Error("el cannot be just a selector");if(null===s)throw new Error("el cannot be null");e={...a,...e},this.t=s,this.i=3;for(const t in a){let i=h(s,`data-${a[t]}`);null!==i&&""!==i&&("true"!==i&&"false"!==i||(i=Boolean(i)),e[t]=i)}e.speed&&(e.duration=parseInt(s.clientWidth)/e.speed*1e3),e.gap=e.duplicated?parseInt(e.gap):0,s.innerHTML=`<div class="js-marquee">${s.innerHTML}</div>`;const n=t("js-marquee",s)[0];n.style.marginRight=`${e.gap}px`,n.style.willChange="transform",n.style.float="left",e.duplicated&&s.appendChild(n.cloneNode(!0)),s.innerHTML=`<div style="width:100000px" class="js-marquee-wrapper">${s.innerHTML}</div>`;const o=t("js-marquee-wrapper",s)[0],u="up"===e.direction||"down"===e.direction;this.h=o,this.o=u,this.u=e.duration,this.l=e,this.p();const l=`marqueeAnimation-${Math.floor(1e7*Math.random())}`,p=this.m(l,e.duration/1e3,e.delayBeforeStart/1e3,"infinite");this.$=l,this.v=p,e.duplicated?(u?e.startVisible?this.h.style.transform="translateY(0px)":this.h.style.transform=`translateY(${"up"===e.direction?this.g:-1*(2*this.I-e.gap)}px)`:e.startVisible?this.h.style.transform="translateX(0px)":this.h.style.transform=`translateX(${"left"===e.direction?this.q:-1*(2*this.j-e.gap)}px)`,e.startVisible||(this.i=1)):e.startVisible?this.i=2:u?this.S():this.X(),i(this.t,"pause",this.pause.bind(this)),i(this.t,"resume",this.resume.bind(this)),e.pauseOnHover&&(i(this.t,"mouseover",this.pause.bind(this)),i(this.t,"mouseout",this.resume.bind(this))),this.Y=()=>{this._(u),this.t.dispatchEvent(new CustomEvent("finished"))},this.C=r,r++,this._(u),e.recalcResize&&i(window,"resize",this.B.bind(this))}m(t="",s=0,i=0,e=""){return`${t} ${s}s ${i}s ${e} ${this.l.css3easing}`}_(e=!1){const h=this.l;if(h.duplicated){if(1===this.i){let t=h.duration;t=e?"up"===h.direction?t+this.g/(this.I/t):2*t:"left"===h.direction?t+this.q/(this.j/t):2*t,this.v=this.m(this.$,t/1e3,h.delayBeforeStart/1e3)}else 2===this.i&&(this.$=`${this.$}0`,this.v=this.m(this.$,h.duration/1e3,0,"infinite"));this.i++}let a="";e?h.duplicated?(this.i>2&&(this.h.style.transform=`translateY(${"up"===h.direction?0:-1*this.I}px)`),a=`translateY(${"up"===h.direction?-1*this.I:0}px)`):h.startVisible?2===this.i?(this.v=this.m(this.$,h.duration/1e3,h.delayBeforeStart/1e3),a=`translateY(${"up"===h.direction?-1*this.I:this.g}px)`,this.i++):3===this.i&&(this.$=`${this.$}0`,this.v=this.m(this.$,this.H/1e3,0,"infinite"),this.S()):(this.S(),a=`translateY(${"up"===h.direction?-1*this.h.clientHeight:this.g}px)`):h.duplicated?(this.i>2&&(this.h.style.transform=`translateX(${"left"===h.direction?0:-1*this.j}px)`),a=`translateX(${"left"===h.direction?-1*this.j:0}px)`):h.startVisible?2===this.i?(this.v=this.m(this.$,h.duration/1e3,h.delayBeforeStart/1e3),a=`translateX(${"left"===h.direction?-1*this.j:this.q}px)`,this.i++):3===this.i&&(this.$=`${this.$}0`,this.v=this.m(this.$,h.duration/1e3,0,"infinite"),this.X()):(this.X(),a=`translateX(${"left"===h.direction?-1*this.j:this.g}px)`),this.t.dispatchEvent(new CustomEvent("beforeStarting")),this.h.style.animation=this.v;const r=`@keyframes ${this.$} {\n 100% {\n transform: ${a};\n }\n }`,o=function(t,s=document){return s.querySelectorAll(t)}("style",this.h);if(o.length)o[o.length-1].innerHTML=r;else if(t(`marq-wrap-style-${this.C}`).length)t(`marq-wrap-style-${this.C}`)[0].innerHTML=r;else{const t=document.createElement("style");!function(t,...i){function e(t,...s){s.forEach((s=>{t.classList.add(s)}))}void 0===t.length?e(t,...i):s(t,(t=>{e(t,...i)}))}(t,`marq-wrap-style-${this.C}`),t.innerHTML=r,function(t,s=document){return s.querySelector(t)}("head").appendChild(t)}i(this.h,"animationiteration",this.M.bind(this),{once:!0}),i(this.h,"animationend",this.Y.bind(this),{once:!0}),this.R="running",n(this.t,"data-runningStatus","resumed")}M(){this.t.dispatchEvent(new CustomEvent("finished"))}S(){this.h.style.transform=`translateY(${"up"===this.l.direction?this.g:-1*this.I}px)`}X(){this.h.style.transform=`translateX(${"left"===this.l.direction?this.q:-1*this.j}px)`}p(){const i=this.t,e=this.l;if(this.o){const h=i.clientHeight;this.g=h,function(t,s){t.removeAttribute(s)}(this.h,"style"),i.style.clientHeight=`${h}px`;const n=t("js-marquee",i),a=n.length-1;s(n,((t,s)=>{t.style.float="none",t.style.marginRight="0px",e.duplicated&&s===a?t.style.marginBottom="0px":t.style.marginBottom=`${e.gap}px`}));const r=parseInt(n[0].clientHeight+e.gap);this.I=r,e.startVisible&&!e.duplicated?(this.H=(r+h)/parseInt(h)*this.u,e.duration=r/parseInt(h)*this.u):e.duration=r/parseInt(h)/parseInt(h)*this.u}else{const s=parseInt(t("js-marquee",i)[0].clientWidth+e.gap),h=i.clientWidth;this.q=h,this.j=s,e.startVisible&&!e.duplicated?(this.H=(s+h)/parseInt(h)*this.u,e.duration=s/parseInt(h)*this.u):e.duration=(s+parseInt(h))/parseInt(h)*this.u}e.duplicated&&(e.duration=e.duration/2)}B(){this.p(),this.i=2,this.Y()}pause(){this.h.style.animationPlayState="paused",this.R="paused",n(this.t,"data-runningStatus","paused"),this.t.dispatchEvent(new CustomEvent("paused"))}resume(){this.h.style.animationPlayState="running",this.R="running",n(this.t,"data-runningStatus","resumed"),this.t.dispatchEvent(new CustomEvent("resumed"))}toggle(){"paused"===this.R?this.resume():"running"===this.R&&this.pause()}V(){e(this.t,"pause",this.pause.bind(this)),e(this.t,"resume",this.resume.bind(this)),this.l.pauseOnHover&&(e(this.t,"mouseover",this.pause.bind(this)),e(this.t,"mouseout",this.resume.bind(this))),e(this.h,"animationiteration",this.M.bind(this),{once:!0}),e(this.h,"animationend",this.Y.bind(this),{once:!0}),this.l.recalcResize&&e(window,"resize",this.B.bind(this))}}
{
"name": "vanilla-marquee",
"version": "1.0.4",
"version": "1.1.0",
"description": "",

@@ -28,11 +28,13 @@ "main": "./dist/vanilla-marquee.js",

"dependencies": {
"matt-utils": "^1.4.2"
"matt-utils": "^1.4.3"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-eslint": "^8.0.1",
"@rollup/plugin-node-resolve": "^11.2.0",
"rollup": "^2.39.1",
"eslint": "^7.21.0",
"rollup": "^2.40.0",
"rollup-plugin-terser": "^7.0.2",
"typescript": "^4.2.2"
"typescript": "^4.2.3"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc