function lib:create_attr_list(parent, cur_data, next_data, hide_bg, gap, attr_bg_hight, bg_img_path, bg_img_prefix,
offset_x, has_simple, name_offset_x)
GUI:removeAllChildren(parent)
attr_bg_hight = attr_bg_hight or 22
local parent_si
🤖 回答引擎: 前端Lua |
🕒 时间: 2026-04-22 12:48:18 |
👁️ 阅读: 18
要实现属性渐变切换效果,我来帮你封装一个带动画的版本。主要思路是:当前属性淡出,下一级属性从右侧滑入,最后淡入显示。
```lua
-- 带动画的属性列表创建函数
function lib:create_attr_list_with_animation(parent, cur_data, next_data, hide_bg, gap, attr_bg_hight, bg_img_path, bg_img_prefix,
offset_x, has_simple, name_offset_x)
-- 先创建基础列表(隐藏所有元素)
local function createBaseList(isVisible)
GUI:removeAllChildren(parent)
attr_bg_hight = attr_bg_hight or 22
local parent_size = GUI:getContentSize(parent)
local allWidgets = {} -- 存储所有创建的控件
for index = 1, next_data.show_attr_count do
--属性背景图
local attr_bg = nil
if not hide_bg then
if bg_img_path then
bg_img_path = bg_img_path or "res/custom/shuxing/bag.png"
attr_bg = GUI:Image_Create(parent, "attr_bg_" .. index, 0.00, 0.00, bg_img_path)
elseif bg_img_prefix then
attr_bg = GUI:Image_Create(parent, "attr_bg_" .. index, 0.00, 0.00, bg_img_prefix .. index .. ".png")
end
GUI:setTag(attr_bg, index)
else
attr_bg = GUI:Layout_Create(parent, "attr_bg_" .. index, 0.00, 0.00, parent_size.width, attr_bg_hight,
false)
GUI:setTag(attr_bg, index)
end
-- 初始设置为透明
GUI:setOpacity(attr_bg, isVisible and 255 or 0)
offset_x = offset_x or 0
local attr_bg_size = GUI:getContentSize(attr_bg)
attr_bg_size.width = attr_bg_size.width - offset_x
--属性名
if not next_data.hide_att_name and next_data["att_name_" .. index] then
next_data["att_name_" .. index] = next_data["att_name_" .. index] or ""
local name_color = SL:GetColorByStyleId(next_data.name_color) or "#ffffff"
local attr_name = GUI:Text_Create(attr_bg, "attr_name_" .. index, name_offset_x or 0, attr_bg_size.height / 2,
14, name_color, next_data["att_name_" .. index] .. ":")
GUI:setAnchorPoint(attr_name, 0, 0.5)
GUI:setOpacity(attr_name, isVisible and 255 or 0)
end
--指向箭头
local next_img = GUI:Image_Create(attr_bg, "next_img_" .. index, offset_x + attr_bg_size.width / 2,
attr_bg_size.height / 2)
GUI:setAnchorPoint(next_img, 0.50, 0.50)
GUI:setOpacity(next_img, isVisible and 255 or 0)
local next_img_pos = GUI:getPosition(next_img)
local next_img_size = GUI:getContentSize(next_img)
--计算左侧x坐标范围
local left_x_range = { offset_x, next_img_pos.x - next_img_size.width / 2 + offset_x }
--计算右侧x坐标范围
local right_x_range = { next_img_pos.x + next_img_size.width / 2, offset_x + attr_bg_size.width }
--左侧当前属性
local cur_attr_val = cur_data["cur_attr_" .. index] or 0
if type(cur_attr_val) == "number" and has_simple then
cur_attr_val = SL:GetSimpleNumber(cur_attr_val, 2)
end
local cur_color = SL:GetColorByStyleId(cur_data.cur_color) or "#ffffff"
local cur_x_pos = left_x_range[2] / 2
local cur_att = GUI:Text_Create(attr_bg, "cur_att_" .. index, cur_x_pos, attr_bg_size.height / 2, 14,
cur_color, cur_attr_val)
GUI:setAnchorPoint(cur_att, 0.5, 0.5)
GUI:setOpacity(cur_att, isVisible and 255 or 0)
--右侧下级属性
local next_attr_val = next_data["cur_attr_" .. index] or 0
if type(next_attr_val) ~= "number" and has_simple then
next_attr_val = SL:GetSimpleNumber(next_attr_val, 2)
end
if next_data and next_attr_val then
local next_color = SL:GetColorByStyleId(next_data.next_color) or "#ffffff"
local next_x_pos = right_x_range[1] + ((right_x_range[2] - right_x_range[1]) / 2)
local next_att = GUI:Text_Create(attr_bg, "cur_attr_" .. index .. "_2", next_x_pos,
attr_bg_size.height / 2, 14, next_color, next_attr_val)
GUI:setAnchorPoint(next_att, 0.5, 0.5)
GUI:setOpacity(next_att, isVisible and 255 or 0)
end
--序列帧箭头
local frames = lib:frames(attr_bg, "/common", 1, 10, offset_x + attr_bg_size.width/2 , attr_bg_size.height / 2,
100, -1, 0,
index)
GUI:setAnchorPoint(frames, 0.5, 0.5)
GUI:setScaleX(frames,0.5)
GUI:setScaleY(frames,0.5)
GUI:setOpacity(frames, isVisible and 255 or 0)
table.insert(allWidgets, {
bg = attr_bg,
index = index
})
end
--自适应布局
gap = gap or 10
GUI:UserUILayout(parent, {
dir = 1,
gap = { y = gap },
sortfunc = function(lists)
table.sort(lists, function(a, b)
return GUI:getTag(a) < GUI:getTag(b)
end)
end
})
return allWidgets
end
-- 第一步:创建并显示当前属性
local curWidgets = createBaseList(true)
-- 第二步:执行动画切换
local function startAnimation()
-- 当前属性淡出
for _, widgetInfo in ipairs(curWidgets) do
local attr_bg = widgetInfo.bg
local children = GUI:getChildren(attr_bg)
for i = 0, GUI:getChildrenCount(attr_bg) - 1 do
local child = GUI:getChild(attr_bg, i)
GUI:runAction(child, GUI:ActionSequence(
GUI:ActionFadeTo(0.3, 0),
GUI:CallFunc(function()
GUI:removeFromParent(child)
end)
))
end
end
-- 延迟后创建下一级属性
SL:ScheduleOnce(function()
-- 创建下一级属性(初始在右侧并透明)
local nextWidgets = createBaseList(false)
-- 设置初始位置(从右侧)
for _, widgetInfo in ipairs(nextWidgets) do
local attr_bg = widgetInfo.bg
local pos = GUI:getPosition(attr_bg)
GUI:setPosition(attr_bg, pos.x + 100, pos.y) -- 向右偏移100像素
GUI:setOpacity(attr_bg, 0)
-- 获取所有子控件
local children = GUI:getChildren(attr_bg)
for i = 0, GUI:getChildrenCount(attr_bg) - 1 do
local child = GUI:getChild(attr_bg, i)
local childPos = GUI:getPosition(child)
GUI:setPosition(child, childPos.x + 100, childPos.y)
GUI:setOpacity(child, 0)
end
end
-- 执行滑入和淡入动画
for _, widgetInfo in ipairs(nextWidgets) do
local attr_bg = widgetInfo.bg
local targetPos = GUI:getPosition(attr_bg)
GUI:setPosition(attr_bg, targetPos.x + 100, targetPos.y)
-- 背景滑入并淡入
GUI:runAction(attr_bg, GUI:ActionSpawn(
GUI:ActionMoveTo(0.4, targetPos.x - 100, targetPos.y),
GUI:ActionFadeTo(0.4, 255)
))
-- 子控件滑入并淡入
local children = GUI:getChildren(attr_bg)
for i = 0, GUI:getChildrenCount(attr_bg) - 1 do
local child = GUI:getChild(attr_bg, i)
local childTargetPos = GUI:getPosition(child)
GUI:runAction(child, GUI:ActionSpawn(
GUI:ActionMoveTo(0.4, childTargetPos.x - 100, childTargetPos.y),
GUI:ActionFadeTo(0.4, 255)
))
end
end
end, 0.35) -- 延迟0.35秒执行
end
-- 返回动画启动函数
return startAnimation
end
```
**使用方式:**
```lua
-- 创建带动画的属性列表
local startAnimation = lib:create_attr_list_with_animation(parent, cur_data, next_data, ...其他参数)
-- 当点击升级按钮时
GUI:addOnClickEvent(upgradeBtn, function()
startAnimation() -- 执行动画切换
end)
```
**动画流程说明:**
1. **当前属性淡出**:所有当前属性在0.3秒内透明度降到0
2. **下一级属性滑入**:从右侧100像素位置滑入到正确位置(0.4秒)
3. **同时淡入**:在滑入过程中透明度从0渐变到255
**注意:**
- 使用了 `GUI:ActionFadeTo` 实现淡入淡出
- 使用了 `GUI:ActionMoveTo` 实现从右向左滑动
- 使用了 `SL:ScheduleOnce` 实现延迟执行
- 动画总时长约0.75秒(淡出0.3秒 + 延迟0.35秒 + 滑入0.4秒)
现在你只需要调用这个封装函数,然后在需要的时候执行返回的动画函数即可!
← 返回问答库