# flutter_parallax_effect_study **Repository Path**: ggbhack/flutter_parallax_effect_study ## Basic Information - **Project Name**: flutter_parallax_effect_study - **Description**: flutter_parallax_effect_study 学习项目 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: study - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-10-26 - **Last Updated**: 2023-11-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # flutter_parallax_study 视觉差效果的学习 ## 效果展示 ![Alt text](image.png) ![Alt text](image-1.png) ## 章节代码 [p01 init project](https://gitee.com/ggbhack/flutter_parallax_effect_study/tree/p01) ## p02 tabs home_page.dart ```dart import 'package:flutter/material.dart'; import 'package:flutter_parallax_effect_study/sliding_cards.dart'; import 'package:flutter_parallax_effect_study/tabs.dart'; import 'exhibition_bottom.sheet.dart'; class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return const Scaffold( backgroundColor: Colors.white, body: Stack( children: [ SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 8, ), Header(), SizedBox(height: 40), Tabs(), ], ),) ], ), ); } } class Header extends StatelessWidget { const Header({super.key}); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.symmetric(horizontal: 32), child: Text( "SAIKE", style: TextStyle(fontSize: 22, fontWeight: FontWeight.w600), ), ); } } ``` tabs.dart ```dart import 'package:flutter/material.dart'; class Tabs extends StatefulWidget { const Tabs({super.key}); @override State createState() => _TabsState(); } class _TabsState extends State { int selcetedIndex = 0; var tabs = ["Nearby", "Recent", "Notice"]; @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(left: 24), child: Row( // 向下对其 crossAxisAlignment: CrossAxisAlignment.end, // children: [ // MyTab(text: 'Nearby', isSelected: false), // MyTab(text: 'Recent', isSelected: true), // MyTab(text: 'Notice', isSelected: false), // ], children: List.generate( tabs.length, (index) => MyTab( text: tabs[index], isSelected: selcetedIndex == index, callback: () => { setState(()=>selcetedIndex = index) }, )), ), ); } } class MyTab extends StatelessWidget { final String text; final bool isSelected; final Function callback; const MyTab( {super.key, required this.text, required this.isSelected, required this.callback }); @override Widget build(BuildContext context) { return GestureDetector( onTap: ()=>callback(), child: Padding( padding: const EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( text, style: TextStyle( fontSize: isSelected ? 16 : 14, color: isSelected ? Colors.black : Colors.grey, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500), ), Container( width: 20, height: 6, decoration: BoxDecoration( borderRadius: BorderRadius.circular(4), color: isSelected ? const Color(0xFFFF5A1D) : Colors.white, boxShadow:isSelected? [ BoxShadow(color: const Color(0xFFFF5A1D).withOpacity(0.4),blurRadius: 5,offset: const Offset(2, 2))]:[], ), ) ], ), ), ); } } ``` ## p03 sliding_cards ```dart List demoData = [ CardModel( name: "Shenzhen GLOBAL DESIGN AWARD 2018", image: "steve-johnson.jpeg", date: "4.20-30", ), CardModel( name: "Dawan District, Guangdong Hong Kong and Macao", image: "rodion-kutsaev.jpeg", date: "4.28-31", ), ]; ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF162A49), textStyle: const TextStyle(color: Colors.white), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(32), )), onPressed: () {}, child: const Text("Reserve"), ), ``` ## 最后一节 Transform.translate 中的 offset 被设置为 Offset(-32 * gauss * pageOffset.sign, 0)。这里使用了高斯函数(gauss)来计算一个平滑过渡的权重,然后乘以 pageOffset.sign(这个表示滑动方向的正负符号)以及一个常数(在这里是 -32),这样可以得到一个基于用户滑动距离和方向的动态偏移量。 ```dart double gauss = math.exp(-(math.pow(pageOffset.abs() - 0.5, 2) / 0.08)); ```