-
Notifications
You must be signed in to change notification settings - Fork 381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Swiper重构 #1711
base: master
Are you sure you want to change the base?
Swiper重构 #1711
Conversation
let renderChild = children.slice() | ||
if (props.circular && totalElements.value > 1) { | ||
if (totalElements.value === 2) { | ||
renderChild = renderChild.concat(children).concat(children) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
添加节点需要cloneElement
renderChild = renderChild.concat(children).concat(children) | ||
} else { | ||
// 最前加两个 | ||
renderChild.unshift(children[totalElements.value - 1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
前面不需要加元素
], { layoutRef: layoutRef }) | ||
|
||
function onWrapperLayout (e: LayoutChangeEvent) { | ||
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
layout里面可以直接获取高宽,不需要measure
|
||
function onWrapperLayout (e: LayoutChangeEvent) { | ||
nodeRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => { | ||
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不需要
} | ||
const attr = dir.value === 'x' ? 'width' : 'height' | ||
changeState[attr] = changeState[attr] - previousMargin - nextMargin | ||
if (dir.value === 'x') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里不应该都去设置么
if (totalElements.value <= 1) return null | ||
const dots: Array<ReactNode> = [] | ||
for (let i = 0; i < totalElements.value; i++) { | ||
const dotStyle = useAnimatedStyle(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不应该在for中使用hooks,假如elements数量更新了就炸了
} | ||
|
||
function handlerInterval (loopv: boolean, oldLoop: boolean | null) { | ||
clearInterval(intervalId.current) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
为啥有一个timeout有一个interval?
intervalId.current = setInterval(() => { | ||
// canLoop变化比较快的情况下 | ||
if (canLoop.value) { | ||
createAutoPlay() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个东西为啥要声明为worklet?看上去是个纯js函数
if (!isInit && props.bindchange) { | ||
runOnJS(handleSwiperChange)(newIndex) | ||
} | ||
}, [targetIndex.value]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里不需要写deps把
} | ||
}, [targetIndex.value]) | ||
|
||
useAnimatedReaction(() => canLoop.value, (loopv, oldLoop) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
canLoop是干啥的
const initHeight = typeof defaultHeight === 'number' ? defaultHeight - previousMargin - nextMargin : defaultHeight | ||
const [widthState, setWidthState] = useState(initWidth) | ||
const [heightState, setHeightState] = useState(initHeight) | ||
const dir = useSharedValue(horizontal === false ? 'y' : 'x') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
没有更新的时机
const touchfinish = useSharedValue(false) | ||
// 用户是否触发了move事件,起点在onStart, 触发move事件才会执行onEnd, 1. 移动一定会触发onStart, onTouchesMove, onEnd 2. 点击未进行操作, 会触发onTouchsUp | ||
const isTriggerStart = useSharedValue(false) | ||
// 记录用户点击时绝对定位坐标 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
注释有问题,应该是上一次的坐标
|
||
function getStepValue () { | ||
'worklet' | ||
return dir.value === 'x' ? widthState : heightState |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worklet里应该拿不到更新的js值,这两个东西应该作为sharedValue
pauseLoop() | ||
} | ||
return () => { pauseLoop() } | ||
}, [props.autoplay, widthState, heightState]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里和上面的useEffect不应该依赖widthState和heightState
const step = useSharedValue(initStep) | ||
const totalElements = useSharedValue(children.length) | ||
// 记录选中元素的索引值 | ||
const targetIndex = useSharedValue(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
currentIndex?
|
||
useEffect(() => { | ||
// 这里stepValue 有时候拿不到 | ||
const stepValue = getStepValue() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stepValue直接作为一个sharedValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在onLayout中直接更新
const dotStep = dotCommonStyle.width + dotCommonStyle.marginRight + dotCommonStyle.marginLeft | ||
return { | ||
transform: [{ | ||
translateX: targetIndex.value * dotStep |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
得考虑纵向
extraStyle | ||
]} | ||
key={ 'page' + index}> | ||
<SwiperContext.Provider value={contextValue}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
顶层包一个就行了
offset, | ||
stepValue: typeof stepValue === 'number' ? stepValue : 0 | ||
} | ||
return (<Animated.View |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不做动画不需要animated.view
} | ||
|
||
function renderItems () { | ||
const pageStyle = { width: widthState, height: heightState } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
确定这块的必要性是啥
const touchfinish = useSharedValue(false) | ||
// 用户是否触发了move事件,起点在onStart, 触发move事件才会执行onEnd, 1. 移动一定会触发onStart, onTouchesMove, onEnd 2. 点击未进行操作, 会触发onTouchsUp | ||
const isTriggerStart = useSharedValue(false) | ||
// 记录上一次的点击时的绝对定位坐标 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个不是点击,是上一帧
useNodesRef<View, SwiperProps>(props, ref, nodeRef, {}) | ||
|
||
// 默认取水平方向的width | ||
const { width } = Dimensions.get('window') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个有啥意义
dots.push(<View style={[dotCommonStyle, { backgroundColor: unActionColor }]} key={i}></View>) | ||
} | ||
return ( | ||
<View pointerEvents="none" style = {[styles['pagination_' + dir.value]]}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
无意义的数组包裹
nextMargin && dir.value === 'y' && (extraStyle.marginBottom = nextMargin) | ||
} | ||
const newChild = React.cloneElement(child, { itemIndex: index, scale: props.scale }) | ||
return (<Animated.View style={[style.itemWrap, itemAnimatedStyles, extraStyle]} key={ 'page' + index}>{newChild}</Animated.View>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
把这个animatedStyle作为props传递到swiper-item中应用就可以了,没必要再包一层view
|
||
function renderItems () { | ||
const itemAnimatedStyles = useAnimatedStyle(() => { | ||
const pageStyle: Object = dir.value === 'x' ? { width: step.value, height: '100%' } : { width: '100%', height: step.value } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
无意义的变量定义
} | ||
const newChild = React.cloneElement(child, { | ||
itemIndex: index, | ||
scale: props.scale, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scale走context传递
} | ||
const arrChilds = renderChild.map((child, index) => { | ||
const extraStyle = {} as { [key: string]: any } | ||
if (index === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
circular判断
duration: easeDuration, | ||
easing: easeMap[easeingFunc] | ||
}, () => { | ||
offset.value = targetOffset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
没必要加的逻辑
} | ||
const targetOffset = getInitOffset() | ||
if (props.autoplay) { | ||
pauseLoop() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pause的意义是啥
const targetOffset = getInitOffset() | ||
if (props.autoplay) { | ||
pauseLoop() | ||
offset.value = targetOffset |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
autoplay变更只应该开启或者关闭定时器,不应该修改offset.value
props.bindchange && props.bindchange(eventData) | ||
} | ||
|
||
function getInitOffset () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个可以直接作为一个index=>offset的转换函数,getOffset(index)=>offset
}) | ||
|
||
useAnimatedReaction(() => step.value, (newIndex, preIndex) => { | ||
const targetOffset = getInitOffset() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
放在onLayout中,当用户没有在触碰操作时,更新offset.value
No description provided.