local GMFloatingIcon = class("GMFloatingIcon", LuaComponent) function GMFloatingIcon:init() self.baseObject:addDragListener(function(eventType, x, y) self:onGrag(eventType, x, y) end) self:adsorbent(true) end function GMFloatingIcon:show() self.baseObject:setActive(true) self:adsorbent(true) end function GMFloatingIcon:hide() if self.aniSequence then self.aniSequence:Kill() self.aniSequence = nil end self.baseObject:setActive(false) end function GMFloatingIcon:adsorbent(immediately, delay) local posX = self.baseObject:getTransform().anchoredPosition.x local posY = self.baseObject:getTransform().anchoredPosition.y local width = GConst.UI_SCREEN_WIDTH local height = GConst.UI_SCREEN_HEIGHT local distanceBottom = posY + height/2 local distanceTop = height - distanceBottom local distanceLeft = posX + width/2 local distanceRight = width - distanceLeft local min = math.min(distanceBottom, distanceTop, distanceLeft, distanceRight) local x, y, duration = width/2, posY, min / 1000 -- 默认向右吸附 if distanceLeft == min then -- 离左边最近 x, y = -width/2, posY elseif distanceTop == min then -- 离上边最近 x, y = posX, height/2 elseif distanceBottom == min then-- 离下边最近 x, y = posX, -height/2 end if self.aniSequence then self.aniSequence:Kill() self.aniSequence = nil end if immediately then self.baseObject:setAnchoredPosition(x, y) else self:playAdsorbentAni(x, y, duration, delay) end end function GMFloatingIcon:playAdsorbentAni(x, y, duration, delay) self.aniSequence = DOTweenManager:createSeqWithIntId() if delay then self.aniSequence:AppendInterval(delay) end self.aniSequence:Append(self.baseObject:getTransform():DOAnchorPos(BF.Vector2(x, y), duration)) end function GMFloatingIcon:onGrag(eventType, x, y) if eventType == GConst.TOUCH_EVENT.DOWN then if self.aniSequence then self.aniSequence:Kill() self.aniSequence = nil end elseif eventType == GConst.TOUCH_EVENT.DRAG then local uiCamera = UIManager:getUICameraComponent() local worldPosition = uiCamera:ScreenToWorldPoint(BF.Vector2(x, y)) local convertPosition = UIManager:getMainCanvas():getTransform():InverseTransformPoint(worldPosition) local x = convertPosition.x local y = convertPosition.y if x > GConst.UI_SCREEN_WIDTH/2 then x = GConst.UI_SCREEN_WIDTH/2 elseif x < -GConst.UI_SCREEN_WIDTH/2 then x = -GConst.UI_SCREEN_WIDTH/2 end if y > GConst.UI_SCREEN_HEIGHT/2 then y = GConst.UI_SCREEN_HEIGHT/2 elseif y < -GConst.UI_SCREEN_HEIGHT/2 then y = -GConst.UI_SCREEN_HEIGHT/2 end self.baseObject:setAnchoredPosition(x, y) elseif eventType == GConst.TOUCH_EVENT.UP_INSIDE then ModuleManager.DevToolManager:showDevListUI() elseif eventType == GConst.TOUCH_EVENT.DRAG_CANCEL_UP then self:adsorbent(false, 1) end end return GMFloatingIcon