这是indexloc提供的服务,不要输入任何密码
Sitemap
Flutter

Flutter is Google's UI framework for crafting high-quality native interfaces on iOS, Android, web, and desktop. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Learn more at https://flutter.dev

How It’s Made: I/O Photo Booth

11 min readMay 17, 2021

--

Zoom image will be displayed
Zoom image will be displayed
Flutter’s Dash, Firebase’s Sparky, Android Jetpack, and Chrome’s Dino

Making a virtual photo booth with Flutter

Building a Flutter camera plugin for the web

Future<CameraImage> takePicture() async {
final videoWidth = videoElement.videoWidth;
final videoHeight = videoElement.videoHeight;
final canvas = html.CanvasElement(
width: videoWidth,
height: videoHeight,
);
canvas.context2D
..translate(videoWidth, 0)
..scale(-1, 1)
..drawImageScaled(videoElement, 0, 0, videoWidth, videoHeight);
final blob = await canvas.toBlob();
return CameraImage(
data: html.Url.createObjectUrl(blob),
width: videoWidth,
height: videoHeight,
);
}

Camera permissions

Camera(
controller: _controller,
placeholder: (_) => const SizedBox(),
preview: (context, preview) => PhotoboothPreview(
preview: preview,
onSnapPressed: _onSnapPressed,
),
error: (context, error) => PhotoboothError(error: error),
)

Mirroring the photo

Zoom image will be displayed
Un-mirrored view
Zoom image will be displayed
Mirrored view

Sticking to a strict aspect ratio

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),
),
),
);

Adding friends and stickers with drag and drop

for (final character in state.characters)
DraggableResizable(
canTransform: character.id == state.selectedAssetId,
onUpdate: (update) {
context.read<PhotoboothBloc>().add(
PhotoCharacterDragged(
character: character,
update: update,
),
);
},
child: _AnimatedCharacter(name: character.asset.name),
),
Transform(
alignment: Alignment.center,
transform: Matrix4.identity()
..scale(scale)
..rotateZ(angle),
child: _DraggablePoint(...),
)
Zoom image will be displayed

Prioritizing Flutter on the web

Web-first development with Flutter

Scalable architecture

Firebase + Flutter = A perfect match

Firebase Auth, storage, hosting, and more

Getting social with Cloud Functions

function renderSharePage(imageFileName: string, baseUrl: string): string {
const context = Object.assign({}, BaseHTMLContext, {
appUrl: baseUrl,
shareUrl: `${baseUrl}/share/${imageFileName}`,
shareImageUrl: bucketPathForFile(`${UPLOAD_PATH}/${imageFileName}`),
});
return renderTemplate(shareTmpl, context);
}
Zoom image will be displayed

Final product

Zoom image will be displayed
Very Good Ventures team who worked on I/O Photo Booth

--

--

Flutter
Flutter

Published in Flutter

Flutter is Google's UI framework for crafting high-quality native interfaces on iOS, Android, web, and desktop. Flutter works with existing code, is used by developers and organizations around the world, and is free and open source. Learn more at https://flutter.dev

Very Good Ventures
Very Good Ventures

Written by Very Good Ventures

Very Good Ventures (https://verygood.ventures), a leading Flutter app development consultancy -- building successful experiences for all.

Responses (5)