You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
229 lines
4.9 KiB
229 lines
4.9 KiB
import * as Hammer from 'hammerjs'
|
|
|
|
/**
|
|
* Mixin for extends Riot-Component
|
|
*
|
|
* @author Björn Hase
|
|
* @license http://opensource.org/licenses/MIT The MIT License
|
|
* @link https://gitea.node001.net/tiny-components/slider
|
|
*
|
|
*/
|
|
|
|
export default {
|
|
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
state: {
|
|
position: 0,
|
|
max: 0,
|
|
slides: undefined,
|
|
classes: {
|
|
item: 'tiny-slider__item'
|
|
}
|
|
},
|
|
|
|
/**
|
|
*
|
|
*
|
|
*/
|
|
onMounted() {
|
|
|
|
if (this.props.slides) {
|
|
this.state.slides = this.props.slides
|
|
}
|
|
|
|
// start and add resize listener
|
|
window.addEventListener('resize', this.update.bind(this))
|
|
|
|
setTimeout(() => {
|
|
this.update()
|
|
}, 100)
|
|
|
|
// Create a manager to manager the element
|
|
const manager = new Hammer(this.root)
|
|
|
|
manager.on('swipe', (event) => {
|
|
if (event.direction === 4) {
|
|
this.handlePrevious(event)
|
|
} else if (event.direction === 2) {
|
|
this.handleNext(event)
|
|
}
|
|
})
|
|
},
|
|
|
|
/**
|
|
* remove resize listener before unmount
|
|
*
|
|
*/
|
|
onBeforeUnmount() {
|
|
window.removeEventListener('resize', this.update.bind(this))
|
|
},
|
|
|
|
/**
|
|
* before update view, calculate values
|
|
*
|
|
* @param {object} props
|
|
* @param {object} state
|
|
*
|
|
*/
|
|
onBeforeUpdate(props, state) {
|
|
|
|
// getting current max
|
|
const max = this.state.max
|
|
const element = this.$('.' + this.state.classes.item)
|
|
|
|
if (element) {
|
|
|
|
// setting max to show visible
|
|
this.state.max = 0
|
|
this.state.width = element.offsetWidth
|
|
|
|
// check how many elements can visible in element
|
|
this.$$('.' + this.state.classes.item).forEach((element, index) => {
|
|
if (element.offsetLeft < this.root.offsetWidth) {
|
|
this.state.max++;
|
|
}
|
|
})
|
|
|
|
// change position to fit new max value
|
|
const value = Math.abs(this.state.max - max)
|
|
|
|
// @TODO check this, at 0 it makes me mad
|
|
if (this.state.position >= value && this.state.position > 1) {
|
|
this.state.position -= value
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* set current position
|
|
*
|
|
*
|
|
*/
|
|
handleSelect(event, position) {
|
|
event.preventDefault()
|
|
|
|
if (this.state.position !== position) {
|
|
this.update({
|
|
position: position
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* set next postion
|
|
*
|
|
*
|
|
*/
|
|
handlePrevious(event) {
|
|
event.preventDefault()
|
|
|
|
if (this.state.position > 0) {
|
|
this.update({
|
|
position: --this.state.position
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* set next postion
|
|
*
|
|
*
|
|
* @param {object} event
|
|
*
|
|
*/
|
|
handleNext(event) {
|
|
event.preventDefault()
|
|
|
|
if (this.state.position < (this.props.slides.length - 1)) {
|
|
this.update({
|
|
position: ++this.state.position
|
|
})
|
|
}
|
|
},
|
|
|
|
/**
|
|
* getting classes for next-button,
|
|
* show button only
|
|
*
|
|
*
|
|
* @return {string}
|
|
*
|
|
*/
|
|
getPreviousClasses() {
|
|
const classes = [
|
|
'tiny-slider__button',
|
|
'tiny-slider__button--previous'
|
|
]
|
|
|
|
if (this.state.position > 0) {
|
|
classes.push('visibility-visible')
|
|
} else {
|
|
classes.push('visibility-hidden')
|
|
}
|
|
|
|
return classes.join(' ')
|
|
},
|
|
|
|
/**
|
|
* getting classes for next-button,
|
|
* show button unless length is smaller then max
|
|
*
|
|
* @return {string}
|
|
*
|
|
*/
|
|
getNextClasses() {
|
|
const classes = [
|
|
'tiny-slider__button',
|
|
'tiny-slider__button--next'
|
|
]
|
|
|
|
if (this.state.position <= (this.props.slides.length - this.state.max)) {
|
|
classes.push('visibility-visible')
|
|
} else {
|
|
classes.push('visibility-hidden')
|
|
}
|
|
|
|
return classes.join(' ')
|
|
},
|
|
|
|
/**
|
|
* getting classes for select,
|
|
* adding current-class if postion and state.postion are equal
|
|
*
|
|
* @param {integer} position
|
|
* @return {string}
|
|
*
|
|
*/
|
|
getSelectClasses(position) {
|
|
const classes = [
|
|
'tiny-slider__select-item'
|
|
]
|
|
|
|
if (this.state.position === position) {
|
|
classes.push('tiny-slider__select-item--current')
|
|
}
|
|
|
|
return classes.join(' ')
|
|
},
|
|
|
|
/**
|
|
* set translate with position and witdh
|
|
*
|
|
*
|
|
* @return {string}
|
|
*
|
|
*/
|
|
getContentStyles() {
|
|
|
|
// getting value for position
|
|
const value = (-(this.state.position * this.state.width));
|
|
|
|
return this.styles({
|
|
transform: 'translate(' + value + 'px, 0px)'
|
|
})
|
|
}
|
|
}
|