我是lua的代码,呜啦啦啦啦~~不过不影响嘛。
首先设置一些参数:
self.r = 260/2 --滚轮半径
self.vd = 330 --视点距离
self.arcPos = {135,180,225,270,315,360,45,90} --平铺放置节点的角度
我是按45度分部的,所以上面的角度先预留出来。这里涉及一个问题,最后再说。
触摸move的时候,move的距离,就是圆转过的弧长,那么这样就可以算出转动的角度arc
function AvatarGallery:move(distance,endMove)
endMove = endMove or false
local arc = distance/self.r
local view
for i = 1,#self.itemViews do
view = self.itemViews[i]
view.currentArc = self:trimArc(view.originArc + arc)
if endMove then
view.originArc = self:trimArc(view.currentArc)
end
local x,scale,zorder = self:get2dXScaleZorder(view.currentArc)
view:setPosition(x,0)
view:setScale(scale)
view:setLocalZOrder(zorder)
end
end
trimArc又是个什么鬼呢。。。因为角度可以无限叠加嘛,361度不就是1度么,trim就是把角度规整为0~359的范围。
然后就是要算,算X的距离,算scale,算Zorder。一个一个来
function AvatarGallery:get2dXScaleZorder(arc)
local x,scale,zorder
x = self.r*math.cos(arc)
scale = self.vd / (self.vd + self.r + self.r*math.sin(arc))
zorder = (arc - math.rad(270))/(math.pi/4)
zorder = 0 - math.abs(zorder)
local zorderI,zorderF = math.modf(zorder)
zorderI = zorderI *2
if math.abs(zorderF)<0.49 then
zorderI = zorderI+1
end
return x,scale,zorderI
end
x距离最简单,一个cos完事,因为原点取的是重点,所以正负什么的也完全不用管。。。
对比x,y其实也就是sin, 正负也刚好合适,然后对比上一个里面的公式,scale也就算出来了。
zorder稍微麻烦一点,正规来说,应该是把所有节点的y算出来,然后做一个排序,但是这么做略微麻烦了一点,本着有懒就偷的原则,我发现了这么一招。。。先看图
我是按45度分布的,那么每个节点之间的间距就是45度。上图的纵轴,就是zorder的分部,纵轴越往上,Zorder越小。所以我们把角度全部减掉一个270,再除以45度,就成了下图这样
现在看出来什么了么。。。只要取个绝对值,然后取负数,不就搞定了么!!!
唯一的问题,-4和-5这2个点的zorder反了。但是这无所谓,因为这2个节点在后面,我们只看得到前面的一个半圆。啦啦啦啦啦
但是这是一种特殊情况。。。当轮子转起来的时候,是不会刚好在这些点上的,一般除下来,会是一个小数,但是zorder只能是整数,小数会自动截取。所以我们需要把精度再提升一下。
zorder = (arc - math.rad(270))/(math.pi/4)
zorder = 0 - math.abs(zorder)
zorder的值小数部分,小数绝对值越小,说明靠上图0越近,应该靠前显示。再把zorder精度提高一下
local zorderI,zorderF = math.modf(zorder)
zorderI = zorderI *2
if math.abs(zorderF)<0.49 then
zorderI = zorderI+1
end
取值0.49是因为浮点数啊,精度啊,反正各种奇奇怪怪的问题。其实就应该是0.5,按中点来分。
(PS:有人说直接把小数乘以一个10,我不得不说这是一个好办法。。。。但是怎么没想到)
然后还有一个问题,滑动完成了之后,应该做一次归位,就是把那些没对齐的对齐,不然滑到一个很诡异的角度,多么奇葩。。。点击什么的逻辑也不好做
if endMove then
local factor = arc / (math.pi/8)
factor = math.floor(math.ceil(factor)/2)
arc = math.pi/4 * factor
view.currentArc = self:trimArc(view.originArc + arc)
view.originArc = self:trimArc(view.currentArc)
end
这个和上面那个方法类似,因为我们是按45度分布的,所以就以22.5度为分界,大于22.5就加一个,小于22.5就少一个。
(PS:突然发现上面的zorder好像也能这么做。。。。。。。。)
再最开始,还提到一个问题,这是一个关于效率的问题,下班回家下次再说。。。