在滑块插件上实现 RTL
Implementing RTL on a slider plugin
在开发者several requests ignored支持RTL之后,我正在尝试自己做。
反转数组顺序非常简单:
self.items = !!(_options.rtl) ? _items = items.reverse() : _items = items; // Reverse the array for RTL
..然而,另一个挑战是滑动 RTL。因此从幻灯片 4(这是第一张幻灯片)向右滑动应该会滑到下一张幻灯片(幻灯片 3)。
我相信所有的魔法都发生在这个函数中,但我不太清楚要调整什么:
_moveMainScroll = function(x, dragging) {
if(!_options.loop && dragging) {
if (_options.rtl) {
console.log('RTL enabled');
console.log('_currentItemIndex: ', _currentItemIndex);
console.log('_slideSize.x: ', _slideSize.x);
console.log('_currPositionIndex: ', _currPositionIndex);
console.log('x: ', x);
var newSlideIndexOffset = _currentItemIndex + (_slideSize.x * _currPositionIndex - x) / _slideSize.x,
delta = Math.round(x - _mainScrollPos.x);
console.log(newSlideIndexOffset, delta);
}
else {
var newSlideIndexOffset = _currentItemIndex + (_slideSize.x * _currPositionIndex - x) / _slideSize.x,
delta = Math.round(x - _mainScrollPos.x);
console.log(newSlideIndexOffset, delta);
}
if( (newSlideIndexOffset < 0 && delta > 0) || (newSlideIndexOffset >= _getNumItems() - 1 && delta < 0) ) {
x = _mainScrollPos.x + delta * _options.mainScrollEndFriction;
}
}
_mainScrollPos.x = x;
_setTranslateX(x, _containerStyle);
}
到目前为止,这是我的代码:https://jsfiddle.net/tdx3p1p3/
以前从未使用过该库,所以我在这里可能有点天真。您的 rtl
选项似乎只会颠倒元素的顺序,否则没有任何效果。查看代码,我看不出这会是个问题,但我没有调查开发人员在您链接到的那篇文章中提到的标题问题。
如果我错了请原谅我,但我认为这就是你想要的:
********
Slide1 < Slide2 < Slide3 < *Slide4*
********
如果是这种情况,您希望顺序相同,但初始元素为幻灯片 4(即索引 3):
var options = {
...
rtl: false,
index: 3
};
如果是这种情况,那么我认为您甚至不需要 _options.rtl
变量。
另一方面,如果您想要这种布局:
********
Slide4 < Slide3 < Slide2 < *Slide1*
********
...那么你可以使用这个配置:
var options = {
...
rtl: true,
index: 3
};
...这当然需要 _options.rtl
变量,并且可能需要围绕字幕进行测试。
如果我理解正确,您想以常规方式使用 PhotoSwipe,特别是照常传递 items
数组(即第一张幻灯片位于索引 0
),但是图库将此幻灯片 0
放在 "right-most" 位置,然后将 1
幻灯片放在其左侧,依此类推,让左上角计数器显示幻灯片 "index"(偏移 1相应地避免显示“0”)(因此仅使用 options.index: 3
是不够的)。
如果这是正确的,你会喜欢@e_i_pi想象中的2nd布局:
********
Slide4 < Slide3 < Slide2 < *Slide1*
********
因此你需要三样东西:
- 反转你的
items
数组。
- 从最右边的幻灯片开始。
- 修改 UI 计数器,使报告的载玻片索引为 "reversed"。
您不需要通过调整 PhotoSwipe 脚本中的代码来执行这 3 个操作。您可以只使用执行这些操作的 "wrapper" 函数,并且仍然使用未修改的 PhotoSwipe 代码(以便您以后更容易升级,并从库的未来改进中受益)。
1.反转你的 items
数组:
如您所见,这是最简单的操作:items = items.reverse()
2。从最右边的幻灯片开始:
正如@e_i_pi 所建议的那样,您只需要传递一个 index
option 等于 new 索引(即反转后)你的 "first" 幻灯片:index = items.length - 1
它最初位于索引 0
,经过反转后现在是 "last" 项。
3。反转 UI 计数器:
这稍微高级一点,但没有太复杂。
正如 PhotoSwipe 作者 shown 所说,自定义 UI 计数器很容易,但需要先初始化图库。因此,"wrapper"函数需要在内部初始化gallery。
那么构建新的 UI 计数器内容的逻辑并不太复杂。您只需要取项目总数并减去items
JS数组中的当前索引:
********
Slide4 < Slide3 < Slide2 < *Slide1*
********
0 1 2 3 <= index in items JS array
4 3 2 1 <= "index" to be shown in UI counter
所以你可以有这样的东西:
var total = gallery.options.getNumItemsFn();
var current = gallery.getCurrentIndex();
var reversed = total - current;
var separator = gallery.options.indexIndicatorSep;
indexIndicatorDOMElement.innerHTML = reversed + separator + total;
把所有东西放在一起,你就有了一个包装函数,你可以把它放在它自己的 JS 文件中,这样你就可以在任何你想用的地方使用它。
// Wrapper initialize function that does the RTL conversion automatically.
// Note: it will also automatically initialize the PhotoSwipe, because it needs to be initialized for UI counter to be modified.
function photoSwipeRTL(pswpElement, uiClass, items, options) {
// 1. Reverse the items.
items = items.reverse();
// 2. Override the start index.
var itemsIndexMax = items.length - 1;
var index = options.index || 0; // If not provided, use 0.
// Now reverse the start index.
options.index = itemsIndexMax - index;
// Now instantiate a PhotoSwipe and initialize it, so that we can modify its UI counter.
var pswp = new PhotoSwipe(pswpElement, uiClass, items, options);
pswp.init();
// Get the counter element provided in options, or get it from DOM.
var indexIndicatorDOMElement = options.indexIndicatorDOMElement || document.querySelectorAll('.pswp__counter')[0];
// 3. Modify the UI counter.
pswp.ui.updateIndexIndicator = function() {
// This code reverses the current index compared to the total number of items in the gallery.
var total = pswp.options.getNumItemsFn();
var current = pswp.getCurrentIndex();
var reversed = total - current;
var separator = pswp.options.indexIndicatorSep;
indexIndicatorDOMElement.innerHTML = reversed + separator + total;
};
// force index update
pswp.ui.updateIndexIndicator();
return pswp;
}
而且你可以非常简单地使用它,几乎就像标准的 PhotoSwipe,只是你只需要执行工厂(不需要 new
关键字),并且不需要初始化图库,因为它已经内部完成。
// INITIALIZE
var pswpElement = document.querySelectorAll('.pswp')[0];
// build items array
var items = [slide1, slide2, slide3, slide4];
// define options (if needed)
var options = {
indexIndicatorSep: ' of ',
indexIndicatorDOMElement: document.querySelectorAll('.pswp__counter')[0]
};
// Initializes and opens PhotoSwipe
var gallery = photoSwipeRTL(pswpElement, PhotoSwipeUI_Default, items, options);
在开发者several requests ignored支持RTL之后,我正在尝试自己做。
反转数组顺序非常简单:
self.items = !!(_options.rtl) ? _items = items.reverse() : _items = items; // Reverse the array for RTL
..然而,另一个挑战是滑动 RTL。因此从幻灯片 4(这是第一张幻灯片)向右滑动应该会滑到下一张幻灯片(幻灯片 3)。
我相信所有的魔法都发生在这个函数中,但我不太清楚要调整什么:
_moveMainScroll = function(x, dragging) {
if(!_options.loop && dragging) {
if (_options.rtl) {
console.log('RTL enabled');
console.log('_currentItemIndex: ', _currentItemIndex);
console.log('_slideSize.x: ', _slideSize.x);
console.log('_currPositionIndex: ', _currPositionIndex);
console.log('x: ', x);
var newSlideIndexOffset = _currentItemIndex + (_slideSize.x * _currPositionIndex - x) / _slideSize.x,
delta = Math.round(x - _mainScrollPos.x);
console.log(newSlideIndexOffset, delta);
}
else {
var newSlideIndexOffset = _currentItemIndex + (_slideSize.x * _currPositionIndex - x) / _slideSize.x,
delta = Math.round(x - _mainScrollPos.x);
console.log(newSlideIndexOffset, delta);
}
if( (newSlideIndexOffset < 0 && delta > 0) || (newSlideIndexOffset >= _getNumItems() - 1 && delta < 0) ) {
x = _mainScrollPos.x + delta * _options.mainScrollEndFriction;
}
}
_mainScrollPos.x = x;
_setTranslateX(x, _containerStyle);
}
到目前为止,这是我的代码:https://jsfiddle.net/tdx3p1p3/
以前从未使用过该库,所以我在这里可能有点天真。您的 rtl
选项似乎只会颠倒元素的顺序,否则没有任何效果。查看代码,我看不出这会是个问题,但我没有调查开发人员在您链接到的那篇文章中提到的标题问题。
如果我错了请原谅我,但我认为这就是你想要的:
********
Slide1 < Slide2 < Slide3 < *Slide4*
********
如果是这种情况,您希望顺序相同,但初始元素为幻灯片 4(即索引 3):
var options = {
...
rtl: false,
index: 3
};
如果是这种情况,那么我认为您甚至不需要 _options.rtl
变量。
另一方面,如果您想要这种布局:
********
Slide4 < Slide3 < Slide2 < *Slide1*
********
...那么你可以使用这个配置:
var options = {
...
rtl: true,
index: 3
};
...这当然需要 _options.rtl
变量,并且可能需要围绕字幕进行测试。
如果我理解正确,您想以常规方式使用 PhotoSwipe,特别是照常传递 items
数组(即第一张幻灯片位于索引 0
),但是图库将此幻灯片 0
放在 "right-most" 位置,然后将 1
幻灯片放在其左侧,依此类推,让左上角计数器显示幻灯片 "index"(偏移 1相应地避免显示“0”)(因此仅使用 options.index: 3
是不够的)。
如果这是正确的,你会喜欢@e_i_pi想象中的2nd布局:
********
Slide4 < Slide3 < Slide2 < *Slide1*
********
因此你需要三样东西:
- 反转你的
items
数组。 - 从最右边的幻灯片开始。
- 修改 UI 计数器,使报告的载玻片索引为 "reversed"。
您不需要通过调整 PhotoSwipe 脚本中的代码来执行这 3 个操作。您可以只使用执行这些操作的 "wrapper" 函数,并且仍然使用未修改的 PhotoSwipe 代码(以便您以后更容易升级,并从库的未来改进中受益)。
1.反转你的 items
数组:
如您所见,这是最简单的操作:items = items.reverse()
2。从最右边的幻灯片开始:
正如@e_i_pi 所建议的那样,您只需要传递一个 index
option 等于 new 索引(即反转后)你的 "first" 幻灯片:index = items.length - 1
它最初位于索引 0
,经过反转后现在是 "last" 项。
3。反转 UI 计数器:
这稍微高级一点,但没有太复杂。
正如 PhotoSwipe 作者 shown 所说,自定义 UI 计数器很容易,但需要先初始化图库。因此,"wrapper"函数需要在内部初始化gallery。
那么构建新的 UI 计数器内容的逻辑并不太复杂。您只需要取项目总数并减去items
JS数组中的当前索引:
********
Slide4 < Slide3 < Slide2 < *Slide1*
********
0 1 2 3 <= index in items JS array
4 3 2 1 <= "index" to be shown in UI counter
所以你可以有这样的东西:
var total = gallery.options.getNumItemsFn();
var current = gallery.getCurrentIndex();
var reversed = total - current;
var separator = gallery.options.indexIndicatorSep;
indexIndicatorDOMElement.innerHTML = reversed + separator + total;
把所有东西放在一起,你就有了一个包装函数,你可以把它放在它自己的 JS 文件中,这样你就可以在任何你想用的地方使用它。
// Wrapper initialize function that does the RTL conversion automatically.
// Note: it will also automatically initialize the PhotoSwipe, because it needs to be initialized for UI counter to be modified.
function photoSwipeRTL(pswpElement, uiClass, items, options) {
// 1. Reverse the items.
items = items.reverse();
// 2. Override the start index.
var itemsIndexMax = items.length - 1;
var index = options.index || 0; // If not provided, use 0.
// Now reverse the start index.
options.index = itemsIndexMax - index;
// Now instantiate a PhotoSwipe and initialize it, so that we can modify its UI counter.
var pswp = new PhotoSwipe(pswpElement, uiClass, items, options);
pswp.init();
// Get the counter element provided in options, or get it from DOM.
var indexIndicatorDOMElement = options.indexIndicatorDOMElement || document.querySelectorAll('.pswp__counter')[0];
// 3. Modify the UI counter.
pswp.ui.updateIndexIndicator = function() {
// This code reverses the current index compared to the total number of items in the gallery.
var total = pswp.options.getNumItemsFn();
var current = pswp.getCurrentIndex();
var reversed = total - current;
var separator = pswp.options.indexIndicatorSep;
indexIndicatorDOMElement.innerHTML = reversed + separator + total;
};
// force index update
pswp.ui.updateIndexIndicator();
return pswp;
}
而且你可以非常简单地使用它,几乎就像标准的 PhotoSwipe,只是你只需要执行工厂(不需要 new
关键字),并且不需要初始化图库,因为它已经内部完成。
// INITIALIZE
var pswpElement = document.querySelectorAll('.pswp')[0];
// build items array
var items = [slide1, slide2, slide3, slide4];
// define options (if needed)
var options = {
indexIndicatorSep: ' of ',
indexIndicatorDOMElement: document.querySelectorAll('.pswp__counter')[0]
};
// Initializes and opens PhotoSwipe
var gallery = photoSwipeRTL(pswpElement, PhotoSwipeUI_Default, items, options);