△ 未镜像的视图

△ 镜像视图

保持宽高比

在大屏幕上保持 4:3 宽高比,以及在小屏幕上保持 3:4 宽高比,这个操作起来比看起来更难!保持宽高比非常重要,既要符合 Web 应用的整体设计,又要确保在社交媒体上分享照片时,令其中的像素呈现出清晰的本色效果。这是一项具有挑战性的任务,因为不同设备上内置摄像头的宽高比差异很大。

为了强制保持宽高比,应用首先使用 JavaScript getUserMedia API 从设备摄像头请求可能的最大分辨率。随后,我们将此 API 传递到 VideoElement 流中,这便是您在摄像头视图中看到的内容 (当然是已镜像的版本)。我们还应用了 object-fit CSS 属性来确保视频元素能盖住其父级容器。我们使用 Flutter 自带的 AspectRatio widget 来设置宽高比。因此,摄像头不会对显示的宽高比做出任何假设;它始终返回支持的最大分辨率,然后遵守 Flutter 提供的约束条件 (在本例中为 4:3 或 3:4)。

final orientation = MediaQuery.of(context).orientation;
final aspectRatio = orientation == Orientation.portrait
? PhotoboothAspectRatio.portrait
: PhotoboothAspectRatio.landscape;
return Scaffold(
body: _PhotoboothBackground(
aspectRatio: aspectRatio,
child: Camera(
controller: controller,
placeholder: (
) => const SizedBox(),
preview: (context, preview) => PhotoboothPreview(
preview: preview,
onSnapPressed: () => _onSnapPressed(
aspectRatio: aspectRatio,
),
),
error: (context, error) => PhotoboothError(error: error),
),
),
);

通过拖放添加贴纸

I/O 照相亭的一大重要体验在于与您最喜欢的 Google 吉祥物合影并添加道具。您能够在照片中拖放吉祥物和道具,以及调整大小和旋转,直到获得您喜欢的图像。您也会发现,在将吉祥物添加到屏幕上时,您可以拖动它们并调整其大小。吉祥物们还是有动画效果的——这种效果由 sprite sheet 来实现。

for (final character in state.characters)
DraggableResizable(
canTransform: character.id == state.selectedAssetId,
onUpd
ate: (update) {
context.read().add(
PhotoCharacterDragged(
character: character,
update: update,
),
);
},
child: _AnimatedCharacter(name: character.asset.name),
),

为调整对象的大小,我们创建了可拖动、可调整大小且可以容纳其他 Flutter widget 的 widget,在本例中,即为吉祥物和道具。该 widget 会使用 LayoutBuilder,根据窗口的约束条件来处理 widget 的缩放。在内部,我们使用 GestureDetector 以挂接到 onScaleStart、onScaleUpdate 和 onScaleEnd 事件。这些回调提供了必要的手势详细信息,以反映用户对吉祥物和道具的操作。

通过多个 GestureDetector 回馈的数据,Transform widget 和 4D 矩阵变换即可根据用户所做的各种手势处理缩放,以及旋转吉祥物和道具。

Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
…scale(scale)
…rotateZ(angle),
child: _DraggablePoint(…),
)

最后,我们创建了单独的 package 来确定您的设备是否支持触摸输入。可拖动、可调整大小的 widget 会根据触摸功能做出相应的调整。在具有触摸输入功能的设备上,您并不能看到调整大小的锚点和旋转图标,因为您可以通过双指张合和平移手势来直接操纵图像;而在不支持触摸输入的设备 (例如您的桌面设备) 上,我们则添加了锚点和旋转图标,以适应单击和拖动操作。

针对 Web 优化 Flutter

使用 Flutter 针对 Web 进行开发

这是我们使用 Flutter 构建的首批纯 Web 项目之一,其与移动应用具有不同的特征。

我们需要确保该应用对任何设备上的任何浏览器都具有 响应性和自适应性。也就是说,我们必须确保 I/O 照相亭可以根据浏览器大小进行缩放,并且能够处理移动设备和 Web 端的输入。我们通过以下几种方式做到了这一点:

  • 响应式调整大小: 用户能够随意调整浏览器的大小,并且界面能做出响应。如果您的浏览器窗口为纵向,则相机会从 4:3 的横向视图翻转为 3:4 的纵向视图。
  • 响应式设计: 针对桌面浏览器,我们设计为在右侧显示 Dash、Android Jetpack、Dino 和 Sparky,而对于移动设备,这些要素则会显示在顶部。我们针对桌面设备,在摄像头右侧设计使用了抽屉式导航栏,而对于移动设备,则使用了 BottomSheet 类。
  • 自适应输入: 如果您使用桌面设备访问 I/O 照相亭,则鼠标点击操作将被视为输入,如果您使用的是平板电脑或手机,则使用触摸输入。在调整贴纸大小并将其放置在照片中时,这一点尤其重要。移动设备支持双指张合和平移手势,桌面设备支持点击和拖动操作。

