如何在Flutter中实现背景图片的反向视差效果?
复刻《孤岛惊魂6》官网视差滚动动画(Flutter实现)
我在《孤岛惊魂6》官网看到了一种视差动画,想在Flutter里复刻它。查了文档和教程也没法精准实现,想要做出官网移动端浏览器的展示效果——图片层叠,滚动时下方图片从下往上反向出现。
我的现有代码如下:
import 'package:flutter/material.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { @override Widget build(BuildContext context) { final height = MediaQuery.of(context).size.height; final width = MediaQuery.of(context).size.width; return Scaffold( body: Material( child: Stack( children: [ Image.network( "https://staticctf.akamaized.net/J3yJr34U2pZ2Ieem48Dwy9uqj5PNUQTn/1mP5aHQYJI5xw08eD2eV0W/7bc890d58c6bcf5efbe8713f147828ae/banner-webasset.jpg", height: height, fit: BoxFit.fitHeight, ), SingleChildScrollView( child: Column( children: [ SizedBox(height: height), Image.network( "https://staticctf.akamaized.net/J3yJr34U2pZ2Ieem48Dwy9uqj5PNUQTn/7ad5MGeYDCekqMiS5qRZuK/1005c73ea409e895058d4273d93dcb1a/banner-background_alt.jpg", height: height, width: width, fit: BoxFit.cover, ), ], ), ) ], ), ), ); } }
实现方案
要实现这种反向视差滚动效果,核心是监听滚动偏移量,动态调整底层图片的位置,让其移动方向与滚动方向相反。具体实现步骤如下:
1. 监听滚动偏移
使用ScrollController获取实时滚动偏移量,以此控制底层图片的位移。
2. 动态调整图片位置
将滚动偏移量取负值,实现“向下滚动时,底层图片向上移动”的反向动画,达到从下往上显现的效果。
完整代码实现
import 'package:flutter/material.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({Key? key}) : super(key: key); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { final ScrollController _scrollController = ScrollController(); double _offset = 0.0; @override void initState() { super.initState(); // 监听滚动事件,更新偏移量 _scrollController.addListener(() { setState(() { _offset = -_scrollController.offset; }); }); } @override void dispose() { _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final height = MediaQuery.of(context).size.height; final width = MediaQuery.of(context).size.width; return Scaffold( body: Stack( children: [ // 底层图片:根据滚动偏移动态调整位置 Positioned( top: _offset, left: 0, right: 0, child: Image.network( "https://staticctf.akamaized.net/J3yJr34U2pZ2Ieem48Dwy9uqj5PNUQTn/7ad5MGeYDCekqMiS5qRZuK/1005c73ea409e895058d4273d93dcb1a/banner-background_alt.jpg", height: height, width: width, fit: BoxFit.cover, ), ), // 滚动层:触发视差的滚动区域 SingleChildScrollView( controller: _scrollController, child: Column( children: [ // 顶部占位,高度与屏幕一致 SizedBox(height: height), // 滚动触发区域,可添加更多内容 Container( height: height, color: Colors.transparent, ), // 示例:后续内容 Container( height: 600, color: Colors.grey[900], child: const Center( child: Text( "更多内容区域", style: TextStyle(color: Colors.white, fontSize: 20), ), ), ), ], ), ), // 前景图片:固定在顶部,不随滚动移动 Image.network( "https://staticctf.akamaized.net/J3yJr34U2pZ2Ieem48Dwy9uqj5PNUQTn/1mP5aHQYJI5xw08eD2eV0W/7bc890d58c6bcf5efbe8713f147828ae/banner-webasset.jpg", height: height, fit: BoxFit.fitHeight, ), ], ), ); } }
关键细节说明
- 反向位移逻辑:通过
_offset = -_scrollController.offset让底层图片与滚动方向反向移动,实现目标视差效果。 - 层叠顺序:前景图片在最上层保持固定,底层图片在最下层动态位移,中间的滚动层用透明区域不遮挡底层内容。
- 动画优化:如果需要更平缓的视差效果,可以给偏移量添加系数(比如
_offset = -_scrollController.offset * 0.7),降低移动幅度。
内容的提问来源于stack exchange,提问作者Maruf Hassan
相关产品推荐
相关产品推荐

