dynamic-marquee
Advanced tools
Comparing version 1.1.1 to 1.2.0
@@ -218,3 +218,3 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
var appendItem = function appendItem(spaceJustAvailable) { | ||
var appendItem = function appendItem(immediatelyFollowsPrevious) { | ||
if (!builders.length || !marquee.isWaitingForItem()) { | ||
@@ -230,3 +230,3 @@ return; | ||
var $item = (0, _helpers.toDomEl)(builder()); | ||
if (spaceJustAvailable && seperatorBuilder) { | ||
if (immediatelyFollowsPrevious && seperatorBuilder) { | ||
var $seperator = (0, _helpers.toDomEl)(seperatorBuilder()); | ||
@@ -242,4 +242,5 @@ var $container = document.createElement('div'); | ||
}; | ||
marquee.onItemRequired(function () { | ||
return appendItem(true); | ||
marquee.onItemRequired(function (_ref) { | ||
var immediatelyFollowsPrevious = _ref.immediatelyFollowsPrevious; | ||
return appendItem(immediatelyFollowsPrevious); | ||
}); | ||
@@ -433,3 +434,5 @@ appendItem(); | ||
this._rendering = false; | ||
this._waitingForItem = true; | ||
this._nextItemImmediatelyFollowsPrevious = false; | ||
this._rate = rate; | ||
@@ -441,3 +444,6 @@ this._direction = upDown ? _direction.DIRECTION.DOWN : _direction.DIRECTION.RIGHT; | ||
this._leftItemOffset = 0; | ||
this._containerSize = 0; | ||
this._items = []; | ||
this._overflowsRight = false; | ||
this._overflowsLeft = false; | ||
this._pendingItem = null; | ||
@@ -448,3 +454,3 @@ var $innerContainer = document.createElement('div'); | ||
this._$container = $innerContainer; | ||
this._containerSize = null; | ||
this._containerSizeInverse = null; | ||
if (this._direction === _direction.DIRECTION.RIGHT) { | ||
@@ -512,2 +518,6 @@ $innerContainer.style.width = '100%'; | ||
this._items = []; | ||
this._waitingForItem = true; | ||
this._overflowsRight = false; | ||
this._overflowsLeft = false; | ||
this._updateContainerSize(); | ||
} | ||
@@ -543,5 +553,5 @@ }, { | ||
item.remove(); | ||
if (item instanceof _item.Item) { | ||
(0, _helpers.defer)(function () { | ||
(0, _helpers.defer)(function () { | ||
item.remove(); | ||
if (item instanceof _item.Item) { | ||
_this2._onItemRemoved.forEach(function (cb) { | ||
@@ -552,4 +562,4 @@ (0, _helpers.deferException)(function () { | ||
}); | ||
}); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -574,4 +584,4 @@ | ||
}, 0); | ||
if (this._containerSize !== maxSize) { | ||
this._containerSize = maxSize; | ||
if (this._containerSizeInverse !== maxSize) { | ||
this._containerSizeInverse = maxSize; | ||
if (this._direction === _direction.DIRECTION.RIGHT) { | ||
@@ -596,12 +606,17 @@ this._$container.style.height = maxSize + 'px'; | ||
if (!this._requestAnimationID) { | ||
this._lastUpdateTime = performance.now(); | ||
this._requestAnimationID = window.requestAnimationFrame(function () { | ||
return _this3._render(); | ||
}); | ||
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: '_render', | ||
value: function _render() { | ||
key: '_onRequestAnimationFrame', | ||
value: function _onRequestAnimationFrame() { | ||
var _this4 = this; | ||
@@ -617,6 +632,17 @@ | ||
this._scheduleRender(); | ||
this._rendering = true; | ||
var shiftAmount = this._rate * (timePassed / 1000); | ||
this._leftItemOffset += shiftAmount; | ||
var containerSize = (0, _helpers.size)(this._$container, this._direction); | ||
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; | ||
var containerSize = this._containerSize; | ||
if (this._rate < 0) { | ||
@@ -633,2 +659,5 @@ while (this._items.length) { | ||
} | ||
if (this._items[0] instanceof _item.VirtualItem) { | ||
this._overflowsLeft = false; | ||
} | ||
} | ||
@@ -640,5 +669,5 @@ | ||
if (nextOffset >= containerSize) { | ||
if (_this4._rate > 0) { | ||
_this4._items.splice(i).forEach(function (a) { | ||
return _this4._removeItem(a); | ||
if (_this5._rate > 0) { | ||
_this5._items.splice(i).forEach(function (a) { | ||
return _this5._removeItem(a); | ||
}); | ||
@@ -652,17 +681,21 @@ } | ||
}); | ||
if (this._items.length && this._items[this._items.length - 1] instanceof _item.VirtualItem) { | ||
this._overflowsRight = false; | ||
} | ||
if (this._pendingItem) { | ||
if (!this._items.length) { | ||
this._leftItemOffset = 0; | ||
} | ||
this._$container.appendChild(this._pendingItem.getContainer()); | ||
if (this._rate <= 0) { | ||
// insert virtual item so that it starts off screen | ||
this._items.push(new _item.VirtualItem(Math.max(0, containerSize - nextOffset))); | ||
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 = containerSize + this._pendingItem.getSize(); | ||
offsets.push(containerSize); | ||
nextOffset += this._pendingItem.getSize(); | ||
this._items.push(this._pendingItem); | ||
this._overflowsRight = true; | ||
} else { | ||
if (this._items.length && this._leftItemOffset > 0) { | ||
if (!this._nextItemImmediatelyFollowsPrevious && this._items.length && this._leftItemOffset > 0) { | ||
this._items.unshift(new _item.VirtualItem(this._leftItemOffset)); | ||
@@ -675,2 +708,3 @@ offsets.unshift(0); | ||
this._items.unshift(this._pendingItem); | ||
this._overflowsLeft = true; | ||
} | ||
@@ -692,3 +726,3 @@ this._pendingItem = null; | ||
offsets.forEach(function (offset, i) { | ||
return _this4._items[i].setOffset(offset); | ||
return _this5._items[i].setOffset(offset); | ||
}); | ||
@@ -698,4 +732,5 @@ this._updateContainerSize(); | ||
if (!this._items.length) { | ||
this._leftItemOffset = 0; | ||
(0, _helpers.defer)(function () { | ||
_this4._onAllItemsRemoved.forEach(function (cb) { | ||
_this5._onAllItemsRemoved.forEach(function (cb) { | ||
(0, _helpers.deferException)(function () { | ||
@@ -708,19 +743,25 @@ return cb(); | ||
this._nextItemImmediatelyFollowsPrevious = false; | ||
if (!this._waitingForItem && (this._rate <= 0 && nextOffset <= containerSize || this._rate > 0 && this._leftItemOffset >= 0)) { | ||
this._waitingForItem = true; | ||
// timer to not block rendering | ||
(0, _helpers.defer)(function () { | ||
if (_this4._waitingForItem) { | ||
var nextItem = void 0; | ||
_this4._onItemRequired.some(function (cb) { | ||
return (0, _helpers.deferException)(function () { | ||
nextItem = cb(); | ||
return !!nextItem; | ||
}); | ||
}); | ||
if (nextItem) { | ||
_this4.appendItem(nextItem); | ||
} | ||
} | ||
// if all items have been cleared then make the next item start offscreen | ||
var nextItemImmediatelyFollowsPrevious = this._nextItemImmediatelyFollowsPrevious = !!this._items.length && (this._rate <= 0 && this._overflowsRight || this._rate > 0 && this._overflowsLeft); | ||
if (this._rate <= 0) { | ||
this._overflowsRight = false; | ||
} else { | ||
this._overflowsLeft = false; | ||
} | ||
var nextItem = void 0; | ||
this._onItemRequired.some(function (cb) { | ||
return (0, _helpers.deferException)(function () { | ||
nextItem = cb({ immediatelyFollowsPrevious: nextItemImmediatelyFollowsPrevious }); | ||
return !!nextItem; | ||
}); | ||
}); | ||
if (nextItem) { | ||
// Note appendItem() will call _scheduleRender(), which will synchronously call | ||
// _render() again | ||
this.appendItem(nextItem); | ||
} | ||
} | ||
@@ -727,0 +768,0 @@ } |
{ | ||
"name": "dynamic-marquee", | ||
"version": "1.1.1", | ||
"version": "1.2.0", | ||
"description": "A small library for creating marquees.", | ||
@@ -5,0 +5,0 @@ "main": "./dist/dynamic-marquee.js", |
@@ -75,3 +75,6 @@ [![npm version](https://badge.fury.io/js/dynamic-marquee.svg)](https://badge.fury.io/js/dynamic-marquee) | ||
``` | ||
**Do not perform any long running tasks in this method as it will block rendering.** | ||
If you need to perform some work in this method consider wrapping it in a `setTimeout` with delay 0. | ||
## Change the scroll rate? (px/s) | ||
@@ -78,0 +81,0 @@ You can change the rate at any time, and set to 0 to pause. |
@@ -13,3 +13,3 @@ import { toDomEl } from './helpers.js'; | ||
const appendItem = (spaceJustAvailable) => { | ||
const appendItem = (immediatelyFollowsPrevious) => { | ||
if (!builders.length || !marquee.isWaitingForItem()) { | ||
@@ -21,3 +21,3 @@ return; | ||
let $item = toDomEl(builder()); | ||
if (spaceJustAvailable && seperatorBuilder) { | ||
if (immediatelyFollowsPrevious && seperatorBuilder) { | ||
const $seperator = toDomEl(seperatorBuilder()); | ||
@@ -33,3 +33,3 @@ const $container = document.createElement('div'); | ||
}; | ||
marquee.onItemRequired(() => appendItem(true)); | ||
marquee.onItemRequired(({ immediatelyFollowsPrevious }) => appendItem(immediatelyFollowsPrevious)); | ||
appendItem(); | ||
@@ -36,0 +36,0 @@ return { |
@@ -15,3 +15,5 @@ import { Item, VirtualItem } from './item.js'; | ||
) { | ||
this._rendering = false; | ||
this._waitingForItem = true; | ||
this._nextItemImmediatelyFollowsPrevious = false; | ||
this._rate = rate; | ||
@@ -23,3 +25,6 @@ this._direction = upDown ? DIRECTION.DOWN : DIRECTION.RIGHT; | ||
this._leftItemOffset = 0; | ||
this._containerSize = 0; | ||
this._items = []; | ||
this._overflowsRight = false; | ||
this._overflowsLeft = false; | ||
this._pendingItem = null; | ||
@@ -30,3 +35,3 @@ const $innerContainer = document.createElement('div'); | ||
this._$container = $innerContainer; | ||
this._containerSize = null; | ||
this._containerSizeInverse = null; | ||
if (this._direction === DIRECTION.RIGHT) { | ||
@@ -75,2 +80,6 @@ $innerContainer.style.width = '100%'; | ||
this._items = []; | ||
this._waitingForItem = true; | ||
this._overflowsRight = false; | ||
this._overflowsLeft = false; | ||
this._updateContainerSize(); | ||
} | ||
@@ -101,10 +110,10 @@ | ||
_removeItem(item) { | ||
item.remove(); | ||
if (item instanceof Item) { | ||
defer(() => { | ||
defer(() => { | ||
item.remove(); | ||
if (item instanceof Item) { | ||
this._onItemRemoved.forEach((cb) => { | ||
deferException(() => cb(item.getOriginalEl())); | ||
}); | ||
}); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -126,4 +135,4 @@ | ||
}, 0); | ||
if (this._containerSize !== maxSize) { | ||
this._containerSize = maxSize; | ||
if (this._containerSizeInverse !== maxSize) { | ||
this._containerSizeInverse = maxSize; | ||
if (this._direction === DIRECTION.RIGHT) { | ||
@@ -142,9 +151,14 @@ this._$container.style.height = `${maxSize}px`; | ||
_scheduleRender() { | ||
if (!this._requestAnimationID) { | ||
this._lastUpdateTime = performance.now(); | ||
this._requestAnimationID = window.requestAnimationFrame(() => this._render()); | ||
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(() => this._onRequestAnimationFrame()); | ||
} | ||
} | ||
} | ||
_render() { | ||
_onRequestAnimationFrame() { | ||
this._requestAnimationID = null; | ||
@@ -158,6 +172,12 @@ if (!this._rate || (!this._items.length && !this._pendingItem)) { | ||
this._scheduleRender(); | ||
this._rendering = true; | ||
const shiftAmount = this._rate * (timePassed / 1000); | ||
this._leftItemOffset += shiftAmount; | ||
const containerSize = size(this._$container, this._direction); | ||
this._containerSize = size(this._$container, this._direction); | ||
deferException(() => this._render()); | ||
this._rendering = false; | ||
} | ||
_render() { | ||
const containerSize = this._containerSize; | ||
if (this._rate < 0) { | ||
@@ -174,2 +194,5 @@ while(this._items.length) { | ||
} | ||
if (this._items[0] instanceof VirtualItem) { | ||
this._overflowsLeft = false; | ||
} | ||
} | ||
@@ -190,17 +213,21 @@ | ||
}); | ||
if (this._items.length && this._items[this._items.length - 1] instanceof VirtualItem) { | ||
this._overflowsRight = false; | ||
} | ||
if (this._pendingItem) { | ||
if (!this._items.length) { | ||
this._leftItemOffset = 0; | ||
} | ||
this._$container.appendChild(this._pendingItem.getContainer()); | ||
if (this._rate <= 0) { | ||
// insert virtual item so that it starts off screen | ||
this._items.push(new VirtualItem(Math.max(0, containerSize - nextOffset))); | ||
if (!this._nextItemImmediatelyFollowsPrevious) { | ||
// insert virtual item so that it starts off screen | ||
this._items.push(new VirtualItem(Math.max(0, containerSize - nextOffset))); | ||
offsets.push(nextOffset); | ||
nextOffset = containerSize; | ||
} | ||
offsets.push(nextOffset); | ||
nextOffset = containerSize + this._pendingItem.getSize(); | ||
offsets.push(containerSize); | ||
nextOffset += this._pendingItem.getSize(); | ||
this._items.push(this._pendingItem); | ||
this._overflowsRight = true; | ||
} else { | ||
if (this._items.length && this._leftItemOffset > 0) { | ||
if (!this._nextItemImmediatelyFollowsPrevious && this._items.length && this._leftItemOffset > 0) { | ||
this._items.unshift(new VirtualItem(this._leftItemOffset)); | ||
@@ -213,2 +240,3 @@ offsets.unshift(0); | ||
this._items.unshift(this._pendingItem); | ||
this._overflowsLeft = true; | ||
} | ||
@@ -233,2 +261,3 @@ this._pendingItem = null; | ||
if (!this._items.length) { | ||
this._leftItemOffset = 0; | ||
defer(() => { | ||
@@ -241,2 +270,3 @@ this._onAllItemsRemoved.forEach((cb) => { | ||
this._nextItemImmediatelyFollowsPrevious = false; | ||
if ( | ||
@@ -249,19 +279,28 @@ !this._waitingForItem && ( | ||
this._waitingForItem = true; | ||
// timer to not block rendering | ||
defer(() => { | ||
if (this._waitingForItem) { | ||
let nextItem; | ||
this._onItemRequired.some((cb) => { | ||
return deferException(() => { | ||
nextItem = cb(); | ||
return !!nextItem; | ||
}); | ||
}); | ||
if (nextItem) { | ||
this.appendItem(nextItem); | ||
} | ||
} | ||
// if all items have been cleared then make the next item start offscreen | ||
const nextItemImmediatelyFollowsPrevious = this._nextItemImmediatelyFollowsPrevious = | ||
!!this._items.length && ( | ||
(this._rate <= 0 && this._overflowsRight) || | ||
(this._rate > 0 && this._overflowsLeft) | ||
); | ||
if (this._rate <= 0) { | ||
this._overflowsRight = false; | ||
} else { | ||
this._overflowsLeft = false; | ||
} | ||
let nextItem; | ||
this._onItemRequired.some((cb) => { | ||
return deferException(() => { | ||
nextItem = cb({ immediatelyFollowsPrevious: nextItemImmediatelyFollowsPrevious }); | ||
return !!nextItem; | ||
}); | ||
}); | ||
if (nextItem) { | ||
// Note appendItem() will call _scheduleRender(), which will synchronously call | ||
// _render() again | ||
this.appendItem(nextItem); | ||
} | ||
} | ||
} | ||
} | ||
} |
57771
1136
132