可扩展架构

我们还为此应用构建了可扩展的移动应用。我们的 I/O 照相亭在创建之初就具有稳固的基础,包括良好的空安全性、国际化,以及从第一次提交开始就做到的 100% 单元和 widget 测试覆盖率。我们使用 flutter_bloc 进行状态管理,因为它支持我们轻松测试业务逻辑,并观察应用中的所有状态变化。这对于生成开发者日志和确保可追溯性特别有用,因为我们可以准确地观察到从一个状态到另一个状态的变化,并更快地隔离问题。

我们还实现了由功能驱动的单一代码库结构。例如,贴纸、分享和实时相机预览,均在各自的文件夹中得到实现,其中每个文件夹包含其各自的界面组件和业务逻辑。这些功能也会用到外部依赖,例如位于 package 子目录中的相机插件。利用这种架构,我们的团队能够在互不干扰的情况下并行处理多个功能,最大限度地减少合并冲突,并有效地重用代码。例如,界面组件库是名为 photobooth_ui 的单独 package,相机插件也是单独的。

通过将组件分成独立的 package,我们可以提取未与此特定项目绑定的各个组件,并将其开源。与 Material 和 Cupertino 组件库类似,我们甚至可以将界面组件库 package 做开源处理,以供 Flutter 社区使用。

Firebase + Flutter = 完美组合

Firebase Auth、存储、托管等

照相亭利用 Firebase 生态系统进行各种后端集成。firebase_auth package 支持用户在应用启动后立即匿名登录。每个会话都使用 Firebase Auth 创建具有唯一 ID 的匿名用户。

当您来到共享页面时,此设置即会开始发挥作用。您可以下载照片以保存为个人头像,也可以直接将其分享到社交媒体。如果您下载照片,则该照片将存储在您的本地设备上。如果您分享照片,我们会使用 firebase_storage package 将照片存储在 Firebase 中,以便稍后检索并生成帖子通过社交媒体发布。

我们在 Firebase 的存储分区上定义了 Firebase 安全规则,确保照片在创建后不可变。这可以防止其他用户修改或删除存储分区中的照片。此外,我们使用 Google Cloud 提供的 对象生命周期管理,定义了一个删除 30 天前所有对象的规则,但您可以按照应用中列出的说明请求尽快删除您的照片。

此应用还使用 Firebase Hosting 快速安全地进行托管。我们可以借助 action-hosting-deploy GitHub Action,根据目标分支,将应用自动部署到 Firebase Hosting。当我们将变更合并到主分支时,该操作会触发一个工作流,用于构建应用的特定开发版本,并将其部署到 Firebase Hosting。同样,当我们将变更合并到发布分支时,该操作也会触发部署生产版本。通过结合使用 GitHub Action 与 Firebase Hosting,我们的团队能够快速迭代,并始终得到最新版本的预览。

最后,我们使用 Firebase 性能监测 来监控主要的 Web 性能指标。

使用 Cloud Functions 进行社交

在生成您的社交帖子之前,我们首先会确保照片内容是像素级完美的。最终图像包含漂亮的边框,以呈现 I/O 照相亭特色,并按 4:3 或 3:4 的宽高比进行裁剪,以便在社交帖子上呈现出色的效果。

我们使用 OffscreenCanvas API 或 CanvasElement 来合成原始照片、吉祥物和道具的图层,并生成您可以下载的单个图像。这个处理步骤由 image_compositor package 负责执行。

然后,我们利用 Firebase 强大的 Cloud Functions,来将照片分享到社交媒体。当您点击分享按钮时,系统会带您前往新标签页,并在所选的社交平台上自动生成待发布的帖子。该帖子还包含一个链接,连接到我们编写的 Cloud Functions。浏览器在分析网址时,会检测 Cloud Functions 生成的动态元数据,并据此在您的社交帖子中显示照片的精美预览,以及一个指向分享页面的链接,您的粉丝们可以在该页面上查看照片,并导航回 I/O 照相亭应用,以获取他们自己的照片。

function renderSharePage(imageFileName: string, baseUrl: string): string {
const context = Object.assign({}, BaseHTMLContext, {
appUrl: baseUrl,
shareUrl: ${baseUrl}/share/${imageFileName},
shareImageUrl: bucketPathForFile(${UPLOAD_PATH}/${imageFileName}),
});
Url,
shareUrl: ${baseUrl}/share/${imageFileName},
shareImageUrl: bucketPathForFile(${UPLOAD_PATH}/${imageFileName}),
});

