Socket
Socket
Sign inDemoInstall

dynamic-marquee

Package Overview
Dependencies
0
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.2.1 to 1.2.2

1310

dist/dynamic-marquee.js

@@ -1,796 +0,736 @@

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["dynamicMarquee"] = factory();
else
root["dynamicMarquee"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 6);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? factory(exports)
: typeof define === 'function' && define.amd
? define(['exports'], factory)
: ((global = global || self), factory((global.dynamicMarquee = {})));
})(this, function(exports) {
'use strict';
"use strict";
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ('value' in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.size = size;
exports.defer = defer;
exports.deferException = deferException;
exports.toDomEl = toDomEl;
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var _direction = __webpack_require__(1);
var DIRECTION = {
RIGHT: 'right',
DOWN: 'down'
};
function size($el, direction) {
return $el[direction === _direction.DIRECTION.RIGHT ? 'offsetWidth' : 'offsetHeight'];
}
function defer(fn) {
window.setTimeout(function () {
return fn();
}, 0);
}
function deferException(cb) {
try {
return cb();
} catch (e) {
defer(function () {
throw e;
});
function size($el, direction) {
return $el[direction === DIRECTION.RIGHT ? 'offsetWidth' : 'offsetHeight'];
}
}
function defer(fn) {
window.setTimeout(function() {
return fn();
}, 0);
}
function deferException(cb) {
try {
return cb();
} catch (e) {
defer(function() {
throw e;
});
}
}
function toDomEl($el) {
if (typeof $el === 'string' || typeof $el === 'number') {
// helper. convert string to div
var $div = document.createElement('div');
$div.textContent = $el + '';
return $div;
}
function toDomEl($el) {
if (typeof $el === 'string' || typeof $el === 'number') {
// helper. convert string to div
var $div = document.createElement('div');
$div.textContent = $el + "";
return $div;
return $el;
}
return $el;
}
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
var Item = /*#__PURE__*/ (function() {
function Item($el, direction, rateWhenAppended) {
_classCallCheck(this, Item);
"use strict";
var $container = document.createElement('div');
$container.style.display = 'block';
$container.style.position = 'absolute';
$container.style.margin = '0';
$container.style.padding = '0';
$container.style[this._direction === DIRECTION.RIGHT ? 'top' : 'left'] =
'0';
$container.style.whiteSpace = 'nowrap';
$container.style.willChange = 'auto';
$container.appendChild($el);
this._$container = $container;
this._$el = $el;
this._direction = direction;
this._rateWhenAppended = rateWhenAppended;
}
_createClass(Item, [
{
key: 'getSize',
value: function getSize() {
var _ref =
arguments.length > 0 && arguments[0] !== undefined
? arguments[0]
: {},
_ref$inverse = _ref.inverse,
inverse = _ref$inverse === void 0 ? false : _ref$inverse;
Object.defineProperty(exports, "__esModule", {
value: true
});
var DIRECTION = exports.DIRECTION = {
RIGHT: 'right',
DOWN: 'down'
};
var dir = this._direction;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
if (inverse) {
dir = dir === DIRECTION.RIGHT ? DIRECTION.DOWN : DIRECTION.RIGHT;
}
"use strict";
return size(this._$container, dir);
}
},
{
key: 'setOffset',
value: function setOffset(offset) {
if (this._direction === DIRECTION.RIGHT) {
this._$container.style.transform = 'translateX('.concat(
offset,
'px)'
);
} else {
this._$container.style.transform = 'translateY('.concat(
offset,
'px)'
);
}
}
},
{
key: 'enableAnimationHint',
value: function enableAnimationHint(enable) {
this._$container.style.willChange = enable ? 'transform' : 'auto';
}
},
{
key: 'remove',
value: function remove() {
this._$container.remove();
}
},
{
key: 'getContainer',
value: function getContainer() {
return this._$container;
}
},
{
key: 'getOriginalEl',
value: function getOriginalEl() {
return this._$el;
}
},
{
key: 'getRateWhenAppended',
value: function getRateWhenAppended() {
return this._rateWhenAppended;
}
}
]);
return Item;
})();
var VirtualItem = /*#__PURE__*/ (function() {
function VirtualItem(size) {
_classCallCheck(this, VirtualItem);
var indexMap = function indexMap(list) {
var map = {};
list.forEach(function (each, i) {
map[each] = map[each] || [];
map[each].push(i);
});
return map;
};
this._size = size;
}
var longestCommonSubstring = function longestCommonSubstring(seq1, seq2) {
var result = { startString1: 0, startString2: 0, length: 0 };
var indexMapBefore = indexMap(seq1);
var previousOverlap = [];
seq2.forEach(function (eachAfter, indexAfter) {
var overlapLength;
var overlap = [];
var indexesBefore = indexMapBefore[eachAfter] || [];
indexesBefore.forEach(function (indexBefore) {
overlapLength = (indexBefore && previousOverlap[indexBefore - 1] || 0) + 1;
if (overlapLength > result.length) {
result.length = overlapLength;
result.startString1 = indexBefore - overlapLength + 1;
result.startString2 = indexAfter - overlapLength + 1;
_createClass(VirtualItem, [
{
key: 'getSize',
value: function getSize() {
var _ref2 =
arguments.length > 0 && arguments[0] !== undefined
? arguments[0]
: {},
_ref2$inverse = _ref2.inverse,
inverse = _ref2$inverse === void 0 ? false : _ref2$inverse;
if (inverse) {
throw new Error('Inverse not supported on virtual item.');
}
return this._size;
}
},
{
key: 'setOffset',
value: function setOffset() {}
},
{
key: 'enableAnimationHint',
value: function enableAnimationHint() {}
},
{
key: 'remove',
value: function remove() {}
}
overlap[indexBefore] = overlapLength;
});
previousOverlap = overlap;
});
return result;
};
]);
module.exports = longestCommonSubstring;
return VirtualItem;
})();
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
var Marquee = /*#__PURE__*/ (function() {
function Marquee($container) {
var _ref =
arguments.length > 1 && arguments[1] !== undefined
? arguments[1]
: {},
_ref$rate = _ref.rate,
rate = _ref$rate === void 0 ? -25 : _ref$rate,
_ref$upDown = _ref.upDown,
upDown = _ref$upDown === void 0 ? false : _ref$upDown;
"use strict";
_classCallCheck(this, Marquee);
this._rendering = false;
this._waitingForItem = true;
this._nextItemImmediatelyFollowsPrevious = false;
this._rate = rate;
this._direction = upDown ? DIRECTION.DOWN : DIRECTION.RIGHT;
this._onItemRequired = [];
this._onItemRemoved = [];
this._onAllItemsRemoved = [];
this._leftItemOffset = 0;
this._containerSize = 0;
this._items = [];
this._pendingItem = null;
var $innerContainer = document.createElement('div');
$innerContainer.style.position = 'relative';
$innerContainer.style.display = 'inline-block';
this._$container = $innerContainer;
this._containerSizeInverse = null;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.loop = loop;
if (this._direction === DIRECTION.RIGHT) {
$innerContainer.style.width = '100%';
} else {
$innerContainer.style.height = '100%';
}
var _helpers = __webpack_require__(0);
this._updateContainerSize();
var _longestCommonSubstring = __webpack_require__(2);
$container.appendChild($innerContainer);
var _longestCommonSubstring2 = _interopRequireDefault(_longestCommonSubstring);
this._scheduleRender();
} // called when there's room for a new item.
// You can return the item to append next
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_createClass(Marquee, [
{
key: 'onItemRequired',
value: function onItemRequired(cb) {
this._onItemRequired.push(cb);
} // Called when an item is removed
},
{
key: 'onItemRemoved',
value: function onItemRemoved(cb) {
this._onItemRemoved.push(cb);
} // Called when the last item is removed
},
{
key: 'onAllItemsRemoved',
value: function onAllItemsRemoved(cb) {
this._onAllItemsRemoved.push(cb);
}
},
{
key: 'getNumItems',
value: function getNumItems() {
return this._items.filter(function(item) {
return item instanceof Item;
}).length;
}
},
{
key: 'setRate',
value: function setRate(rate) {
if (!rate !== !this._rate) {
this._enableAnimationHint(!!rate);
function loop(marquee) {
var buildersIn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var seperatorBuilder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (rate) {
this._scheduleRender();
}
}
var lastIndex = -1;
var builders = buildersIn.slice();
this._rate = rate;
}
},
{
key: 'getRate',
value: function getRate() {
return this._rate;
}
},
{
key: 'clear',
value: function clear() {
var _this = this;
var getNextBuilder = function getNextBuilder() {
var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
this._items.forEach(function($a) {
return _this._removeItem($a);
});
var nextIndex = (lastIndex + offset) % builders.length;
return { builder: builders[nextIndex], index: nextIndex };
};
this._items = [];
this._waitingForItem = true;
var appendItem = function appendItem(immediatelyFollowsPrevious) {
if (!builders.length || !marquee.isWaitingForItem()) {
return;
}
this._updateContainerSize();
}
},
{
key: 'isWaitingForItem',
value: function isWaitingForItem() {
return this._waitingForItem;
}
},
{
key: 'appendItem',
value: function appendItem($el) {
if (!this._waitingForItem) {
throw new Error('No room for item.');
} // convert to div if $el is a string
var _getNextBuilder = getNextBuilder(),
builder = _getNextBuilder.builder,
index = _getNextBuilder.index;
$el = toDomEl($el);
lastIndex = index;
var $item = (0, _helpers.toDomEl)(builder());
if (immediatelyFollowsPrevious && seperatorBuilder) {
var $seperator = (0, _helpers.toDomEl)(seperatorBuilder());
var $container = document.createElement('div');
$seperator.style.display = 'inline';
$item.style.display = 'inline';
if (marquee.getRate() <= 0) {
$container.appendChild($seperator);
$container.appendChild($item);
} else {
$container.appendChild($item);
$container.appendChild($seperator);
}
$item = $container;
}
marquee.appendItem($item);
};
marquee.onItemRequired(function (_ref) {
var immediatelyFollowsPrevious = _ref.immediatelyFollowsPrevious;
return appendItem(immediatelyFollowsPrevious);
});
appendItem();
return {
update: function update(newBuilders) {
// try and start from somewhere that makes sense
var calculateNewIndex = function calculateNewIndex() {
// convert array of function references to array of ids
var buildersStructure = builders.map(function (b, i) {
var prevIndex = builders.indexOf(b);
// if already seen builder, give it the same number
return prevIndex < i ? prevIndex : i;
});
var newBuildersStructure = newBuilders.map(function (b, i) {
// matching indexes where they exist, and -1 for all unknown
return builders.indexOf(b);
});
var itemAlreadyExists = this._items.some(function(item) {
return item instanceof Item && item.getOriginalEl() === $el;
});
var _longestSubstring = (0, _longestCommonSubstring2.default)(buildersStructure, newBuildersStructure),
startString1 = _longestSubstring.startString1,
startString2 = _longestSubstring.startString2,
length = _longestSubstring.length;
if (itemAlreadyExists) {
throw new Error('Item already exists.');
}
if (lastIndex >= startString1 && lastIndex < startString1 + length) {
// we are in the overlapping region
return lastIndex + (startString2 - startString1);
this._waitingForItem = false;
this._pendingItem = new Item($el, this._direction, this._rate);
this._pendingItem.enableAnimationHint(!!this._rate);
this._scheduleRender();
}
return -1;
};
},
{
key: '_removeItem',
value: function _removeItem(item) {
var _this2 = this;
lastIndex = calculateNewIndex();
builders = newBuilders.slice();
appendItem(false);
}
};
}
defer(function() {
item.remove();
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
if (item instanceof Item) {
_this2._onItemRemoved.forEach(function(cb) {
deferException(function() {
return cb(item.getOriginalEl());
});
});
}
});
} // update size of container so that the marquee items fit inside it.
// This is needed because the items are posisitioned absolutely, so not in normal flow.
// Without this, the height of the container would always be 0px, which is not useful
},
{
key: '_updateContainerSize',
value: function _updateContainerSize() {
var maxSize = this._items.reduce(function(size, item) {
if (item instanceof VirtualItem) {
return size;
}
"use strict";
var a = item.getSize({
inverse: true
});
if (a > size) {
return a;
}
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.VirtualItem = exports.Item = undefined;
return size;
}, 0);
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
if (this._containerSizeInverse !== maxSize) {
this._containerSizeInverse = maxSize;
var _direction = __webpack_require__(1);
if (this._direction === DIRECTION.RIGHT) {
this._$container.style.height = ''.concat(maxSize, 'px');
} else {
this._$container.style.width = ''.concat(maxSize, 'px');
}
}
}
},
{
key: '_enableAnimationHint',
value: function _enableAnimationHint(enable) {
this._items.forEach(function(item) {
return item.enableAnimationHint(enable);
});
}
},
{
key: '_scheduleRender',
value: function _scheduleRender() {
var _this3 = this;
var _helpers = __webpack_require__(0);
if (this._rendering) {
// we are already rendering, so call the render method synchronously
this._render();
} else {
if (!this._requestAnimationID) {
this._lastUpdateTime = performance.now();
this._requestAnimationID = window.requestAnimationFrame(
function() {
return _this3._onRequestAnimationFrame();
}
);
}
}
}
},
{
key: '_onRequestAnimationFrame',
value: function _onRequestAnimationFrame() {
var _this4 = this;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
this._requestAnimationID = null;
var Item = exports.Item = function () {
function Item($el, direction, rateWhenAppended) {
_classCallCheck(this, Item);
if (!this._rate || (!this._items.length && !this._pendingItem)) {
return;
}
var $container = document.createElement('div');
$container.style.display = 'block';
$container.style.position = 'absolute';
$container.style.margin = '0';
$container.style.padding = '0';
$container.style[this._direction === _direction.DIRECTION.RIGHT ? 'top' : 'left'] = '0';
$container.style.whiteSpace = 'nowrap';
$container.style.willChange = 'auto';
$container.appendChild($el);
var now = performance.now();
var timePassed = now - this._lastUpdateTime;
this._$container = $container;
this._$el = $el;
this._direction = direction;
this._rateWhenAppended = rateWhenAppended;
}
this._scheduleRender();
_createClass(Item, [{
key: 'getSize',
value: function getSize() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$inverse = _ref.inverse,
inverse = _ref$inverse === undefined ? false : _ref$inverse;
this._rendering = true;
var shiftAmount = this._rate * (timePassed / 1000);
this._leftItemOffset += shiftAmount;
this._containerSize = size(this._$container, this._direction);
deferException(function() {
return _this4._render();
});
this._rendering = false;
}
},
{
key: '_render',
value: function _render() {
var _this5 = this;
var dir = this._direction;
if (inverse) {
dir = dir === _direction.DIRECTION.RIGHT ? _direction.DIRECTION.DOWN : _direction.DIRECTION.RIGHT;
}
return (0, _helpers.size)(this._$container, dir);
}
}, {
key: 'setOffset',
value: function setOffset(offset) {
if (this._direction === _direction.DIRECTION.RIGHT) {
this._$container.style.transform = 'translateX(' + offset + 'px)';
} else {
this._$container.style.transform = 'translateY(' + offset + 'px)';
}
}
}, {
key: 'enableAnimationHint',
value: function enableAnimationHint(enable) {
this._$container.style.willChange = enable ? 'transform' : 'auto';
}
}, {
key: 'remove',
value: function remove() {
this._$container.remove();
}
}, {
key: 'getContainer',
value: function getContainer() {
return this._$container;
}
}, {
key: 'getOriginalEl',
value: function getOriginalEl() {
return this._$el;
}
}, {
key: 'getRateWhenAppended',
value: function getRateWhenAppended() {
return this._rateWhenAppended;
}
}]);
var containerSize = this._containerSize;
return Item;
}();
if (this._rate < 0) {
while (this._items.length) {
var item = this._items[0];
var VirtualItem = exports.VirtualItem = function () {
function VirtualItem(size) {
_classCallCheck(this, VirtualItem);
var _size = item.getSize();
this._size = size;
}
if (this._leftItemOffset + _size > 0) {
break;
}
_createClass(VirtualItem, [{
key: 'getSize',
value: function getSize() {
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref2$inverse = _ref2.inverse,
inverse = _ref2$inverse === undefined ? false : _ref2$inverse;
this._removeItem(this._items[0]);
if (inverse) {
throw new Error('Inverse not supported on virtual item.');
}
return this._size;
}
}, {
key: 'setOffset',
value: function setOffset() {}
}, {
key: 'enableAnimationHint',
value: function enableAnimationHint() {}
}, {
key: 'remove',
value: function remove() {}
}]);
this._items.shift();
return VirtualItem;
}();
this._leftItemOffset += _size;
}
}
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
var offsets = [];
var nextOffset = this._leftItemOffset;
"use strict";
this._items.some(function(item, i) {
if (nextOffset >= containerSize) {
if (_this5._rate > 0) {
_this5._items.splice(i).forEach(function(a) {
return _this5._removeItem(a);
});
}
return true;
}
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Marquee = undefined;
offsets.push(nextOffset);
nextOffset += item.getSize();
return false;
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
if (this._pendingItem) {
this._$container.appendChild(this._pendingItem.getContainer());
var _item = __webpack_require__(4);
if (this._rate <= 0) {
if (!this._nextItemImmediatelyFollowsPrevious) {
// insert virtual item so that it starts off screen
this._items.push(
new VirtualItem(Math.max(0, containerSize - nextOffset))
);
var _direction = __webpack_require__(1);
offsets.push(nextOffset);
nextOffset = containerSize;
}
var _helpers = __webpack_require__(0);
offsets.push(nextOffset);
nextOffset += this._pendingItem.getSize();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
this._items.push(this._pendingItem);
} else {
if (
!this._nextItemImmediatelyFollowsPrevious &&
this._items.length &&
this._leftItemOffset > 0
) {
this._items.unshift(new VirtualItem(this._leftItemOffset));
var Marquee = exports.Marquee = function () {
function Marquee($container) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$rate = _ref.rate,
rate = _ref$rate === undefined ? -25 : _ref$rate,
_ref$upDown = _ref.upDown,
upDown = _ref$upDown === undefined ? false : _ref$upDown;
offsets.unshift(0);
this._leftItemOffset = 0;
}
_classCallCheck(this, Marquee);
this._leftItemOffset -= this._pendingItem.getSize();
offsets.unshift(this._leftItemOffset);
this._rendering = false;
this._waitingForItem = true;
this._nextItemImmediatelyFollowsPrevious = false;
this._rate = rate;
this._direction = upDown ? _direction.DIRECTION.DOWN : _direction.DIRECTION.RIGHT;
this._onItemRequired = [];
this._onItemRemoved = [];
this._onAllItemsRemoved = [];
this._leftItemOffset = 0;
this._containerSize = 0;
this._items = [];
this._pendingItem = null;
var $innerContainer = document.createElement('div');
$innerContainer.style.position = 'relative';
$innerContainer.style.display = 'inline-block';
this._$container = $innerContainer;
this._containerSizeInverse = null;
if (this._direction === _direction.DIRECTION.RIGHT) {
$innerContainer.style.width = '100%';
} else {
$innerContainer.style.height = '100%';
}
this._updateContainerSize();
$container.appendChild($innerContainer);
this._scheduleRender();
}
this._items.unshift(this._pendingItem);
}
// called when there's room for a new item.
// You can return the item to append next
this._pendingItem = null;
} // trim virtual items
while (this._items[0] instanceof VirtualItem) {
offsets.shift();
_createClass(Marquee, [{
key: 'onItemRequired',
value: function onItemRequired(cb) {
this._onItemRequired.push(cb);
}
this._items.shift();
// Called when an item is removed
this._leftItemOffset = offsets[0] || 0;
}
}, {
key: 'onItemRemoved',
value: function onItemRemoved(cb) {
this._onItemRemoved.push(cb);
}
while (this._items[this._items.length - 1] instanceof VirtualItem) {
offsets.pop();
// Called when the last item is removed
this._items.pop();
}
}, {
key: 'onAllItemsRemoved',
value: function onAllItemsRemoved(cb) {
this._onAllItemsRemoved.push(cb);
}
}, {
key: 'getNumItems',
value: function getNumItems() {
return this._items.filter(function (item) {
return item instanceof _item.Item;
}).length;
}
}, {
key: 'setRate',
value: function setRate(rate) {
if (!rate !== !this._rate) {
this._enableAnimationHint(!!rate);
if (rate) {
this._scheduleRender();
}
}
this._rate = rate;
}
}, {
key: 'getRate',
value: function getRate() {
return this._rate;
}
}, {
key: 'clear',
value: function clear() {
var _this = this;
offsets.forEach(function(offset, i) {
return _this5._items[i].setOffset(offset);
});
this._items.forEach(function ($a) {
return _this._removeItem($a);
});
this._items = [];
this._waitingForItem = true;
this._updateContainerSize();
}
}, {
key: 'isWaitingForItem',
value: function isWaitingForItem() {
return this._waitingForItem;
}
}, {
key: 'appendItem',
value: function appendItem($el) {
if (!this._waitingForItem) {
throw new Error('No room for item.');
}
// convert to div if $el is a string
$el = (0, _helpers.toDomEl)($el);
var itemAlreadyExists = this._items.some(function (item) {
return item instanceof _item.Item && item.getOriginalEl() === $el;
});
if (itemAlreadyExists) {
throw new Error('Item already exists.');
}
this._waitingForItem = false;
this._pendingItem = new _item.Item($el, this._direction, this._rate);
this._pendingItem.enableAnimationHint(!!this._rate);
this._scheduleRender();
}
}, {
key: '_removeItem',
value: function _removeItem(item) {
var _this2 = this;
this._updateContainerSize();
(0, _helpers.defer)(function () {
item.remove();
if (item instanceof _item.Item) {
_this2._onItemRemoved.forEach(function (cb) {
(0, _helpers.deferException)(function () {
return cb(item.getOriginalEl());
if (!this._items.length) {
this._leftItemOffset = 0;
defer(function() {
_this5._onAllItemsRemoved.forEach(function(cb) {
deferException(function() {
return cb();
});
});
});
});
}
});
}
}
// update size of container so that the marquee items fit inside it.
// This is needed because the items are posisitioned absolutely, so not in normal flow.
// Without this, the height of the container would always be 0px, which is not useful
this._nextItemImmediatelyFollowsPrevious = false;
}, {
key: '_updateContainerSize',
value: function _updateContainerSize() {
var maxSize = this._items.reduce(function (size, item) {
if (item instanceof _item.VirtualItem) {
return size;
}
var a = item.getSize({ inverse: true });
if (a > size) {
return a;
}
return size;
}, 0);
if (this._containerSizeInverse !== maxSize) {
this._containerSizeInverse = maxSize;
if (this._direction === _direction.DIRECTION.RIGHT) {
this._$container.style.height = maxSize + 'px';
} else {
this._$container.style.width = maxSize + 'px';
}
}
}
}, {
key: '_enableAnimationHint',
value: function _enableAnimationHint(enable) {
this._items.forEach(function (item) {
return item.enableAnimationHint(enable);
});
}
}, {
key: '_scheduleRender',
value: function _scheduleRender() {
var _this3 = this;
if (
!this._waitingForItem &&
((this._rate <= 0 && nextOffset <= containerSize) ||
(this._rate > 0 && this._leftItemOffset >= 0))
) {
this._waitingForItem = true; // if an item is appended immediately below, it would be considered immediately following
// the previous if the item it would follow was appended from the same side
// This is useful when deciding whether to add a separator on the side that enters the
// screen first or not
if (this._rendering) {
// we are already rendering, so call the render method synchronously
this._render();
} else {
if (!this._requestAnimationID) {
this._lastUpdateTime = performance.now();
this._requestAnimationID = window.requestAnimationFrame(function () {
return _this3._onRequestAnimationFrame();
});
}
}
}
}, {
key: '_onRequestAnimationFrame',
value: function _onRequestAnimationFrame() {
var _this4 = this;
var previousItem = null;
this._requestAnimationID = null;
if (!this._rate || !this._items.length && !this._pendingItem) {
return;
}
if (this._items.length) {
if (this._rate <= 0) {
previousItem = this._items[this._items.length - 1];
} else {
previousItem = this._items[0];
}
}
var now = performance.now();
var timePassed = now - this._lastUpdateTime;
this._scheduleRender();
this._rendering = true;
var shiftAmount = this._rate * (timePassed / 1000);
this._leftItemOffset += shiftAmount;
this._containerSize = (0, _helpers.size)(this._$container, this._direction);
(0, _helpers.deferException)(function () {
return _this4._render();
});
this._rendering = false;
}
}, {
key: '_render',
value: function _render() {
var _this5 = this;
this._nextItemImmediatelyFollowsPrevious =
previousItem &&
previousItem.getRateWhenAppended() * this._rate >= 0;
var nextItem;
var containerSize = this._containerSize;
if (this._rate < 0) {
while (this._items.length) {
var item = this._items[0];
var _size = item.getSize();
if (this._leftItemOffset + _size > 0) {
break;
this._onItemRequired.some(function(cb) {
return deferException(function() {
nextItem = cb({
immediatelyFollowsPrevious:
_this5._nextItemImmediatelyFollowsPrevious
});
return !!nextItem;
});
});
if (nextItem) {
// Note appendItem() will call _scheduleRender(), which will synchronously call
// _render() again
this.appendItem(nextItem);
}
this._nextItemImmediatelyFollowsPrevious = false;
}
this._removeItem(this._items[0]);
this._items.shift();
this._leftItemOffset += _size;
}
}
]);
var offsets = [];
var nextOffset = this._leftItemOffset;
this._items.some(function (item, i) {
if (nextOffset >= containerSize) {
if (_this5._rate > 0) {
_this5._items.splice(i).forEach(function (a) {
return _this5._removeItem(a);
});
}
return true;
return Marquee;
})();
var indexMap = function(list) {
var map = {};
list.forEach(function(each, i) {
map[each] = map[each] || [];
map[each].push(i);
});
return map;
};
var longestCommonSubstring = function(seq1, seq2) {
var result = { startString1: 0, startString2: 0, length: 0 };
var indexMapBefore = indexMap(seq1);
var previousOverlap = [];
seq2.forEach(function(eachAfter, indexAfter) {
var overlapLength;
var overlap = [];
var indexesBefore = indexMapBefore[eachAfter] || [];
indexesBefore.forEach(function(indexBefore) {
overlapLength =
((indexBefore && previousOverlap[indexBefore - 1]) || 0) + 1;
if (overlapLength > result.length) {
result.length = overlapLength;
result.startString1 = indexBefore - overlapLength + 1;
result.startString2 = indexAfter - overlapLength + 1;
}
offsets.push(nextOffset);
nextOffset += item.getSize();
return false;
overlap[indexBefore] = overlapLength;
});
previousOverlap = overlap;
});
return result;
};
if (this._pendingItem) {
this._$container.appendChild(this._pendingItem.getContainer());
if (this._rate <= 0) {
if (!this._nextItemImmediatelyFollowsPrevious) {
// insert virtual item so that it starts off screen
this._items.push(new _item.VirtualItem(Math.max(0, containerSize - nextOffset)));
offsets.push(nextOffset);
nextOffset = containerSize;
}
offsets.push(nextOffset);
nextOffset += this._pendingItem.getSize();
this._items.push(this._pendingItem);
} else {
if (!this._nextItemImmediatelyFollowsPrevious && this._items.length && this._leftItemOffset > 0) {
this._items.unshift(new _item.VirtualItem(this._leftItemOffset));
offsets.unshift(0);
this._leftItemOffset = 0;
}
this._leftItemOffset -= this._pendingItem.getSize();
offsets.unshift(this._leftItemOffset);
this._items.unshift(this._pendingItem);
}
this._pendingItem = null;
}
var longestCommonSubstring_1 = longestCommonSubstring;
// trim virtual items
while (this._items[0] instanceof _item.VirtualItem) {
offsets.shift();
this._items.shift();
this._leftItemOffset = offsets[0] || 0;
}
while (this._items[this._items.length - 1] instanceof _item.VirtualItem) {
offsets.pop();
this._items.pop();
}
function loop(marquee) {
var buildersIn =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var seperatorBuilder =
arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var lastIndex = -1;
var builders = buildersIn.slice();
offsets.forEach(function (offset, i) {
return _this5._items[i].setOffset(offset);
});
this._updateContainerSize();
var getNextBuilder = function getNextBuilder() {
var offset =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
var nextIndex = (lastIndex + offset) % builders.length;
return {
builder: builders[nextIndex],
index: nextIndex
};
};
if (!this._items.length) {
this._leftItemOffset = 0;
(0, _helpers.defer)(function () {
_this5._onAllItemsRemoved.forEach(function (cb) {
(0, _helpers.deferException)(function () {
return cb();
});
});
});
var appendItem = function appendItem(immediatelyFollowsPrevious) {
if (!builders.length || !marquee.isWaitingForItem()) {
return;
}
this._nextItemImmediatelyFollowsPrevious = false;
if (!this._waitingForItem && (this._rate <= 0 && nextOffset <= containerSize || this._rate > 0 && this._leftItemOffset >= 0)) {
this._waitingForItem = true;
// if an item is appended immediately below, it would be considered immediately following
// the previous if the item it would follow was appended from the same side
// This is useful when deciding whether to add a separator on the side that enters the
// screen first or not
var previousItem = null;
if (this._items.length) {
if (this._rate <= 0) {
previousItem = this._items[this._items.length - 1];
} else {
previousItem = this._items[0];
}
var _getNextBuilder = getNextBuilder(),
builder = _getNextBuilder.builder,
index = _getNextBuilder.index;
lastIndex = index;
var $item = toDomEl(builder());
if (immediatelyFollowsPrevious && seperatorBuilder) {
var $seperator = toDomEl(seperatorBuilder());
var $container = document.createElement('div');
$seperator.style.display = 'inline';
$item.style.display = 'inline';
if (marquee.getRate() <= 0) {
$container.appendChild($seperator);
$container.appendChild($item);
} else {
$container.appendChild($item);
$container.appendChild($seperator);
}
this._nextItemImmediatelyFollowsPrevious = previousItem && previousItem.getRateWhenAppended() * this._rate >= 0;
var nextItem = void 0;
this._onItemRequired.some(function (cb) {
return (0, _helpers.deferException)(function () {
nextItem = cb({ immediatelyFollowsPrevious: _this5._nextItemImmediatelyFollowsPrevious });
return !!nextItem;
});
});
if (nextItem) {
// Note appendItem() will call _scheduleRender(), which will synchronously call
// _render() again
this.appendItem(nextItem);
}
this._nextItemImmediatelyFollowsPrevious = false;
$item = $container;
}
}
}]);
return Marquee;
}();
marquee.appendItem($item);
};
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
marquee.onItemRequired(function(_ref) {
var immediatelyFollowsPrevious = _ref.immediatelyFollowsPrevious;
return appendItem(immediatelyFollowsPrevious);
});
appendItem();
return {
update: function update(newBuilders) {
// try and start from somewhere that makes sense
var calculateNewIndex = function calculateNewIndex() {
// convert array of function references to array of ids
var buildersStructure = builders.map(function(b, i) {
var prevIndex = builders.indexOf(b); // if already seen builder, give it the same number
"use strict";
return prevIndex < i ? prevIndex : i;
});
var newBuildersStructure = newBuilders.map(function(b, i) {
// matching indexes where they exist, and -1 for all unknown
return builders.indexOf(b);
});
var _longestSubstring = longestCommonSubstring_1(
buildersStructure,
newBuildersStructure
),
startString1 = _longestSubstring.startString1,
startString2 = _longestSubstring.startString2,
length = _longestSubstring.length;
Object.defineProperty(exports, "__esModule", {
value: true
});
if (lastIndex >= startString1 && lastIndex < startString1 + length) {
// we are in the overlapping region
return lastIndex + (startString2 - startString1);
}
var _marquee = __webpack_require__(5);
return -1;
};
Object.defineProperty(exports, 'Marquee', {
enumerable: true,
get: function get() {
return _marquee.Marquee;
lastIndex = calculateNewIndex();
builders = newBuilders.slice();
appendItem(false);
}
};
}
});
var _loop = __webpack_require__(3);
exports.Marquee = Marquee;
exports.loop = loop;
Object.defineProperty(exports, 'loop', {
enumerable: true,
get: function get() {
return _loop.loop;
}
Object.defineProperty(exports, '__esModule', { value: true });
});
/***/ })
/******/ ]);
});
{
"name": "dynamic-marquee",
"version": "1.2.1",
"version": "1.2.2",
"description": "A small library for creating marquees.",
"main": "./dist/dynamic-marquee.js",
"scripts": {
"build": "webpack",
"lint": "eslint ./src/**/*.js",
"lintFix": "eslint --fix ./src/**/*.js"
"build": "rollup --config rollup.config.js",
"watch": "rollup --config rollup.config.js --watch",
"prettier": "prettier --write **/*.{js,md}",
"preversion": "npm run build"
},
"files": [
"dist/**/*"
],
"husky": {
"hooks": {
"pre-commit": "npm run lint"
"pre-commit": "npm run prettier"
}

@@ -34,11 +38,12 @@ },

"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"eslint": "^4.19.1",
"husky": "^0.14.3",
"@babel/core": "^7.8.7",
"@babel/preset-env": "^7.8.7",
"@rollup/plugin-commonjs": "^11.0.2",
"@rollup/plugin-node-resolve": "^7.1.1",
"husky": "^4.2.3",
"longest-common-substring": "0.0.1",
"webpack": "^4.6.0",
"webpack-cli": "^2.0.15"
"prettier": "^1.19.1",
"rollup": "^2.0.6",
"rollup-plugin-babel": "^4.4.0"
}
}
[![npm version](https://badge.fury.io/js/dynamic-marquee.svg)](https://badge.fury.io/js/dynamic-marquee)
# Dynamic Marquee
A small library for creating marquees.
Features:
- You can change the rate on the fly.

@@ -15,2 +18,3 @@ - Direction can either be up/down or right/left.

# Demo
View the demo [here](https://tjenkinson.github.io/dynamic-marquee/demo.html).

@@ -21,11 +25,18 @@

# Installation
```
npm install --save dynamic-marquee
```
```js
import { Marquee } from 'dynamic-marquee';
```
or
```html
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dynamic-marquee@1"></script>
<script
type="text/javascript"
src="https://cdn.jsdelivr.net/npm/dynamic-marquee@1"
></script>
<script type="text/javascript">

@@ -35,7 +46,11 @@ const Marquee = dynamicMarquee.Marquee;

```
thanks to [jsDelivr](https://github.com/jsdelivr/jsdelivr).
# Usage
## Construct Marquee Instance
### With Default Options
```js

@@ -46,2 +61,3 @@ const marquee = new Marquee(document.getElementById('marquee'));

### With Custom Options
```js

@@ -55,5 +71,7 @@ const marquee = new Marquee(document.getElementById('marquee'), {

## Append Item
You can add DOM elements, or just a string (which will automatically be wrapped in a div).
**Each DOM element is only allowed on the marquee at one time.**
```js

@@ -66,2 +84,3 @@ const $item = document.createElement('div');

You are only allowed to append an item when there is room. You can check this like so:
```js

@@ -74,2 +93,3 @@ if (marquee.isWaitingForItem()) {

You can be notified when an item is required with
```js

@@ -86,2 +106,3 @@ marquee.onItemRequired(({ immediatelyFollowsPrevious }) => {

```
**Do not perform any long running tasks in this method as it will block rendering.**

@@ -92,3 +113,5 @@

## Change the scroll rate? (px/s)
You can change the rate at any time, and set to 0 to pause.
```js

@@ -99,3 +122,5 @@ marquee.setRate(-20);

## Reset
To remove all items call
```js

@@ -106,5 +131,7 @@ marquee.clear();

## When has an item been removed?
You can be notified when an item has been removed with:
```js
marquee.onItemRemove(($el) => {
marquee.onItemRemove($el => {
// $el has just been removed

@@ -115,3 +142,5 @@ });

## When have all items finished scrolling?
You can be notified when the scroller is empty with:
```js

@@ -122,3 +151,5 @@ marquee.onAllItemsRemoved(() => {

```
You can check at any time with:
```js

@@ -129,2 +160,3 @@ marquee.getNumItems();

# Loop
A `loop()` function is provided for making looping content simple.

@@ -139,12 +171,6 @@

const marquee = new Marquee($marquee);
const control = loop(marquee, [
() => 'item 1',
() => 'item 2'
]);
const control = loop(marquee, [() => 'item 1', () => 'item 2']);
// later
control.update([
() => 'new item 1',
() => 'new item 2'
])
control.update([() => 'new item 1', () => 'new item 2']);
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc