如何在Flutter中实现分步解锁垂直滑入的转账动画?
实现分步转账的垂直滑入解锁动画效果
需求概述
需要实现一个4步骤的转账操作流程,核心交互逻辑如下:
- 初始状态仅显示第一步(指定转账目标),后续3个步骤处于锁定不可用状态,隐藏在可视区域外
- 完成当前步骤的操作后,下一个步骤自动解锁并以垂直向上滑入的动画呈现
- 示例流程:选定转账目标 → 金额输入模块滑入解锁 → 确认信息模块滑入解锁 → 完成转账模块滑入解锁
实现方案
核心思路
- CSS动画控制:利用
transform: translateY()和opacity属性控制步骤的显示/隐藏,配合transition实现平滑的滑入动画 - 状态管理:通过给步骤容器添加
active类标记已解锁状态,未激活的步骤默认向下移出可视区域并透明化 - 交互触发:监听每一步操作的完成事件(如按钮点击、输入确认),动态为下一步添加
active类并启用交互控件
代码示例
HTML结构
<div class="transfer-flow"> <!-- 步骤1:选择转账目标 --> <div class="step step-1 active"> <h3>选择转账目标</h3> <select id="target-select"> <option value="">请选择目标账户</option> <option value="1">账户A</option> <option value="2">账户B</option> </select> <button class="next-btn" data-target="step-2">确认目标</button> </div> <!-- 步骤2:输入转账金额 --> <div class="step step-2"> <h3>输入转账金额</h3> <input type="number" id="amount-input" disabled placeholder="请输入金额" /> <button class="next-btn" data-target="step-3" disabled>确认金额</button> </div> <!-- 步骤3:确认转账信息 --> <div class="step step-3"> <h3>确认转账信息</h3> <div class="info">目标账户:<span id="target-info"></span></div> <div class="info">转账金额:<span id="amount-info"></span></div> <button class="next-btn" data-target="step-4" disabled>确认信息</button> </div> <!-- 步骤4:完成转账 --> <div class="step step-4"> <h3>转账完成</h3> <p>您的转账已提交,等待处理</p> <button class="finish-btn">返回首页</button> </div> </div>
CSS样式
.transfer-flow { width: 400px; margin: 20px auto; overflow: hidden; /* 隐藏未激活步骤的溢出部分 */ } .step { padding: 20px; background: #fff; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin-bottom: 10px; transition: all 0.5s ease; } /* 未激活步骤的初始状态:向下移出+透明 */ .step:not(.active) { transform: translateY(100%); opacity: 0; pointer-events: none; /* 禁止未激活步骤的交互 */ } /* 锁定状态的控件样式 */ .step:not(.active) input, .step:not(.active) select, .step:not(.active) button { background: #f0f0f0; cursor: not-allowed; } .next-btn, .finish-btn { margin-top: 15px; padding: 8px 16px; background: #007bff; color: #fff; border: none; border-radius: 4px; cursor: pointer; } .next-btn:disabled { background: #6c757d; }
JavaScript逻辑
// 获取所有下一步按钮 const nextBtns = document.querySelectorAll('.next-btn'); nextBtns.forEach(btn => { btn.addEventListener('click', function() { const targetStepId = this.getAttribute('data-target'); const currentStep = this.closest('.step'); const targetStep = document.querySelector(`.${targetStepId}`); // 记录当前步骤的信息(示例:传递目标账户和金额) if (currentStep.classList.contains('step-1')) { const targetValue = document.getElementById('target-select').value; document.getElementById('target-info').textContent = targetValue === '1' ? '账户A' : '账户B'; } else if (currentStep.classList.contains('step-2')) { const amountValue = document.getElementById('amount-input').value; document.getElementById('amount-info').textContent = `¥${amountValue}`; } // 激活目标步骤 targetStep.classList.add('active'); // 启用目标步骤内的交互控件 const controls = targetStep.querySelectorAll('input, select, button'); controls.forEach(ctrl => ctrl.disabled = false); }); }); // 监听金额输入,输入内容后启用确认按钮 document.getElementById('amount-input').addEventListener('input', function() { const confirmBtn = document.querySelector('.step-2 .next-btn'); confirmBtn.disabled = this.value.trim() === ''; });
效果展示
初始状态

解锁后状态(完成第一步后)

内容的提问来源于stack exchange,提问作者Kevin Alexis Martinez Herrera
相关产品推荐
相关产品推荐

