Commit 2b93f563 by Иван Кубота

Debounce resize event

Add mobile slider behaviour and paddings
parent 9e7938e0
......@@ -24,13 +24,16 @@ export default function() {
)}
</div>;
const w = window;
w.addEventListener('resize', function() {
let resizeFn;
w.addEventListener('resize', Store.debounce(resizeFn = function() {
tmpStore.set({
isMobile: w.innerWidth < 1025,
width: w.innerWidth
});
});
},1000/20));
resizeFn();
tmpStore.set('loaded', true);
};
......@@ -8,39 +8,62 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
hash = {},
items = [],
cardWidth = 160,
minPadding = 20,
minPadding = 10,
mobilePadding = 10,
wrap,
width,
fullCardsCount,
padding,
updateSize = function () {
width = dom.clientWidth;
width = dom.clientWidth - paddingLeft - paddingRight;
fullCardsCount = width / (cardWidth + minPadding) | 0;
padding = (width - fullCardsCount * cardWidth) / (fullCardsCount - 1);
padding = mobile ? mobilePadding: (width - fullCardsCount * cardWidth) / (fullCardsCount - 1);
wrap.style.width = (items.length * (padding + cardWidth) - padding) + 'px';
},
update = function () {
updateSize();
updateVisibleDom();
};
let paddingLeft = 30, paddingRight = 30, mobile = false;
tmpStore.sub('width', Store.debounce(function (w) {
let firstItem = Math.round(dom.scrollLeft / (cardWidth + padding));
console.log(firstItem);
update();
dom.scrollLeft = firstItem * (cardWidth + padding);
}, 30));
let waitTimeout = false;
let tuning = false;
let tuning;
let leftestItem = 0;
let lastLeftestItem = 0;
let tuneScrollPosition = function () {
let leftButtonDisabled = new Store.Value.Boolean(true), rightButtonDisabled = new Store.Value.Boolean(true);
let updateButtonsState = function() {
let fromLeft = dom.scrollLeft;
let firstItem = Math.round( fromLeft / ( cardWidth + padding ));
leftButtonDisabled.set(firstItem===0);
rightButtonDisabled.set(firstItem+fullCardsCount===items.length);
};
let untune = function() {
updateButtonsState();
tuning = false;
};
let tuneScrollPosition = function (x) {
if(tuning)
return untune();
waitTimeout = false;
tuning = true;
let fromLeft = dom.scrollLeft;
let firstItem = Math.round(fromLeft / (cardWidth + padding) - (lastLeftestItem > leftestItem ? 0.4 : -0.4));
let toLeft = Math.round(firstItem * (cardWidth + padding));
let firstItem, toLeft;
if(x){
firstItem = Math.round( fromLeft / ( cardWidth + padding ));
if(firstItem+x<0 || firstItem+fullCardsCount+x>items.length){
return untune();
}
toLeft = Math.round( (firstItem + x) * ( cardWidth + padding ));
}else{
firstItem = Math.round( fromLeft / ( cardWidth + padding ) - ( lastLeftestItem > leftestItem ? 0.4 : -0.4 ) );
toLeft = Math.round( firstItem * ( cardWidth + padding ) );
}
let deltaMove = (toLeft - fromLeft) / Math.ceil(200 / (1000 / 60));
while (deltaMove > 0 && deltaMove < 1) {
deltaMove *= 2;
......@@ -49,15 +72,15 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
deltaMove = toLeft - fromLeft;
}
let tune = function () {
if (Math.abs(toLeft - dom.scrollLeft) > (cardWidth + padding)) {
return tuning = false;
if (Math.abs(toLeft - dom.scrollLeft) > (cardWidth + padding)*1.3) {
return untune();
}
if (Math.sign(toLeft - dom.scrollLeft) !== Math.sign(deltaMove)) {
return tuning = false;
return untune();
}
if (Math.abs(dom.scrollLeft - toLeft) < Math.abs(deltaMove)) {
dom.scrollLeft = toLeft;
return tuning = false;
return untune();
} else {
dom.scrollLeft += deltaMove;
requestAnimationFrame(tune);
......@@ -66,7 +89,7 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
if (Math.abs(deltaMove) > 0) {
requestAnimationFrame(tune);
} else {
tuning = false;
return untune();
}
};
......@@ -83,11 +106,25 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
};
let dom;
let theDOM = <div class="card-slider">
<button class="card-slider__control card-slider__control--prev" type="button"
<button class={D.cls(
'card-slider__control',
'card-slider__control--prev',
{'card-slider__control-disabled': leftButtonDisabled}
)} type="button"
onClick={()=>{
tuneScrollPosition(-1);
}}
aria-label="Показать предыдущую карточку">
<ArrPrev width="14" height="12"/>
</button>
<button className="card-slider__control card-slider__control--next" type="button"
<button class={D.cls(
'card-slider__control',
'card-slider__control--next',
{'card-slider__control-disabled': rightButtonDisabled}
)} type="button"
onClick={()=>{
tuneScrollPosition(1);
}}
aria-label="Показать предыдущую карточку">
<ArrNext width="14" height="12"/>
</button>
......@@ -137,7 +174,7 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
}
}
for (let i = from; i < to; i++) {
let x = i * (cardWidth + padding);
let x = paddingLeft + i * (cardWidth + padding);
if (hash[i].x !== x) {
hash[i].dom.style.left = (hash[i].x = x) + 'px';
}
......@@ -151,7 +188,7 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
lastFrom = from;
lastTo = to;
last = true;
updateButtonsState();
};
dom.addEventListener('scroll', Store.debounce(function () {
......@@ -166,6 +203,19 @@ const CardSlider = D.declare('view.cmp.CardSlider', (cfg) => {
});
tmpStore.sub('width', Store.debounce(function (w) {
let firstItem = Math.round(dom.scrollLeft / (cardWidth + padding));
update();
dom.scrollLeft = firstItem * (cardWidth + padding);
}, 30));
tmpStore.sub('isMobile', function(is) {
mobile = is;
paddingLeft = paddingRight = is ? 10 : 30;
update();
});
return theDOM;
});
......
......@@ -14,3 +14,6 @@
flex-direction: column;
margin-bottom: 30px;
}
.card-slider__control-disabled {
display: none;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment