Skip to content

Commit

Permalink
Support carousel pagination, improve index and translate calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
omares committed Mar 18, 2019
1 parent 32f1496 commit 5db80b1
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 111 deletions.
2 changes: 1 addition & 1 deletion src/components/gaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function (Glide, Components, Events) {
* @returns {Number}
*/
get () {
return Gaps.value * (Components.Sizes.length - 1)
return Gaps.value * (Components.Sizes.length)
}
})

Expand Down
233 changes: 149 additions & 84 deletions src/components/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function (Glide, Components, Events) {
Events.emit('run', this.move)

Components.Transition.after(() => {
if (this.isOffset('<') || this.isOffset('>')) {
if (this.isOffset()) {
this._o = false

Events.emit('run.offset', this.move)
Expand All @@ -46,86 +46,145 @@ export default function (Glide, Components, Events) {
/**
* Calculates current index based on defined move.
*
* @return {Void}
* @return {void}
*/
calculate () {
let { move, length } = this
let { steps, direction } = move

let countableSteps = (isNumber(toInt(steps))) && (toInt(steps) !== 0)
// jump to specified index
if (direction === '=') {
Glide.index = steps

switch (direction) {
case '|':
const pageSize = Glide.settings.perView || 1
// bound does funny things with the length, therefor fallback to the default length
// when bound is deactivated calculate the last index that is meaningful to provide a pleasant pagination
const lastMeaningfulIndex = this.isBound() ? length : Math.floor(length / pageSize) * pageSize
return
}

if (steps === '>') {
const nextIndex = Glide.index + pageSize
// << fast forward
if (direction === '>' && steps === '>') {
Glide.index = length

// do not go further than the last index that is meaningful
let allowedMin = lastMeaningfulIndex
return
}

// when rewind is enabled and the next index is above the amount of slides, rewind to the first slide
if (Glide.settings.rewind && nextIndex > length) {
// bound does funny things with the length, therefor we have to be certain
// that we reached the last possible length value before we rewind
allowedMin = !this.isBoundEnd() ? length : 0
}
// >> rewind
if (direction === '<' && steps === '<') {
// pageSize = length - Glide.index
Glide.index = 0

Glide.index = Math.min(allowedMin, nextIndex)
} else {
const page = Math.ceil(Glide.index / pageSize)
const prevIndex = (page - 1) * pageSize
return
}

// when rewind is enabled and the previous index is below zero, rewind to the last index that is meaningful
// when rewind is disabled and previous index is below zero, stop at the fist slide
const allowedMax = (Glide.settings.rewind && prevIndex < 0) ? lastMeaningfulIndex : 0
// < or > movement
let pageSize = 1

Glide.index = Math.max(allowedMax, prevIndex)
}
break
case '>':
if (steps === '>') {
Glide.index = length
} else if (this.isEnd()) {
if (!(Glide.isType('slider') && !Glide.settings.rewind)) {
this._o = true

Glide.index = 0
}

Events.emit('run.end', move)
} else if (countableSteps) {
Glide.index += Math.min(length - Glide.index, -toInt(steps))
} else {
Glide.index++
}
break

case '<':
if (steps === '<') {
Glide.index = 0
} else if (this.isStart()) {
if (!(Glide.isType('slider') && !Glide.settings.rewind)) {
this._o = true

Glide.index = length
}

Events.emit('run.start', move)
} else if (countableSteps) {
Glide.index -= Math.min(Glide.index, toInt(steps))
} else {
Glide.index--
}
break
const countableSteps = isNumber(toInt(steps)) && toInt(steps) !== 0
// >$steps (drag) movement
if (direction === '>' && countableSteps) {
pageSize = toInt(steps) * -1
}

// $steps< (drag) movement
if (direction === '<' && countableSteps) {
pageSize = toInt(steps)
}

// pagination movement
if (direction === '|') {
// Glide.index += Math.min(length - Glide.index, -toInt(steps))
pageSize = Glide.settings.perView || 1
}

// we are moving forward
if (direction === '>' || (direction === '|' && steps === '>')) {
const index = this.calculateForwardIndex(pageSize)

if (index > length) {
this._o = true
Events.emit('run.end', move)
}

Glide.index = this.normalizeForwardIndex(index, length, pageSize)

return
}

case '=':
Glide.index = steps
break
const index = this.calculateBackwardIndex(pageSize)

if (index < 0) {
this._o = true
Events.emit('run.end', move)
}

Glide.index = this.normalizeBackwardIndex(index, length, pageSize)
},

calculateForwardIndex (pageSize) {
return Glide.index + pageSize
},

/**
* x
*/
normalizeForwardIndex (index, length, pageSize) {
if (index <= length) {
return index
}

if (Glide.isType('carousel')) {
return index - (length + 1)
}

if (Glide.settings.rewind) {
// bound does funny things with the length, therefor we have to be certain
// that we are on the last possible index value given by bound
if (this.isBound() && !this.isEnd()) {
return length
}

return 0
}

if (this.isBound()) {
return length
}

return Math.floor(length / pageSize) * pageSize
},

calculateBackwardIndex (pageSize) {
if (Glide.isType('carousel')) {
return Glide.index - pageSize
}

// ensure our back navigation results in the same index as a forward navigation
// to experience a homogeneous paging
const page = Math.ceil(Glide.index / pageSize)
return (page - 1) * pageSize
},

/**
* x
*/
normalizeBackwardIndex (index, length, pageSize) {
if (index >= 0) {
return index
}

if (Glide.isType('carousel')) {
return index + (length + 1)
}

if (Glide.settings.rewind) {
// bound does funny things with the length, therefor we have to be certain
// that we are on first possible index value before we to rewind to the length given by bound
if (this.isBound() && this.isStart()) {
return length
}

return Math.floor(length / pageSize) * pageSize
}

return 0
},

/**
Expand All @@ -134,7 +193,7 @@ export default function (Glide, Components, Events) {
* @return {Boolean}
*/
isStart () {
return Glide.index === 0
return Glide.index <= 0
},

/**
Expand All @@ -152,8 +211,26 @@ export default function (Glide, Components, Events) {
* @param {String} direction
* @return {Boolean}
*/
isOffset (direction) {
return this._o && this.move.direction === direction
isOffset (direction = undefined) {
if (!direction) {
return this._o
}

if (!this._o) {
return false
}

// did we page to the right?
if (direction === '|>') {
return this.move.direction === '|' && this.move.steps === '>'
}

// did we page to the left?
if (direction === '|<') {
return this.move.direction === '|' && this.move.steps === '<'
}

return this.move.direction === direction
},

/**
Expand All @@ -163,19 +240,6 @@ export default function (Glide, Components, Events) {
*/
isBound () {
return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound
},

/**
* Checks if slides should be rewinded
*
* @return {Boolean}
*/
isBoundEnd () {
if (this.isBound() && this.isEnd()) {
return true
}

return !this.isBound()
}
}

Expand Down Expand Up @@ -216,7 +280,8 @@ export default function (Glide, Components, Events) {
// If the `bound` option is active, a maximum running distance should be
// reduced by `perView` and `focusAt` settings. Running distance
// should end before creating an empty space after instance.
if (this.isBound()) {
// if (this.isBound()) {
if (Glide.isType('slider') && settings.focusAt !== 'center' && settings.bound) {
return (length - 1) - (toInt(settings.perView) - 1) + toInt(settings.focusAt)
}

Expand Down
8 changes: 4 additions & 4 deletions src/components/sizes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default function (Glide, Components, Events) {
*
* @return {Void}
*/
setupWrapper (dimention) {
setupWrapper () {
Components.Html.wrapper.style.width = `${this.wrapperSize}px`
},

Expand Down Expand Up @@ -54,7 +54,7 @@ export default function (Glide, Components, Events) {

define(Sizes, 'width', {
/**
* Gets width value of the glide.
* Gets width value of the slider (visible area).
*
* @return {Number}
*/
Expand All @@ -70,13 +70,13 @@ export default function (Glide, Components, Events) {
* @return {Number}
*/
get () {
return (Sizes.slideWidth * Sizes.length) + Components.Gaps.grow + Components.Clones.grow
return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow
}
})

define(Sizes, 'slideWidth', {
/**
* Gets width value of the single slide.
* Gets width value of a single slide.
*
* @return {Number}
*/
Expand Down

0 comments on commit 5db80b1

Please sign in to comment.