I would create a slider like the MacDonalds one:
the objective is that my slider fit the contained element, then when I click the right or left button that my slider go on one side or another, and come back to other boundary if the user has reached one or other boundary side.
The problem is that my slider is fully inconsistent, it doesn't responses to the event triggering correctly and the management of the state seems very buggy also, so I m wondering how to improve my application,
My slider fails to have a fluent behavior, here the demo -beware the script bugs on my browser using StackOverflow but JSFiddle succeeds to read the script well:
let scopeProps= 5
class App extends React.Component{
state={
// number of items in he slider
totalSliderItem:0,
// deplacement range to handle the sliding => default to scopeProps
moveRange: scopeProps,
// range of sliderView => default to scopeProps
boxScope:scopeProps,
// unitWidth of each box item => scopeProps/ number of item desired inside a box view
unitWidth:0,
// number of item outside box view localize at the right of box
outsideBoxRight:0,
// number of item outside box view localize at the left of box
outsideBoxLeft:0
}
componentDidMount(){
// set CSS variable
// § call body variable
let root= document.body;
// § update css variable --slider-container-scope
root.style.setProperty('--slider-container-scope', scopeProps);
// § update css variable CSS variable --unit-width
// call metacontainer ref
let SliderMetaContainer= this.refs.sliderMetaContainer
// get metacontainer width
let metaContainerWidth=SliderMetaContainer.getBoundingClientRect().width
let unitWidth= metaContainerWidth/scopeProps
root.style.setProperty('--unit-width', unitWidth + "px") ;
// set number of items contained in slider
let sliderContainer= this.refs.sliderContainer
let sliderContainerLength= sliderContainer.childElementCount
console.log("sliderContainerRef length: ", sliderContainerLength);
// initial number of items localized outside box view == all box overcosm slider scope
let outsideBoxRight=sliderContainerLength-scopeProps
// initialize state after componentDidMount
this.setState({
totalSliderItem:sliderContainerLength,
outsideBoxRight,
unitWidth
})
}
// when user click a button to move => handleSlideMove()
handleSlideMove=(direction)=>{
console.log("window: ", window)
console.log("in handleSlideMove")
// appreciate number of item outsideBox depending of direction targeted
let outsideBoxUnit= direction==="left" ? -(this.state["outsideBoxLeft"]) : this.state["outsideBoxRight"];
// direction => if(outsideBox(direction)<=0 ==> call boundary
if(outsideBoxUnit <= 0){
// go to other boundary
let boundaryRange = this.state.totalSliderItem - this.state.boxScope;
this.boundaryMove(boundaryRange, direction)
}
// else make a move further in the slider
else this.furtherMove(outsideBoxUnit, direction)
}
boundaryMove=(boundaryRange, direction)=>{
console.log("in boundaryMove")
// each category has a specific unitWidth
let unitWidth=this.state.unitWidth
let boxScope=this.state.boxScope
// set other boundary range
let moveRange= boundaryRange
let move= unitWidth * moveRange
// console.log("unitWidth, boxScope, outsideBoxUnit: ", unitWidth, boxScope, outsideBoxUnit);
// set movement range
// let move= outsideBoxUnit < boxScope? unitWidth * outsideBoxUnit: unitWidth * boxScope
// console.log("move: ", move);
// handle movement direction
if(direction==="left") move= -move
console.log("move value: ", move)
// trigger movement
document.body.style.setProperty('--item-left', move + "px");
this.updateItemRepartition(moveRange)
}
furtherMove=(outsideBoxUnit, direction)=>{
console.log("in furtherMove")
// each category has a specific unitWidth
let unitWidth=this.state.unitWidth
console.log("line 109, unitWidth: ", unitWidth)
let boxScope=this.state.boxScope
let move
let moveRange = outsideBoxUnit < boxScope? outsideBoxUnit: boxScope
// handle movement direction
move= unitWidth * moveRange
// if(direction==="left") move=move
console.log("outsideBoxUnit line 104: ", outsideBoxUnit)
console.log("move value: ", move)
// trigger movement
document.body.style.setProperty('--item-left', move + "px");
this.updateItemRepartition(moveRange, direction)
}
// update how many items are outside the box view from each side
updateItemRepartition=(moveRange, direction)=>{
// get boxScope
let boxScope=this.state.boxScope
// appreciate if the number to use for update should be boxScope _ outsideBox
let range= moveRange < boxScope? moveRange : boxScope
// update outsideBox value according to movement direction
this.setState( currentState =>{
// move to left => increase right outsideBoxItem _ decrease left outsideBoxItem
let updateBoxRight= direction === "left" ?
currentState.outsideBoxRight + range
:
currentState.outsideBoxRight - range
// move to righ => increase left outsideBoxItem _ decrease right outsideBoxItem
let updateBoxLeft= direction !== "left" ?
currentState.outsideBoxLeft + range
:
currentState.outsideBoxLeft - range
// debugging => appreciate number to evaluate if update would be relevant
console.log(
"currentState.outsideBoxLeft, currentState.outsideBoxRight, range: ",
currentState.outsideBoxLeft, currentState.outsideBoxRight, range
)
// update component state
return ({
outsideBoxRight:updateBoxRight,
outsideBoxLeft:updateBoxLeft
})
})
}
render(){
return (
<div className="page">
Awesome containers here!
<button onClick={() => this.handleSlideMove("left")} >
move left
</button>
<div ref="sliderMetaContainer" className="slider_metacontainer">
<div ref="sliderContainer" className="slider_container">
<div className="slider_item">
1
</div>
<div className="slider_item">
2
</div>
<div className="slider_item">
3
</div>
<div className="slider_item">
4
</div>
<div className="slider_item">
5
</div>
<div className="slider_item">
6
</div>
<div className="slider_item">
7
</div>
<div className="slider_item">
8
</div>
<div className="slider_item">
9
</div>
<div className="slider_item">
10
</div>
<div className="slider_item">
11
</div>
<div className="slider_item">
12
</div>
<div className="slider_item">
13
</div>
<div className="slider_item">
14
</div>
<div className="slider_item">
15
</div>
</div>
</div>
<button onClick={() => this.handleSlideMove("right")} >
move right
</button>
</div>
)
};
}
ReactDOM.render(<App />, document.querySelector("#app"))
:root{
--slider-container-scope: 0;
--unit-width: 0;
--item-left:0;
}
.page {
text-align: center;
display:flex;
width:100%;
flex-direction: column;
align-items:center;
justify-content: center;
}
.slider_metacontainer{
width: 400px;
background: #444;
display: flex;
overflow: auto;
margin: 10vh 0;
}
.slider_container{
position:relative;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
left:var(--item-left);
transition: left 0.5s ease-out;
}
.slider_item{
width: var(--unit-width);
height:25vh;
}
.slider_item:nth-child(3n-2) { background-color: #EF5350; }
.slider_item:nth-child(3n-1) { background-color: #2E7D32; }
.slider_item:nth-child(3n) { background-color: #03A9A4; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Any hint to understand how to handle my slider would be great, Thanks!!
from Buggy slider - how make my slider well fit the component inside?
No comments:
Post a Comment