• Stars
    star
    165
  • Rank 221,632 (Top 5 %)
  • Language
    Dart
  • License
    GNU General Publi...
  • Created almost 3 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

github 限制图片大小,失效图片请移步掘金查看:拿去吧你!Flutter 仿自如 App 裸眼 3D 效果

引言

最近看到 自如团队 发布的 自如客APP裸眼3D效果的实现,这个布局确实做得很有趣,越玩越上瘾,感谢自如团队的分享。随即按照自己的思路用 Flutter 实现一遍,来看看最终效果。

banner 样式 全屏样式
IMG_0020.gif IMG_0021.gif

apk 下载可直接运行:https://github.com/fluttercandies/flutter_interactional_widget/blob/main/app-release.apk

本文会着重介绍我在实现过程中的思路和设计,所以无论你是前端 /iOS/Android/Flutter 都可以参考同样的路子去实现。如果有任何问题,也欢迎探讨。


一、整体构思

从效果上可以看出,随着我们设备的旋转,有的部分顺着倾斜方向滑动,有的朝着相反方向,而有的则不动。所以图片上的元素肯定分为不同的图层,旋转设备让图层发生移动即可达到效果。

将图片分为了前、中、后三层,随着手机角度的旋转,中层保持不动,上层顺着旋转方向移动,下层与上层相逆。

(图片来自自如分享)

所以在图片分层之后,这个效果就变成了两步:

1、获取手机的旋转信息

2、根据旋转信息移动不同的图层


二、获取手机的旋转信息

Flutter 中有这样一个插件 sensors_plus ,使用它可以帮助我们获取两个传感器的信息:Accelerometer(加速度传感器)、Gyroscope(陀螺仪)。

传感器.gif

每个传感器提供了一个 Stream ,其发送的事件包含 X、Y、Z 表示手机不同方向的变化的速度。通过对 Stream 的监听,我们便可实时获取相关传感器数据。

这个仓库中也附带了一个体感贪吃蛇的 demo,倾斜设备,小蛇便朝着倾斜方向前进。

贪吃蛇.gif

插件的更多介绍可以查看视频: Flutter Widgets 介绍合集 —— 103. Sensors_plus

我们实现的效果需要根据手机旋转移动图层,自然使用陀螺仪传感器即可:

 gyroscopeEvents.listen(
       (GyroscopeEvent event) {
       // event.x  event.y  event.z
     ································
   },
 ),

回调的 GyroscopeEvent 包含三个属性,x、y、z,分别对应下图三个方向所检测到的旋转速度(单位:弧度/秒)

xyz.png

结合需求来看,我们只需使用 Y 轴(对应图像在水平方向的移动)和 X 轴(对应图像在竖直方向的移动)的数据即可。


三、根据旋转信息移动图层

在网上找了一个 psd 文件,导出图片之后整体长这样:

封面.png

我在 psd 文件中导出 3 个图层,需要注意图片格式要为 .png,这样上一个图层的透明区域不会被填充为白色而遮挡住下一个图层,之后直接使用 Image widget 展示图片即可:

前景 中景(白色的文字,所以看不见) 背景
fore.png mid.png back.png

1、让图层动起来

图片分为三层,我们自然想到使用 Stack 作为容器,依次放入三个图层(Widget)

 // 背景图层
 Widget? backgroundWidget;
 // 中景图层
 Widget? middleWidget;
 // 前景图层
 Widget? foregroundWidget;

图层移动其实很简单,就是去修改每一个图层的偏移量。再观察这个实现效果,会发现随着我们的旋转,图层中的内容好像 出来一样。

所以我们一开始进入时,看到的肯定只是图片的部分区域。我的想法是给每一个图层设置 scale,将图片进行放大。显示窗口是固定的,那么一开始只能看到图片的正中位置。(中层可以不用,因为中层本身是不移动的,所以也不必放大)

image.png

旋转手机修改偏移量,为前景和背景层设置相反的偏移量,便可达到两个图层反向运动的效果。

在计算偏移量的时候还需要考虑两个因素:

1、图层的最大偏移量

图层经过了一定比例的放大,所以存在一个最大的偏移范围,偏移量不能超过这个范围。

image.png

不难看出水平方向上最大偏移计算方法为:(缩放比例-1) * 宽 / 2, 竖直方向同理。

2、前景与背景图层的相对偏移速度

因为前景和背景的缩放比例可能不同,如果两者以 1:1 的相对偏移,可能会出现以下情况。

image-20210729005136818.png 假如 前景缩放是 1.4,背景为 1.8,当显示区域向左移动 2 像素的时候。这时背景层所显示的区域同样向左移动 2 个像素,前景层相反。但这时前景已经达最大的偏移量,不能再继续移动。而背景其实还有区域未能显示,所以可以通过两者的缩放比计算对应的偏移比,保证两个图片都能完整的展示出来。

 // 通过背景偏移计算前景偏移
 Offset getForegroundOffset(Offset backgroundOffset) {
   // 假如前景缩放比是 1.4 背景是 1.8 控件宽度为 10
   // 那么前景最大移动 4 像素,背景最大 8 像素
   double offsetRate = ((widget.foregroundScale ?? 1) - 1) /
       ((widget.backgroundScale ?? 1) - 1);
   // 前景取反
   return -Offset(
       backgroundOffset.dx * offsetRate, backgroundOffset.dy * offsetRate);
 }

这里我通过背景偏移为标准,计算前景偏移,并且在计算背景偏移的之前先考虑了最大偏移范围,这样保证前景和背景都不会发生越界行为。先通过拖拽改变偏移量调用 setState 更新界面,看看图层部分实现的效果:

1627550866693665.gif

背景随着手指滑动而位移,同时前景朝相反的方向移动,当滑动到图层边界时无法继续,整个过程中层保持不动。

2、传感器控制偏移

图层位移实现之后,我们只需要将上面由手指滑动触发的偏移改变为由传感器触发即可。

这里我们来想一个问题,我们设备处于水平状态时,显示区域居中,而当设备倾斜的时候,显示区域移动。

image.png

那么该旋转多少角度达到最大偏移量呢?

所以这里我定义了两个变量:

  double maxAngleX;
  double maxAngleY;

分别表示水平和垂直方向的最大旋转角度。假设 maxAngleX 为 10,表示当你在水平方向旋转设备 10° 度的时候,图像显示到边界了。

有了这个定义我们便可反推出背景层 旋转 1° 的偏移量为:

1/maxAngleX * maxBackgroundOffset.dx,垂直方向同理。

思路就是这样,不过我在实现的时候还遇到了一个棘手的问题:

由于 sensors_plus 插件中提供的是各方向的旋转速度(rad/s),我们改如何计算实际的旋转角度?

其实并不难:旋转弧度 = (旋转速度(rad/s) * 时间),那么这里时间是多少?

看 sensors_plus 插件的安卓端实现,这个插件通过 SensorManager 注册陀螺仪传感器的回调,通过 chanel 将采集到的数据直接传递到 Flutter 侧。

sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);

在安卓端 SensorManager 的采集灵敏度分几种

  • SensorManager.SENSOR_DELAY_FASTEST(0微秒):最快。最低延迟,一般不是特别敏感的处理不推荐使用,该模式可能在成手机电力大量消耗,由于传递的为原始数据,算法不处理好会影响游戏逻辑和UI的性能
  • SensorManager.SENSOR_DELAY_GAME(20000微秒):游戏。游戏延迟,一般绝大多数的实时性较高的游戏都是用该级别
  • SensorManager.SENSOR_DELAY_NORMAL(200000微秒):普通。标准延时,对于一般的益智类或EASY级别的游戏可以使用,但过低的采样率可能对一些赛车类游戏有跳帧现象
  • SensorManager.SENSOR_DELAY_UI(60000微秒):用户界面。一般对于屏幕方向自动旋转使用,相对节省电能和逻辑处理,一般游戏开发中不使用

不同灵敏度的采集时间不同,sensors_plus 默认是 SENSOR_DELAY_NORMAL 即 0.2S ,实际使用时感觉响应并没那么及时。所以我直接 fork 项目下来,将 SENSOR_DELAY_NORMAL 改为了 SENSOR_DELAY_GAME ,即每次采集时间为 20000微秒(0.02秒)

换算成角度就是:x * 0.02 * 180 / π,再用角度换算背景偏移量,背景偏移量考虑最大偏移范围之后,计算前景,调用 setState 更新界面即可。关键步骤如下:

gyroscopeEvents.listen((event) {
  setState(() {
    // 通过采集的旋转速度计算出背景 delta 偏移
    Offset deltaOffset = gyroscopeToOffset(-event.y, -event.x);
    // 初始偏移量 + delta 偏移 之后考虑越界
    backgroundOffset = considerBoundary(deltaOffset + backgroundOffset);
    // 背景偏移根据缩放比例获取前景偏移
    foregroundOffset = getForegroundOffset(backgroundOffset);
  });
});

四、构造函数说明

InteractionalWidget

属性 说明 是否必选
double width 视窗宽度
double height 视窗高度
double maxAngleX 水平方向最大的旋转角度
double maxAngleY 竖直方向最大的旋转角度
double? backgroundScale 背景层缩放比
double? middleScale 中景层缩放比
double? foregroundScale 前景层的缩放比
Widget? backgroundWidget 背景层 widget
Widget? middleWidget 中景层 widget
Widget? foregroundWidget 前景层 widget

三个图层均非必传,所以你也可以只指定 前景/背景 单一图层的位移。

仓库已上传至 pub 通过依赖:

所有代码皆已上传至 github,其中演示程序 apk 可以直接下载运行,后面这个仓库还会更新一些交互式的小组件,给个点赞、关注、 star 不过分吧~


五、最后

本来是打算接着写网络编程,中途看到 自如客APP裸眼3D效果的实现 于是趁着周末赶紧实现了一下,再次感谢 自如团队 提供这么妙的创意。下一期,还是按照之前的计划,通过 广播/组播的方式实现一个基础的局域网多端群聊服务。

如果你有任何疑问可以通过公众号与联系我,如果文章对你有所启发,希望能得到你的点赞、关注和收藏,这是我持续写作的最大动力。Thanks~

公众号:进击的Flutter或者 runflutter 里面整理收集了最详细的Flutter进阶与优化指南,欢迎关注。

往期精彩内容:

Flutter 进阶优化

Flutter核心渲染机制

Flutter路由设计与源码解析

More Repositories

1

wechat_flutter

wechat_flutter is Flutter version WeChat, an excellent Flutter instant messaging IM open source library!
Dart
2,453
star
2

extended_image

A powerful official extension library of image, which support placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide out page, editor(crop,rotate,flip), paint custom etc.
Dart
1,850
star
3

NeteaseCloudMusic

Flutter - NeteaseCloudMusic Flutter 版本的网易云音乐
Dart
1,754
star
4

flutter_wechat_assets_picker

An image picker (also with video and audio) for Flutter projects based on the WeChat's UI.
Dart
1,422
star
5

flutter_smart_dialog

An elegant Flutter Dialog solution | 一种更优雅的 Flutter Dialog 解决方案
Dart
1,005
star
6

flutter_candies

custom flutter candies(widgets) for you to build flutter app easily, enjoy it
Dart
795
star
7

flutter_photo_manager

A Flutter plugin that provides images, videos, and audio abstraction management APIs without interface integration, available on Android, iOS, macOS and OpenHarmony..
Dart
634
star
8

extended_text

A powerful extended official text for Flutter, which supports Speical Text(Image,@somebody), Custom Background, Custom overFlow, Text Selection.
Dart
622
star
9

flutter_image_compress

flutter image compress
Dart
602
star
10

extended_nested_scroll_view

extended nested scroll view to fix following issues. 1.pinned sliver header issue 2.inner scrollables in tabview sync issue 3.pull to refresh is not work. 4.do without ScrollController in NestedScrollView's body
Dart
576
star
11

FlutterJsonBeanFactory

What I do is generate dart beans based on json, as well as generics parameters and json build instances
Kotlin
560
star
12

extended_text_field

extended official text field to quickly build special text like inline image, @somebody, custom background etc.
Dart
532
star
13

flutter_custom_calendar

Flutter的一个日历控件
Dart
497
star
14

like_button

Like Button is a flutter library that allows you to create a button with animation effects similar to Twitter's heart when you like something and animation effects to increase like count.
Dart
436
star
15

flutter_image_editor

Flutter plugin, support android/ios.Support crop, flip, rotate, color martix, mix image, add text. merge multi images.
Dart
391
star
16

JsonToDart

The tool to convert json to dart code, support Windows,Mac,Web.
Dart
353
star
17

flutter_scrollview_observer

A widget for observing data related to the child widgets being displayed in a ScrollView. Maintainer: @LinXunFeng
Dart
349
star
18

waterfall_flow

A Flutter grid view which supports waterfall flow layout.
Dart
345
star
19

flutter_wechat_camera_picker

A camera picker (take photos and videos) for Flutter projects based on WeChat's UI. It's a standalone module of wechat_assets_picker yet it can be run separately.
Dart
335
star
20

loading_more_list

A loading more list which supports ListView,GridView,WaterfallFlow and Slivers.
Dart
331
star
21

ncov_2019

An online query App for COVID-19 statistics developed by Flutter was used.
Dart
256
star
22

extended_tabs

A powerful official extension library of Tab/TabBar/TabView, which support to scroll ancestor or child Tabs when current is overscroll, and set scroll direction and cache extent.
Dart
254
star
23

flutter-interactive-chart

A candlestick chart that supports pinch-to-zoom and panning.
Dart
191
star
24

pull_to_refresh_notification

Flutter plugin for building pull to refresh effects with PullToRefreshNotification and PullToRefreshContainer quickly.
Dart
183
star
25

extended_sliver

A powerful extension library of Sliver, which include SliverToNestedScrollBoxAdapter, SliverPinnedPersistentHeader, SliverPinnedToBoxAdapter and ExtendedSliverAppbar.
Dart
157
star
26

extended_image_library

package library for extended_image, extended_text and extended_text_field,provide common base class.
Dart
146
star
27

flutter_drawing_board

A new Flutter package of drawing board
Dart
137
star
28

ff_annotation_route

Provide route generator to create route map quickly by annotations.
Dart
118
star
29

flutter_filereader

Flutter实现的本地文件(pdf word excel 等)查看插件,非在线预览
Dart
109
star
30

flutter_tilt

👀 Easily apply tilt parallax hover effects for Flutter, which supports tilt, light, shadow effects, and gyroscope sensors | 为 Flutter 轻松创建倾斜视差悬停效果,支持倾斜、光照、阴影效果和陀螺仪传感器
Dart
105
star
31

nav_router

flutter The lightest, easiest and most convenient route management!
Dart
103
star
32

w_popup_menu

w_popup_menu # A pop-up menu that mimics the iOS WeChat page
Dart
90
star
33

left-scroll-actions

Flutter的左滑删除组件
Dart
82
star
34

flutter_asset_generator

Generate an R file for mapping all assets. Supports preview of image.
Dart
79
star
35

extended_text_library

extended_text_library for extended_text and extended_text_field
Dart
74
star
36

flutter_hsvcolor_picker

An HSV color picker designed for your Flutter app. Pickers: RGB, HSV, Color Wheel, Palette Hue, Palette Saturation, Palette Value, Swatches.
Dart
65
star
37

stack_board

层叠控件摆放
Dart
60
star
38

no-free-usage-action

A NO-FREE-USAGE action for github. (Only worked with github action.)
Dart
60
star
39

flex_grid

The FlexGrid control provides a powerful and quickly way to display data in a tabular format. It is including that frozened column/row,loading more, high performance and better experience in TabBarView/PageView.
Dart
57
star
40

extended_list

extended list(ListView/GridView) support track collect garbage of children/viewport indexes, build lastChild as special child in the case that it is loadmore/no more item and enable to layout close to trailing.
Dart
50
star
41

flutter_juejin

https://juejin.cn in Flutter
Dart
48
star
42

gitcandies

A GitHub Flutter application.
Dart
47
star
43

fconsole

一个用于调试的面板
Dart
44
star
44

ripple_backdrop_animate_route

A ripple animation with backdrop of route.
Dart
44
star
45

flutter_ali_auth

Flutter Ali Auth Plugin 阿里云一键登录Flutter插件
Java
42
star
46

flutter_apodidae

🔥🔥 收录 Flutter 优化合集,apodidae (雨燕)是飞翔速度最快的鸟类,与 flutter (颤动)不谋而合。
40
star
47

flutter_bdface_collect

a baidu face offline collect plugin. Only Android and IOS platforms are supported. 百度人脸离线采集插件,只支持安卓和iOS。
Objective-C
35
star
48

flutter_record_mp3

flutter record mp3 using the native api
Dart
34
star
49

assets_generator

The flutter tool to generate assets‘s configs(yaml) and consts automatically for single project and multiple modules.
Dart
34
star
50

flutter_draggable_container

A Draggable Widget Container
Dart
27
star
51

flutter_qweather

和风天气 Flutter 插件
Dart
26
star
52

baidupan

Baidu net disk api for dart, 百度网盘的 dart 库
Dart
26
star
53

flutter_switch_clipper

A Flutter package that two widgets switch with clipper.
Dart
24
star
54

http_client_helper

A Flutter plugin for http request with cancel and retry fuctions.
Dart
24
star
55

dash_painter

a package for flutter canvas paint dash line path easily.
Dart
23
star
56

flutter_slider_view

A slider view widget that supports custom type models and various configs.
Dart
21
star
57

flutter_live_activities

Flutter Live Activities Plugin
Dart
21
star
58

extra_hittest_area

Manually add the extra hitTest area of a widget without changing its size or layout.
Dart
17
star
59

ios_willpop_transition_theme

A Flutter package to solve the conflict between ios sliding back and Willpop
Dart
17
star
60

flutter_learning_tests

学习 Flutter 路上的点滴及小测~
Dart
16
star
61

flutter_mlkit_scan_plugin

Kotlin
15
star
62

should_rebuild

Dart
14
star
63

saver_gallery

Kotlin
12
star
64

candies_analyzer_plugin

The plugin to help create custom analyzer plugin quickly and provide some useful lints and get suggestion and auto import for extension member.
Dart
12
star
65

flutter_candies_gallery

flutter_candies
Dart
11
star
66

scan_barcode

Barcode/QRCode scan, base of google mikit.
Dart
11
star
67

CandiesBot

Java
11
star
68

packages

Custom Flutter Candies (packages) for you to easily build your Flutter app. Enjoy it!
11
star
69

flutter_float_window

flutter_float_window是一个悬浮窗插件,具备悬浮窗权限申请等功能
Java
11
star
70

extended_list_library

package library for extended_list and waterfall_flow, it provides core classes.
Dart
10
star
71

photo_widget

Base on photo_manager, wraps up some UI components to quickly display the photo_manager as a usable widget, inserting it wherever you need it.
Dart
10
star
72

flutter_app_build_tool

A CLI tool that helps to build Flutter apps.
Dart
9
star
73

douget

Dart
9
star
74

flutter_custom_inspector

A customizable inspector that can called directly through Flutter apps.
Dart
8
star
75

adaptation

Screen for adaptation.
C++
8
star
76

ff_native_screenshot

A Flutter plugin to take or listen screenshot(support Platform Views) for Android and iOS with native code.
Java
8
star
77

coordtransform

A coord transform tool. 提供百度坐标系(BD-09)、火星坐标系(国测局坐标系、GCJ02)、WGS84坐标系的相互转换。
Dart
8
star
78

properties

Load properties format in dart or flutter
Dart
7
star
79

w_reorder_list

Dart
7
star
80

JsonToDartWeb

JsonToDart Web 带字体文件
7
star
81

flutter_candies_demo_library

package library for demo of flutter candies, it provides core classes.
Dart
7
star
82

JsonToDartFlutterWeb

6
star
83

sync_scroll_library

The library for extended_tabs and flex_grid
Dart
5
star
84

env2dart

A simple way to generate `dart` code from a `.env` file.
Dart
5
star
85

loading_more_list_library

dart package library for LoadingMoreList, it provides core classes.
Dart
5
star
86

flutter_challenges

Just do the first one, don't do second who.
Dart
4
star
87

dext

Some extension for dart
Dart
4
star
88

flutter_candies_package_tools

tool to create package and demo
Dart
4
star
89

flutter_clean

help clean all of Flutter and Dart projects
Dart
3
star
90

simple_provider

flutter simple provider
Dart
3
star
91

ff_annotation_route_library

The library for ff_annotation_route
Dart
3
star
92

upgrade_tool

Resolve warnings caused by xxxbinding. Instance in Flutter 3.0
Dart
2
star
93

note_edit

A library of flutter note editor plugins.
Dart
2
star
94

blue_flutter

blue_flutter是flutter的蓝牙通讯插件
Java
2
star
95

ff_annotation_route_core

The core library for ff_annotation_route
Dart
2
star
96

dart_wake_on_lan

A CLI application to send Wake-On-Lan packets.
Dart
2
star
97

maven

Organizational maven deploy;组织的maven仓库;
1
star
98

.github-workflow

Run some workflows for the organization.
Python
1
star
99

flutter_photo_manager_plugins

Extra plugins for the photo_manager plugin.
C++
1
star
100

flutter_bindings_compatible

Provides compatible bindings instance across different Flutter version.
C++
1
star