用 Flutter 和 Firebase 轻松构建 Web 应用,秀出天际相关推荐

  1. 用 Flutter 和 Firebase 轻松构建 Web 应用

    作者 / Very Good Ventures Team 我们 (Very Good Ventures 团队) 与 Google 合作,在今年的 Google I/O 大会上推出了 照相亭互动体验[1 ...

  2. I/O 照相亭 | Flutter + Firebase = 轻松构建 Web 应用

    作者 / Very Good Ventures Team 我们 (Very Good Ventures 团队) 与 Google 合作,在今年的 Google I/O 大会上推出了照相亭互动体验 (I ...

  3. Flutter 2.0 发布 | 针对 Web,移动端和桌面端构建的下一代 Flutter

    Flutter 2.0 发布 | 针对 Web,移动端和桌面端构建的下一代 Flutter 英文原文地址:https://developers.googleblog.com/2021/03/annou ...

  4. 使用 Flutter 与 Firebase 制作 I/O 弹球游戏

    文/ Very Good Ventures 团队,5 月 11 日发表于 Flutter 官方博客 为了今年的 Google I/O 大会,Flutter 团队使用 Flutter 以及 Fireba ...

  5. maven(3)------maven构建web项目详细步骤

    eclipse集成工具,轻松通过maven构建web项目步骤如下: 一, 右键,new -->project, 进入下一页面 二,选择"Maven Project", 点击下 ...

  6. Spring-Spring MVC + Spring JDBC + Spring Transaction + Maven 构建web登录模块

    概述 功能简介 环境准备 构建工具Maven 数据库脚本Oracle 建立工程 类包及Spring配置文件规划 持久层 建立领域对象 用户领域对象 登录日志领域对象 UserDao LoginLogD ...

  7. winserver2016 401您无权使用所提供的凭据查看此目录或页面_不用找了,30分钟帮你搞定使用 Spring Cloud 和 Docker 轻松构建微服务架构!...

    点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] [编者的话]如何使用Spring Boot.Spring Cloud.Docker和Netflix的一些开源工具来构建一个微服务架构.本文 ...

  8. 还没使用过Web Worker? 推荐一款开源工具Workerize-Loader,让你在webpack项目中轻松使用Web Worker

    还没使用过Web Worker? 推荐一款开源工具Workerize-Loader,让你在webpack项目中轻松使用Web Worker Workerize-Loader 将模块及其依赖项移动到 W ...

  9. idea自动构建web项目_构建Web应用程序以自动执行系统管理员任务

    idea自动构建web项目 系统管理员(sysadmin)每年在重复性任务上浪费数千小时. 幸运的是,使用开源工具构建的Web应用程序可以自动消除很大一部分痛苦. 例如,使用Python和JavaSc ...

最新文章

  1. 工信部 学习类app_工信部整治APP侵权行为,私自收集个人信息等8类问题被点名...
  2. Java凝视Annotation
  3. activity切换交互动画
  4. ajax 访问mysql_AJAX 数据库实例
  5. Maven 配置文件 POM 的常用依赖配置代码
  6. LCD显示实验----STM32f4--HAL
  7. 手机浏览器网址_打开URL(在其他应用中访问网址)app下载-打开URL(在其他应用中访问网址)v2.6安卓版下载...
  8. javascript对话框_JavaScript中的对话框
  9. 全球最畅销的10款手机:iPhone 11继续无敌,能对拼的只有它!
  10. ipad safari php readfile mp4,php – 在mac上的safari中没有加载Wav文件
  11. 软件工程-软件小组的组织形式
  12. 中国专利电子申请网CPC客户端的安装教程
  13. 华为 android 5.0系统下载地址,Emui5.0+Android 华为Nova内测包
  14. 链接测试工具-Xenu
  15. 中国医科大学2021年9月《社区护理学》作业考核试题
  16. 《关键对话》思维导图
  17. android edittext怎么输入中文,为什么android中edittext不能输入中文
  18. Excel中CTRL+D的别样用法 隔行和隔列向下填充示例
  19. 电报加密C语言版(字符串整体后移一位的方法)
  20. 编程的技术|艺术|术术——面向开发者编程

热门文章

  1. 【编程题】【Scratch二级】2020.06 别碰红块
  2. 用SymPy验证圆锥曲线性质
  3. Oracle EBS 导出EXCEL文件CSS样式应用
  4. 若父设置了overflow: hidden;子如何不受影响
  5. java毕业设计离散制造业产品销售管理系统mybatis+源码+调试部署+系统+数据库+lw
  6. 两个颜色叠加之后是什么颜色
  7. Python正则表达式书写容易碰到的陷阱:\W*和\W*?匹配过程遇到的问题
  8. 马云回应淘宝造假指责:淘宝不生成假货
  9. Linux根文件系统(rootfs原理详解)
  10. 讲讲PCA主成分分析