Closed isaachinman closed 6 years ago
So, I've engineered the following solution:
This is not the most ideal solution, but I think it's what we'll have to live with. The limiting factor is that we're using React Native's built-in LayoutAnimation
, which means the entire layout is animating for one specific duration.
If you log into an account with a massive queue, and deselect the top item: the time it takes for that top item to reach the very bottom of the list must be the same amount of time it takes for the top edge of the second item to reach the spot where the top edge of the first item previously was.
Hopefully that makes sense, and demonstrates our limitation. There will be animation degradation as queues exceed 40-50 items, in that the item which has been selected or deselected will move exceedingly fast. Not much to be done about that without handling animations in-house.
69fe7cb
Explanation is clear.
Two things:
Are the animatinos al linear? Difficult to see. It looks like the queue is easing as it is "filling the gap" but not sure about the start of the moving single image. Perhaps that could keep the moving image visible in long queues as it leaves its position. Even within the described duration limitations.
The deselect looks smooth and the moving image is clearly visible in front of the layout as it leaves it's position. The select action is less smooth / visible. It seems that not all elements of the moving "image cell" are in front of the queue. Perhaps only the thumbnail. As it moves up, the thumbnails higher in the queue are flashing a bit during the transition.
Here's the way we'd approach the elevation/zIndex issue if it became possible:
@action
selectImage = async (imageID) => {
this.setImageLoading(imageID)
this.setImageRaised(imageID)
try {
const res = await apiRequest({ url: `/pv/queue/${this.queueType}/images/select`, data: { imageID } })
const { data } = res
const distanceTravelled = Math.abs(this.data.images.findIndex(i => i._id === imageID) -
[...data.selectedImages, ...data.deselectedImages].findIndex(i => i._id === imageID))
const animationDuration = Math.min((300 + (distanceTravelled * 30)), 800)
this.mergeIntoLocalData(data, true, animationDuration)
setTimeout(() => this.removeImageRaised(imageID), animationDuration)
} catch (error) {
runInAction(() => this.error = error)
this.removeImageRaised(imageID)
}
this.removeImageLoading(imageID)
}
The closest workaround I could find is in this issue, where I've attempted to implement it and failed. We'll see if anyone follows up. Otherwise, this may have to wait. It's a relatively small issue nonetheless.
OK. Shall we put this issue on backlog as reminder for when RN team has solution?
No. This issue is solved. The animation time now includes a distance-travelled modifier.
If you want to open another issue regarding animation zIndex, feel free.
Is your feature request related to a problem? Please describe. From Mick:
Describe the solution you'd like We must calculate the distance travelled (distance in index of two items), and use this as a multiplier for the layout animation duration.
Describe alternatives you've considered N/A.
Additional context This calculation will need to happen in the select and deselect actions. Eg here.