Skip to content
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

使用rem导致非整数itemHeight带来的误差 #206

Closed
TotooriaHyperion opened this issue Sep 10, 2017 · 7 comments
Closed

使用rem导致非整数itemHeight带来的误差 #206

TotooriaHyperion opened this issue Sep 10, 2017 · 7 comments

Comments

@TotooriaHyperion
Copy link

TotooriaHyperion commented Sep 10, 2017

https://codepen.io/torihyper/pen/wqbYZN

移动端用户大多使用rem来设置高度,经常产生非整数的itemHeight,
应该根据scrollerHeight和items.length采用先乘后除的方式来消除误差。

https://codepen.io/torihyper/pen/vJodEO

这个是iscroll就一直有的bug,由于绝大多数场景使用的是transition,所以一般不会遇到。
开始一个新的animation之前,要清除旧的animation,否则如果旧animation的结束时间早于新animation则会导致最终定位为旧animation,并且画面闪动。
比如,在index-list的demo中,如果强制关闭transition(useTransition: false)那么在动画结束之前,点击右侧index的操作将被动画效果覆盖。

关联pr:#184

@TotooriaHyperion TotooriaHyperion changed the title 修复bug 使用rem导致非整数itemHeight带来的误差 Sep 10, 2017
@ustbhuangyi
Copy link
Owner

ustbhuangyi commented Sep 10, 2017

animation 这个确实可以先清除一下
关于itemHeight,最终渲染到页面上都是整数像素的,有一个取整策略,具体可以参考:http://trac.webkit.org/wiki/LayoutUnit,而且你给的 demo 地址我也没看出问题,可以适当给 demo 加一些样式方便看出问题。

@TotooriaHyperion
Copy link
Author

TotooriaHyperion commented Sep 11, 2017

实际上我所描述的问题和渲染误差并无关系,而是计算误差。

虽然渲染到页面上的都是整数像素,但是他们并不是一致的,
在snap里,这种情况其实是得到了处理的:
比如10.25px的item,会生成
10px 10px 10px 11px 10px 10px 10px 11px的page,正因如此,snap并不会出现误差问题。
而在wheel中,这种情况并没有得到处理(统一使用唯一的itemHeight),所以才会出现误差。
至于demo的情况,在item非常多的时候,是会有很大误差的:
image

@TotooriaHyperion
Copy link
Author

TotooriaHyperion commented Sep 11, 2017

如上图,在90的时候,已经错了整整1个itemHeight
在下图中,错位约半个itemHeight,截断了上面的43
image

@TotooriaHyperion
Copy link
Author

TotooriaHyperion commented Sep 11, 2017

image
如图,这是将官方picker demo修改为36.25px高度时的情况。
实际的clientHeight是不同的,取items[0].clientHeight显然是不合理的。
考虑到浮点数精度问题,使用scroller.clientHeight / items.length也是不精确的(在极端情况下)
这里要么使用nearestSnap来获得wheel对应的正确index,要么使用先乘后除的方式来消除误差。

nearestSnap显然会更精确,恩那么让我们改成nearestSnap吧。
同时发现了另一个bug:maxScrollY的计算,在wheel时,使用itemHeight显然也会计算出错误的值。

emmm好像不是很好改。。。snap会触发flick导致wheel失效。。。

那么问题来了,
1.snap的page是否应该作为一个公共的属性以便其它功能的调用?
2.snap是否应该拥有默认的flick事件,如果有,是否应该允许用户取消默认的flick事件?
3.在wheel中,如果用户注册了flick事件,则wheel会失效,因此,wheel是否应该注册自己的flick事件?

初步思考的建议是,snap和wheel不带默认flick事件,让用户自行注册flick事件。
这样,在用户不注册flick事件时,snap和wheel事件都是绝对正常并且结果可预测的。
flick事件本身会return掉_end,以避免和wheel、momentum产生冲突,而如果用户需要flick事件,那么肯定是会专门进行处理的,也应该将这一操作的具体行为交由用户选择。在flick事件中告知用户flick的方向即可。

我认为默认事件不应该修改原本的行为,应该只是触发新的事件(如pullup、pulldown)或同步ui(如scrollbar)。

@ghost
Copy link

ghost commented Sep 11, 2017

@TotooriaHyperion 是的我也遇到这样问题,rem适配,item越多,误差越大

@TotooriaHyperion
Copy link
Author

TotooriaHyperion commented Sep 11, 2017

@1657413883 你可以先参照我上面先乘后除的方法临时处理一下。也可以使用平面滚动 + snap(实际上wheel是比较消耗性能的。因为目前的实现中,所有的item都会有rotate行为。)
对于这个问题,我还是觉得,pages不应该是snap独享,应该拿出来给大家使用。
而flick不应该修改原本行为,应该由用户来处理。并且应该作为单独的事件存在,不应该和momentum的判断标准混淆在一起。

@ustbhuangyi
Copy link
Owner

恩,rem 布局看来确实有问题

ustbhuangyi added a commit that referenced this issue Sep 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants